@3sixty/api-tenant-processor 0.20.0-next.0 → 0.20.0-next.1
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.
- package/dist/es/entities/tenant.js.map +1 -1
- package/dist/es/entities/tenantV0.js.map +1 -1
- package/dist/es/entities/tenantV1.js.map +1 -1
- package/dist/es/index.js +4 -3
- package/dist/es/index.js.map +1 -1
- package/dist/es/models/ISingleTenantProcessorConfig.js.map +1 -1
- package/dist/es/models/ISingleTenantProcessorConstructorOptions.js.map +1 -1
- package/dist/es/models/ITenantAdminServiceConfig.js.map +1 -1
- package/dist/es/models/ITenantAdminServiceConstructorOptions.js.map +1 -1
- package/dist/es/models/ITenantProcessorConfig.js.map +1 -1
- package/dist/es/models/ITenantProcessorConstructorOptions.js.map +1 -1
- package/dist/es/models/api/ITenantCreateRequest.js.map +1 -1
- package/dist/es/models/api/ITenantGetByApiKeyRequest.js.map +1 -1
- package/dist/es/models/api/ITenantGetByIdRequest.js.map +1 -1
- package/dist/es/models/api/ITenantGetByPublicOriginRequest.js.map +1 -1
- package/dist/es/models/api/ITenantGetResponse.js.map +1 -1
- package/dist/es/models/api/ITenantListRequest.js.map +1 -1
- package/dist/es/models/api/ITenantListResponse.js.map +1 -1
- package/dist/es/models/api/ITenantRemoveRequest.js.map +1 -1
- package/dist/es/models/api/ITenantUpdateRequest.js.map +1 -1
- package/dist/es/restEntryPoints.js.map +1 -1
- package/dist/es/schema.js.map +1 -1
- package/dist/es/singleTenantProcessor.js.map +1 -1
- package/dist/es/tenantAdminService.js +12 -2
- package/dist/es/tenantAdminService.js.map +1 -1
- package/dist/es/tenantIdContextIdHandler.js.map +1 -1
- package/dist/es/tenantProcessor.js.map +1 -1
- package/dist/es/tenantRoutes.js +20 -7
- package/dist/es/tenantRoutes.js.map +1 -1
- package/dist/es/utils/tenantIdHelper.js.map +1 -1
- package/dist/types/index.d.ts +3 -3
- package/dist/types/models/ITenantAdminServiceConstructorOptions.d.ts +5 -0
- package/docs/changelog.md +17 -0
- package/docs/reference/classes/SingleTenantProcessor.md +2 -0
- package/docs/reference/classes/TenantAdminService.md +1 -1
- package/docs/reference/classes/TenantProcessor.md +2 -0
- package/docs/reference/classes/TenantV0.md +61 -0
- package/docs/reference/classes/TenantV1.md +77 -0
- package/docs/reference/index.md +3 -3
- package/docs/reference/interfaces/ITenantAdminServiceConstructorOptions.md +14 -0
- package/docs/reference/variables/restEntryPoints.md +5 -0
- package/locales/en.json +0 -4
- package/package.json +2 -2
- package/dist/es/models/ITenantOverrideProcessorConfig.js +0 -4
- package/dist/es/models/ITenantOverrideProcessorConfig.js.map +0 -1
- package/dist/es/models/ITenantOverrideProcessorConstructorOptions.js +0 -2
- package/dist/es/models/ITenantOverrideProcessorConstructorOptions.js.map +0 -1
- package/dist/es/tenantOverrideProcessor.js +0 -119
- package/dist/es/tenantOverrideProcessor.js.map +0 -1
- package/dist/types/models/ITenantOverrideProcessorConfig.d.ts +0 -13
- package/dist/types/models/ITenantOverrideProcessorConstructorOptions.d.ts +0 -15
- package/dist/types/tenantOverrideProcessor.d.ts +0 -44
- package/docs/reference/classes/TenantOverrideProcessor.md +0 -119
- package/docs/reference/interfaces/ITenantOverrideProcessorConfig.md +0 -19
- package/docs/reference/interfaces/ITenantOverrideProcessorConstructorOptions.md +0 -25
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenantProcessor.js","sourceRoot":"","sources":["../../src/tenantProcessor.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,OAAO,EACN,eAAe,EAOf,iBAAiB,EACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAoB,MAAM,iBAAiB,CAAC;AAClE,OAAO,EACN,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,EAAE,EACF,aAAa,EACb,iBAAiB,EACjB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C;;GAEG;AACH,MAAM,OAAO,eAAe;IAC3B;;;OAGG;IACI,MAAM,CAAU,oBAAoB,GAAW,WAAW,CAAC;IAElE;;OAEG;IACI,MAAM,CAAU,UAAU,qBAAqC;IAEtE;;;OAGG;IACK,MAAM,CAAU,0BAA0B,GAAa,CAAC,SAAS,CAAC,CAAC;IAE3E;;;OAGG;IACc,qBAAqB,CAAwB;IAE9D;;;OAGG;IACc,WAAW,CAAS;IAErC;;;OAGG;IACc,gBAAgB,CAAW;IAE5C;;;OAGG;IACc,kBAAkB,CAAU;IAE7C;;;OAGG;IACH,YAAY,OAA4C;QACvD,IAAI,CAAC,qBAAqB,GAAG,gBAAgB,CAAC,GAAG,CAChD,OAAO,EAAE,wBAAwB,IAAI,cAAc,CACnD,CAAC;QACF,IAAI,CAAC,WAAW,GAAG,OAAO,EAAE,MAAM,EAAE,UAAU,IAAI,eAAe,CAAC,oBAAoB,CAAC;QACvF,IAAI,CAAC,gBAAgB,GAAG,CACvB,OAAO,EAAE,MAAM,EAAE,eAAe,IAAI,eAAe,CAAC,0BAA0B,CAC9E,CAAC,GAAG,CAAC,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,kBAAkB,GAAG,OAAO,EAAE,MAAM,EAAE,iBAAiB,IAAI,KAAK,CAAC;IACvE,CAAC;IAED;;;OAGG;IACI,SAAS;QACf,OAAO,eAAe,CAAC,UAAU,CAAC;IACnC,CAAC;IAED;;;;;;;;OAQG;IACI,KAAK,CAAC,GAAG,CACf,OAA2B,EAC3B,QAAuB,EACvB,KAA6B,EAC7B,UAAuB,EACvB,cAAyC;QAEzC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,EAAE,CAAC;YACtD,IAAI,CAAC;gBACJ,IAAI,MAAM,CAAC;gBACX,MAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC;gBAC3C,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC,QAAQ,CAAC;gBAClE,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;gBAE5E,IAAI,gBAAgB,EAAE,CAAC;oBACtB,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;oBACxF,IAAI,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;wBAC5B,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;oBAC7C,CAAC;yBAAM,CAAC;wBACP,MAAM,IAAI,iBAAiB,CAAC,eAAe,CAAC,UAAU,EAAE,eAAe,EAAE;4BACxE,OAAO,EAAE,IAAI,CAAC,WAAW;yBACzB,CAAC,CAAC;oBACJ,CAAC;gBACF,CAAC;qBAAM,CAAC;oBACP,MAAM,wBAAwB,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;oBAC7E,IAAI,EAAE,CAAC,WAAW,CAAC,wBAAwB,CAAC,EAAE,CAAC;wBAC9C,MAAM,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,wBAAwB,CAAC,CAAC;oBACvE,CAAC;yBAAM,IAAI,UAAU,EAAE,CAAC;wBACvB,MAAM,IAAI,iBAAiB,CAAC,eAAe,CAAC,UAAU,EAAE,uBAAuB,EAAE;4BAChF,SAAS,EAAE,aAAa,CAAC,YAAY;yBACrC,CAAC,CAAC;oBACJ,CAAC;gBACF,CAAC;gBAED,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;oBACvB,UAAU,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC;oBAC7C,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,GAAG,MAAM,CAAC,cAAc,CAAC;oBAE/D,uGAAuG;oBACvG,IAAI,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;wBACzC,UAAU,CAAC,iBAAiB,CAAC,YAAY,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC;oBAClE,CAAC;gBACF,CAAC;YACF,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,eAAe,CAAC,aAAa,CAC5B,QAAQ,EACR,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,EACxB,cAAc,CAAC,YAAY,EAC3B,IAAI,CAAC,kBAAkB,CACvB,CAAC;YACH,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACK,KAAK,CAAC,eAAe,CAAC,MAAc;QAC3C,IAAI,CAAC;YACJ,OAAO,MAAM,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/B,MAAM,IAAI,iBAAiB,CAC1B,eAAe,CAAC,UAAU,EAC1B,gBAAgB,EAChB,EAAE,GAAG,EAAE,MAAM,EAAE,EACf,GAAG,CACH,CAAC;YACH,CAAC;YACD,MAAM,GAAG,CAAC;QACX,CAAC;IACF,CAAC;IAED;;;;;;;OAOG;IACK,KAAK,CAAC,uBAAuB,CAAC,cAAsB;QAC3D,IAAI,CAAC;YACJ,OAAO,MAAM,IAAI,CAAC,qBAAqB,CAAC,yBAAyB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;QACzF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/B,MAAM,IAAI,iBAAiB,CAC1B,eAAe,CAAC,UAAU,EAC1B,wBAAwB,EACxB,EAAE,cAAc,EAAE,EAClB,GAAG,CACH,CAAC;YACH,CAAC;YACD,MAAM,GAAG,CAAC;QACX,CAAC;IACF,CAAC;IAED;;;;;;;OAOG;IACK,eAAe,CAAC,GAAY;QACnC,OAAO,CACN,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,aAAa,CAAC,UAAU,CAAC;YACpD,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,UAAU,CAAC,UAAU,CAAC,CACjD,CAAC;IACH,CAAC","sourcesContent":["// Copyright 2025 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport {\n\tHttpErrorHelper,\n\ttype IBaseRoute,\n\ttype IBaseRouteProcessor,\n\ttype IHttpResponse,\n\ttype IHttpServerRequest,\n\ttype ITenant,\n\ttype ITenantAdminComponent,\n\tHttpContextIdKeys\n} from \"@3sixty/api-models\";\nimport { ContextIdKeys, type IContextIds } from \"@3sixty/context\";\nimport {\n\tBaseError,\n\tComponentFactory,\n\tGuardError,\n\tIs,\n\tNotFoundError,\n\tUnauthorizedError\n} from \"@3sixty/core\";\nimport { nameof } from \"@3sixty/nameof\";\nimport { HttpStatusCode } from \"@3sixty/web\";\nimport type { ITenantProcessorConstructorOptions } from \"./models/ITenantProcessorConstructorOptions.js\";\n\n/**\n * Handles incoming api keys and maps them to tenant ids.\n */\nexport class TenantProcessor implements IBaseRouteProcessor {\n\t/**\n\t * The default name for the api key header.\n\t * @internal\n\t */\n\tpublic static readonly DEFAULT_API_KEY_NAME: string = \"x-api-key\";\n\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<TenantProcessor>();\n\n\t/**\n\t * The default endpoints to match for api key processing.\n\t * @internal\n\t */\n\tprivate static readonly _DEFAULT_API_KEY_ENDPOINTS: string[] = [\"/login$\"];\n\n\t/**\n\t * The component used to resolve tenants, which also provides the lookup caching.\n\t * @internal\n\t */\n\tprivate readonly _tenantAdminComponent: ITenantAdminComponent;\n\n\t/**\n\t * The key in the header to look for the api key.\n\t * @internal\n\t */\n\tprivate readonly _apiKeyName: string;\n\n\t/**\n\t * The list of regexp patterns to match against the request URL to determine if the api key header should be processed.\n\t * @internal\n\t */\n\tprivate readonly _apiKeyEndpoints: RegExp[];\n\n\t/**\n\t * Include the stack with errors.\n\t * @internal\n\t */\n\tprivate readonly _includeErrorStack: boolean;\n\n\t/**\n\t * Create a new instance of TenantProcessor.\n\t * @param options Options for the processor.\n\t */\n\tconstructor(options?: ITenantProcessorConstructorOptions) {\n\t\tthis._tenantAdminComponent = ComponentFactory.get<ITenantAdminComponent>(\n\t\t\toptions?.tenantAdminComponentType ?? \"tenant-admin\"\n\t\t);\n\t\tthis._apiKeyName = options?.config?.apiKeyName ?? TenantProcessor.DEFAULT_API_KEY_NAME;\n\t\tthis._apiKeyEndpoints = (\n\t\t\toptions?.config?.apiKeyEndpoints ?? TenantProcessor._DEFAULT_API_KEY_ENDPOINTS\n\t\t).map((ep: string) => new RegExp(ep));\n\t\tthis._includeErrorStack = options?.config?.includeErrorStack ?? false;\n\t}\n\n\t/**\n\t * Returns the class name of the component.\n\t * @returns The class name of the component.\n\t */\n\tpublic className(): string {\n\t\treturn TenantProcessor.CLASS_NAME;\n\t}\n\n\t/**\n\t * Pre process the REST request for the specified route.\n\t * @param request The incoming request.\n\t * @param response The outgoing response.\n\t * @param route The route to process.\n\t * @param contextIds The context IDs of the request.\n\t * @param processorState The state handed through the processors.\n\t * @returns A promise that resolves when the tenant context has been resolved and injected, or an error response set.\n\t */\n\tpublic async pre(\n\t\trequest: IHttpServerRequest,\n\t\tresponse: IHttpResponse,\n\t\troute: IBaseRoute | undefined,\n\t\tcontextIds: IContextIds,\n\t\tprocessorState: { [id: string]: unknown }\n\t): Promise<void> {\n\t\tif (!Is.empty(route) && !(route.skipTenant ?? false)) {\n\t\t\ttry {\n\t\t\t\tlet tenant;\n\t\t\t\tconst isSkipAuth = route.skipAuth ?? false;\n\t\t\t\tconst urlPath = new URL(request.url, \"http://localhost\").pathname;\n\t\t\t\tconst isApiKeyEndpoint = this._apiKeyEndpoints.some(re => re.test(urlPath));\n\n\t\t\t\tif (isApiKeyEndpoint) {\n\t\t\t\t\tconst apiKey = request.headers?.[this._apiKeyName] ?? request.query?.[this._apiKeyName];\n\t\t\t\t\tif (Is.stringValue(apiKey)) {\n\t\t\t\t\t\ttenant = await this.resolveByApiKey(apiKey);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow new UnauthorizedError(TenantProcessor.CLASS_NAME, \"missingApiKey\", {\n\t\t\t\t\t\t\tkeyName: this._apiKeyName\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst organizationIdQueryParam = request.query?.[ContextIdKeys.Organization];\n\t\t\t\t\tif (Is.stringValue(organizationIdQueryParam)) {\n\t\t\t\t\t\ttenant = await this.resolveByOrganizationId(organizationIdQueryParam);\n\t\t\t\t\t} else if (isSkipAuth) {\n\t\t\t\t\t\tthrow new UnauthorizedError(TenantProcessor.CLASS_NAME, \"missingOrganizationId\", {\n\t\t\t\t\t\t\tparamName: ContextIdKeys.Organization\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!Is.empty(tenant)) {\n\t\t\t\t\tcontextIds[ContextIdKeys.Tenant] = tenant.id;\n\t\t\t\t\tcontextIds[ContextIdKeys.Organization] = tenant.organizationId;\n\n\t\t\t\t\t// If the tenant has a custom public origin, we set it in the context for downstream processors to use.\n\t\t\t\t\tif (Is.stringValue(tenant.publicOrigin)) {\n\t\t\t\t\t\tcontextIds[HttpContextIdKeys.PublicOrigin] = tenant.publicOrigin;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tHttpErrorHelper.buildResponse(\n\t\t\t\t\tresponse,\n\t\t\t\t\tBaseError.fromError(err),\n\t\t\t\t\tHttpStatusCode.unauthorized,\n\t\t\t\t\tthis._includeErrorStack\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Resolve the tenant context from an api key.\n\t * @param apiKey The api key sent by the caller.\n\t * @returns The tenant associated with the api key.\n\t * @throws UnauthorizedError if no tenant matches the api key.\n\t * @internal\n\t */\n\tprivate async resolveByApiKey(apiKey: string): Promise<ITenant> {\n\t\ttry {\n\t\t\treturn await this._tenantAdminComponent.getByApiKey(apiKey);\n\t\t} catch (err) {\n\t\t\tif (this.isLookupFailure(err)) {\n\t\t\t\tthrow new UnauthorizedError(\n\t\t\t\t\tTenantProcessor.CLASS_NAME,\n\t\t\t\t\t\"apiKeyNotFound\",\n\t\t\t\t\t{ key: apiKey },\n\t\t\t\t\terr\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Resolve the tenant context from a plain organization query param.\n\t * Matches against the organization id or one of the legacy organization ids.\n\t * @param organizationId The organization id from the query param.\n\t * @returns The tenant associated with the organization id.\n\t * @throws UnauthorizedError if no tenant matches the organization id.\n\t * @internal\n\t */\n\tprivate async resolveByOrganizationId(organizationId: string): Promise<ITenant> {\n\t\ttry {\n\t\t\treturn await this._tenantAdminComponent.getTenantByOrganizationId(organizationId, true);\n\t\t} catch (err) {\n\t\t\tif (this.isLookupFailure(err)) {\n\t\t\t\tthrow new UnauthorizedError(\n\t\t\t\t\tTenantProcessor.CLASS_NAME,\n\t\t\t\t\t\"organizationIdNotFound\",\n\t\t\t\t\t{ organizationId },\n\t\t\t\t\terr\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Determine whether a tenant lookup failure means the credential is unusable.\n\t * A credential that matches no tenant, or is not even well formed, is unauthorized; anything\n\t * else is a genuine fault and is passed through untouched.\n\t * @param err The error raised by the tenant admin component.\n\t * @returns True if the credential should be reported as unauthorized.\n\t * @internal\n\t */\n\tprivate isLookupFailure(err: unknown): boolean {\n\t\treturn (\n\t\t\tBaseError.isErrorName(err, NotFoundError.CLASS_NAME) ||\n\t\t\tBaseError.isErrorName(err, GuardError.CLASS_NAME)\n\t\t);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tenantProcessor.js","sources":["../../src/tenantProcessor.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2025 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport {\n\tHttpErrorHelper,\n\ttype IBaseRoute,\n\ttype IBaseRouteProcessor,\n\ttype IHttpResponse,\n\ttype IHttpServerRequest,\n\ttype ITenant,\n\ttype ITenantAdminComponent,\n\tHttpContextIdKeys\n} from \"@3sixty/api-models\";\nimport { ContextIdKeys, type IContextIds } from \"@3sixty/context\";\nimport {\n\tBaseError,\n\tComponentFactory,\n\tGuardError,\n\tIs,\n\tNotFoundError,\n\tUnauthorizedError\n} from \"@3sixty/core\";\n\nimport { HttpStatusCode } from \"@3sixty/web\";\nimport type { ITenantProcessorConstructorOptions } from \"./models/ITenantProcessorConstructorOptions.js\";\n\n/**\n * Handles incoming api keys and maps them to tenant ids.\n */\nexport class TenantProcessor implements IBaseRouteProcessor {\n\t/**\n\t * The default name for the api key header.\n\t * @internal\n\t */\n\tpublic static readonly DEFAULT_API_KEY_NAME: string = \"x-api-key\";\n\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = \"TenantProcessor\";\n\n\t/**\n\t * The default endpoints to match for api key processing.\n\t * @internal\n\t */\n\tprivate static readonly _DEFAULT_API_KEY_ENDPOINTS: string[] = [\"/login$\"];\n\n\t/**\n\t * The component used to resolve tenants, which also provides the lookup caching.\n\t * @internal\n\t */\n\tprivate readonly _tenantAdminComponent: ITenantAdminComponent;\n\n\t/**\n\t * The key in the header to look for the api key.\n\t * @internal\n\t */\n\tprivate readonly _apiKeyName: string;\n\n\t/**\n\t * The list of regexp patterns to match against the request URL to determine if the api key header should be processed.\n\t * @internal\n\t */\n\tprivate readonly _apiKeyEndpoints: RegExp[];\n\n\t/**\n\t * Include the stack with errors.\n\t * @internal\n\t */\n\tprivate readonly _includeErrorStack: boolean;\n\n\t/**\n\t * Create a new instance of TenantProcessor.\n\t * @param options Options for the processor.\n\t */\n\tconstructor(options?: ITenantProcessorConstructorOptions) {\n\t\tthis._tenantAdminComponent = ComponentFactory.get<ITenantAdminComponent>(\n\t\t\toptions?.tenantAdminComponentType ?? \"tenant-admin\"\n\t\t);\n\t\tthis._apiKeyName = options?.config?.apiKeyName ?? TenantProcessor.DEFAULT_API_KEY_NAME;\n\t\tthis._apiKeyEndpoints = (\n\t\t\toptions?.config?.apiKeyEndpoints ?? TenantProcessor._DEFAULT_API_KEY_ENDPOINTS\n\t\t).map((ep: string) => new RegExp(ep));\n\t\tthis._includeErrorStack = options?.config?.includeErrorStack ?? false;\n\t}\n\n\t/**\n\t * Returns the class name of the component.\n\t * @returns The class name of the component.\n\t */\n\tpublic className(): string {\n\t\treturn TenantProcessor.CLASS_NAME;\n\t}\n\n\t/**\n\t * Pre process the REST request for the specified route.\n\t * @param request The incoming request.\n\t * @param response The outgoing response.\n\t * @param route The route to process.\n\t * @param contextIds The context IDs of the request.\n\t * @param processorState The state handed through the processors.\n\t * @returns A promise that resolves when the tenant context has been resolved and injected, or an error response set.\n\t */\n\tpublic async pre(\n\t\trequest: IHttpServerRequest,\n\t\tresponse: IHttpResponse,\n\t\troute: IBaseRoute | undefined,\n\t\tcontextIds: IContextIds,\n\t\tprocessorState: { [id: string]: unknown }\n\t): Promise<void> {\n\t\tif (!Is.empty(route) && !(route.skipTenant ?? false)) {\n\t\t\ttry {\n\t\t\t\tlet tenant;\n\t\t\t\tconst isSkipAuth = route.skipAuth ?? false;\n\t\t\t\tconst urlPath = new URL(request.url, \"http://localhost\").pathname;\n\t\t\t\tconst isApiKeyEndpoint = this._apiKeyEndpoints.some(re => re.test(urlPath));\n\n\t\t\t\tif (isApiKeyEndpoint) {\n\t\t\t\t\tconst apiKey = request.headers?.[this._apiKeyName] ?? request.query?.[this._apiKeyName];\n\t\t\t\t\tif (Is.stringValue(apiKey)) {\n\t\t\t\t\t\ttenant = await this.resolveByApiKey(apiKey);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow new UnauthorizedError(TenantProcessor.CLASS_NAME, \"missingApiKey\", {\n\t\t\t\t\t\t\tkeyName: this._apiKeyName\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst organizationIdQueryParam = request.query?.[ContextIdKeys.Organization];\n\t\t\t\t\tif (Is.stringValue(organizationIdQueryParam)) {\n\t\t\t\t\t\ttenant = await this.resolveByOrganizationId(organizationIdQueryParam);\n\t\t\t\t\t} else if (isSkipAuth) {\n\t\t\t\t\t\tthrow new UnauthorizedError(TenantProcessor.CLASS_NAME, \"missingOrganizationId\", {\n\t\t\t\t\t\t\tparamName: ContextIdKeys.Organization\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!Is.empty(tenant)) {\n\t\t\t\t\tcontextIds[ContextIdKeys.Tenant] = tenant.id;\n\t\t\t\t\tcontextIds[ContextIdKeys.Organization] = tenant.organizationId;\n\n\t\t\t\t\t// If the tenant has a custom public origin, we set it in the context for downstream processors to use.\n\t\t\t\t\tif (Is.stringValue(tenant.publicOrigin)) {\n\t\t\t\t\t\tcontextIds[HttpContextIdKeys.PublicOrigin] = tenant.publicOrigin;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tHttpErrorHelper.buildResponse(\n\t\t\t\t\tresponse,\n\t\t\t\t\tBaseError.fromError(err),\n\t\t\t\t\tHttpStatusCode.unauthorized,\n\t\t\t\t\tthis._includeErrorStack\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Resolve the tenant context from an api key.\n\t * @param apiKey The api key sent by the caller.\n\t * @returns The tenant associated with the api key.\n\t * @throws UnauthorizedError if no tenant matches the api key.\n\t * @internal\n\t */\n\tprivate async resolveByApiKey(apiKey: string): Promise<ITenant> {\n\t\ttry {\n\t\t\treturn await this._tenantAdminComponent.getByApiKey(apiKey);\n\t\t} catch (err) {\n\t\t\tif (this.isLookupFailure(err)) {\n\t\t\t\tthrow new UnauthorizedError(\n\t\t\t\t\tTenantProcessor.CLASS_NAME,\n\t\t\t\t\t\"apiKeyNotFound\",\n\t\t\t\t\t{ key: apiKey },\n\t\t\t\t\terr\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Resolve the tenant context from a plain organization query param.\n\t * Matches against the organization id or one of the legacy organization ids.\n\t * @param organizationId The organization id from the query param.\n\t * @returns The tenant associated with the organization id.\n\t * @throws UnauthorizedError if no tenant matches the organization id.\n\t * @internal\n\t */\n\tprivate async resolveByOrganizationId(organizationId: string): Promise<ITenant> {\n\t\ttry {\n\t\t\treturn await this._tenantAdminComponent.getTenantByOrganizationId(organizationId, true);\n\t\t} catch (err) {\n\t\t\tif (this.isLookupFailure(err)) {\n\t\t\t\tthrow new UnauthorizedError(\n\t\t\t\t\tTenantProcessor.CLASS_NAME,\n\t\t\t\t\t\"organizationIdNotFound\",\n\t\t\t\t\t{ organizationId },\n\t\t\t\t\terr\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Determine whether a tenant lookup failure means the credential is unusable.\n\t * A credential that matches no tenant, or is not even well formed, is unauthorized; anything\n\t * else is a genuine fault and is passed through untouched.\n\t * @param err The error raised by the tenant admin component.\n\t * @returns True if the credential should be reported as unauthorized.\n\t * @internal\n\t */\n\tprivate isLookupFailure(err: unknown): boolean {\n\t\treturn (\n\t\t\tBaseError.isErrorName(err, NotFoundError.CLASS_NAME) ||\n\t\t\tBaseError.isErrorName(err, GuardError.CLASS_NAME)\n\t\t);\n\t}\n}\n"]}
|
package/dist/es/tenantRoutes.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// Copyright 2024 IOTA Stiftung.
|
|
2
|
+
// Copyright 2026 3Sixty Trade Ltd.
|
|
2
3
|
// SPDX-License-Identifier: Apache-2.0.
|
|
3
4
|
import { HttpContextIdKeys, HttpHeaderHelper, HttpParameterHelper, HttpUrlHelper } from "@3sixty/api-models";
|
|
4
5
|
import { ContextIdStore } from "@3sixty/context";
|
|
@@ -8,6 +9,18 @@ import { HeaderTypes, HttpStatusCode } from "@3sixty/web";
|
|
|
8
9
|
* The source used when communicating about these routes.
|
|
9
10
|
*/
|
|
10
11
|
const ROUTES_SOURCE = "tenantRoutes";
|
|
12
|
+
/**
|
|
13
|
+
* The default authorization for the routes, used to seed authorization rules.
|
|
14
|
+
*/
|
|
15
|
+
const DEFAULT_AUTHORIZATION_READER = {
|
|
16
|
+
permission: "tenant:read",
|
|
17
|
+
role: "tenant-admin"
|
|
18
|
+
};
|
|
19
|
+
const DEFAULT_AUTHORIZATION_WRITER = {
|
|
20
|
+
permission: "tenant:write",
|
|
21
|
+
role: "tenant-admin",
|
|
22
|
+
inherits: [DEFAULT_AUTHORIZATION_READER.permission]
|
|
23
|
+
};
|
|
11
24
|
/**
|
|
12
25
|
* The tag to associate with the routes.
|
|
13
26
|
*/
|
|
@@ -58,7 +71,7 @@ export function generateRestRoutesTenants(baseRouteName, componentName) {
|
|
|
58
71
|
]
|
|
59
72
|
}
|
|
60
73
|
],
|
|
61
|
-
|
|
74
|
+
defaultAuthorization: DEFAULT_AUTHORIZATION_READER
|
|
62
75
|
};
|
|
63
76
|
const tenantGetByIdRoute = {
|
|
64
77
|
operationId: "tenantGetById",
|
|
@@ -102,7 +115,7 @@ export function generateRestRoutesTenants(baseRouteName, componentName) {
|
|
|
102
115
|
]
|
|
103
116
|
}
|
|
104
117
|
],
|
|
105
|
-
|
|
118
|
+
defaultAuthorization: DEFAULT_AUTHORIZATION_READER
|
|
106
119
|
};
|
|
107
120
|
const tenantGetByApiKeyRoute = {
|
|
108
121
|
operationId: "tenantGetByApiKey",
|
|
@@ -133,7 +146,7 @@ export function generateRestRoutesTenants(baseRouteName, componentName) {
|
|
|
133
146
|
]
|
|
134
147
|
}
|
|
135
148
|
],
|
|
136
|
-
|
|
149
|
+
defaultAuthorization: DEFAULT_AUTHORIZATION_READER
|
|
137
150
|
};
|
|
138
151
|
const tenantGetByPublicOriginRoute = {
|
|
139
152
|
operationId: "tenantGetByPublicOrigin",
|
|
@@ -162,7 +175,7 @@ export function generateRestRoutesTenants(baseRouteName, componentName) {
|
|
|
162
175
|
]
|
|
163
176
|
}
|
|
164
177
|
],
|
|
165
|
-
|
|
178
|
+
defaultAuthorization: DEFAULT_AUTHORIZATION_READER
|
|
166
179
|
};
|
|
167
180
|
const tenantRemoveRoute = {
|
|
168
181
|
operationId: "tenantRemove",
|
|
@@ -190,7 +203,7 @@ export function generateRestRoutesTenants(baseRouteName, componentName) {
|
|
|
190
203
|
type: "INoContentResponse"
|
|
191
204
|
}
|
|
192
205
|
],
|
|
193
|
-
|
|
206
|
+
defaultAuthorization: DEFAULT_AUTHORIZATION_WRITER
|
|
194
207
|
};
|
|
195
208
|
const tenantCreateRoute = {
|
|
196
209
|
operationId: "tenantCreate",
|
|
@@ -221,7 +234,7 @@ export function generateRestRoutesTenants(baseRouteName, componentName) {
|
|
|
221
234
|
type: "ICreatedResponse"
|
|
222
235
|
}
|
|
223
236
|
],
|
|
224
|
-
|
|
237
|
+
defaultAuthorization: DEFAULT_AUTHORIZATION_WRITER
|
|
225
238
|
};
|
|
226
239
|
const tenantUpdateRoute = {
|
|
227
240
|
operationId: "tenantUpdate",
|
|
@@ -255,7 +268,7 @@ export function generateRestRoutesTenants(baseRouteName, componentName) {
|
|
|
255
268
|
type: "INoContentResponse"
|
|
256
269
|
}
|
|
257
270
|
],
|
|
258
|
-
|
|
271
|
+
defaultAuthorization: DEFAULT_AUTHORIZATION_WRITER
|
|
259
272
|
};
|
|
260
273
|
return [
|
|
261
274
|
tenantListRoute,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenantRoutes.js","sourceRoot":"","sources":["../../src/tenantRoutes.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport {\n\tHttpContextIdKeys,\n\tHttpHeaderHelper,\n\tHttpParameterHelper,\n\tHttpUrlHelper,\n\ttype ICreatedResponse,\n\ttype IHttpRequestContext,\n\ttype INoContentResponse,\n\ttype IRestRoute,\n\ttype ITag,\n\ttype ITenantAdminComponent\n} from \"@3sixty/api-models\";\nimport { ContextIdStore } from \"@3sixty/context\";\nimport { Coerce, ComponentFactory, Guards, Is } from \"@3sixty/core\";\nimport { nameof } from \"@3sixty/nameof\";\nimport { HeaderTypes, HttpStatusCode, type IHttpHeaders } from \"@3sixty/web\";\nimport type { ITenantCreateRequest } from \"./models/api/ITenantCreateRequest.js\";\nimport type { ITenantGetByApiKeyRequest } from \"./models/api/ITenantGetByApiKeyRequest.js\";\nimport type { ITenantGetByIdRequest } from \"./models/api/ITenantGetByIdRequest.js\";\nimport type { ITenantGetByPublicOriginRequest } from \"./models/api/ITenantGetByPublicOriginRequest.js\";\nimport type { ITenantGetResponse } from \"./models/api/ITenantGetResponse.js\";\nimport type { ITenantListRequest } from \"./models/api/ITenantListRequest.js\";\nimport type { ITenantListResponse } from \"./models/api/ITenantListResponse.js\";\nimport type { ITenantRemoveRequest } from \"./models/api/ITenantRemoveRequest.js\";\nimport type { ITenantUpdateRequest } from \"./models/api/ITenantUpdateRequest.js\";\n\n/**\n * The source used when communicating about these routes.\n */\nconst ROUTES_SOURCE = \"tenantRoutes\";\n\n/**\n * The tag to associate with the routes.\n */\nexport const tagsTenants: ITag[] = [\n\t{\n\t\tname: \"Tenants\",\n\t\tdescription: \"Tenants endpoints for the REST server.\"\n\t}\n];\n\n/**\n * The REST routes for tenant management.\n * @param baseRouteName Prefix to prepend to the paths.\n * @param componentName The name of the component to use in the routes stored in the ComponentFactory.\n * @returns The generated routes.\n */\nexport function generateRestRoutesTenants(\n\tbaseRouteName: string,\n\tcomponentName: string\n): IRestRoute[] {\n\tconst tenantListRoute: IRestRoute<ITenantListRequest, ITenantListResponse> = {\n\t\toperationId: \"tenantList\",\n\t\tsummary: \"Get the list of tenants\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"GET\",\n\t\tpath: `${baseRouteName}/`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantList(httpRequestContext, componentName, request),\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<ITenantListResponse>(),\n\t\t\t\texamples: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"tenantListResponse\",\n\t\t\t\t\t\tdescription: \"The response for the list tenants request.\",\n\t\t\t\t\t\tresponse: {\n\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\t[HeaderTypes.Link]: '<https://api.3sixty.global/tenants/1>; rel=\"next\"'\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbody: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\",\n\t\t\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\t\t\tdateCreated: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\t\tdateModified: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\",\n\t\t\t\t\t\t\t\t\torganizationId: \"org-1\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\trequiredScope: [\"tenant-admin\"]\n\t};\n\n\tconst tenantGetByIdRoute: IRestRoute<ITenantGetByIdRequest, ITenantGetResponse> = {\n\t\toperationId: \"tenantGetById\",\n\t\tsummary: \"Get the tenant by id\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"GET\",\n\t\tpath: `${baseRouteName}/:id`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantById(httpRequestContext, componentName, request),\n\t\trequestType: {\n\t\t\ttype: nameof<ITenantGetByIdRequest>(),\n\t\t\texamples: [\n\t\t\t\t{\n\t\t\t\t\tid: \"tenantGetByIdRequestExample\",\n\t\t\t\t\trequest: {\n\t\t\t\t\t\tpathParams: {\n\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<ITenantGetResponse>(),\n\t\t\t\texamples: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"tenantGetByIdResponse\",\n\t\t\t\t\t\tdescription: \"The response for the get tenant by id request.\",\n\t\t\t\t\t\tresponse: {\n\t\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\",\n\t\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\t\tdateCreated: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\tdateModified: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\",\n\t\t\t\t\t\t\t\torganizationId: \"org-1\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\trequiredScope: [\"tenant-admin\"]\n\t};\n\n\tconst tenantGetByApiKeyRoute: IRestRoute<ITenantGetByApiKeyRequest, ITenantGetResponse> = {\n\t\toperationId: \"tenantGetByApiKey\",\n\t\tsummary: \"Get the tenant by api key\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"GET\",\n\t\tpath: `${baseRouteName}/api-key/:apiKey`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantByApiKey(httpRequestContext, componentName, request),\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<ITenantGetResponse>(),\n\t\t\t\texamples: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"tenantGetByApiKeyResponse\",\n\t\t\t\t\t\tdescription: \"The response for the get tenant by api key request.\",\n\t\t\t\t\t\tresponse: {\n\t\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\",\n\t\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\t\tdateCreated: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\tdateModified: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\",\n\t\t\t\t\t\t\t\torganizationId: \"org-1\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\trequiredScope: [\"tenant-admin\"]\n\t};\n\n\tconst tenantGetByPublicOriginRoute: IRestRoute = {\n\t\toperationId: \"tenantGetByPublicOrigin\",\n\t\tsummary: \"Get the tenant by public origin\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"GET\",\n\t\tpath: `${baseRouteName}/public-origin/:publicOrigin`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantByPublicOrigin(httpRequestContext, componentName, request),\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<ITenantGetResponse>(),\n\t\t\t\texamples: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"tenantGetByPublicOriginResponse\",\n\t\t\t\t\t\tdescription: \"The response for the get tenant by public origin request.\",\n\t\t\t\t\t\tresponse: {\n\t\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\",\n\t\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\t\tdateCreated: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\trequiredScope: [\"tenant-admin\"]\n\t};\n\n\tconst tenantRemoveRoute: IRestRoute<ITenantRemoveRequest, INoContentResponse> = {\n\t\toperationId: \"tenantRemove\",\n\t\tsummary: \"Remove the tenant by id\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"DELETE\",\n\t\tpath: `${baseRouteName}/:id`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantRemove(httpRequestContext, componentName, request),\n\t\trequestType: {\n\t\t\ttype: nameof<ITenantRemoveRequest>(),\n\t\t\texamples: [\n\t\t\t\t{\n\t\t\t\t\tid: \"tenantRemoveRequestExample\",\n\t\t\t\t\tdescription: \"The request for the remove tenant by id request.\",\n\t\t\t\t\trequest: {\n\t\t\t\t\t\tpathParams: {\n\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<INoContentResponse>()\n\t\t\t}\n\t\t],\n\t\trequiredScope: [\"tenant-admin\"]\n\t};\n\n\tconst tenantCreateRoute: IRestRoute<ITenantCreateRequest, ICreatedResponse> = {\n\t\toperationId: \"tenantCreate\",\n\t\tsummary: \"Create a new tenant\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"POST\",\n\t\tpath: `${baseRouteName}/`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantCreate(httpRequestContext, componentName, request, baseRouteName),\n\t\trequestType: {\n\t\t\ttype: nameof<ITenantCreateRequest>(),\n\t\t\texamples: [\n\t\t\t\t{\n\t\t\t\t\tid: \"tenantCreateRequestExample\",\n\t\t\t\t\tdescription: \"The request for the create tenant request.\",\n\t\t\t\t\trequest: {\n\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\",\n\t\t\t\t\t\t\torganizationId: \"org-1\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<ICreatedResponse>()\n\t\t\t}\n\t\t],\n\t\trequiredScope: [\"tenant-admin\"]\n\t};\n\n\tconst tenantUpdateRoute: IRestRoute<ITenantUpdateRequest, INoContentResponse> = {\n\t\toperationId: \"tenantUpdate\",\n\t\tsummary: \"Update an existing tenant\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"PUT\",\n\t\tpath: `${baseRouteName}/:id`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantUpdate(httpRequestContext, componentName, request),\n\t\trequestType: {\n\t\t\ttype: nameof<ITenantUpdateRequest>(),\n\t\t\texamples: [\n\t\t\t\t{\n\t\t\t\t\tid: \"tenantUpdateRequestExample\",\n\t\t\t\t\tdescription: \"The request for the update tenant request.\",\n\t\t\t\t\trequest: {\n\t\t\t\t\t\tpathParams: {\n\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\",\n\t\t\t\t\t\t\torganizationId: \"org-1\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<INoContentResponse>()\n\t\t\t}\n\t\t],\n\t\trequiredScope: [\"tenant-admin\"]\n\t};\n\n\treturn [\n\t\ttenantListRoute,\n\t\ttenantCreateRoute,\n\t\ttenantGetByIdRoute,\n\t\ttenantGetByApiKeyRoute,\n\t\ttenantGetByPublicOriginRoute,\n\t\ttenantRemoveRoute,\n\t\ttenantUpdateRoute\n\t];\n}\n\n/**\n * Get the list of tenants.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantList(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantListRequest\n): Promise<ITenantListResponse> {\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tconst result = await component.query(\n\t\tHttpParameterHelper.objectFromString(request.query?.conditions),\n\t\tHttpParameterHelper.arrayFromString(request.query?.properties),\n\t\trequest.query?.cursor,\n\t\tCoerce.integer(request.query?.limit)\n\t);\n\n\tconst headers: ITenantListResponse[\"headers\"] = {};\n\tconst contextIds = await ContextIdStore.getContextIds();\n\tconst publicOrigin = contextIds?.[HttpContextIdKeys.PublicOrigin];\n\n\tHttpHeaderHelper.buildCursor(\n\t\theaders,\n\t\thttpRequestContext.serverRequest.url,\n\t\tpublicOrigin,\n\t\tresult.cursor\n\t);\n\n\treturn {\n\t\theaders,\n\t\tbody: result.tenants.map(t => ({\n\t\t\t...t,\n\t\t\tpublicOrigin: t.publicOrigin ?? publicOrigin\n\t\t}))\n\t};\n}\n\n/**\n * Get the tenant by id.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantById(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantGetByIdRequest\n): Promise<ITenantGetResponse> {\n\tGuards.stringValue(ROUTES_SOURCE, nameof(request.pathParams.id), request.pathParams.id);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tconst result = await component.get(request.pathParams.id);\n\n\tif (!Is.stringValue(result.publicOrigin)) {\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst publicOrigin = contextIds?.[HttpContextIdKeys.PublicOrigin];\n\n\t\tresult.publicOrigin ??= publicOrigin;\n\t}\n\n\treturn {\n\t\tbody: result\n\t};\n}\n\n/**\n * Get the tenant by api key.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantByApiKey(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantGetByApiKeyRequest\n): Promise<ITenantGetResponse> {\n\tGuards.stringValue(ROUTES_SOURCE, nameof(request.pathParams.apiKey), request.pathParams.apiKey);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tconst result = await component.getByApiKey(request.pathParams.apiKey);\n\n\tif (!Is.stringValue(result.publicOrigin)) {\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst publicOrigin = contextIds?.[HttpContextIdKeys.PublicOrigin];\n\t\tresult.publicOrigin ??= publicOrigin;\n\t}\n\n\treturn {\n\t\tbody: result\n\t};\n}\n\n/**\n * Get the tenant by public origin.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantByPublicOrigin(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantGetByPublicOriginRequest\n): Promise<ITenantGetResponse> {\n\tGuards.stringValue(\n\t\tROUTES_SOURCE,\n\t\tnameof(request.pathParams.publicOrigin),\n\t\trequest.pathParams.publicOrigin\n\t);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tconst result = await component.getByPublicOrigin(request.pathParams.publicOrigin);\n\n\tif (!Is.stringValue(result.publicOrigin)) {\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst publicOrigin = contextIds?.[HttpContextIdKeys.PublicOrigin];\n\t\tresult.publicOrigin ??= publicOrigin;\n\t}\n\n\treturn {\n\t\tbody: result\n\t};\n}\n\n/**\n * Remove the tenant by id.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantRemove(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantRemoveRequest\n): Promise<INoContentResponse> {\n\tGuards.stringValue(ROUTES_SOURCE, nameof(request.pathParams.id), request.pathParams.id);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tawait component.remove(request.pathParams.id);\n\n\treturn {\n\t\tstatusCode: HttpStatusCode.noContent\n\t};\n}\n\n/**\n * Create the tenant.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @param baseRouteName The base route name for the tenant.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantCreate(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantCreateRequest,\n\tbaseRouteName: string\n): Promise<ICreatedResponse> {\n\tGuards.stringValue(ROUTES_SOURCE, nameof(request.body), request.body);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tconst createdId = await component.create(request.body);\n\n\tconst contextIds = await ContextIdStore.getContextIds();\n\tconst publicOrigin = contextIds?.[HttpContextIdKeys.PublicOrigin];\n\n\tconst headers: IHttpHeaders = {};\n\tHttpHeaderHelper.buildId(\n\t\theaders,\n\t\tcreatedId,\n\t\tHttpUrlHelper.combineOriginPath(publicOrigin, `${baseRouteName}/:id`)\n\t);\n\n\treturn {\n\t\tstatusCode: HttpStatusCode.created,\n\t\theaders\n\t};\n}\n\n/**\n * Update the tenant.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantUpdate(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantUpdateRequest\n): Promise<INoContentResponse> {\n\tGuards.stringValue(ROUTES_SOURCE, nameof(request.pathParams.id), request.pathParams.id);\n\tGuards.stringValue(ROUTES_SOURCE, nameof(request.body), request.body);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tawait component.update(request.body);\n\n\treturn {\n\t\tstatusCode: HttpStatusCode.noContent\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tenantRoutes.js","sources":["../../src/tenantRoutes.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// Copyright 2026 3Sixty Trade Ltd.\n// SPDX-License-Identifier: Apache-2.0.\nimport {\n\tHttpContextIdKeys,\n\tHttpHeaderHelper,\n\tHttpParameterHelper,\n\tHttpUrlHelper,\n\ttype ICreatedResponse,\n\ttype IHttpRequestContext,\n\ttype INoContentResponse,\n\ttype IRestRoute,\n\ttype ITag,\n\ttype ITenantAdminComponent,\n\ttype IRouteAuthorization\n} from \"@3sixty/api-models\";\nimport { ContextIdStore } from \"@3sixty/context\";\nimport { Coerce, ComponentFactory, Guards, Is } from \"@3sixty/core\";\n\nimport { HeaderTypes, HttpStatusCode, type IHttpHeaders } from \"@3sixty/web\";\nimport type { ITenantCreateRequest } from \"./models/api/ITenantCreateRequest.js\";\nimport type { ITenantGetByApiKeyRequest } from \"./models/api/ITenantGetByApiKeyRequest.js\";\nimport type { ITenantGetByIdRequest } from \"./models/api/ITenantGetByIdRequest.js\";\nimport type { ITenantGetByPublicOriginRequest } from \"./models/api/ITenantGetByPublicOriginRequest.js\";\nimport type { ITenantGetResponse } from \"./models/api/ITenantGetResponse.js\";\nimport type { ITenantListRequest } from \"./models/api/ITenantListRequest.js\";\nimport type { ITenantListResponse } from \"./models/api/ITenantListResponse.js\";\nimport type { ITenantRemoveRequest } from \"./models/api/ITenantRemoveRequest.js\";\nimport type { ITenantUpdateRequest } from \"./models/api/ITenantUpdateRequest.js\";\n\n/**\n * The source used when communicating about these routes.\n */\nconst ROUTES_SOURCE = \"tenantRoutes\";\n\n/**\n * The default authorization for the routes, used to seed authorization rules.\n */\nconst DEFAULT_AUTHORIZATION_READER: IRouteAuthorization = {\n\tpermission: \"tenant:read\",\n\trole: \"tenant-admin\"\n};\nconst DEFAULT_AUTHORIZATION_WRITER: IRouteAuthorization = {\n\tpermission: \"tenant:write\",\n\trole: \"tenant-admin\",\n\tinherits: [DEFAULT_AUTHORIZATION_READER.permission]\n};\n\n/**\n * The tag to associate with the routes.\n */\nexport const tagsTenants: ITag[] = [\n\t{\n\t\tname: \"Tenants\",\n\t\tdescription: \"Tenants endpoints for the REST server.\"\n\t}\n];\n\n/**\n * The REST routes for tenant management.\n * @param baseRouteName Prefix to prepend to the paths.\n * @param componentName The name of the component to use in the routes stored in the ComponentFactory.\n * @returns The generated routes.\n */\nexport function generateRestRoutesTenants(\n\tbaseRouteName: string,\n\tcomponentName: string\n): IRestRoute[] {\n\tconst tenantListRoute: IRestRoute<ITenantListRequest, ITenantListResponse> = {\n\t\toperationId: \"tenantList\",\n\t\tsummary: \"Get the list of tenants\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"GET\",\n\t\tpath: `${baseRouteName}/`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantList(httpRequestContext, componentName, request),\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: \"ITenantListResponse\",\n\t\t\t\texamples: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"tenantListResponse\",\n\t\t\t\t\t\tdescription: \"The response for the list tenants request.\",\n\t\t\t\t\t\tresponse: {\n\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\t[HeaderTypes.Link]: '<https://api.3sixty.global/tenants/1>; rel=\"next\"'\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbody: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\",\n\t\t\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\t\t\tdateCreated: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\t\tdateModified: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\",\n\t\t\t\t\t\t\t\t\torganizationId: \"org-1\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\tdefaultAuthorization: DEFAULT_AUTHORIZATION_READER\n\t};\n\n\tconst tenantGetByIdRoute: IRestRoute<ITenantGetByIdRequest, ITenantGetResponse> = {\n\t\toperationId: \"tenantGetById\",\n\t\tsummary: \"Get the tenant by id\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"GET\",\n\t\tpath: `${baseRouteName}/:id`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantById(httpRequestContext, componentName, request),\n\t\trequestType: {\n\t\t\ttype: \"ITenantGetByIdRequest\",\n\t\t\texamples: [\n\t\t\t\t{\n\t\t\t\t\tid: \"tenantGetByIdRequestExample\",\n\t\t\t\t\trequest: {\n\t\t\t\t\t\tpathParams: {\n\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: \"ITenantGetResponse\",\n\t\t\t\texamples: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"tenantGetByIdResponse\",\n\t\t\t\t\t\tdescription: \"The response for the get tenant by id request.\",\n\t\t\t\t\t\tresponse: {\n\t\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\",\n\t\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\t\tdateCreated: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\tdateModified: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\",\n\t\t\t\t\t\t\t\torganizationId: \"org-1\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\tdefaultAuthorization: DEFAULT_AUTHORIZATION_READER\n\t};\n\n\tconst tenantGetByApiKeyRoute: IRestRoute<ITenantGetByApiKeyRequest, ITenantGetResponse> = {\n\t\toperationId: \"tenantGetByApiKey\",\n\t\tsummary: \"Get the tenant by api key\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"GET\",\n\t\tpath: `${baseRouteName}/api-key/:apiKey`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantByApiKey(httpRequestContext, componentName, request),\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: \"ITenantGetResponse\",\n\t\t\t\texamples: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"tenantGetByApiKeyResponse\",\n\t\t\t\t\t\tdescription: \"The response for the get tenant by api key request.\",\n\t\t\t\t\t\tresponse: {\n\t\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\",\n\t\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\t\tdateCreated: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\tdateModified: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\",\n\t\t\t\t\t\t\t\torganizationId: \"org-1\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\tdefaultAuthorization: DEFAULT_AUTHORIZATION_READER\n\t};\n\n\tconst tenantGetByPublicOriginRoute: IRestRoute = {\n\t\toperationId: \"tenantGetByPublicOrigin\",\n\t\tsummary: \"Get the tenant by public origin\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"GET\",\n\t\tpath: `${baseRouteName}/public-origin/:publicOrigin`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantByPublicOrigin(httpRequestContext, componentName, request),\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: \"ITenantGetResponse\",\n\t\t\t\texamples: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"tenantGetByPublicOriginResponse\",\n\t\t\t\t\t\tdescription: \"The response for the get tenant by public origin request.\",\n\t\t\t\t\t\tresponse: {\n\t\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\",\n\t\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\t\tdateCreated: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\tdefaultAuthorization: DEFAULT_AUTHORIZATION_READER\n\t};\n\n\tconst tenantRemoveRoute: IRestRoute<ITenantRemoveRequest, INoContentResponse> = {\n\t\toperationId: \"tenantRemove\",\n\t\tsummary: \"Remove the tenant by id\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"DELETE\",\n\t\tpath: `${baseRouteName}/:id`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantRemove(httpRequestContext, componentName, request),\n\t\trequestType: {\n\t\t\ttype: \"ITenantRemoveRequest\",\n\t\t\texamples: [\n\t\t\t\t{\n\t\t\t\t\tid: \"tenantRemoveRequestExample\",\n\t\t\t\t\tdescription: \"The request for the remove tenant by id request.\",\n\t\t\t\t\trequest: {\n\t\t\t\t\t\tpathParams: {\n\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: \"INoContentResponse\"\n\t\t\t}\n\t\t],\n\t\tdefaultAuthorization: DEFAULT_AUTHORIZATION_WRITER\n\t};\n\n\tconst tenantCreateRoute: IRestRoute<ITenantCreateRequest, ICreatedResponse> = {\n\t\toperationId: \"tenantCreate\",\n\t\tsummary: \"Create a new tenant\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"POST\",\n\t\tpath: `${baseRouteName}/`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantCreate(httpRequestContext, componentName, request, baseRouteName),\n\t\trequestType: {\n\t\t\ttype: \"ITenantCreateRequest\",\n\t\t\texamples: [\n\t\t\t\t{\n\t\t\t\t\tid: \"tenantCreateRequestExample\",\n\t\t\t\t\tdescription: \"The request for the create tenant request.\",\n\t\t\t\t\trequest: {\n\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\",\n\t\t\t\t\t\t\torganizationId: \"org-1\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: \"ICreatedResponse\"\n\t\t\t}\n\t\t],\n\t\tdefaultAuthorization: DEFAULT_AUTHORIZATION_WRITER\n\t};\n\n\tconst tenantUpdateRoute: IRestRoute<ITenantUpdateRequest, INoContentResponse> = {\n\t\toperationId: \"tenantUpdate\",\n\t\tsummary: \"Update an existing tenant\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"PUT\",\n\t\tpath: `${baseRouteName}/:id`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantUpdate(httpRequestContext, componentName, request),\n\t\trequestType: {\n\t\t\ttype: \"ITenantUpdateRequest\",\n\t\t\texamples: [\n\t\t\t\t{\n\t\t\t\t\tid: \"tenantUpdateRequestExample\",\n\t\t\t\t\tdescription: \"The request for the update tenant request.\",\n\t\t\t\t\trequest: {\n\t\t\t\t\t\tpathParams: {\n\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\",\n\t\t\t\t\t\t\torganizationId: \"org-1\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: \"INoContentResponse\"\n\t\t\t}\n\t\t],\n\t\tdefaultAuthorization: DEFAULT_AUTHORIZATION_WRITER\n\t};\n\n\treturn [\n\t\ttenantListRoute,\n\t\ttenantCreateRoute,\n\t\ttenantGetByIdRoute,\n\t\ttenantGetByApiKeyRoute,\n\t\ttenantGetByPublicOriginRoute,\n\t\ttenantRemoveRoute,\n\t\ttenantUpdateRoute\n\t];\n}\n\n/**\n * Get the list of tenants.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantList(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantListRequest\n): Promise<ITenantListResponse> {\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tconst result = await component.query(\n\t\tHttpParameterHelper.objectFromString(request.query?.conditions),\n\t\tHttpParameterHelper.arrayFromString(request.query?.properties),\n\t\trequest.query?.cursor,\n\t\tCoerce.integer(request.query?.limit)\n\t);\n\n\tconst headers: ITenantListResponse[\"headers\"] = {};\n\tconst contextIds = await ContextIdStore.getContextIds();\n\tconst publicOrigin = contextIds?.[HttpContextIdKeys.PublicOrigin];\n\n\tHttpHeaderHelper.buildCursor(\n\t\theaders,\n\t\thttpRequestContext.serverRequest.url,\n\t\tpublicOrigin,\n\t\tresult.cursor\n\t);\n\n\treturn {\n\t\theaders,\n\t\tbody: result.tenants.map(t => ({\n\t\t\t...t,\n\t\t\tpublicOrigin: t.publicOrigin ?? publicOrigin\n\t\t}))\n\t};\n}\n\n/**\n * Get the tenant by id.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantById(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantGetByIdRequest\n): Promise<ITenantGetResponse> {\n\tGuards.stringValue(ROUTES_SOURCE, \"request.pathParams.id\", request.pathParams.id);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tconst result = await component.get(request.pathParams.id);\n\n\tif (!Is.stringValue(result.publicOrigin)) {\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst publicOrigin = contextIds?.[HttpContextIdKeys.PublicOrigin];\n\n\t\tresult.publicOrigin ??= publicOrigin;\n\t}\n\n\treturn {\n\t\tbody: result\n\t};\n}\n\n/**\n * Get the tenant by api key.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantByApiKey(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantGetByApiKeyRequest\n): Promise<ITenantGetResponse> {\n\tGuards.stringValue(ROUTES_SOURCE, \"request.pathParams.apiKey\", request.pathParams.apiKey);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tconst result = await component.getByApiKey(request.pathParams.apiKey);\n\n\tif (!Is.stringValue(result.publicOrigin)) {\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst publicOrigin = contextIds?.[HttpContextIdKeys.PublicOrigin];\n\t\tresult.publicOrigin ??= publicOrigin;\n\t}\n\n\treturn {\n\t\tbody: result\n\t};\n}\n\n/**\n * Get the tenant by public origin.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantByPublicOrigin(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantGetByPublicOriginRequest\n): Promise<ITenantGetResponse> {\n\tGuards.stringValue(\n\t\tROUTES_SOURCE,\n\t\t\"request.pathParams.publicOrigin\",\n\t\trequest.pathParams.publicOrigin\n\t);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tconst result = await component.getByPublicOrigin(request.pathParams.publicOrigin);\n\n\tif (!Is.stringValue(result.publicOrigin)) {\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst publicOrigin = contextIds?.[HttpContextIdKeys.PublicOrigin];\n\t\tresult.publicOrigin ??= publicOrigin;\n\t}\n\n\treturn {\n\t\tbody: result\n\t};\n}\n\n/**\n * Remove the tenant by id.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantRemove(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantRemoveRequest\n): Promise<INoContentResponse> {\n\tGuards.stringValue(ROUTES_SOURCE, \"request.pathParams.id\", request.pathParams.id);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tawait component.remove(request.pathParams.id);\n\n\treturn {\n\t\tstatusCode: HttpStatusCode.noContent\n\t};\n}\n\n/**\n * Create the tenant.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @param baseRouteName The base route name for the tenant.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantCreate(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantCreateRequest,\n\tbaseRouteName: string\n): Promise<ICreatedResponse> {\n\tGuards.stringValue(ROUTES_SOURCE, \"request.body\", request.body);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tconst createdId = await component.create(request.body);\n\n\tconst contextIds = await ContextIdStore.getContextIds();\n\tconst publicOrigin = contextIds?.[HttpContextIdKeys.PublicOrigin];\n\n\tconst headers: IHttpHeaders = {};\n\tHttpHeaderHelper.buildId(\n\t\theaders,\n\t\tcreatedId,\n\t\tHttpUrlHelper.combineOriginPath(publicOrigin, `${baseRouteName}/:id`)\n\t);\n\n\treturn {\n\t\tstatusCode: HttpStatusCode.created,\n\t\theaders\n\t};\n}\n\n/**\n * Update the tenant.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantUpdate(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantUpdateRequest\n): Promise<INoContentResponse> {\n\tGuards.stringValue(ROUTES_SOURCE, \"request.pathParams.id\", request.pathParams.id);\n\tGuards.stringValue(ROUTES_SOURCE, \"request.body\", request.body);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tawait component.update(request.body);\n\n\treturn {\n\t\tstatusCode: HttpStatusCode.noContent\n\t};\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenantIdHelper.js","
|
|
1
|
+
{"version":3,"file":"tenantIdHelper.js","sources":["../../../src/utils/tenantIdHelper.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C;;GAEG;AACH,MAAM,OAAO,cAAc;IAC1B;;;OAGG;IACI,MAAM,CAAC,gBAAgB;QAC7B,OAAO,YAAY,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,cAAc;QAC3B,OAAO,YAAY,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC;CACD","sourcesContent":["// Copyright 2025 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { RandomHelper } from \"@3sixty/core\";\n\n/**\n * Helper class for tenant id related operations.\n */\nexport class TenantIdHelper {\n\t/**\n\t * Generates a new tenant ID.\n\t * @returns A new tenant ID.\n\t */\n\tpublic static generateTenantId(): string {\n\t\treturn RandomHelper.generateUuidV7(\"compact\");\n\t}\n\n\t/**\n\t * Generates a new API Key.\n\t * @returns A new API Key.\n\t */\n\tpublic static generateApiKey(): string {\n\t\treturn RandomHelper.generateUuidV7(\"compact\");\n\t}\n}\n"]}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export * from "./entities/tenant.js";
|
|
2
|
+
export * from "./entities/tenantV0.js";
|
|
3
|
+
export * from "./entities/tenantV1.js";
|
|
2
4
|
export * from "./models/api/ITenantCreateRequest.js";
|
|
3
5
|
export * from "./models/api/ITenantGetByApiKeyRequest.js";
|
|
4
6
|
export * from "./models/api/ITenantGetByIdRequest.js";
|
|
@@ -12,15 +14,13 @@ export * from "./models/ISingleTenantProcessorConfig.js";
|
|
|
12
14
|
export * from "./models/ISingleTenantProcessorConstructorOptions.js";
|
|
13
15
|
export * from "./models/ITenantAdminServiceConfig.js";
|
|
14
16
|
export * from "./models/ITenantAdminServiceConstructorOptions.js";
|
|
15
|
-
export * from "./models/ITenantOverrideProcessorConfig.js";
|
|
16
|
-
export * from "./models/ITenantOverrideProcessorConstructorOptions.js";
|
|
17
17
|
export * from "./models/ITenantProcessorConfig.js";
|
|
18
18
|
export * from "./models/ITenantProcessorConstructorOptions.js";
|
|
19
|
+
export * from "./restEntryPoints.js";
|
|
19
20
|
export * from "./schema.js";
|
|
20
21
|
export * from "./singleTenantProcessor.js";
|
|
21
22
|
export * from "./tenantAdminService.js";
|
|
22
23
|
export * from "./tenantIdContextIdHandler.js";
|
|
23
|
-
export * from "./tenantOverrideProcessor.js";
|
|
24
24
|
export * from "./tenantProcessor.js";
|
|
25
25
|
export * from "./tenantRoutes.js";
|
|
26
26
|
export * from "./utils/tenantIdHelper.js";
|
|
@@ -8,6 +8,11 @@ export interface ITenantAdminServiceConstructorOptions {
|
|
|
8
8
|
* @default tenant
|
|
9
9
|
*/
|
|
10
10
|
tenantEntityStorageType?: string;
|
|
11
|
+
/**
|
|
12
|
+
* The component type to use for firing tenant events.
|
|
13
|
+
* @default platform
|
|
14
|
+
*/
|
|
15
|
+
platformComponentType?: string;
|
|
11
16
|
/**
|
|
12
17
|
* Configuration for the service.
|
|
13
18
|
*/
|
package/docs/changelog.md
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.20.0-next.1](https://github.com/3sixtyglobal/api/compare/api-tenant-processor-v0.20.0-next.0...api-tenant-processor-v0.20.0-next.1) (2026-10-23)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* authorization ([#51](https://github.com/3sixtyglobal/api/issues/51)) ([023ef94](https://github.com/3sixtyglobal/api/commit/023ef94925114e88522cbe6f703d9b05a202bc6d))
|
|
9
|
+
* publish packages under the [@3sixty](https://github.com/3sixty) namespace ([91b1822](https://github.com/3sixtyglobal/api/commit/91b1822dba38f70692087ad4643572531d6634dc))
|
|
10
|
+
* updated ts compile ([d9a5c86](https://github.com/3sixtyglobal/api/commit/d9a5c86ec7dd1faf3045b5cd1e0d38a4b331313d))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Dependencies
|
|
14
|
+
|
|
15
|
+
* The following workspace dependencies were updated
|
|
16
|
+
* dependencies
|
|
17
|
+
* @3sixty/api-models bumped from 0.20.0-next.0 to 0.20.0-next.1
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Class: TenantV0
|
|
2
|
+
|
|
3
|
+
Class defining the storage for node tenants.
|
|
4
|
+
|
|
5
|
+
## Constructors
|
|
6
|
+
|
|
7
|
+
### Constructor
|
|
8
|
+
|
|
9
|
+
> **new TenantV0**(): `TenantV0`
|
|
10
|
+
|
|
11
|
+
#### Returns
|
|
12
|
+
|
|
13
|
+
`TenantV0`
|
|
14
|
+
|
|
15
|
+
## Properties
|
|
16
|
+
|
|
17
|
+
### id {#id}
|
|
18
|
+
|
|
19
|
+
> **id**: `string`
|
|
20
|
+
|
|
21
|
+
The unique identifier for the tenant.
|
|
22
|
+
|
|
23
|
+
***
|
|
24
|
+
|
|
25
|
+
### apiKey {#apikey}
|
|
26
|
+
|
|
27
|
+
> **apiKey**: `string`
|
|
28
|
+
|
|
29
|
+
The api key for the tenant.
|
|
30
|
+
|
|
31
|
+
***
|
|
32
|
+
|
|
33
|
+
### label {#label}
|
|
34
|
+
|
|
35
|
+
> **label**: `string`
|
|
36
|
+
|
|
37
|
+
The label of the tenant.
|
|
38
|
+
|
|
39
|
+
***
|
|
40
|
+
|
|
41
|
+
### dateCreated {#datecreated}
|
|
42
|
+
|
|
43
|
+
> **dateCreated**: `string`
|
|
44
|
+
|
|
45
|
+
The date the tenant was created.
|
|
46
|
+
|
|
47
|
+
***
|
|
48
|
+
|
|
49
|
+
### dateModified {#datemodified}
|
|
50
|
+
|
|
51
|
+
> **dateModified**: `string`
|
|
52
|
+
|
|
53
|
+
The date the tenant was modified.
|
|
54
|
+
|
|
55
|
+
***
|
|
56
|
+
|
|
57
|
+
### publicOrigin? {#publicorigin}
|
|
58
|
+
|
|
59
|
+
> `optional` **publicOrigin?**: `string`
|
|
60
|
+
|
|
61
|
+
The origin available to the public for accessing the API.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Class: TenantV1
|
|
2
|
+
|
|
3
|
+
Class defining the storage for node tenants.
|
|
4
|
+
|
|
5
|
+
## Constructors
|
|
6
|
+
|
|
7
|
+
### Constructor
|
|
8
|
+
|
|
9
|
+
> **new TenantV1**(): `TenantV1`
|
|
10
|
+
|
|
11
|
+
#### Returns
|
|
12
|
+
|
|
13
|
+
`TenantV1`
|
|
14
|
+
|
|
15
|
+
## Properties
|
|
16
|
+
|
|
17
|
+
### id {#id}
|
|
18
|
+
|
|
19
|
+
> **id**: `string`
|
|
20
|
+
|
|
21
|
+
The unique identifier for the tenant.
|
|
22
|
+
|
|
23
|
+
***
|
|
24
|
+
|
|
25
|
+
### apiKey {#apikey}
|
|
26
|
+
|
|
27
|
+
> **apiKey**: `string`
|
|
28
|
+
|
|
29
|
+
The api key for the tenant.
|
|
30
|
+
|
|
31
|
+
***
|
|
32
|
+
|
|
33
|
+
### label {#label}
|
|
34
|
+
|
|
35
|
+
> **label**: `string`
|
|
36
|
+
|
|
37
|
+
The label of the tenant.
|
|
38
|
+
|
|
39
|
+
***
|
|
40
|
+
|
|
41
|
+
### dateCreated {#datecreated}
|
|
42
|
+
|
|
43
|
+
> **dateCreated**: `string`
|
|
44
|
+
|
|
45
|
+
The date the tenant was created.
|
|
46
|
+
|
|
47
|
+
***
|
|
48
|
+
|
|
49
|
+
### dateModified {#datemodified}
|
|
50
|
+
|
|
51
|
+
> **dateModified**: `string`
|
|
52
|
+
|
|
53
|
+
The date the tenant was modified.
|
|
54
|
+
|
|
55
|
+
***
|
|
56
|
+
|
|
57
|
+
### publicOrigin? {#publicorigin}
|
|
58
|
+
|
|
59
|
+
> `optional` **publicOrigin?**: `string`
|
|
60
|
+
|
|
61
|
+
The origin available to the public for accessing the API.
|
|
62
|
+
|
|
63
|
+
***
|
|
64
|
+
|
|
65
|
+
### organizationId {#organizationid}
|
|
66
|
+
|
|
67
|
+
> **organizationId**: `string`
|
|
68
|
+
|
|
69
|
+
The organization id for the tenant.
|
|
70
|
+
|
|
71
|
+
***
|
|
72
|
+
|
|
73
|
+
### organizationIdLegacy? {#organizationidlegacy}
|
|
74
|
+
|
|
75
|
+
> `optional` **organizationIdLegacy?**: `string`
|
|
76
|
+
|
|
77
|
+
Optional list of organization aliases that can be used for legacy lookups, indexed format.
|
package/docs/reference/index.md
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
## Classes
|
|
4
4
|
|
|
5
5
|
- [Tenant](classes/Tenant.md)
|
|
6
|
+
- [TenantV0](classes/TenantV0.md)
|
|
7
|
+
- [TenantV1](classes/TenantV1.md)
|
|
6
8
|
- [SingleTenantProcessor](classes/SingleTenantProcessor.md)
|
|
7
9
|
- [TenantAdminService](classes/TenantAdminService.md)
|
|
8
10
|
- [TenantIdContextIdHandler](classes/TenantIdContextIdHandler.md)
|
|
9
|
-
- [TenantOverrideProcessor](classes/TenantOverrideProcessor.md)
|
|
10
11
|
- [TenantProcessor](classes/TenantProcessor.md)
|
|
11
12
|
- [TenantIdHelper](classes/TenantIdHelper.md)
|
|
12
13
|
|
|
@@ -16,8 +17,6 @@
|
|
|
16
17
|
- [ISingleTenantProcessorConstructorOptions](interfaces/ISingleTenantProcessorConstructorOptions.md)
|
|
17
18
|
- [ITenantAdminServiceConfig](interfaces/ITenantAdminServiceConfig.md)
|
|
18
19
|
- [ITenantAdminServiceConstructorOptions](interfaces/ITenantAdminServiceConstructorOptions.md)
|
|
19
|
-
- [ITenantOverrideProcessorConfig](interfaces/ITenantOverrideProcessorConfig.md)
|
|
20
|
-
- [ITenantOverrideProcessorConstructorOptions](interfaces/ITenantOverrideProcessorConstructorOptions.md)
|
|
21
20
|
- [ITenantProcessorConfig](interfaces/ITenantProcessorConfig.md)
|
|
22
21
|
- [ITenantProcessorConstructorOptions](interfaces/ITenantProcessorConstructorOptions.md)
|
|
23
22
|
- [ITenantCreateRequest](interfaces/ITenantCreateRequest.md)
|
|
@@ -32,6 +31,7 @@
|
|
|
32
31
|
|
|
33
32
|
## Variables
|
|
34
33
|
|
|
34
|
+
- [restEntryPoints](variables/restEntryPoints.md)
|
|
35
35
|
- [tagsTenants](variables/tagsTenants.md)
|
|
36
36
|
|
|
37
37
|
## Functions
|
|
@@ -18,6 +18,20 @@ tenant
|
|
|
18
18
|
|
|
19
19
|
***
|
|
20
20
|
|
|
21
|
+
### platformComponentType? {#platformcomponenttype}
|
|
22
|
+
|
|
23
|
+
> `optional` **platformComponentType?**: `string`
|
|
24
|
+
|
|
25
|
+
The component type to use for firing tenant events.
|
|
26
|
+
|
|
27
|
+
#### Default
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
platform
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
***
|
|
34
|
+
|
|
21
35
|
### config? {#config}
|
|
22
36
|
|
|
23
37
|
> `optional` **config?**: [`ITenantAdminServiceConfig`](ITenantAdminServiceConfig.md)
|
package/locales/en.json
CHANGED
|
@@ -6,10 +6,6 @@
|
|
|
6
6
|
"apiKeyNotFound": "No tenant found for API key \"{key}\".",
|
|
7
7
|
"organizationIdNotFound": "No tenant found for organization ID \"{organizationId}\"."
|
|
8
8
|
},
|
|
9
|
-
"tenantOverrideProcessor": {
|
|
10
|
-
"insufficientScopeForTenantOverride": "Caller does not hold the required scope for tenant override.",
|
|
11
|
-
"tenantNotFound": "Tenant \"{notFoundId}\" not found."
|
|
12
|
-
},
|
|
13
9
|
"singleTenantProcessor": {
|
|
14
10
|
"invalidOrganizationId": "Organization ID query parameter \"{paramName}\" value \"{value}\" is not valid for this node"
|
|
15
11
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@3sixty/api-tenant-processor",
|
|
3
|
-
"version": "0.20.0-next.
|
|
3
|
+
"version": "0.20.0-next.1",
|
|
4
4
|
"description": "Tenant resolution services and route handlers that derive tenant context from API keys.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"node": ">=24.0.0"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@3sixty/api-models": "0.20.0-next.
|
|
17
|
+
"@3sixty/api-models": "0.20.0-next.1",
|
|
18
18
|
"@3sixty/context": "next",
|
|
19
19
|
"@3sixty/core": "next",
|
|
20
20
|
"@3sixty/crypto": "next",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ITenantOverrideProcessorConfig.js","sourceRoot":"","sources":["../../../src/models/ITenantOverrideProcessorConfig.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2026 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Configuration for the TenantOverrideProcessor.\n */\nexport interface ITenantOverrideProcessorConfig {\n\t/**\n\t * Include the stack with errors.\n\t */\n\tincludeErrorStack?: boolean;\n\n\t/**\n\t * The scope value that grants escalated privilege for cross-tenant access. Defaults to \"global-admin\".\n\t */\n\tescalatedPrivilegeScope?: string;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ITenantOverrideProcessorConstructorOptions.js","sourceRoot":"","sources":["../../../src/models/ITenantOverrideProcessorConstructorOptions.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2026 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { ITenantOverrideProcessorConfig } from \"./ITenantOverrideProcessorConfig.js\";\n\n/**\n * Options for the TenantOverrideProcessor constructor.\n */\nexport interface ITenantOverrideProcessorConstructorOptions {\n\t/**\n\t * The component used to resolve tenants, which also provides the lookup caching.\n\t * @default tenant-admin\n\t */\n\ttenantAdminComponentType?: string;\n\n\t/**\n\t * Configuration for the processor.\n\t */\n\tconfig?: ITenantOverrideProcessorConfig;\n}\n"]}
|