CoreModule.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. * Copyright (C) 2024 Puter Technologies Inc.
  3. *
  4. * This file is part of Puter.
  5. *
  6. * Puter is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License as published
  8. * by the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Affero General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Affero General Public License
  17. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. const { AdvancedBase } = require("@heyputer/puter-js-common");
  20. const { Context } = require('./util/context');
  21. class CoreModule extends AdvancedBase {
  22. async install (context) {
  23. const services = context.get('services');
  24. const app = context.get('app');
  25. await install({ services, app });
  26. }
  27. // Some services were created before the BaseService
  28. // class existed. They don't listen to the init event
  29. // and the order in which they're instantiated matters.
  30. // They all need to be installed after the init event
  31. // is dispatched, so they get a separate install method.
  32. async install_legacy (context) {
  33. const services = context.get('services');
  34. await install_legacy({ services });
  35. }
  36. }
  37. module.exports = CoreModule;
  38. const install = async ({ services, app }) => {
  39. const config = require('./config');
  40. // /!\ IMPORTANT /!\
  41. // For new services, put the import immediate above the
  42. // call to services.registerService. We'll clean this up
  43. // in a future PR.
  44. const { LogService } = require('./services/runtime-analysis/LogService');
  45. const { PagerService } = require('./services/runtime-analysis/PagerService');
  46. const { AlarmService } = require('./services/runtime-analysis/AlarmService');
  47. const { ErrorService } = require('./services/runtime-analysis/ErrorService');
  48. const { CommandService } = require('./services/CommandService');
  49. const { ExpectationService } = require('./services/runtime-analysis/ExpectationService');
  50. const { HTTPThumbnailService } = require('./services/thumbnails/HTTPThumbnailService');
  51. const { PureJSThumbnailService } = require('./services/thumbnails/PureJSThumbnailService');
  52. const { NAPIThumbnailService } = require('./services/thumbnails/NAPIThumbnailService');
  53. const { DevConsoleService } = require('./services/DevConsoleService');
  54. const { RateLimitService } = require('./services/sla/RateLimitService');
  55. const { MonthlyUsageService } = require('./services/sla/MonthlyUsageService');
  56. const { AuthService } = require('./services/auth/AuthService');
  57. const { SLAService } = require('./services/sla/SLAService');
  58. const { PermissionService } = require('./services/auth/PermissionService');
  59. const { ACLService } = require('./services/auth/ACLService');
  60. const { CoercionService } = require('./services/drivers/CoercionService');
  61. const { PuterSiteService } = require('./services/PuterSiteService');
  62. const { ContextInitService } = require('./services/ContextInitService');
  63. const { IdentificationService } = require('./services/abuse-prevention/IdentificationService');
  64. const { AuthAuditService } = require('./services/abuse-prevention/AuthAuditService');
  65. const { RegistryService } = require('./services/RegistryService');
  66. const { RegistrantService } = require('./services/RegistrantService');
  67. const { SystemValidationService } = require('./services/SystemValidationService');
  68. const { EntityStoreService } = require('./services/EntityStoreService');
  69. const SQLES = require('./om/entitystorage/SQLES');
  70. const ValidationES = require('./om/entitystorage/ValidationES');
  71. const { SetOwnerES } = require('./om/entitystorage/SetOwnerES');
  72. const AppES = require('./om/entitystorage/AppES');
  73. const WriteByOwnerOnlyES = require('./om/entitystorage/WriteByOwnerOnlyES');
  74. const SubdomainES = require('./om/entitystorage/SubdomainES');
  75. const { MaxLimitES } = require('./om/entitystorage/MaxLimitES');
  76. const { AppLimitedES } = require('./om/entitystorage/AppLimitedES');
  77. const { ESBuilder } = require('./om/entitystorage/ESBuilder');
  78. const { Eq, Or } = require('./om/query/query');
  79. const { TrackSpendingService } = require('./services/TrackSpendingService');
  80. const { ServerHealthService } = require('./services/runtime-analysis/ServerHealthService');
  81. const { MakeProdDebuggingLessAwfulService } = require('./services/MakeProdDebuggingLessAwfulService');
  82. const { ConfigurableCountingService } = require('./services/ConfigurableCountingService');
  83. const { FSLockService } = require('./services/fs/FSLockService');
  84. const { StrategizedService } = require('./services/StrategizedService');
  85. const WebServerService = require('./services/WebServerService');
  86. const FilesystemAPIService = require('./services/FilesystemAPIService');
  87. const ServeGUIService = require('./services/ServeGUIService');
  88. const PuterAPIService = require('./services/PuterAPIService');
  89. const { RefreshAssociationsService } = require("./services/RefreshAssociationsService");
  90. // Service names beginning with '__' aren't called by other services;
  91. // these provide data/functionality to other services or produce
  92. // side-effects from the events of other services.
  93. // === Services which extend BaseService ===
  94. services.registerService('system-validation', SystemValidationService);
  95. services.registerService('server-health', ServerHealthService);
  96. services.registerService('log-service', LogService);
  97. services.registerService('commands', CommandService);
  98. services.registerService('web-server', WebServerService, { app });
  99. services.registerService('__api-filesystem', FilesystemAPIService);
  100. services.registerService('__api', PuterAPIService);
  101. services.registerService('__gui', ServeGUIService);
  102. services.registerService('expectations', ExpectationService);
  103. services.registerService('pager', PagerService);
  104. services.registerService('alarm', AlarmService);
  105. services.registerService('error-service', ErrorService);
  106. services.registerService('registry', RegistryService);
  107. services.registerService('__registrant', RegistrantService);
  108. services.registerService('fslock', FSLockService);
  109. services.registerService('es:app', EntityStoreService, {
  110. entity: 'app',
  111. upstream: ESBuilder.create([
  112. SQLES, { table: 'app', debug: true, },
  113. AppES,
  114. AppLimitedES, {
  115. // When apps query es:apps, they're allowed to see apps which
  116. // are approved for listing and they're allowed to see their
  117. // own entry.
  118. exception: async () => {
  119. const actor = Context.get('actor');
  120. return new Or({
  121. children: [
  122. new Eq({
  123. key: 'approved_for_listing',
  124. value: 1,
  125. }),
  126. new Eq({
  127. key: 'uid',
  128. value: actor.type.app.uid,
  129. }),
  130. ]
  131. });
  132. },
  133. },
  134. WriteByOwnerOnlyES,
  135. ValidationES,
  136. SetOwnerES,
  137. MaxLimitES, { max: 50 },
  138. ]),
  139. });
  140. services.registerService('es:subdomain', EntityStoreService, {
  141. entity: 'subdomain',
  142. upstream: ESBuilder.create([
  143. SQLES, { table: 'subdomains', debug: true, },
  144. SubdomainES,
  145. AppLimitedES,
  146. WriteByOwnerOnlyES,
  147. ValidationES,
  148. SetOwnerES,
  149. MaxLimitES, { max: 50 },
  150. ]),
  151. });
  152. services.registerService('rate-limit', RateLimitService);
  153. services.registerService('monthly-usage', MonthlyUsageService);
  154. services.registerService('auth', AuthService);
  155. services.registerService('permission', PermissionService);
  156. services.registerService('sla', SLAService);
  157. services.registerService('acl', ACLService);
  158. services.registerService('coercion', CoercionService);
  159. services.registerService('puter-site', PuterSiteService);
  160. services.registerService('context-init', ContextInitService);
  161. services.registerService('identification', IdentificationService);
  162. services.registerService('auth-audit', AuthAuditService);
  163. services.registerService('spending', TrackSpendingService);
  164. services.registerService('counting', ConfigurableCountingService);
  165. services.registerService('thumbnails', StrategizedService, {
  166. strategy_key: 'engine',
  167. strategies: {
  168. napi: [NAPIThumbnailService],
  169. purejs: [PureJSThumbnailService],
  170. http: [HTTPThumbnailService],
  171. }
  172. });
  173. services.registerService('__refresh-assocs', RefreshAssociationsService);
  174. services.registerService('__prod-debugging', MakeProdDebuggingLessAwfulService);
  175. if ( config.env == 'dev' ) {
  176. services.registerService('dev-console', DevConsoleService);
  177. }
  178. const { EventService } = require('./services/EventService');
  179. services.registerService('event', EventService);
  180. const { PuterVersionService } = require('./services/PuterVersionService');
  181. services.registerService('puter-version', PuterVersionService);
  182. const { SessionService } = require('./services/SessionService');
  183. services.registerService('session', SessionService);
  184. const { EdgeRateLimitService } = require('./services/abuse-prevention/EdgeRateLimitService');
  185. services.registerService('edge-rate-limit', EdgeRateLimitService);
  186. }
  187. const install_legacy = async ({ services }) => {
  188. const { ProcessEventService } = require('./services/runtime-analysis/ProcessEventService');
  189. const { ParameterService } = require('./services/ParameterService');
  190. const { InformationService } = require('./services/information/InformationService');
  191. const { FilesystemService } = require('./filesystem/FilesystemService');
  192. const PerformanceMonitor = require('./monitor/PerformanceMonitor');
  193. const { OperationTraceService } = require('./services/OperationTraceService');
  194. const { WSPushService } = require('./services/WSPushService');
  195. const { ReferralCodeService } = require('./services/ReferralCodeService');
  196. const { Emailservice } = require('./services/EmailService');
  197. const { ClientOperationService } = require('./services/ClientOperationService');
  198. const { EngPortalService } = require('./services/EngPortalService');
  199. const { AppInformationService } = require('./services/AppInformationService');
  200. const { FileCacheService } = require('./services/file-cache/FileCacheService');
  201. // === Services which do not yet extend BaseService ===
  202. services.registerService('process-event', ProcessEventService);
  203. services.registerService('params', ParameterService);
  204. services.registerService('information', InformationService)
  205. services.registerService('filesystem', FilesystemService);
  206. services.registerService('operationTrace', OperationTraceService);
  207. services.registerService('__event-push-ws', WSPushService);
  208. services.registerService('referral-code', ReferralCodeService);
  209. services.registerService('email', Emailservice);
  210. services.registerService('file-cache', FileCacheService);
  211. services.registerService('client-operation', ClientOperationService);
  212. services.registerService('app-information', AppInformationService);
  213. services.registerService('engineering-portal', EngPortalService);
  214. // TODO: add to here: ResourceService and DatabaseFSEntryService
  215. // This singleton was made before services existed,
  216. // so we have to pass that to it manually
  217. PerformanceMonitor.provideServices(services);
  218. };