@rt-tools/auth-server 0.2.1 → 0.2.2

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.
@@ -2,10 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.undeclaredAccess = undeclaredAccess;
4
4
  exports.accessAuditError = accessAuditError;
5
- const constants_1 = require("@nestjs/common/constants");
5
+ const constants_js_1 = require("@nestjs/common/constants.js");
6
6
  const access_js_1 = require("./access.js");
7
7
  function isRoute(handler) {
8
- return Reflect.getMetadata(constants_1.PATH_METADATA, handler) !== undefined && Reflect.getMetadata(constants_1.METHOD_METADATA, handler) !== undefined;
8
+ return Reflect.getMetadata(constants_js_1.PATH_METADATA, handler) !== undefined && Reflect.getMetadata(constants_js_1.METHOD_METADATA, handler) !== undefined;
9
9
  }
10
10
  /**
11
11
  * The route handlers of the controllers that declare no access or more than one, as
@@ -1 +1 @@
1
- {"version":3,"file":"access-audit.js","sourceRoot":"","sources":["../../../../projects/auth-server/src/lib/access-audit.ts"],"names":[],"mappings":";;AAkBA,4CAgBC;AAGD,4CAGC;AAxCD,wDAA0E;AAE1E,2CAAmD;AAKnD,SAAS,OAAO,CAAC,OAAe;IAC5B,OAAO,OAAO,CAAC,WAAW,CAAC,yBAAa,EAAE,OAAO,CAAC,KAAK,SAAS,IAAI,OAAO,CAAC,WAAW,CAAC,2BAAe,EAAE,OAAO,CAAC,KAAK,SAAS,CAAC;AACpI,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,gBAAgB,CAAC,WAAwC;IACrE,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACnC,MAAM,SAAS,GAAW,UAAU,CAAC,SAAmB,CAAC;QACzD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC;YACvD,MAAM,OAAO,GAAY,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YACtD,IAAI,IAAI,KAAK,aAAa,IAAI,OAAO,OAAO,KAAK,UAAU,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC/E,SAAS;YACb,CAAC;YACD,MAAM,KAAK,GAAW,IAAA,gCAAoB,EAAC,OAAO,CAAC,CAAC,MAAM,CAAC;YAC3D,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gBACd,MAAM,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,IAAI,IAAI,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACxF,CAAC;QACL,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,uEAAuE;AACvE,SAAgB,gBAAgB,CAAC,MAAyB;IACtD,MAAM,KAAK,GAAW,MAAM,CAAC,GAAG,CAAC,CAAC,KAAa,EAAU,EAAE,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrF,OAAO,IAAI,KAAK,CAAC,+DAA+D,KAAK,EAAE,CAAC,CAAC;AAC7F,CAAC"}
1
+ {"version":3,"file":"access-audit.js","sourceRoot":"","sources":["../../../../projects/auth-server/src/lib/access-audit.ts"],"names":[],"mappings":";;AAkBA,4CAgBC;AAGD,4CAGC;AAxCD,8DAA6E;AAE7E,2CAAmD;AAKnD,SAAS,OAAO,CAAC,OAAe;IAC5B,OAAO,OAAO,CAAC,WAAW,CAAC,4BAAa,EAAE,OAAO,CAAC,KAAK,SAAS,IAAI,OAAO,CAAC,WAAW,CAAC,8BAAe,EAAE,OAAO,CAAC,KAAK,SAAS,CAAC;AACpI,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,gBAAgB,CAAC,WAAwC;IACrE,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACnC,MAAM,SAAS,GAAW,UAAU,CAAC,SAAmB,CAAC;QACzD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC;YACvD,MAAM,OAAO,GAAY,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YACtD,IAAI,IAAI,KAAK,aAAa,IAAI,OAAO,OAAO,KAAK,UAAU,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC/E,SAAS;YACb,CAAC;YACD,MAAM,KAAK,GAAW,IAAA,gCAAoB,EAAC,OAAO,CAAC,CAAC,MAAM,CAAC;YAC3D,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gBACd,MAAM,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,IAAI,IAAI,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACxF,CAAC;QACL,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,uEAAuE;AACvE,SAAgB,gBAAgB,CAAC,MAAyB;IACtD,MAAM,KAAK,GAAW,MAAM,CAAC,GAAG,CAAC,CAAC,KAAa,EAAU,EAAE,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrF,OAAO,IAAI,KAAK,CAAC,+DAA+D,KAAK,EAAE,CAAC,CAAC;AAC7F,CAAC"}
@@ -1,4 +1,4 @@
1
- import { METHOD_METADATA, PATH_METADATA } from '@nestjs/common/constants';
1
+ import { METHOD_METADATA, PATH_METADATA } from '@nestjs/common/constants.js';
2
2
  import { accessDeclarationsOf } from './access.js';
3
3
  function isRoute(handler) {
4
4
  return Reflect.getMetadata(PATH_METADATA, handler) !== undefined && Reflect.getMetadata(METHOD_METADATA, handler) !== undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"access-audit.js","sourceRoot":"","sources":["../../../../projects/auth-server/src/lib/access-audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAKnD,SAAS,OAAO,CAAC,OAAe;IAC5B,OAAO,OAAO,CAAC,WAAW,CAAC,aAAa,EAAE,OAAO,CAAC,KAAK,SAAS,IAAI,OAAO,CAAC,WAAW,CAAC,eAAe,EAAE,OAAO,CAAC,KAAK,SAAS,CAAC;AACpI,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,WAAwC;IACrE,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACnC,MAAM,SAAS,GAAW,UAAU,CAAC,SAAmB,CAAC;QACzD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC;YACvD,MAAM,OAAO,GAAY,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YACtD,IAAI,IAAI,KAAK,aAAa,IAAI,OAAO,OAAO,KAAK,UAAU,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC/E,SAAS;YACb,CAAC;YACD,MAAM,KAAK,GAAW,oBAAoB,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;YAC3D,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gBACd,MAAM,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,IAAI,IAAI,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACxF,CAAC;QACL,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,gBAAgB,CAAC,MAAyB;IACtD,MAAM,KAAK,GAAW,MAAM,CAAC,GAAG,CAAC,CAAC,KAAa,EAAU,EAAE,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrF,OAAO,IAAI,KAAK,CAAC,+DAA+D,KAAK,EAAE,CAAC,CAAC;AAC7F,CAAC","sourcesContent":["import { METHOD_METADATA, PATH_METADATA } from '@nestjs/common/constants';\n\nimport { accessDeclarationsOf } from './access.js';\n\n/** A class whose prototype holds the route handlers. */\nexport type TControllerClass = abstract new (...args: never[]) => object;\n\nfunction isRoute(handler: object): boolean {\n return Reflect.getMetadata(PATH_METADATA, handler) !== undefined && Reflect.getMetadata(METHOD_METADATA, handler) !== undefined;\n}\n\n/**\n * The route handlers of the controllers that declare no access or more than one, as\n * `Controller.method — none` / `— 2`.\n *\n * A handler is a prototype method with a route mark of the framework. An empty list means every\n * handler declares exactly one access.\n */\nexport function undeclaredAccess(controllers: readonly TControllerClass[]): readonly string[] {\n const faults: string[] = [];\n for (const controller of controllers) {\n const prototype: object = controller.prototype as object;\n for (const name of Object.getOwnPropertyNames(prototype)) {\n const handler: unknown = Reflect.get(prototype, name);\n if (name === 'constructor' || typeof handler !== 'function' || !isRoute(handler)) {\n continue;\n }\n const count: number = accessDeclarationsOf(handler).length;\n if (count !== 1) {\n faults.push(`${controller.name}.${name} — ${count === 0 ? 'none' : String(count)}`);\n }\n }\n }\n return faults;\n}\n\n/** The refusal of the start, naming every faulty operation at once. */\nexport function accessAuditError(faults: readonly string[]): Error {\n const lines: string = faults.map((fault: string): string => ' ' + fault).join('\\n');\n return new Error(`Every operation declares exactly one access; these do not:\\n${lines}`);\n}\n"]}
1
+ {"version":3,"file":"access-audit.js","sourceRoot":"","sources":["../../../../projects/auth-server/src/lib/access-audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAKnD,SAAS,OAAO,CAAC,OAAe;IAC5B,OAAO,OAAO,CAAC,WAAW,CAAC,aAAa,EAAE,OAAO,CAAC,KAAK,SAAS,IAAI,OAAO,CAAC,WAAW,CAAC,eAAe,EAAE,OAAO,CAAC,KAAK,SAAS,CAAC;AACpI,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,WAAwC;IACrE,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACnC,MAAM,SAAS,GAAW,UAAU,CAAC,SAAmB,CAAC;QACzD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC;YACvD,MAAM,OAAO,GAAY,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YACtD,IAAI,IAAI,KAAK,aAAa,IAAI,OAAO,OAAO,KAAK,UAAU,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC/E,SAAS;YACb,CAAC;YACD,MAAM,KAAK,GAAW,oBAAoB,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;YAC3D,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gBACd,MAAM,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,IAAI,IAAI,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACxF,CAAC;QACL,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,gBAAgB,CAAC,MAAyB;IACtD,MAAM,KAAK,GAAW,MAAM,CAAC,GAAG,CAAC,CAAC,KAAa,EAAU,EAAE,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrF,OAAO,IAAI,KAAK,CAAC,+DAA+D,KAAK,EAAE,CAAC,CAAC;AAC7F,CAAC","sourcesContent":["import { METHOD_METADATA, PATH_METADATA } from '@nestjs/common/constants.js';\n\nimport { accessDeclarationsOf } from './access.js';\n\n/** A class whose prototype holds the route handlers. */\nexport type TControllerClass = abstract new (...args: never[]) => object;\n\nfunction isRoute(handler: object): boolean {\n return Reflect.getMetadata(PATH_METADATA, handler) !== undefined && Reflect.getMetadata(METHOD_METADATA, handler) !== undefined;\n}\n\n/**\n * The route handlers of the controllers that declare no access or more than one, as\n * `Controller.method — none` / `— 2`.\n *\n * A handler is a prototype method with a route mark of the framework. An empty list means every\n * handler declares exactly one access.\n */\nexport function undeclaredAccess(controllers: readonly TControllerClass[]): readonly string[] {\n const faults: string[] = [];\n for (const controller of controllers) {\n const prototype: object = controller.prototype as object;\n for (const name of Object.getOwnPropertyNames(prototype)) {\n const handler: unknown = Reflect.get(prototype, name);\n if (name === 'constructor' || typeof handler !== 'function' || !isRoute(handler)) {\n continue;\n }\n const count: number = accessDeclarationsOf(handler).length;\n if (count !== 1) {\n faults.push(`${controller.name}.${name} — ${count === 0 ? 'none' : String(count)}`);\n }\n }\n }\n return faults;\n}\n\n/** The refusal of the start, naming every faulty operation at once. */\nexport function accessAuditError(faults: readonly string[]): Error {\n const lines: string = faults.map((fault: string): string => ' ' + fault).join('\\n');\n return new Error(`Every operation declares exactly one access; these do not:\\n${lines}`);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"auth-server.module.js","sourceRoot":"","sources":["../../../../projects/auth-server/src/lib/auth-server.module.ts"],"names":[],"mappings":"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","sourcesContent":["import { DynamicModule, Logger, Module, OnApplicationBootstrap } from '@nestjs/common';\nimport { APP_GUARD, DiscoveryModule, DiscoveryService } from '@nestjs/core';\nimport { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper';\n\nimport { TPermission } from '@rt-tools/auth-contract';\n\nimport { accessAuditError, TControllerClass, undeclaredAccess } from './access-audit.js';\nimport { AuthGuard } from './auth.guard.js';\nimport { AUTH_SERVER_OPTIONS, AUTH_TOKEN_VERIFIER } from './auth.tokens.js';\nimport { ICatalogSyncOptions, ICatalogSyncResult, syncPermissionCatalog } from './catalog-sync.js';\nimport { ITokenCheckOptions, KeycloakTokenVerifier } from './token-verifier.js';\n\n/** What an admin server tells the module. */\nexport interface IAuthServerOptions extends ITokenCheckOptions {\n /** Every right of this admin — `definePermissions(…)` of the contract. */\n readonly catalog: readonly TPermission[];\n /** Where the catalog is sent at start; without it nothing is sent. */\n readonly sync?: Omit<ICatalogSyncOptions, 'clientId'>;\n}\n\n/**\n * At start: every operation declares exactly one access, and the catalog reaches Keycloak.\n *\n * An operation without a declaration or with two stops the start and is named; the catalog sync\n * creates the roles Keycloak lacks and names the extra ones in the log.\n */\nexport class AuthStartCheck implements OnApplicationBootstrap {\n readonly #discovery: DiscoveryService;\n readonly #options: IAuthServerOptions;\n readonly #logger: Logger = new Logger('AuthServer');\n\n constructor(discovery: DiscoveryService, options: IAuthServerOptions) {\n this.#discovery = discovery;\n this.#options = options;\n }\n\n public async onApplicationBootstrap(): Promise<void> {\n const controllers: TControllerClass[] = this.#discovery\n .getControllers()\n .map((wrapper: InstanceWrapper): unknown => wrapper.metatype)\n .filter((metatype: unknown): metatype is TControllerClass => typeof metatype === 'function');\n const faults: readonly string[] = undeclaredAccess(controllers);\n if (faults.length) {\n throw accessAuditError(faults);\n }\n if (this.#options.sync) {\n const result: ICatalogSyncResult = await syncPermissionCatalog(\n { ...this.#options.sync, clientId: this.#options.clientId },\n this.#options.catalog\n );\n this.#logger.log(`catalog: ${this.#options.catalog.length} rights, created ${result.created.length}`);\n if (result.extra.length) {\n this.#logger.warn(`Keycloak holds rights the catalog lacks: ${result.extra.join(', ')}`);\n }\n }\n }\n}\n\n/** The entry module of an admin server: the token check, the guard and the start check. */\n@Module({})\nexport class AuthServerModule {\n public static forRoot(options: IAuthServerOptions): DynamicModule {\n return {\n module: AuthServerModule,\n global: true,\n imports: [DiscoveryModule],\n providers: [\n { provide: AUTH_SERVER_OPTIONS, useValue: options },\n { provide: AUTH_TOKEN_VERIFIER, useValue: new KeycloakTokenVerifier(options) },\n { provide: APP_GUARD, useClass: AuthGuard },\n {\n provide: AuthStartCheck,\n useFactory: (discovery: DiscoveryService): AuthStartCheck => new AuthStartCheck(discovery, options),\n inject: [DiscoveryService],\n },\n ],\n exports: [AUTH_SERVER_OPTIONS, AUTH_TOKEN_VERIFIER],\n };\n }\n}\n"]}
1
+ {"version":3,"file":"auth-server.module.js","sourceRoot":"","sources":["../../../../projects/auth-server/src/lib/auth-server.module.ts"],"names":[],"mappings":"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","sourcesContent":["import { DynamicModule, Logger, Module, OnApplicationBootstrap } from '@nestjs/common';\nimport { APP_GUARD, DiscoveryModule, DiscoveryService } from '@nestjs/core';\nimport { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper.js';\n\nimport { TPermission } from '@rt-tools/auth-contract';\n\nimport { accessAuditError, TControllerClass, undeclaredAccess } from './access-audit.js';\nimport { AuthGuard } from './auth.guard.js';\nimport { AUTH_SERVER_OPTIONS, AUTH_TOKEN_VERIFIER } from './auth.tokens.js';\nimport { ICatalogSyncOptions, ICatalogSyncResult, syncPermissionCatalog } from './catalog-sync.js';\nimport { ITokenCheckOptions, KeycloakTokenVerifier } from './token-verifier.js';\n\n/** What an admin server tells the module. */\nexport interface IAuthServerOptions extends ITokenCheckOptions {\n /** Every right of this admin — `definePermissions(…)` of the contract. */\n readonly catalog: readonly TPermission[];\n /** Where the catalog is sent at start; without it nothing is sent. */\n readonly sync?: Omit<ICatalogSyncOptions, 'clientId'>;\n}\n\n/**\n * At start: every operation declares exactly one access, and the catalog reaches Keycloak.\n *\n * An operation without a declaration or with two stops the start and is named; the catalog sync\n * creates the roles Keycloak lacks and names the extra ones in the log.\n */\nexport class AuthStartCheck implements OnApplicationBootstrap {\n readonly #discovery: DiscoveryService;\n readonly #options: IAuthServerOptions;\n readonly #logger: Logger = new Logger('AuthServer');\n\n constructor(discovery: DiscoveryService, options: IAuthServerOptions) {\n this.#discovery = discovery;\n this.#options = options;\n }\n\n public async onApplicationBootstrap(): Promise<void> {\n const controllers: TControllerClass[] = this.#discovery\n .getControllers()\n .map((wrapper: InstanceWrapper): unknown => wrapper.metatype)\n .filter((metatype: unknown): metatype is TControllerClass => typeof metatype === 'function');\n const faults: readonly string[] = undeclaredAccess(controllers);\n if (faults.length) {\n throw accessAuditError(faults);\n }\n if (this.#options.sync) {\n const result: ICatalogSyncResult = await syncPermissionCatalog(\n { ...this.#options.sync, clientId: this.#options.clientId },\n this.#options.catalog\n );\n this.#logger.log(`catalog: ${this.#options.catalog.length} rights, created ${result.created.length}`);\n if (result.extra.length) {\n this.#logger.warn(`Keycloak holds rights the catalog lacks: ${result.extra.join(', ')}`);\n }\n }\n }\n}\n\n/** The entry module of an admin server: the token check, the guard and the start check. */\n@Module({})\nexport class AuthServerModule {\n public static forRoot(options: IAuthServerOptions): DynamicModule {\n return {\n module: AuthServerModule,\n global: true,\n imports: [DiscoveryModule],\n providers: [\n { provide: AUTH_SERVER_OPTIONS, useValue: options },\n { provide: AUTH_TOKEN_VERIFIER, useValue: new KeycloakTokenVerifier(options) },\n { provide: APP_GUARD, useClass: AuthGuard },\n {\n provide: AuthStartCheck,\n useFactory: (discovery: DiscoveryService): AuthStartCheck => new AuthStartCheck(discovery, options),\n inject: [DiscoveryService],\n },\n ],\n exports: [AUTH_SERVER_OPTIONS, AUTH_TOKEN_VERIFIER],\n };\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rt-tools/auth-server",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Keycloak token check, access declarations and the rights catalog sync for NestJS controllers and Connect procedures",
5
5
  "author": "RT Team",
6
6
  "license": "Apache-2.0",