@authup/server-core 1.0.0-beta.57 → 1.0.0-beta.58

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/dist/adapters/database/logger/module.mjs +2 -4
  2. package/dist/adapters/database/logger/module.mjs.map +1 -1
  3. package/dist/adapters/http/controllers/entities/identity-provider/module.d.ts.map +1 -1
  4. package/dist/adapters/http/controllers/entities/identity-provider/module.mjs +1 -1
  5. package/dist/adapters/http/controllers/entities/identity-provider/module.mjs.map +1 -1
  6. package/dist/adapters/http/middleware/built-in/authorization/module.mjs +2 -1
  7. package/dist/adapters/http/middleware/built-in/authorization/module.mjs.map +1 -1
  8. package/dist/adapters/http/middleware/built-in/rate-limit.mjs +2 -2
  9. package/dist/adapters/http/middleware/built-in/rate-limit.mjs.map +1 -1
  10. package/dist/adapters/http/request/client-certificate.mjs +1 -1
  11. package/dist/adapters/http/request/client-certificate.mjs.map +1 -1
  12. package/dist/adapters/http/request/helpers/locations.mjs +1 -3
  13. package/dist/adapters/http/request/helpers/locations.mjs.map +1 -1
  14. package/dist/app/modules/authentication/module.mjs +6 -3
  15. package/dist/app/modules/authentication/module.mjs.map +1 -1
  16. package/dist/app/modules/config/helpers.mjs +3 -2
  17. package/dist/app/modules/config/helpers.mjs.map +1 -1
  18. package/dist/app/modules/config/read/module.mjs +8 -3
  19. package/dist/app/modules/config/read/module.mjs.map +1 -1
  20. package/dist/app/modules/database/module.mjs +2 -1
  21. package/dist/app/modules/database/module.mjs.map +1 -1
  22. package/dist/app/modules/http/modules/controller.mjs +197 -126
  23. package/dist/app/modules/http/modules/controller.mjs.map +1 -1
  24. package/dist/app/modules/http/modules/middleware.mjs +10 -5
  25. package/dist/app/modules/http/modules/middleware.mjs.map +1 -1
  26. package/dist/app/modules/identity/module.mjs +6 -3
  27. package/dist/app/modules/identity/module.mjs.map +1 -1
  28. package/dist/app/modules/oauth2/module.mjs +37 -17
  29. package/dist/app/modules/oauth2/module.mjs.map +1 -1
  30. package/dist/app/modules/oauth2/repositories/authorize/state/repository.mjs +1 -1
  31. package/dist/app/modules/oauth2/repositories/authorize/state/repository.mjs.map +1 -1
  32. package/dist/app/modules/oauth2/repositories/token/repository.mjs +1 -1
  33. package/dist/app/modules/oauth2/repositories/token/repository.mjs.map +1 -1
  34. package/dist/app/modules/provisioning/module.mjs +9 -8
  35. package/dist/app/modules/provisioning/module.mjs.map +1 -1
  36. package/dist/app/modules/provisioning/sources/file/module.d.ts.map +1 -1
  37. package/dist/app/modules/provisioning/sources/file/module.mjs +11 -2
  38. package/dist/app/modules/provisioning/sources/file/module.mjs.map +1 -1
  39. package/dist/core/authentication/session/module.mjs +2 -4
  40. package/dist/core/authentication/session/module.mjs.map +1 -1
  41. package/dist/core/entities/client/service.d.ts.map +1 -1
  42. package/dist/core/entities/client/service.mjs +1 -1
  43. package/dist/core/entities/client/service.mjs.map +1 -1
  44. package/dist/core/entities/client-permission/service.mjs +12 -9
  45. package/dist/core/entities/client-permission/service.mjs.map +1 -1
  46. package/dist/core/entities/key/service.mjs +4 -2
  47. package/dist/core/entities/key/service.mjs.map +1 -1
  48. package/dist/core/entities/permission/service.d.ts.map +1 -1
  49. package/dist/core/entities/permission/service.mjs +1 -1
  50. package/dist/core/entities/permission/service.mjs.map +1 -1
  51. package/dist/core/entities/policy/service.d.ts.map +1 -1
  52. package/dist/core/entities/policy/service.mjs +3 -2
  53. package/dist/core/entities/policy/service.mjs.map +1 -1
  54. package/dist/core/entities/realm/service.d.ts.map +1 -1
  55. package/dist/core/entities/realm/service.mjs +1 -1
  56. package/dist/core/entities/realm/service.mjs.map +1 -1
  57. package/dist/core/entities/role/service.d.ts.map +1 -1
  58. package/dist/core/entities/role/service.mjs +1 -1
  59. package/dist/core/entities/role/service.mjs.map +1 -1
  60. package/dist/core/entities/role-permission/service.mjs +12 -9
  61. package/dist/core/entities/role-permission/service.mjs.map +1 -1
  62. package/dist/core/entities/scope/service.d.ts.map +1 -1
  63. package/dist/core/entities/scope/service.mjs +1 -1
  64. package/dist/core/entities/scope/service.mjs.map +1 -1
  65. package/dist/core/entities/user/service.d.ts.map +1 -1
  66. package/dist/core/entities/user/service.mjs +1 -1
  67. package/dist/core/entities/user/service.mjs.map +1 -1
  68. package/dist/core/entities/user-authenticator/helpers.mjs +1 -1
  69. package/dist/core/entities/user-authenticator/helpers.mjs.map +1 -1
  70. package/dist/core/entities/user-authenticator/service.mjs +7 -7
  71. package/dist/core/entities/user-authenticator/service.mjs.map +1 -1
  72. package/dist/core/entities/user-permission/service.mjs +12 -9
  73. package/dist/core/entities/user-permission/service.mjs.map +1 -1
  74. package/dist/core/identity/password-recovery/service.mjs +1 -1
  75. package/dist/core/identity/password-recovery/service.mjs.map +1 -1
  76. package/dist/core/provisioning/synchronizer/client/module.mjs +0 -1
  77. package/dist/core/provisioning/synchronizer/client/module.mjs.map +1 -1
  78. package/dist/core/provisioning/synchronizer/permission/module.mjs +0 -1
  79. package/dist/core/provisioning/synchronizer/permission/module.mjs.map +1 -1
  80. package/dist/core/provisioning/synchronizer/realm/module.mjs +0 -1
  81. package/dist/core/provisioning/synchronizer/realm/module.mjs.map +1 -1
  82. package/dist/core/provisioning/synchronizer/role/module.mjs +0 -1
  83. package/dist/core/provisioning/synchronizer/role/module.mjs.map +1 -1
  84. package/dist/core/provisioning/synchronizer/scope/module.mjs +0 -1
  85. package/dist/core/provisioning/synchronizer/scope/module.mjs.map +1 -1
  86. package/dist/core/provisioning/synchronizer/user/module.mjs +0 -1
  87. package/dist/core/provisioning/synchronizer/user/module.mjs.map +1 -1
  88. package/dist/path.mjs.map +1 -1
  89. package/dist/swagger.json +435 -11
  90. package/dist/ui/client/.vite/ssr-manifest.json +172 -10
  91. package/dist/ui/client/assets/index-BTK3GPZZ.js +106 -0
  92. package/dist/ui/client/assets/{index-Bk6-OZy9.css → index-Cx_pI7BS.css} +1 -1
  93. package/dist/ui/client/index.html +2 -2
  94. package/dist/ui/server/server.js +1894 -5045
  95. package/package.json +25 -24
  96. package/dist/ui/client/assets/index-DO6_7NTJ.js +0 -106
@@ -1 +1 @@
1
- {"version":3,"file":"module.mjs","names":["DomainEventPublisher","DomainEventRedisHandler","DomainEventSocketHandler","createRedisClient","AuthupError","DataSource","InstanceChecker","checkDatabase","createDatabase","synchronizeDatabaseSchema","DataSourceOptionsBuilder","DatabaseQueryResultCache","EntitySubscriber","EventEntity","isDatabaseTypeSupported","isDatabaseTypeSupportedForEnvironment","EntityEventHandler","EventService","useRequestEventContext","EventRepositoryAdapter","validateEntitySchemas","CacheInjectionKey","ModuleName","DatabaseInjectionKey","ConfigInjectionKey","LoggerInjectionKey","DatabaseModule","name","dependencies","optionsBuilder","options","eventRedisClient","eventPublisher","DATABASE","CONFIG","LOGGER","setup","container","logger","resolve","prepareBuild","dataSourceOptions","buildDataSourceOptions","setupDatabase","dataSource","debug","initialize","migrate","registerRepositories","registerEvents","registerEventPublisher","register","useValue","e","isInitialized","destroy","disposeEventPublisher","cleanupError","warn","teardown","tryResolve","success","data","unregister","EventRepository","dispose","undefined","disconnect","check","exists","synchronize","ifNotExist","config","db","buildWith","buildWithEnv","type","env","cacheResult","Object","assign","cache","provider","entities","Array","isArray","entity","isEntitySchema","useFactory","getRepository","publisher","redis","client","eventLogEnabled","eventLogEntityEnabled","eventService","requestContext","retentionDays","eventLogEntityRetentionDays","i","subscribers","length","subscriber","setPublisher","repository","service","enabled","eventLogRetentionDays"],"sources":["../../../../src/app/modules/database/module.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport {\n DomainEventPublisher,\n DomainEventRedisHandler,\n DomainEventSocketHandler,\n createRedisClient,\n} from '@authup/server-kit';\nimport type { RedisClient } from '@authup/server-kit';\nimport { AuthupError } from '@authup/errors';\nimport type { DataSourceOptions } from 'typeorm';\nimport { DataSource, InstanceChecker } from 'typeorm';\nimport {\n checkDatabase,\n createDatabase,\n synchronizeDatabaseSchema,\n} from 'typeorm-extension';\nimport {\n DataSourceOptionsBuilder,\n DatabaseQueryResultCache,\n EntitySubscriber,\n EventEntity,\n isDatabaseTypeSupported,\n isDatabaseTypeSupportedForEnvironment,\n} from '../../../adapters/database/index.ts';\nimport type { Event } from '@authup/core-kit';\nimport { EntityEventHandler, EventService } from '../../../core/index.ts';\nimport { useRequestEventContext } from '../../../adapters/http/request/index.ts';\nimport { EventRepositoryAdapter } from './repositories/index.ts';\nimport { validateEntitySchemas } from './repositories/schema-validation.ts';\nimport { CacheInjectionKey } from '../cache/index.ts';\nimport type { IModule } from 'orkos';\nimport { ModuleName } from '../constants.ts';\nimport { DatabaseInjectionKey } from './constants.ts';\nimport { ConfigInjectionKey } from '../config/index.ts';\nimport type { IContainer } from 'eldin';\nimport { LoggerInjectionKey } from '../logger/index.ts';\n\nexport type DatabaseModuleOptions = {\n prepareBuild?: (container: IContainer) => Promise<void>;\n setup?: (container: IContainer, options: DataSourceOptions) => Promise<void>;\n migrate?: (container: IContainer, dataSource: DataSource) => Promise<void>;\n};\n\nexport class DatabaseModule implements IModule {\n readonly name: string;\n\n readonly dependencies: string[];\n\n protected optionsBuilder : DataSourceOptionsBuilder;\n\n protected options: DatabaseModuleOptions;\n\n protected eventRedisClient? : RedisClient;\n\n protected eventPublisher? : DomainEventPublisher;\n\n constructor(options: DatabaseModuleOptions = {}) {\n this.name = ModuleName.DATABASE;\n this.dependencies = [ModuleName.CONFIG, ModuleName.LOGGER];\n\n this.optionsBuilder = new DataSourceOptionsBuilder();\n this.options = options;\n }\n\n async setup(container: IContainer): Promise<void> {\n const logger = container.resolve(LoggerInjectionKey);\n\n if (this.options.prepareBuild) {\n await this.options.prepareBuild(container);\n }\n\n const dataSourceOptions = await this.buildDataSourceOptions(container);\n\n if (this.options.setup) {\n await this.options.setup(container, dataSourceOptions);\n } else {\n await this.setupDatabase(container, dataSourceOptions);\n }\n\n const dataSource = new DataSource(dataSourceOptions);\n\n logger.debug('Establishing database connection...');\n await dataSource.initialize();\n logger.debug('Established database connection.');\n\n try {\n if (this.options.migrate) {\n await this.options.migrate(container, dataSource);\n } else {\n await this.migrate(container, dataSource);\n }\n\n validateEntitySchemas(dataSource);\n this.registerRepositories(container, dataSource);\n // the event service must exist before the publisher wiring — the\n // entity-CRUD bridge handler resolves it from the container.\n this.registerEvents(container, dataSource);\n this.registerEventPublisher(container, dataSource);\n\n container.register(DatabaseInjectionKey.DataSource, { useValue: dataSource });\n } catch (e) {\n // teardown() is skipped for a module that fails its own setup(),\n // so release the connection pool and any event-publisher handles\n // here. Guard cleanup so it can never mask the original error.\n try {\n if (dataSource.isInitialized) {\n await dataSource.destroy();\n }\n\n await this.disposeEventPublisher();\n } catch (cleanupError) {\n logger.warn(`Failed to clean up database resources after setup error: ${cleanupError}`);\n }\n\n throw e;\n }\n }\n\n async teardown(container: IContainer): Promise<void> {\n const dataSource = container.tryResolve(DatabaseInjectionKey.DataSource);\n if (dataSource.success) {\n if (dataSource.data.isInitialized) {\n await dataSource.data.destroy();\n }\n\n container.unregister(DatabaseInjectionKey.DataSource);\n }\n\n container.unregister(DatabaseInjectionKey.DomainEventPublisher);\n container.unregister(DatabaseInjectionKey.EventRepository);\n container.unregister(DatabaseInjectionKey.EventService);\n\n await this.disposeEventPublisher();\n }\n\n protected async disposeEventPublisher(): Promise<void> {\n if (this.eventPublisher) {\n await this.eventPublisher.dispose();\n this.eventPublisher = undefined;\n }\n\n if (this.eventRedisClient) {\n this.eventRedisClient.disconnect();\n this.eventRedisClient = undefined;\n }\n }\n\n // ----------------------------------------------------\n\n protected async setupDatabase(container: IContainer, options: DataSourceOptions): Promise<void> {\n const logger = container.resolve(LoggerInjectionKey);\n\n const check = await checkDatabase({ options });\n\n if (!check.exists) {\n logger.debug('Creating database...');\n await createDatabase({\n options,\n synchronize: false,\n ifNotExist: true, \n });\n logger.debug('Created database');\n }\n }\n\n protected async migrate(container: IContainer, dataSource: DataSource): Promise<void> {\n const logger = container.resolve(LoggerInjectionKey);\n\n logger.debug('Migrating database...');\n await synchronizeDatabaseSchema(dataSource);\n logger.debug('Migrated database');\n }\n\n // ----------------------------------------------------\n\n /**\n * Load data source options for connection.\n *\n * @protected\n */\n protected async buildDataSourceOptions(container: IContainer) : Promise<DataSourceOptions> {\n const config = container.resolve(ConfigInjectionKey);\n\n let options : DataSourceOptions | undefined;\n if (config.db) {\n options = this.optionsBuilder.buildWith(config.db);\n } else {\n options = this.optionsBuilder.buildWithEnv();\n }\n\n if (!isDatabaseTypeSupported(options.type)) {\n throw new AuthupError(`Database type ${options.type} is not supported (only: mysql, better-sqlite3 and postgres).`);\n }\n\n if (!isDatabaseTypeSupportedForEnvironment(options.type, config.env)) {\n throw new AuthupError(`Database type ${options.type} is not supported for ${config.env}.`);\n }\n\n const cacheResult = container.tryResolve(CacheInjectionKey);\n if (cacheResult.success) {\n Object.assign(options, {\n cache: {\n provider() {\n return new DatabaseQueryResultCache(cacheResult.data);\n },\n },\n } satisfies Partial<DataSourceOptions>);\n }\n\n return options;\n }\n\n protected registerRepositories(container: IContainer, dataSource: DataSource) : void {\n const entities = dataSource.options.entities || [];\n if (!Array.isArray(entities)) {\n return;\n }\n\n for (const entity of entities) {\n if (InstanceChecker.isEntitySchema(entity)) {\n continue;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n container.register(entity, { useFactory: () => dataSource.getRepository(entity) });\n }\n }\n\n protected registerEventPublisher(container: IContainer, dataSource: DataSource) {\n const config = container.resolve(ConfigInjectionKey);\n const logger = container.resolve(LoggerInjectionKey);\n\n const publisher = new DomainEventPublisher({ logger });\n this.eventPublisher = publisher;\n if (config.redis) {\n const client = createRedisClient(config.redis);\n if (client !== config.redis) {\n this.eventRedisClient = client;\n }\n\n publisher.register(new DomainEventRedisHandler(client));\n publisher.register(new DomainEventSocketHandler(client));\n }\n\n if (config.eventLogEnabled && config.eventLogEntityEnabled) {\n publisher.register(new EntityEventHandler({\n eventService: container.resolve(DatabaseInjectionKey.EventService),\n requestContext: useRequestEventContext,\n options: { retentionDays: config.eventLogEntityRetentionDays },\n }));\n }\n\n container.register(DatabaseInjectionKey.DomainEventPublisher, { useValue: publisher });\n\n for (let i = 0; i < dataSource.subscribers.length; i++) {\n const subscriber = dataSource.subscribers[i];\n if (subscriber instanceof EntitySubscriber) {\n subscriber.setPublisher(publisher);\n }\n }\n }\n\n protected registerEvents(container: IContainer, dataSource: DataSource) {\n const config = container.resolve(ConfigInjectionKey);\n const logger = container.resolve(LoggerInjectionKey);\n\n const repository = new EventRepositoryAdapter(\n dataSource.getRepository<Event>(EventEntity),\n );\n container.register(DatabaseInjectionKey.EventRepository, { useValue: repository });\n\n const service = new EventService({\n repository,\n options: {\n enabled: config.eventLogEnabled,\n retentionDays: config.eventLogRetentionDays,\n },\n logger,\n });\n container.register(DatabaseInjectionKey.EventService, { useValue: service });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"module.mjs","names":["DomainEventPublisher","DomainEventRedisHandler","DomainEventSocketHandler","createRedisClient","AuthupError","DataSource","InstanceChecker","checkDatabase","createDatabase","synchronizeDatabaseSchema","DataSourceOptionsBuilder","DatabaseQueryResultCache","EntitySubscriber","EventEntity","isDatabaseTypeSupported","isDatabaseTypeSupportedForEnvironment","EntityEventHandler","EventService","useRequestEventContext","EventRepositoryAdapter","validateEntitySchemas","CacheInjectionKey","ModuleName","DatabaseInjectionKey","ConfigInjectionKey","LoggerInjectionKey","DatabaseModule","name","dependencies","optionsBuilder","options","eventRedisClient","eventPublisher","DATABASE","CONFIG","LOGGER","setup","container","logger","resolve","prepareBuild","dataSourceOptions","buildDataSourceOptions","setupDatabase","dataSource","debug","initialize","migrate","registerRepositories","registerEvents","registerEventPublisher","register","useValue","e","isInitialized","destroy","disposeEventPublisher","cleanupError","warn","teardown","tryResolve","success","data","unregister","EventRepository","dispose","undefined","disconnect","check","exists","synchronize","ifNotExist","config","db","buildWith","buildWithEnv","type","env","cacheResult","Object","assign","cache","provider","entities","Array","isArray","entity","isEntitySchema","useFactory","getRepository","publisher","redis","client","eventLogEnabled","eventLogEntityEnabled","eventService","requestContext","retentionDays","eventLogEntityRetentionDays","i","subscribers","length","subscriber","setPublisher","repository","service","enabled","eventLogRetentionDays"],"sources":["../../../../src/app/modules/database/module.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport {\n DomainEventPublisher,\n DomainEventRedisHandler,\n DomainEventSocketHandler,\n createRedisClient,\n} from '@authup/server-kit';\nimport type { RedisClient } from '@authup/server-kit';\nimport { AuthupError } from '@authup/errors';\nimport type { DataSourceOptions } from 'typeorm';\nimport { DataSource, InstanceChecker } from 'typeorm';\nimport {\n checkDatabase,\n createDatabase,\n synchronizeDatabaseSchema,\n} from 'typeorm-extension';\nimport {\n DataSourceOptionsBuilder,\n DatabaseQueryResultCache,\n EntitySubscriber,\n EventEntity,\n isDatabaseTypeSupported,\n isDatabaseTypeSupportedForEnvironment,\n} from '../../../adapters/database/index.ts';\nimport type { Event } from '@authup/core-kit';\nimport { EntityEventHandler, EventService } from '../../../core/index.ts';\nimport { useRequestEventContext } from '../../../adapters/http/request/index.ts';\nimport { EventRepositoryAdapter } from './repositories/index.ts';\nimport { validateEntitySchemas } from './repositories/schema-validation.ts';\nimport { CacheInjectionKey } from '../cache/index.ts';\nimport type { IModule } from 'orkos';\nimport { ModuleName } from '../constants.ts';\nimport { DatabaseInjectionKey } from './constants.ts';\nimport { ConfigInjectionKey } from '../config/index.ts';\nimport type { IContainer } from 'eldin';\nimport { LoggerInjectionKey } from '../logger/index.ts';\n\nexport type DatabaseModuleOptions = {\n prepareBuild?: (container: IContainer) => Promise<void>;\n setup?: (container: IContainer, options: DataSourceOptions) => Promise<void>;\n migrate?: (container: IContainer, dataSource: DataSource) => Promise<void>;\n};\n\nexport class DatabaseModule implements IModule {\n readonly name: string;\n\n readonly dependencies: string[];\n\n protected optionsBuilder : DataSourceOptionsBuilder;\n\n protected options: DatabaseModuleOptions;\n\n protected eventRedisClient? : RedisClient;\n\n protected eventPublisher? : DomainEventPublisher;\n\n constructor(options: DatabaseModuleOptions = {}) {\n this.name = ModuleName.DATABASE;\n this.dependencies = [ModuleName.CONFIG, ModuleName.LOGGER];\n\n this.optionsBuilder = new DataSourceOptionsBuilder();\n this.options = options;\n }\n\n async setup(container: IContainer): Promise<void> {\n const logger = container.resolve(LoggerInjectionKey);\n\n if (this.options.prepareBuild) {\n await this.options.prepareBuild(container);\n }\n\n const dataSourceOptions = await this.buildDataSourceOptions(container);\n\n if (this.options.setup) {\n await this.options.setup(container, dataSourceOptions);\n } else {\n await this.setupDatabase(container, dataSourceOptions);\n }\n\n const dataSource = new DataSource(dataSourceOptions);\n\n logger.debug('Establishing database connection...');\n await dataSource.initialize();\n logger.debug('Established database connection.');\n\n try {\n if (this.options.migrate) {\n await this.options.migrate(container, dataSource);\n } else {\n await this.migrate(container, dataSource);\n }\n\n validateEntitySchemas(dataSource);\n this.registerRepositories(container, dataSource);\n // the event service must exist before the publisher wiring — the\n // entity-CRUD bridge handler resolves it from the container.\n this.registerEvents(container, dataSource);\n this.registerEventPublisher(container, dataSource);\n\n container.register(DatabaseInjectionKey.DataSource, { useValue: dataSource });\n } catch (e) {\n // teardown() is skipped for a module that fails its own setup(),\n // so release the connection pool and any event-publisher handles\n // here. Guard cleanup so it can never mask the original error.\n try {\n if (dataSource.isInitialized) {\n await dataSource.destroy();\n }\n\n await this.disposeEventPublisher();\n } catch (cleanupError) {\n logger.warn(`Failed to clean up database resources after setup error: ${cleanupError}`);\n }\n\n throw e;\n }\n }\n\n async teardown(container: IContainer): Promise<void> {\n const dataSource = container.tryResolve(DatabaseInjectionKey.DataSource);\n if (dataSource.success) {\n if (dataSource.data.isInitialized) {\n await dataSource.data.destroy();\n }\n\n container.unregister(DatabaseInjectionKey.DataSource);\n }\n\n container.unregister(DatabaseInjectionKey.DomainEventPublisher);\n container.unregister(DatabaseInjectionKey.EventRepository);\n container.unregister(DatabaseInjectionKey.EventService);\n\n await this.disposeEventPublisher();\n }\n\n protected async disposeEventPublisher(): Promise<void> {\n if (this.eventPublisher) {\n await this.eventPublisher.dispose();\n this.eventPublisher = undefined;\n }\n\n if (this.eventRedisClient) {\n this.eventRedisClient.disconnect();\n this.eventRedisClient = undefined;\n }\n }\n\n // ----------------------------------------------------\n\n protected async setupDatabase(container: IContainer, options: DataSourceOptions): Promise<void> {\n const logger = container.resolve(LoggerInjectionKey);\n\n const check = await checkDatabase({ options });\n\n if (!check.exists) {\n logger.debug('Creating database...');\n await createDatabase({\n options,\n synchronize: false,\n ifNotExist: true, \n });\n logger.debug('Created database');\n }\n }\n\n protected async migrate(container: IContainer, dataSource: DataSource): Promise<void> {\n const logger = container.resolve(LoggerInjectionKey);\n\n logger.debug('Migrating database...');\n await synchronizeDatabaseSchema(dataSource);\n logger.debug('Migrated database');\n }\n\n // ----------------------------------------------------\n\n /**\n * Load data source options for connection.\n *\n * @protected\n */\n protected async buildDataSourceOptions(container: IContainer) : Promise<DataSourceOptions> {\n const config = container.resolve(ConfigInjectionKey);\n\n let options : DataSourceOptions | undefined;\n if (config.db) {\n options = this.optionsBuilder.buildWith(config.db);\n } else {\n options = this.optionsBuilder.buildWithEnv();\n }\n\n if (!isDatabaseTypeSupported(options.type)) {\n throw new AuthupError(`Database type ${options.type} is not supported (only: mysql, better-sqlite3 and postgres).`);\n }\n\n if (!isDatabaseTypeSupportedForEnvironment(options.type, config.env)) {\n throw new AuthupError(`Database type ${options.type} is not supported for ${config.env}.`);\n }\n\n const cacheResult = container.tryResolve(CacheInjectionKey);\n if (cacheResult.success) {\n Object.assign(options, {\n cache: {\n provider() {\n return new DatabaseQueryResultCache(cacheResult.data);\n },\n },\n } satisfies Partial<DataSourceOptions>);\n }\n\n return options;\n }\n\n protected registerRepositories(container: IContainer, dataSource: DataSource) : void {\n const entities = dataSource.options.entities || [];\n if (!Array.isArray(entities)) {\n return;\n }\n\n for (const entity of entities) {\n if (InstanceChecker.isEntitySchema(entity)) {\n continue;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n container.register(entity, { useFactory: () => dataSource.getRepository(entity) });\n }\n }\n\n protected registerEventPublisher(container: IContainer, dataSource: DataSource) {\n const config = container.resolve(ConfigInjectionKey);\n const logger = container.resolve(LoggerInjectionKey);\n\n const publisher = new DomainEventPublisher({ logger });\n this.eventPublisher = publisher;\n if (config.redis) {\n const client = createRedisClient(config.redis);\n if (client !== config.redis) {\n this.eventRedisClient = client;\n }\n\n publisher.register(new DomainEventRedisHandler(client));\n publisher.register(new DomainEventSocketHandler(client));\n }\n\n if (config.eventLogEnabled && config.eventLogEntityEnabled) {\n publisher.register(new EntityEventHandler({\n eventService: container.resolve(DatabaseInjectionKey.EventService),\n requestContext: useRequestEventContext,\n options: { retentionDays: config.eventLogEntityRetentionDays },\n }));\n }\n\n container.register(DatabaseInjectionKey.DomainEventPublisher, { useValue: publisher });\n\n for (let i = 0; i < dataSource.subscribers.length; i++) {\n const subscriber = dataSource.subscribers[i];\n if (subscriber instanceof EntitySubscriber) {\n subscriber.setPublisher(publisher);\n }\n }\n }\n\n protected registerEvents(container: IContainer, dataSource: DataSource) {\n const config = container.resolve(ConfigInjectionKey);\n const logger = container.resolve(LoggerInjectionKey);\n\n const repository = new EventRepositoryAdapter(\n dataSource.getRepository<Event>(EventEntity),\n );\n container.register(DatabaseInjectionKey.EventRepository, { useValue: repository });\n\n const service = new EventService({\n repository,\n options: {\n enabled: config.eventLogEnabled,\n retentionDays: config.eventLogRetentionDays,\n },\n logger,\n });\n container.register(DatabaseInjectionKey.EventService, { useValue: service });\n }\n}\n"],"mappings":"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"}
@@ -253,6 +253,16 @@ var HTTPControllerModule = class {
253
253
  identityResolver,
254
254
  certificateValidator: new ClientCertificateValidator({ trustAnchorRepository: new TrustAnchorRepositoryAdapter(dataSource) })
255
255
  });
256
+ const eventService = container.resolve(DatabaseInjectionKey.EventService);
257
+ const metrics = container.resolve(MetricsInjectionKey);
258
+ const loginThrottleService = new LoginThrottleService({
259
+ repository: container.resolve(DatabaseInjectionKey.EventRepository),
260
+ options: {
261
+ enabled: config.loginAttemptThrottleEnabled,
262
+ threshold: config.loginAttemptThreshold,
263
+ windowSeconds: config.loginAttemptWindow
264
+ }
265
+ });
256
266
  return new TokenController({
257
267
  codeVerifier,
258
268
  accessTokenIssuer,
@@ -263,16 +273,9 @@ var HTTPControllerModule = class {
263
273
  tokenRevoker,
264
274
  tokenRepository,
265
275
  sessionTokenRepository,
266
- eventService: container.resolve(DatabaseInjectionKey.EventService),
267
- metrics: container.resolve(MetricsInjectionKey),
268
- loginThrottleService: new LoginThrottleService({
269
- repository: container.resolve(DatabaseInjectionKey.EventRepository),
270
- options: {
271
- enabled: config.loginAttemptThrottleEnabled,
272
- threshold: config.loginAttemptThreshold,
273
- windowSeconds: config.loginAttemptWindow
274
- }
275
- }),
276
+ eventService,
277
+ metrics,
278
+ loginThrottleService,
276
279
  userAuthenticatorService: this.resolveUserAuthenticatorService(container),
277
280
  mfaLoginService: this.resolveMfaLoginService(container),
278
281
  accessPolicyEvaluator: this.resolveAccessPolicyEvaluator(container),
@@ -288,7 +291,8 @@ var HTTPControllerModule = class {
288
291
  });
289
292
  }
290
293
  createOpenIDController(container) {
291
- return new OpenIDController({ baseURL: container.resolve(ConfigInjectionKey).publicUrl });
294
+ const config = container.resolve(ConfigInjectionKey);
295
+ return new OpenIDController({ baseURL: config.publicUrl });
292
296
  }
293
297
  createActivateController(container) {
294
298
  const config = container.resolve(ConfigInjectionKey);
@@ -328,9 +332,11 @@ var HTTPControllerModule = class {
328
332
  repository: new UserRepository(dataSource),
329
333
  realmRepository
330
334
  });
335
+ const mailClient = container.resolve(MailInjectionKey);
336
+ const mailTemplateRenderer = container.resolve(MailTemplateRendererInjectionKey);
331
337
  return new PasswordRecoveryService({
332
- mailClient: container.resolve(MailInjectionKey),
333
- mailTemplateRenderer: container.resolve(MailTemplateRendererInjectionKey),
338
+ mailClient,
339
+ mailTemplateRenderer,
334
340
  repository,
335
341
  realmRepository: new RealmRepositoryAdapter(realmRepository),
336
342
  eventService: container.resolve(DatabaseInjectionKey.EventService),
@@ -354,11 +360,15 @@ var HTTPControllerModule = class {
354
360
  }
355
361
  createLogoutController(container) {
356
362
  const config = container.resolve(ConfigInjectionKey);
363
+ const tokenVerifier = container.resolve(OAuth2InjectionToken.TokenVerifier);
364
+ const sessionManager = container.resolve(AuthenticationInjectionKey.SessionManager);
365
+ const clientRepository = container.resolve(OAuth2InjectionToken.ClientRepository);
366
+ const realmRepository = new RealmRepositoryAdapter(container.resolve(RealmEntity));
357
367
  const endSessionService = new OAuth2EndSessionService({
358
- tokenVerifier: container.resolve(OAuth2InjectionToken.TokenVerifier),
359
- sessionManager: container.resolve(AuthenticationInjectionKey.SessionManager),
360
- clientRepository: container.resolve(OAuth2InjectionToken.ClientRepository),
361
- realmRepository: new RealmRepositoryAdapter(container.resolve(RealmEntity)),
368
+ tokenVerifier,
369
+ sessionManager,
370
+ clientRepository,
371
+ realmRepository,
362
372
  eventService: container.resolve(DatabaseInjectionKey.EventService),
363
373
  hintGracePeriod: config.endSessionHintGracePeriod
364
374
  });
@@ -386,9 +396,11 @@ var HTTPControllerModule = class {
386
396
  repository: new UserRepository(dataSource),
387
397
  realmRepository
388
398
  });
399
+ const mailClient = container.resolve(MailInjectionKey);
400
+ const mailTemplateRenderer = container.resolve(MailTemplateRendererInjectionKey);
389
401
  return new RegistrationService({
390
- mailClient: container.resolve(MailInjectionKey),
391
- mailTemplateRenderer: container.resolve(MailTemplateRendererInjectionKey),
402
+ mailClient,
403
+ mailTemplateRenderer,
392
404
  repository,
393
405
  realmRepository: new RealmRepositoryAdapter(realmRepository),
394
406
  eventService: container.resolve(DatabaseInjectionKey.EventService),
@@ -430,11 +442,13 @@ var HTTPControllerModule = class {
430
442
  repository: container.resolve(ClientEntity),
431
443
  realmRepository
432
444
  });
445
+ const realmRepositoryAdapter = new RealmRepositoryAdapter(realmRepository);
446
+ const service = new ClientService({
447
+ repository,
448
+ realmRepository: realmRepositoryAdapter
449
+ });
433
450
  return new ClientController({
434
- service: new ClientService({
435
- repository,
436
- realmRepository: new RealmRepositoryAdapter(realmRepository)
437
- }),
451
+ service,
438
452
  repository
439
453
  });
440
454
  }
@@ -458,103 +472,137 @@ var HTTPControllerModule = class {
458
472
  realmRepository
459
473
  });
460
474
  const realmRepositoryAdapter = new RealmRepositoryAdapter(realmRepository);
475
+ const roleRepository = new RoleRepositoryAdapter({
476
+ repository: container.resolve(RoleEntity),
477
+ realmRepository
478
+ });
479
+ const rolePermissionRepository = new RolePermissionRepositoryAdapter(container.resolve(RolePermissionEntity));
480
+ const policyRepository = new PolicyRepositoryAdapter({
481
+ repository: new PolicyRepository(dataSource),
482
+ realmRepository
483
+ });
484
+ const permissionPolicyRepository = new PermissionPolicyRepositoryAdapter(container.resolve(PermissionPolicyEntity));
461
485
  const service = new PermissionService({
462
486
  repository,
463
487
  realmRepository: realmRepositoryAdapter,
464
- roleRepository: new RoleRepositoryAdapter({
465
- repository: container.resolve(RoleEntity),
466
- realmRepository
467
- }),
468
- rolePermissionRepository: new RolePermissionRepositoryAdapter(container.resolve(RolePermissionEntity)),
469
- policyRepository: new PolicyRepositoryAdapter({
470
- repository: new PolicyRepository(dataSource),
471
- realmRepository
472
- }),
473
- permissionPolicyRepository: new PermissionPolicyRepositoryAdapter(container.resolve(PermissionPolicyEntity))
488
+ roleRepository,
489
+ rolePermissionRepository,
490
+ policyRepository,
491
+ permissionPolicyRepository
474
492
  });
475
493
  const identityPermissionProvider = container.resolve(IdentityInjectionKey.PermissionProvider);
494
+ const permissionProvider = new PermissionDatabaseProvider(dataSource);
495
+ const checkerService = new PermissionCheckerService({
496
+ repository,
497
+ realmRepository: realmRepositoryAdapter,
498
+ permissionProvider,
499
+ identityPermissionProvider
500
+ });
476
501
  return new PermissionController({
477
502
  service,
478
- checkerService: new PermissionCheckerService({
479
- repository,
480
- realmRepository: realmRepositoryAdapter,
481
- permissionProvider: new PermissionDatabaseProvider(dataSource),
482
- identityPermissionProvider
483
- })
503
+ checkerService
484
504
  });
485
505
  }
486
506
  createRoleController(container) {
487
507
  const realmRepository = new RealmRepositoryAdapter(container.resolve(RealmEntity));
488
- return new RoleController({ service: new RoleService({
489
- repository: new RoleRepositoryAdapter({
490
- repository: container.resolve(RoleEntity),
491
- realmRepository: container.resolve(RealmEntity)
492
- }),
508
+ const repository = new RoleRepositoryAdapter({
509
+ repository: container.resolve(RoleEntity),
510
+ realmRepository: container.resolve(RealmEntity)
511
+ });
512
+ const service = new RoleService({
513
+ repository,
493
514
  realmRepository
494
- }) });
515
+ });
516
+ return new RoleController({ service });
495
517
  }
496
518
  createClientPermissionController(container) {
497
- return new ClientPermissionController({ service: new ClientPermissionService({
498
- repository: new ClientPermissionRepositoryAdapter(container.resolve(ClientPermissionEntity)),
499
- permissionRepository: this.createPermissionRepository(container),
500
- identityPermissionProvider: container.resolve(IdentityInjectionKey.PermissionProvider)
501
- }) });
519
+ const repository = new ClientPermissionRepositoryAdapter(container.resolve(ClientPermissionEntity));
520
+ const permissionRepository = this.createPermissionRepository(container);
521
+ const identityPermissionProvider = container.resolve(IdentityInjectionKey.PermissionProvider);
522
+ const service = new ClientPermissionService({
523
+ repository,
524
+ permissionRepository,
525
+ identityPermissionProvider
526
+ });
527
+ return new ClientPermissionController({ service });
502
528
  }
503
529
  createClientRoleController(container) {
504
- return new ClientRoleController({ service: new ClientRoleService({
505
- repository: new ClientRoleRepositoryAdapter(container.resolve(ClientRoleEntity)),
506
- identityPermissionProvider: container.resolve(IdentityInjectionKey.PermissionProvider)
507
- }) });
530
+ const repository = new ClientRoleRepositoryAdapter(container.resolve(ClientRoleEntity));
531
+ const identityPermissionProvider = container.resolve(IdentityInjectionKey.PermissionProvider);
532
+ const service = new ClientRoleService({
533
+ repository,
534
+ identityPermissionProvider
535
+ });
536
+ return new ClientRoleController({ service });
508
537
  }
509
538
  createClientScopeController(container) {
510
- return new ClientScopeController({ service: new ClientScopeService({ repository: new ClientScopeRepositoryAdapter(container.resolve(ClientScopeEntity)) }) });
539
+ const repository = new ClientScopeRepositoryAdapter(container.resolve(ClientScopeEntity));
540
+ const service = new ClientScopeService({ repository });
541
+ return new ClientScopeController({ service });
511
542
  }
512
543
  createRoleAttributeController(container) {
513
544
  const dataSource = container.resolve(DatabaseInjectionKey.DataSource);
514
- return new RoleAttributeController({ service: new RoleAttributeService({
515
- repository: new RoleAttributeRepositoryAdapter(container.resolve(RoleAttributeEntity)),
516
- reservedNames: new Set(dataSource.getMetadata(RoleEntity).columns.map((c) => c.propertyName))
517
- }) });
545
+ const repository = new RoleAttributeRepositoryAdapter(container.resolve(RoleAttributeEntity));
546
+ const reservedNames = new Set(dataSource.getMetadata(RoleEntity).columns.map((c) => c.propertyName));
547
+ const service = new RoleAttributeService({
548
+ repository,
549
+ reservedNames
550
+ });
551
+ return new RoleAttributeController({ service });
518
552
  }
519
553
  createRolePermissionController(container) {
520
- return new RolePermissionController({ service: new RolePermissionService({
521
- repository: new RolePermissionRepositoryAdapter(container.resolve(RolePermissionEntity)),
522
- permissionRepository: this.createPermissionRepository(container),
523
- identityPermissionProvider: container.resolve(IdentityInjectionKey.PermissionProvider)
524
- }) });
554
+ const repository = new RolePermissionRepositoryAdapter(container.resolve(RolePermissionEntity));
555
+ const permissionRepository = this.createPermissionRepository(container);
556
+ const identityPermissionProvider = container.resolve(IdentityInjectionKey.PermissionProvider);
557
+ const service = new RolePermissionService({
558
+ repository,
559
+ permissionRepository,
560
+ identityPermissionProvider
561
+ });
562
+ return new RolePermissionController({ service });
525
563
  }
526
564
  createPermissionPolicyController(container) {
527
- return new PermissionPolicyController({ service: new PermissionPolicyService({ repository: new PermissionPolicyRepositoryAdapter(container.resolve(PermissionPolicyEntity)) }) });
565
+ const repository = new PermissionPolicyRepositoryAdapter(container.resolve(PermissionPolicyEntity));
566
+ const service = new PermissionPolicyService({ repository });
567
+ return new PermissionPolicyController({ service });
528
568
  }
529
569
  createScopeController(container) {
530
570
  const realmRepository = new RealmRepositoryAdapter(container.resolve(RealmEntity));
531
- return new ScopeController({ service: new ScopeService({
532
- repository: new ScopeRepositoryAdapter({
533
- repository: container.resolve(ScopeEntity),
534
- realmRepository: container.resolve(RealmEntity)
535
- }),
571
+ const repository = new ScopeRepositoryAdapter({
572
+ repository: container.resolve(ScopeEntity),
573
+ realmRepository: container.resolve(RealmEntity)
574
+ });
575
+ const service = new ScopeService({
576
+ repository,
536
577
  realmRepository
537
- }) });
578
+ });
579
+ return new ScopeController({ service });
538
580
  }
539
581
  createKeyController(container) {
540
- return new KeyController({ service: new KeyService({
582
+ const service = new KeyService({
541
583
  repository: container.resolve(OAuth2InjectionToken.KeyStore),
542
584
  eventService: container.resolve(DatabaseInjectionKey.EventService),
543
585
  requestContext: useRequestEventContext
544
- }) });
586
+ });
587
+ return new KeyController({ service });
545
588
  }
546
589
  createTrustAnchorController(container) {
547
- return new TrustAnchorController({ service: new TrustAnchorService({
548
- repository: new TrustAnchorRepositoryAdapter(container.resolve(DatabaseInjectionKey.DataSource)),
590
+ const repository = new TrustAnchorRepositoryAdapter(container.resolve(DatabaseInjectionKey.DataSource));
591
+ const service = new TrustAnchorService({
592
+ repository,
549
593
  eventService: container.resolve(DatabaseInjectionKey.EventService),
550
594
  requestContext: useRequestEventContext
551
- }) });
595
+ });
596
+ return new TrustAnchorController({ service });
552
597
  }
553
598
  createSessionController(container) {
554
- return new SessionController({ service: new SessionService({ repository: container.resolve(AuthenticationInjectionKey.SessionRepository) }) });
599
+ const repository = container.resolve(AuthenticationInjectionKey.SessionRepository);
600
+ const service = new SessionService({ repository });
601
+ return new SessionController({ service });
555
602
  }
556
603
  createConsentService(container) {
557
- return new ConsentService({ repository: container.resolve(OAuth2InjectionToken.ConsentRepository) });
604
+ const repository = container.resolve(OAuth2InjectionToken.ConsentRepository);
605
+ return new ConsentService({ repository });
558
606
  }
559
607
  createConsentController(container) {
560
608
  return new ConsentController({ service: this.createConsentService(container) });
@@ -636,18 +684,21 @@ var HTTPControllerModule = class {
636
684
  });
637
685
  }
638
686
  createEventController(container) {
639
- return new EventController({ service: container.resolve(DatabaseInjectionKey.EventService) });
687
+ const service = container.resolve(DatabaseInjectionKey.EventService);
688
+ return new EventController({ service });
640
689
  }
641
690
  createUserService(container) {
642
691
  const config = container.resolve(ConfigInjectionKey);
643
692
  const dataSource = container.resolve(DatabaseInjectionKey.DataSource);
644
693
  const realmRepository = container.resolve(RealmEntity);
694
+ const repository = new UserRepositoryAdapter({
695
+ repository: new UserRepository(dataSource),
696
+ realmRepository
697
+ });
698
+ const realmRepositoryAdapter = new RealmRepositoryAdapter(realmRepository);
645
699
  return new UserService({
646
- repository: new UserRepositoryAdapter({
647
- repository: new UserRepository(dataSource),
648
- realmRepository
649
- }),
650
- realmRepository: new RealmRepositoryAdapter(realmRepository),
700
+ repository,
701
+ realmRepository: realmRepositoryAdapter,
651
702
  passwordMinLength: config.passwordMinLength
652
703
  });
653
704
  }
@@ -659,23 +710,33 @@ var HTTPControllerModule = class {
659
710
  }
660
711
  createUserAttributeController(container) {
661
712
  const dataSource = container.resolve(DatabaseInjectionKey.DataSource);
662
- return new UserAttributeController({ service: new UserAttributeService({
663
- repository: new UserAttributeRepositoryAdapter(container.resolve(UserAttributeEntity)),
664
- reservedNames: new Set(dataSource.getMetadata(UserEntity).columns.map((c) => c.propertyName))
665
- }) });
713
+ const repository = new UserAttributeRepositoryAdapter(container.resolve(UserAttributeEntity));
714
+ const reservedNames = new Set(dataSource.getMetadata(UserEntity).columns.map((c) => c.propertyName));
715
+ const service = new UserAttributeService({
716
+ repository,
717
+ reservedNames
718
+ });
719
+ return new UserAttributeController({ service });
666
720
  }
667
721
  createUserPermissionController(container) {
668
- return new UserPermissionController({ service: new UserPermissionService({
669
- repository: new UserPermissionRepositoryAdapter(container.resolve(UserPermissionEntity)),
670
- permissionRepository: this.createPermissionRepository(container),
671
- identityPermissionProvider: container.resolve(IdentityInjectionKey.PermissionProvider)
672
- }) });
722
+ const repository = new UserPermissionRepositoryAdapter(container.resolve(UserPermissionEntity));
723
+ const permissionRepository = this.createPermissionRepository(container);
724
+ const identityPermissionProvider = container.resolve(IdentityInjectionKey.PermissionProvider);
725
+ const service = new UserPermissionService({
726
+ repository,
727
+ permissionRepository,
728
+ identityPermissionProvider
729
+ });
730
+ return new UserPermissionController({ service });
673
731
  }
674
732
  createUserRoleController(container) {
675
- return new UserRoleController({ service: new UserRoleService({
676
- repository: new UserRoleRepositoryAdapter(container.resolve(UserRoleEntity)),
677
- identityPermissionProvider: container.resolve(IdentityInjectionKey.PermissionProvider)
678
- }) });
733
+ const repository = new UserRoleRepositoryAdapter(container.resolve(UserRoleEntity));
734
+ const identityPermissionProvider = container.resolve(IdentityInjectionKey.PermissionProvider);
735
+ const service = new UserRoleService({
736
+ repository,
737
+ identityPermissionProvider
738
+ });
739
+ return new UserRoleController({ service });
679
740
  }
680
741
  createPolicyController(container) {
681
742
  const dataSource = container.resolve(DatabaseInjectionKey.DataSource);
@@ -685,27 +746,35 @@ var HTTPControllerModule = class {
685
746
  realmRepository
686
747
  });
687
748
  const realmRepositoryAdapter = new RealmRepositoryAdapter(realmRepository);
749
+ const service = new PolicyService({
750
+ repository,
751
+ realmRepository: realmRepositoryAdapter
752
+ });
753
+ const identityPermissionProvider = container.resolve(IdentityInjectionKey.PermissionProvider);
754
+ const checkerService = new PolicyCheckerService({
755
+ repository,
756
+ realmRepository: realmRepositoryAdapter,
757
+ identityPermissionProvider
758
+ });
688
759
  return new PolicyController({
689
- service: new PolicyService({
690
- repository,
691
- realmRepository: realmRepositoryAdapter
692
- }),
693
- checkerService: new PolicyCheckerService({
694
- repository,
695
- realmRepository: realmRepositoryAdapter,
696
- identityPermissionProvider: container.resolve(IdentityInjectionKey.PermissionProvider)
697
- })
760
+ service,
761
+ checkerService
698
762
  });
699
763
  }
700
764
  createIdentityProviderRoleController(container) {
701
- return new IdentityProviderRoleMappingController({ service: new IdentityProviderRoleMappingService({
702
- repository: new IdentityProviderRoleMappingRepositoryAdapter(container.resolve(IdentityProviderRoleMappingEntity)),
703
- roleRepository: this.createRoleRepository(container),
704
- identityPermissionProvider: container.resolve(IdentityInjectionKey.PermissionProvider)
705
- }) });
765
+ const repository = new IdentityProviderRoleMappingRepositoryAdapter(container.resolve(IdentityProviderRoleMappingEntity));
766
+ const roleRepository = this.createRoleRepository(container);
767
+ const identityPermissionProvider = container.resolve(IdentityInjectionKey.PermissionProvider);
768
+ const service = new IdentityProviderRoleMappingService({
769
+ repository,
770
+ roleRepository,
771
+ identityPermissionProvider
772
+ });
773
+ return new IdentityProviderRoleMappingController({ service });
706
774
  }
707
775
  createJwkController(container) {
708
- return new JwkController({ repository: container.resolve(DatabaseInjectionKey.DataSource).getRepository(KeyEntity) });
776
+ const repository = container.resolve(DatabaseInjectionKey.DataSource).getRepository(KeyEntity);
777
+ return new JwkController({ repository });
709
778
  }
710
779
  createRealmController(container) {
711
780
  const config = container.resolve(ConfigInjectionKey);
@@ -717,22 +786,24 @@ var HTTPControllerModule = class {
717
786
  realmRepository
718
787
  });
719
788
  const logger = container.resolve(LoggerInjectionKey);
789
+ const webClientProvisioner = new WebClientProvisioner({
790
+ clientRepository,
791
+ scopeRepository: new ScopeRepositoryAdapter({
792
+ repository: container.resolve(ScopeEntity),
793
+ realmRepository
794
+ }),
795
+ clientScopeRepository: new ClientScopeRepositoryAdapter(container.resolve(ClientScopeEntity)),
796
+ appOrigins: getAppOrigins(config),
797
+ logger
798
+ });
799
+ const keyProvisioner = new KeyProvisioner({
800
+ keyStore: container.resolve(OAuth2InjectionToken.KeyStore),
801
+ logger
802
+ });
720
803
  const service = new RealmService({
721
804
  repository,
722
- webClientProvisioner: new WebClientProvisioner({
723
- clientRepository,
724
- scopeRepository: new ScopeRepositoryAdapter({
725
- repository: container.resolve(ScopeEntity),
726
- realmRepository
727
- }),
728
- clientScopeRepository: new ClientScopeRepositoryAdapter(container.resolve(ClientScopeEntity)),
729
- appOrigins: getAppOrigins(config),
730
- logger
731
- }),
732
- keyProvisioner: new KeyProvisioner({
733
- keyStore: container.resolve(OAuth2InjectionToken.KeyStore),
734
- logger
735
- }),
805
+ webClientProvisioner,
806
+ keyProvisioner,
736
807
  logger
737
808
  });
738
809
  const keyRepository = dataSource.getRepository(KeyEntity);