@twin.org/api-tenant-processor 0.0.3-next.1 → 0.0.3-next.10

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.
@@ -1,4 +1,4 @@
1
- import { Guards } from "@twin.org/core";
1
+ import { Converter, Guards } from "@twin.org/core";
2
2
  /**
3
3
  * Context Id handler for testing as a tenant id.
4
4
  */
@@ -8,12 +8,19 @@ export class TenantIdContextIdHandler {
8
8
  */
9
9
  static CLASS_NAME = "TenantIdContextIdHandler";
10
10
  /**
11
- * The short form of the tenant id is the same as the full version.
11
+ * The class name of the component.
12
+ * @returns The class name.
13
+ */
14
+ className() {
15
+ return TenantIdContextIdHandler.CLASS_NAME;
16
+ }
17
+ /**
18
+ * The short form of the tenant id is the base64 version to compact.
12
19
  * @param value The full context id value.
13
20
  * @returns Short form string.
14
21
  */
15
22
  short(value) {
16
- return value;
23
+ return Converter.bytesToBase64Url(Converter.hexToBytes(value));
17
24
  }
18
25
  /**
19
26
  * Guard the value ensuring length.
@@ -1 +1 @@
1
- {"version":3,"file":"tenantIdContextIdHandler.js","sourceRoot":"","sources":["../../src/tenantIdContextIdHandler.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAGxC;;GAEG;AACH,MAAM,OAAO,wBAAwB;IACpC;;OAEG;IACI,MAAM,CAAU,UAAU,8BAA8C;IAE/E;;;;OAIG;IACI,KAAK,CAAC,KAAa;QACzB,OAAO,KAAK,CAAC;IACd,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,KAAa;QACzB,MAAM,CAAC,eAAe,CAAC,wBAAwB,CAAC,UAAU,WAAiB,KAAK,EAAE,EAAE,CAAC,CAAC;IACvF,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { IContextIdHandler } from \"@twin.org/context\";\nimport { Guards } from \"@twin.org/core\";\nimport { nameof } from \"@twin.org/nameof\";\n\n/**\n * Context Id handler for testing as a tenant id.\n */\nexport class TenantIdContextIdHandler implements IContextIdHandler {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<TenantIdContextIdHandler>();\n\n\t/**\n\t * The short form of the tenant id is the same as the full version.\n\t * @param value The full context id value.\n\t * @returns Short form string.\n\t */\n\tpublic short(value: string): string {\n\t\treturn value;\n\t}\n\n\t/**\n\t * Guard the value ensuring length.\n\t * @param value The value to guard.\n\t * @throws GeneralError if the value is too short.\n\t */\n\tpublic guard(value: string): void {\n\t\tGuards.stringHexLength(TenantIdContextIdHandler.CLASS_NAME, nameof(value), value, 32);\n\t}\n}\n"]}
1
+ {"version":3,"file":"tenantIdContextIdHandler.js","sourceRoot":"","sources":["../../src/tenantIdContextIdHandler.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAGnD;;GAEG;AACH,MAAM,OAAO,wBAAwB;IACpC;;OAEG;IACI,MAAM,CAAU,UAAU,8BAA8C;IAE/E;;;OAGG;IACI,SAAS;QACf,OAAO,wBAAwB,CAAC,UAAU,CAAC;IAC5C,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,KAAa;QACzB,OAAO,SAAS,CAAC,gBAAgB,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IAChE,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,KAAa;QACzB,MAAM,CAAC,eAAe,CAAC,wBAAwB,CAAC,UAAU,WAAiB,KAAK,EAAE,EAAE,CAAC,CAAC;IACvF,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { IContextIdHandler } from \"@twin.org/context\";\nimport { Converter, Guards } from \"@twin.org/core\";\nimport { nameof } from \"@twin.org/nameof\";\n\n/**\n * Context Id handler for testing as a tenant id.\n */\nexport class TenantIdContextIdHandler implements IContextIdHandler {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<TenantIdContextIdHandler>();\n\n\t/**\n\t * The class name of the component.\n\t * @returns The class name.\n\t */\n\tpublic className(): string {\n\t\treturn TenantIdContextIdHandler.CLASS_NAME;\n\t}\n\n\t/**\n\t * The short form of the tenant id is the base64 version to compact.\n\t * @param value The full context id value.\n\t * @returns Short form string.\n\t */\n\tpublic short(value: string): string {\n\t\treturn Converter.bytesToBase64Url(Converter.hexToBytes(value));\n\t}\n\n\t/**\n\t * Guard the value ensuring length.\n\t * @param value The value to guard.\n\t * @throws GeneralError if the value is too short.\n\t */\n\tpublic guard(value: string): void {\n\t\tGuards.stringHexLength(TenantIdContextIdHandler.CLASS_NAME, nameof(value), value, 32);\n\t}\n}\n"]}
@@ -52,31 +52,33 @@ export class TenantProcessor {
52
52
  * @param processorState The state handed through the processors.
53
53
  */
54
54
  async pre(request, response, route, contextIds, processorState) {
55
- const apiKey = request.headers?.[this._apiKeyName] ?? request.query?.[this._apiKeyName];
56
- let errorResponse;
57
- if (Is.stringValue(apiKey)) {
58
- try {
59
- const nodeTenant = await this._entityStorageConnector.get(apiKey, "apiKey");
60
- if (Is.empty(nodeTenant)) {
61
- errorResponse = new UnauthorizedError(TenantProcessor.CLASS_NAME, "apiKeyNotFound", {
62
- key: apiKey
63
- });
55
+ if (!Is.empty(route) && !(route.skipTenant ?? false)) {
56
+ const apiKey = request.headers?.[this._apiKeyName] ?? request.query?.[this._apiKeyName];
57
+ let errorResponse;
58
+ if (Is.stringValue(apiKey)) {
59
+ try {
60
+ const nodeTenant = await this._entityStorageConnector.get(apiKey, "apiKey");
61
+ if (Is.empty(nodeTenant)) {
62
+ errorResponse = new UnauthorizedError(TenantProcessor.CLASS_NAME, "apiKeyNotFound", {
63
+ key: apiKey
64
+ });
65
+ }
66
+ else {
67
+ contextIds[ContextIdKeys.Tenant] = nodeTenant.id;
68
+ }
64
69
  }
65
- else {
66
- contextIds[ContextIdKeys.Tenant] = nodeTenant.id;
70
+ catch (err) {
71
+ errorResponse = BaseError.fromError(err);
67
72
  }
68
73
  }
69
- catch (err) {
70
- errorResponse = BaseError.fromError(err);
74
+ else {
75
+ errorResponse = new UnauthorizedError(TenantProcessor.CLASS_NAME, "missingApiKey", {
76
+ keyName: this._apiKeyName
77
+ });
78
+ }
79
+ if (!Is.empty(errorResponse)) {
80
+ HttpErrorHelper.buildResponse(response, errorResponse, HttpStatusCode.unauthorized);
71
81
  }
72
- }
73
- else {
74
- errorResponse = new UnauthorizedError(TenantProcessor.CLASS_NAME, "missingApiKey", {
75
- keyName: this._apiKeyName
76
- });
77
- }
78
- if (!Is.empty(errorResponse)) {
79
- HttpErrorHelper.buildResponse(response, errorResponse, HttpStatusCode.unauthorized);
80
82
  }
81
83
  }
82
84
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tenantProcessor.js","sourceRoot":"","sources":["../../src/tenantProcessor.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,OAAO,EACN,eAAe,EAKf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAoB,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,SAAS,EAAe,EAAE,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EACN,6BAA6B,EAE7B,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAI/C;;GAEG;AACH,MAAM,OAAO,eAAe;IAC3B;;;OAGG;IACI,MAAM,CAAU,oBAAoB,GAAW,WAAW,CAAC;IAElE;;OAEG;IACI,MAAM,CAAU,UAAU,qBAAqC;IAEtE;;;OAGG;IACc,uBAAuB,CAAkC;IAE1E;;;OAGG;IACc,WAAW,CAAS;IAErC;;;OAGG;IACH,YAAY,OAA4C;QACvD,IAAI,CAAC,uBAAuB,GAAG,6BAA6B,CAAC,GAAG,CAC/D,OAAO,EAAE,uBAAuB,IAAI,QAAQ,CAC5C,CAAC;QACF,IAAI,CAAC,WAAW,GAAG,OAAO,EAAE,MAAM,EAAE,UAAU,IAAI,eAAe,CAAC,oBAAoB,CAAC;IACxF,CAAC;IAED;;;OAGG;IACI,SAAS;QACf,OAAO,eAAe,CAAC,UAAU,CAAC;IACnC,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,GAAG,CACf,OAA2B,EAC3B,QAAuB,EACvB,KAA6B,EAC7B,UAAuB,EACvB,cAAyC;QAEzC,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACxF,IAAI,aAAiC,CAAC;QAEtC,IAAI,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACJ,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;gBAE5E,IAAI,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC1B,aAAa,GAAG,IAAI,iBAAiB,CAAC,eAAe,CAAC,UAAU,EAAE,gBAAgB,EAAE;wBACnF,GAAG,EAAE,MAAM;qBACX,CAAC,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACP,UAAU,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,EAAE,CAAC;gBAClD,CAAC;YACF,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,aAAa,GAAG,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YAC1C,CAAC;QACF,CAAC;aAAM,CAAC;YACP,aAAa,GAAG,IAAI,iBAAiB,CAAC,eAAe,CAAC,UAAU,EAAE,eAAe,EAAE;gBAClF,OAAO,EAAE,IAAI,CAAC,WAAW;aACzB,CAAC,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;YAC9B,eAAe,CAAC,aAAa,CAAC,QAAQ,EAAE,aAAa,EAAE,cAAc,CAAC,YAAY,CAAC,CAAC;QACrF,CAAC;IACF,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} from \"@twin.org/api-models\";\nimport { ContextIdKeys, type IContextIds } from \"@twin.org/context\";\nimport { BaseError, type IError, Is, UnauthorizedError } from \"@twin.org/core\";\nimport {\n\tEntityStorageConnectorFactory,\n\ttype IEntityStorageConnector\n} from \"@twin.org/entity-storage-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { HttpStatusCode } from \"@twin.org/web\";\nimport type { Tenant } from \"./entities/tenant.js\";\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 entity storage for api keys.\n\t * @internal\n\t */\n\tprivate readonly _entityStorageConnector: IEntityStorageConnector<Tenant>;\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 * Create a new instance of NodeTenantProcessor.\n\t * @param options Options for the processor.\n\t */\n\tconstructor(options?: ITenantProcessorConstructorOptions) {\n\t\tthis._entityStorageConnector = EntityStorageConnectorFactory.get(\n\t\t\toptions?.tenantEntityStorageType ?? \"tenant\"\n\t\t);\n\t\tthis._apiKeyName = options?.config?.apiKeyName ?? TenantProcessor.DEFAULT_API_KEY_NAME;\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 */\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\tconst apiKey = request.headers?.[this._apiKeyName] ?? request.query?.[this._apiKeyName];\n\t\tlet errorResponse: IError | undefined;\n\n\t\tif (Is.stringValue(apiKey)) {\n\t\t\ttry {\n\t\t\t\tconst nodeTenant = await this._entityStorageConnector.get(apiKey, \"apiKey\");\n\n\t\t\t\tif (Is.empty(nodeTenant)) {\n\t\t\t\t\terrorResponse = new UnauthorizedError(TenantProcessor.CLASS_NAME, \"apiKeyNotFound\", {\n\t\t\t\t\t\tkey: apiKey\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tcontextIds[ContextIdKeys.Tenant] = nodeTenant.id;\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\terrorResponse = BaseError.fromError(err);\n\t\t\t}\n\t\t} else {\n\t\t\terrorResponse = new UnauthorizedError(TenantProcessor.CLASS_NAME, \"missingApiKey\", {\n\t\t\t\tkeyName: this._apiKeyName\n\t\t\t});\n\t\t}\n\n\t\tif (!Is.empty(errorResponse)) {\n\t\t\tHttpErrorHelper.buildResponse(response, errorResponse, HttpStatusCode.unauthorized);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"tenantProcessor.js","sourceRoot":"","sources":["../../src/tenantProcessor.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,OAAO,EACN,eAAe,EAKf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAoB,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,SAAS,EAAe,EAAE,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EACN,6BAA6B,EAE7B,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAI/C;;GAEG;AACH,MAAM,OAAO,eAAe;IAC3B;;;OAGG;IACI,MAAM,CAAU,oBAAoB,GAAW,WAAW,CAAC;IAElE;;OAEG;IACI,MAAM,CAAU,UAAU,qBAAqC;IAEtE;;;OAGG;IACc,uBAAuB,CAAkC;IAE1E;;;OAGG;IACc,WAAW,CAAS;IAErC;;;OAGG;IACH,YAAY,OAA4C;QACvD,IAAI,CAAC,uBAAuB,GAAG,6BAA6B,CAAC,GAAG,CAC/D,OAAO,EAAE,uBAAuB,IAAI,QAAQ,CAC5C,CAAC;QACF,IAAI,CAAC,WAAW,GAAG,OAAO,EAAE,MAAM,EAAE,UAAU,IAAI,eAAe,CAAC,oBAAoB,CAAC;IACxF,CAAC;IAED;;;OAGG;IACI,SAAS;QACf,OAAO,eAAe,CAAC,UAAU,CAAC;IACnC,CAAC;IAED;;;;;;;OAOG;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,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACxF,IAAI,aAAiC,CAAC;YAEtC,IAAI,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5B,IAAI,CAAC;oBACJ,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;oBAE5E,IAAI,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;wBAC1B,aAAa,GAAG,IAAI,iBAAiB,CAAC,eAAe,CAAC,UAAU,EAAE,gBAAgB,EAAE;4BACnF,GAAG,EAAE,MAAM;yBACX,CAAC,CAAC;oBACJ,CAAC;yBAAM,CAAC;wBACP,UAAU,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,EAAE,CAAC;oBAClD,CAAC;gBACF,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACd,aAAa,GAAG,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBAC1C,CAAC;YACF,CAAC;iBAAM,CAAC;gBACP,aAAa,GAAG,IAAI,iBAAiB,CAAC,eAAe,CAAC,UAAU,EAAE,eAAe,EAAE;oBAClF,OAAO,EAAE,IAAI,CAAC,WAAW;iBACzB,CAAC,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC9B,eAAe,CAAC,aAAa,CAAC,QAAQ,EAAE,aAAa,EAAE,cAAc,CAAC,YAAY,CAAC,CAAC;YACrF,CAAC;QACF,CAAC;IACF,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} from \"@twin.org/api-models\";\nimport { ContextIdKeys, type IContextIds } from \"@twin.org/context\";\nimport { BaseError, type IError, Is, UnauthorizedError } from \"@twin.org/core\";\nimport {\n\tEntityStorageConnectorFactory,\n\ttype IEntityStorageConnector\n} from \"@twin.org/entity-storage-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { HttpStatusCode } from \"@twin.org/web\";\nimport type { Tenant } from \"./entities/tenant.js\";\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 entity storage for api keys.\n\t * @internal\n\t */\n\tprivate readonly _entityStorageConnector: IEntityStorageConnector<Tenant>;\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 * Create a new instance of NodeTenantProcessor.\n\t * @param options Options for the processor.\n\t */\n\tconstructor(options?: ITenantProcessorConstructorOptions) {\n\t\tthis._entityStorageConnector = EntityStorageConnectorFactory.get(\n\t\t\toptions?.tenantEntityStorageType ?? \"tenant\"\n\t\t);\n\t\tthis._apiKeyName = options?.config?.apiKeyName ?? TenantProcessor.DEFAULT_API_KEY_NAME;\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 */\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\tconst apiKey = request.headers?.[this._apiKeyName] ?? request.query?.[this._apiKeyName];\n\t\t\tlet errorResponse: IError | undefined;\n\n\t\t\tif (Is.stringValue(apiKey)) {\n\t\t\t\ttry {\n\t\t\t\t\tconst nodeTenant = await this._entityStorageConnector.get(apiKey, \"apiKey\");\n\n\t\t\t\t\tif (Is.empty(nodeTenant)) {\n\t\t\t\t\t\terrorResponse = new UnauthorizedError(TenantProcessor.CLASS_NAME, \"apiKeyNotFound\", {\n\t\t\t\t\t\t\tkey: apiKey\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontextIds[ContextIdKeys.Tenant] = nodeTenant.id;\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\terrorResponse = BaseError.fromError(err);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\terrorResponse = new UnauthorizedError(TenantProcessor.CLASS_NAME, \"missingApiKey\", {\n\t\t\t\t\tkeyName: this._apiKeyName\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (!Is.empty(errorResponse)) {\n\t\t\t\tHttpErrorHelper.buildResponse(response, errorResponse, HttpStatusCode.unauthorized);\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
@@ -8,7 +8,12 @@ export declare class TenantIdContextIdHandler implements IContextIdHandler {
8
8
  */
9
9
  static readonly CLASS_NAME: string;
10
10
  /**
11
- * The short form of the tenant id is the same as the full version.
11
+ * The class name of the component.
12
+ * @returns The class name.
13
+ */
14
+ className(): string;
15
+ /**
16
+ * The short form of the tenant id is the base64 version to compact.
12
17
  * @param value The full context id value.
13
18
  * @returns Short form string.
14
19
  */
package/docs/changelog.md CHANGED
@@ -1,5 +1,162 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.0.3-next.10](https://github.com/twinfoundation/api/compare/api-tenant-processor-v0.0.3-next.9...api-tenant-processor-v0.0.3-next.10) (2026-01-05)
4
+
5
+
6
+ ### Miscellaneous Chores
7
+
8
+ * **api-tenant-processor:** Synchronize repo versions
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * The following workspace dependencies were updated
14
+ * dependencies
15
+ * @twin.org/api-models bumped from 0.0.3-next.9 to 0.0.3-next.10
16
+
17
+ ## [0.0.3-next.9](https://github.com/twinfoundation/api/compare/api-tenant-processor-v0.0.3-next.8...api-tenant-processor-v0.0.3-next.9) (2026-01-05)
18
+
19
+
20
+ ### Features
21
+
22
+ * add context id features ([#42](https://github.com/twinfoundation/api/issues/42)) ([0186055](https://github.com/twinfoundation/api/commit/0186055c48afde842a4254b4df9ac9249c40fe40))
23
+ * add livez endpoint ([#57](https://github.com/twinfoundation/api/issues/57)) ([ef007db](https://github.com/twinfoundation/api/commit/ef007db8201736dd3053211f849ffd03baaa485e))
24
+ * add tests for tenant id handler ([c868e7e](https://github.com/twinfoundation/api/commit/c868e7e5831e13df39b8994c40834e51f69fa0b9))
25
+ * check tenant id in auth if set ([937ba0c](https://github.com/twinfoundation/api/commit/937ba0cd790038556a7b2af251e52b43cb059df4))
26
+ * check tenant id in auth if set ([66f7337](https://github.com/twinfoundation/api/commit/66f73374d3cf4c1c85ea96ec74bb30712fb84dd7))
27
+ * reduce short form tenant id length ([bcda377](https://github.com/twinfoundation/api/commit/bcda377daed03b21fd1c6ffe47bad4a45d96602b))
28
+
29
+
30
+ ### Bug Fixes
31
+
32
+ * do not check x-api-key for health resourcr ([#54](https://github.com/twinfoundation/api/issues/54)) ([897a747](https://github.com/twinfoundation/api/commit/897a747a57ed76ee37035f7ea3d40953df3f5fb0))
33
+ * remove extraneous type ([f85c52c](https://github.com/twinfoundation/api/commit/f85c52c55caa3a7a64f6f675842f0ea59289a5d9))
34
+ * use base64Url for tenant id short form so it doesn't include slash ([7210771](https://github.com/twinfoundation/api/commit/72107718650acd05440ce9d9bf10905e6052281c))
35
+
36
+
37
+ ### Dependencies
38
+
39
+ * The following workspace dependencies were updated
40
+ * dependencies
41
+ * @twin.org/api-models bumped from 0.0.3-next.8 to 0.0.3-next.9
42
+
43
+ ## [0.0.3-next.8](https://github.com/twinfoundation/api/compare/api-tenant-processor-v0.0.3-next.7...api-tenant-processor-v0.0.3-next.8) (2025-12-17)
44
+
45
+
46
+ ### Bug Fixes
47
+
48
+ * do not check x-api-key for health resourcr ([#54](https://github.com/twinfoundation/api/issues/54)) ([897a747](https://github.com/twinfoundation/api/commit/897a747a57ed76ee37035f7ea3d40953df3f5fb0))
49
+
50
+
51
+ ### Dependencies
52
+
53
+ * The following workspace dependencies were updated
54
+ * dependencies
55
+ * @twin.org/api-models bumped from 0.0.3-next.7 to 0.0.3-next.8
56
+
57
+ ## [0.0.3-next.7](https://github.com/twinfoundation/api/compare/api-tenant-processor-v0.0.3-next.6...api-tenant-processor-v0.0.3-next.7) (2025-11-26)
58
+
59
+
60
+ ### Miscellaneous Chores
61
+
62
+ * **api-tenant-processor:** Synchronize repo versions
63
+
64
+
65
+ ### Dependencies
66
+
67
+ * The following workspace dependencies were updated
68
+ * dependencies
69
+ * @twin.org/api-models bumped from 0.0.3-next.6 to 0.0.3-next.7
70
+
71
+ ## [0.0.3-next.6](https://github.com/twinfoundation/api/compare/api-tenant-processor-v0.0.3-next.5...api-tenant-processor-v0.0.3-next.6) (2025-11-20)
72
+
73
+
74
+ ### Features
75
+
76
+ * check tenant id in auth if set ([937ba0c](https://github.com/twinfoundation/api/commit/937ba0cd790038556a7b2af251e52b43cb059df4))
77
+ * check tenant id in auth if set ([66f7337](https://github.com/twinfoundation/api/commit/66f73374d3cf4c1c85ea96ec74bb30712fb84dd7))
78
+
79
+
80
+ ### Dependencies
81
+
82
+ * The following workspace dependencies were updated
83
+ * dependencies
84
+ * @twin.org/api-models bumped from 0.0.3-next.5 to 0.0.3-next.6
85
+
86
+ ## [0.0.3-next.5](https://github.com/twinfoundation/api/compare/api-tenant-processor-v0.0.3-next.4...api-tenant-processor-v0.0.3-next.5) (2025-11-14)
87
+
88
+
89
+ ### Miscellaneous Chores
90
+
91
+ * **api-tenant-processor:** Synchronize repo versions
92
+
93
+
94
+ ### Dependencies
95
+
96
+ * The following workspace dependencies were updated
97
+ * dependencies
98
+ * @twin.org/api-models bumped from 0.0.3-next.4 to 0.0.3-next.5
99
+
100
+ ## [0.0.3-next.4](https://github.com/twinfoundation/api/compare/api-tenant-processor-v0.0.3-next.3...api-tenant-processor-v0.0.3-next.4) (2025-11-14)
101
+
102
+
103
+ ### Features
104
+
105
+ * add context id features ([#42](https://github.com/twinfoundation/api/issues/42)) ([0186055](https://github.com/twinfoundation/api/commit/0186055c48afde842a4254b4df9ac9249c40fe40))
106
+ * add tests for tenant id handler ([c868e7e](https://github.com/twinfoundation/api/commit/c868e7e5831e13df39b8994c40834e51f69fa0b9))
107
+ * reduce short form tenant id length ([bcda377](https://github.com/twinfoundation/api/commit/bcda377daed03b21fd1c6ffe47bad4a45d96602b))
108
+
109
+
110
+ ### Bug Fixes
111
+
112
+ * remove extraneous type ([f85c52c](https://github.com/twinfoundation/api/commit/f85c52c55caa3a7a64f6f675842f0ea59289a5d9))
113
+ * use base64Url for tenant id short form so it doesn't include slash ([7210771](https://github.com/twinfoundation/api/commit/72107718650acd05440ce9d9bf10905e6052281c))
114
+
115
+
116
+ ### Dependencies
117
+
118
+ * The following workspace dependencies were updated
119
+ * dependencies
120
+ * @twin.org/api-models bumped from 0.0.3-next.3 to 0.0.3-next.4
121
+
122
+ ## [0.0.3-next.3](https://github.com/twinfoundation/api/compare/api-tenant-processor-v0.0.3-next.2...api-tenant-processor-v0.0.3-next.3) (2025-11-14)
123
+
124
+
125
+ ### Features
126
+
127
+ * add tests for tenant id handler ([c868e7e](https://github.com/twinfoundation/api/commit/c868e7e5831e13df39b8994c40834e51f69fa0b9))
128
+
129
+
130
+ ### Bug Fixes
131
+
132
+ * use base64Url for tenant id short form so it doesn't include slash ([7210771](https://github.com/twinfoundation/api/commit/72107718650acd05440ce9d9bf10905e6052281c))
133
+
134
+
135
+ ### Dependencies
136
+
137
+ * The following workspace dependencies were updated
138
+ * dependencies
139
+ * @twin.org/api-models bumped from 0.0.3-next.2 to 0.0.3-next.3
140
+
141
+ ## [0.0.3-next.2](https://github.com/twinfoundation/api/compare/api-tenant-processor-v0.0.3-next.1...api-tenant-processor-v0.0.3-next.2) (2025-11-12)
142
+
143
+
144
+ ### Features
145
+
146
+ * reduce short form tenant id length ([bcda377](https://github.com/twinfoundation/api/commit/bcda377daed03b21fd1c6ffe47bad4a45d96602b))
147
+
148
+
149
+ ### Bug Fixes
150
+
151
+ * remove extraneous type ([f85c52c](https://github.com/twinfoundation/api/commit/f85c52c55caa3a7a64f6f675842f0ea59289a5d9))
152
+
153
+
154
+ ### Dependencies
155
+
156
+ * The following workspace dependencies were updated
157
+ * dependencies
158
+ * @twin.org/api-models bumped from 0.0.3-next.1 to 0.0.3-next.2
159
+
3
160
  ## [0.0.3-next.1](https://github.com/twinfoundation/api/compare/api-tenant-processor-v0.0.3-next.0...api-tenant-processor-v0.0.3-next.1) (2025-11-10)
4
161
 
5
162
 
@@ -26,11 +26,29 @@ Runtime name for the class.
26
26
 
27
27
  ## Methods
28
28
 
29
+ ### className()
30
+
31
+ > **className**(): `string`
32
+
33
+ The class name of the component.
34
+
35
+ #### Returns
36
+
37
+ `string`
38
+
39
+ The class name.
40
+
41
+ #### Implementation of
42
+
43
+ `IContextIdHandler.className`
44
+
45
+ ***
46
+
29
47
  ### short()
30
48
 
31
49
  > **short**(`value`): `string`
32
50
 
33
- The short form of the tenant id is the same as the full version.
51
+ The short form of the tenant id is the base64 version to compact.
34
52
 
35
53
  #### Parameters
36
54
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/api-tenant-processor",
3
- "version": "0.0.3-next.1",
3
+ "version": "0.0.3-next.10",
4
4
  "description": "API Tenant Processor for converting and api key to a tenant id.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,7 +14,7 @@
14
14
  "node": ">=20.0.0"
15
15
  },
16
16
  "dependencies": {
17
- "@twin.org/api-models": "0.0.3-next.1",
17
+ "@twin.org/api-models": "0.0.3-next.10",
18
18
  "@twin.org/context": "next",
19
19
  "@twin.org/core": "next",
20
20
  "@twin.org/entity": "next",