@twin.org/api-tenant-processor 0.0.3-next.15 → 0.0.3-next.16
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 +16 -0
- package/dist/es/entities/tenant.js.map +1 -1
- package/dist/es/index.js +0 -2
- package/dist/es/index.js.map +1 -1
- package/dist/es/tenantAdminService.js +38 -5
- package/dist/es/tenantAdminService.js.map +1 -1
- package/dist/es/tenantProcessor.js +3 -0
- package/dist/es/tenantProcessor.js.map +1 -1
- package/dist/es/utils/tenantIdHelper.js +3 -3
- package/dist/es/utils/tenantIdHelper.js.map +1 -1
- package/dist/types/entities/tenant.d.ts +8 -0
- package/dist/types/index.d.ts +0 -2
- package/dist/types/tenantAdminService.d.ts +12 -3
- package/docs/changelog.md +14 -0
- package/docs/reference/classes/Tenant.md +16 -0
- package/docs/reference/classes/TenantAdminService.md +49 -13
- package/docs/reference/index.md +0 -2
- package/package.json +2 -2
- package/dist/es/models/ITenant.js +0 -4
- package/dist/es/models/ITenant.js.map +0 -1
- package/dist/es/models/ITenantAdminComponent.js +0 -2
- package/dist/es/models/ITenantAdminComponent.js.map +0 -1
- package/dist/types/models/ITenant.d.ts +0 -21
- package/dist/types/models/ITenantAdminComponent.d.ts +0 -41
- package/docs/reference/interfaces/ITenant.md +0 -35
- package/docs/reference/interfaces/ITenantAdminComponent.md +0 -123
|
@@ -21,6 +21,14 @@ let Tenant = class Tenant {
|
|
|
21
21
|
* The date the tenant was created.
|
|
22
22
|
*/
|
|
23
23
|
dateCreated;
|
|
24
|
+
/**
|
|
25
|
+
* The origin available to the public for accessing the API.
|
|
26
|
+
*/
|
|
27
|
+
publicOrigin;
|
|
28
|
+
/**
|
|
29
|
+
* Indicates whether the tenant is the node tenant.
|
|
30
|
+
*/
|
|
31
|
+
isNodeTenant;
|
|
24
32
|
};
|
|
25
33
|
__decorate([
|
|
26
34
|
property({ type: "string", isPrimary: true }),
|
|
@@ -38,6 +46,14 @@ __decorate([
|
|
|
38
46
|
property({ type: "string" }),
|
|
39
47
|
__metadata("design:type", String)
|
|
40
48
|
], Tenant.prototype, "dateCreated", void 0);
|
|
49
|
+
__decorate([
|
|
50
|
+
property({ type: "string", optional: true }),
|
|
51
|
+
__metadata("design:type", String)
|
|
52
|
+
], Tenant.prototype, "publicOrigin", void 0);
|
|
53
|
+
__decorate([
|
|
54
|
+
property({ type: "boolean" }),
|
|
55
|
+
__metadata("design:type", Boolean)
|
|
56
|
+
], Tenant.prototype, "isNodeTenant", void 0);
|
|
41
57
|
Tenant = __decorate([
|
|
42
58
|
entity()
|
|
43
59
|
], Tenant);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenant.js","sourceRoot":"","sources":["../../../src/entities/tenant.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;GAEG;AAEI,IAAM,MAAM,GAAZ,MAAM,MAAM;IAClB;;OAEG;IAEI,EAAE,CAAU;IAEnB;;OAEG;IAEI,MAAM,CAAU;IAEvB;;OAEG;IAEI,KAAK,CAAU;IAEtB;;OAEG;IAEI,WAAW,CAAU;
|
|
1
|
+
{"version":3,"file":"tenant.js","sourceRoot":"","sources":["../../../src/entities/tenant.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;GAEG;AAEI,IAAM,MAAM,GAAZ,MAAM,MAAM;IAClB;;OAEG;IAEI,EAAE,CAAU;IAEnB;;OAEG;IAEI,MAAM,CAAU;IAEvB;;OAEG;IAEI,KAAK,CAAU;IAEtB;;OAEG;IAEI,WAAW,CAAU;IAE5B;;OAEG;IAEI,YAAY,CAAU;IAE7B;;OAEG;IAEI,YAAY,CAAW;CAC9B,CAAA;AA/BO;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;;kCAC3B;AAMZ;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;;sCACN;AAMhB;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;;qCACP;AAMf;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;;2CACD;AAMrB;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;4CAChB;AAMtB;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;;4CACA;AAnClB,MAAM;IADlB,MAAM,EAAE;GACI,MAAM,CAoClB","sourcesContent":["// Copyright 2025 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { entity, property } from \"@twin.org/entity\";\n\n/**\n * Class defining the storage for node tenants.\n */\n@entity()\nexport class Tenant {\n\t/**\n\t * The unique identifier for the tenant.\n\t */\n\t@property({ type: \"string\", isPrimary: true })\n\tpublic id!: string;\n\n\t/**\n\t * The api key for the tenant.\n\t */\n\t@property({ type: \"string\" })\n\tpublic apiKey!: string;\n\n\t/**\n\t * The label of the tenant.\n\t */\n\t@property({ type: \"string\" })\n\tpublic label!: string;\n\n\t/**\n\t * The date the tenant was created.\n\t */\n\t@property({ type: \"string\" })\n\tpublic dateCreated!: string;\n\n\t/**\n\t * The origin available to the public for accessing the API.\n\t */\n\t@property({ type: \"string\", optional: true })\n\tpublic publicOrigin?: string;\n\n\t/**\n\t * Indicates whether the tenant is the node tenant.\n\t */\n\t@property({ type: \"boolean\" })\n\tpublic isNodeTenant!: boolean;\n}\n"]}
|
package/dist/es/index.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
// Copyright 2025 IOTA Stiftung.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0.
|
|
3
3
|
export * from "./entities/tenant.js";
|
|
4
|
-
export * from "./models/ITenant.js";
|
|
5
|
-
export * from "./models/ITenantAdminComponent.js";
|
|
6
4
|
export * from "./models/ITenantAdminServiceConfig.js";
|
|
7
5
|
export * from "./models/ITenantAdminServiceConstructorOptions.js";
|
|
8
6
|
export * from "./models/ITenantProcessorConfig.js";
|
package/dist/es/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uCAAuC,CAAC;AACtD,cAAc,mDAAmD,CAAC;AAClE,cAAc,oCAAoC,CAAC;AACnD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC","sourcesContent":["// Copyright 2025 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nexport * from \"./entities/tenant.js\";\nexport * from \"./models/ITenantAdminServiceConfig.js\";\nexport * from \"./models/ITenantAdminServiceConstructorOptions.js\";\nexport * from \"./models/ITenantProcessorConfig.js\";\nexport * from \"./models/ITenantProcessorConstructorOptions.js\";\nexport * from \"./schema.js\";\nexport * from \"./tenantAdminService.js\";\nexport * from \"./tenantIdContextIdHandler.js\";\nexport * from \"./tenantProcessor.js\";\nexport * from \"./utils/tenantIdHelper.js\";\n"]}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { GeneralError, Guards } from "@twin.org/core";
|
|
1
|
+
import { GeneralError, Guards, Is, Url } from "@twin.org/core";
|
|
2
|
+
import { ComparisonOperator } from "@twin.org/entity";
|
|
4
3
|
import { EntityStorageConnectorFactory } from "@twin.org/entity-storage-models";
|
|
5
4
|
import { Tenant } from "./entities/tenant.js";
|
|
6
5
|
/**
|
|
@@ -58,6 +57,20 @@ export class TenantAdminService {
|
|
|
58
57
|
catch { }
|
|
59
58
|
return tenant;
|
|
60
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Get a tenant by its public origin.
|
|
62
|
+
* @param publicOrigin The public origin of the tenant.
|
|
63
|
+
* @returns The tenant or undefined if not found.
|
|
64
|
+
*/
|
|
65
|
+
async getByPublicOrigin(publicOrigin) {
|
|
66
|
+
Guards.stringValue(TenantAdminService.CLASS_NAME, "publicOrigin", publicOrigin);
|
|
67
|
+
let tenant;
|
|
68
|
+
try {
|
|
69
|
+
tenant = await this._entityStorageConnector.get(publicOrigin, "publicOrigin");
|
|
70
|
+
}
|
|
71
|
+
catch { }
|
|
72
|
+
return tenant;
|
|
73
|
+
}
|
|
61
74
|
/**
|
|
62
75
|
* Set a tenant.
|
|
63
76
|
* @param tenant The tenant to store.
|
|
@@ -67,6 +80,13 @@ export class TenantAdminService {
|
|
|
67
80
|
Guards.objectValue(TenantAdminService.CLASS_NAME, "tenant", tenant);
|
|
68
81
|
Guards.stringHexLength(TenantAdminService.CLASS_NAME, "tenant.id", tenant.id, 32);
|
|
69
82
|
Guards.stringHexLength(TenantAdminService.CLASS_NAME, "tenant.apiKey", tenant.apiKey, 32);
|
|
83
|
+
let publicOrigin;
|
|
84
|
+
if (Is.stringValue(tenant.publicOrigin)) {
|
|
85
|
+
Url.guard(TenantAdminService.CLASS_NAME, "tenant.publicOrigin", tenant.publicOrigin);
|
|
86
|
+
const url = new Url(tenant.publicOrigin);
|
|
87
|
+
const parts = url.parts();
|
|
88
|
+
publicOrigin = `${parts.schema}://${parts.host}${Is.integer(parts.port) ? `:${parts.port}` : ""}`;
|
|
89
|
+
}
|
|
70
90
|
const existingApiKey = await this.getByApiKey(tenant.apiKey);
|
|
71
91
|
if (existingApiKey && existingApiKey.id !== tenant.id) {
|
|
72
92
|
throw new GeneralError(TenantAdminService.CLASS_NAME, "apiKeyAlreadyInUse");
|
|
@@ -76,6 +96,9 @@ export class TenantAdminService {
|
|
|
76
96
|
tenantEntity.apiKey = tenant.apiKey;
|
|
77
97
|
tenantEntity.dateCreated = new Date(Date.now()).toISOString();
|
|
78
98
|
tenantEntity.label = tenant.label;
|
|
99
|
+
tenantEntity.dateCreated = new Date(Date.now()).toISOString();
|
|
100
|
+
tenantEntity.publicOrigin = publicOrigin;
|
|
101
|
+
tenantEntity.isNodeTenant = tenant.isNodeTenant;
|
|
79
102
|
await this._entityStorageConnector.set(tenantEntity);
|
|
80
103
|
}
|
|
81
104
|
/**
|
|
@@ -89,12 +112,22 @@ export class TenantAdminService {
|
|
|
89
112
|
}
|
|
90
113
|
/**
|
|
91
114
|
* Query tenants with pagination.
|
|
115
|
+
* @param options Optional query options.
|
|
116
|
+
* @param options.isNodeTenant Whether to filter for node admin tenants.
|
|
92
117
|
* @param cursor The cursor to start from.
|
|
93
118
|
* @param limit The maximum number of tenants to return.
|
|
94
119
|
* @returns The tenants and the next cursor if more tenants are available.
|
|
95
120
|
*/
|
|
96
|
-
async query(cursor, limit) {
|
|
97
|
-
const
|
|
121
|
+
async query(options, cursor, limit) {
|
|
122
|
+
const conditions = [];
|
|
123
|
+
if (Is.boolean(options?.isNodeTenant)) {
|
|
124
|
+
conditions.push({
|
|
125
|
+
property: "isNodeTenant",
|
|
126
|
+
value: options.isNodeTenant,
|
|
127
|
+
comparison: ComparisonOperator.Equals
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
const result = await this._entityStorageConnector.query(conditions.length > 0 ? { conditions } : undefined, undefined, undefined, cursor, limit);
|
|
98
131
|
return {
|
|
99
132
|
tenants: result.entities,
|
|
100
133
|
cursor: result.cursor
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenantAdminService.js","sourceRoot":"","sources":["../../src/tenantAdminService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tenantAdminService.js","sourceRoot":"","sources":["../../src/tenantAdminService.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { ITenantAdminComponent, ITenant } from \"@twin.org/api-models\";\nimport { GeneralError, Guards, Is, Url } from \"@twin.org/core\";\nimport { ComparisonOperator } from \"@twin.org/entity\";\nimport {\n\tEntityStorageConnectorFactory,\n\ttype IEntityStorageConnector\n} from \"@twin.org/entity-storage-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { Tenant } from \"./entities/tenant.js\";\nimport type { ITenantAdminServiceConstructorOptions } from \"./models/ITenantAdminServiceConstructorOptions.js\";\n\n/**\n * Service for performing email messaging operations to a connector.\n */\nexport class TenantAdminService implements ITenantAdminComponent {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<TenantAdminService>();\n\n\t/**\n\t * Entity storage connector used by the service.\n\t * @internal\n\t */\n\tprivate readonly _entityStorageConnector: IEntityStorageConnector<Tenant>;\n\n\t/**\n\t * Create a new instance of TenantAdminService.\n\t * @param options The options for the connector.\n\t */\n\tconstructor(options?: ITenantAdminServiceConstructorOptions) {\n\t\tthis._entityStorageConnector = EntityStorageConnectorFactory.get(\n\t\t\toptions?.tenantEntityStorageType ?? \"tenant\"\n\t\t);\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 TenantAdminService.CLASS_NAME;\n\t}\n\n\t/**\n\t * Get a tenant by its id.\n\t * @param tenantId The id of the tenant.\n\t * @returns The tenant or undefined if not found.\n\t */\n\tpublic async get(tenantId: string): Promise<ITenant | undefined> {\n\t\tGuards.stringHexLength(TenantAdminService.CLASS_NAME, nameof(tenantId), tenantId, 32);\n\n\t\tlet tenant;\n\n\t\ttry {\n\t\t\ttenant = await this._entityStorageConnector.get(tenantId);\n\t\t} catch {}\n\n\t\treturn tenant;\n\t}\n\n\t/**\n\t * Get a tenant by its api key.\n\t * @param apiKey The api key of the tenant.\n\t * @returns The tenant or undefined if not found.\n\t */\n\tpublic async getByApiKey(apiKey: string): Promise<ITenant | undefined> {\n\t\tGuards.stringHexLength(TenantAdminService.CLASS_NAME, nameof(apiKey), apiKey, 32);\n\n\t\tlet tenant;\n\n\t\ttry {\n\t\t\ttenant = await this._entityStorageConnector.get(apiKey, \"apiKey\");\n\t\t} catch {}\n\n\t\treturn tenant;\n\t}\n\n\t/**\n\t * Get a tenant by its public origin.\n\t * @param publicOrigin The public origin of the tenant.\n\t * @returns The tenant or undefined if not found.\n\t */\n\tpublic async getByPublicOrigin(publicOrigin: string): Promise<ITenant | undefined> {\n\t\tGuards.stringValue(TenantAdminService.CLASS_NAME, nameof(publicOrigin), publicOrigin);\n\n\t\tlet tenant;\n\n\t\ttry {\n\t\t\ttenant = await this._entityStorageConnector.get(publicOrigin, \"publicOrigin\");\n\t\t} catch {}\n\n\t\treturn tenant;\n\t}\n\n\t/**\n\t * Set a tenant.\n\t * @param tenant The tenant to store.\n\t * @returns Nothing.\n\t */\n\tpublic async set(tenant: ITenant): Promise<void> {\n\t\tGuards.objectValue<ITenant>(TenantAdminService.CLASS_NAME, nameof(tenant), tenant);\n\t\tGuards.stringHexLength(TenantAdminService.CLASS_NAME, nameof(tenant.id), tenant.id, 32);\n\t\tGuards.stringHexLength(TenantAdminService.CLASS_NAME, nameof(tenant.apiKey), tenant.apiKey, 32);\n\n\t\tlet publicOrigin: string | undefined;\n\t\tif (Is.stringValue(tenant.publicOrigin)) {\n\t\t\tUrl.guard(TenantAdminService.CLASS_NAME, nameof(tenant.publicOrigin), tenant.publicOrigin);\n\n\t\t\tconst url = new Url(tenant.publicOrigin);\n\t\t\tconst parts = url.parts();\n\t\t\tpublicOrigin = `${parts.schema}://${parts.host}${Is.integer(parts.port) ? `:${parts.port}` : \"\"}`;\n\t\t}\n\n\t\tconst existingApiKey = await this.getByApiKey(tenant.apiKey);\n\t\tif (existingApiKey && existingApiKey.id !== tenant.id) {\n\t\t\tthrow new GeneralError(TenantAdminService.CLASS_NAME, \"apiKeyAlreadyInUse\");\n\t\t}\n\n\t\tconst tenantEntity = new Tenant();\n\t\ttenantEntity.id = tenant.id;\n\t\ttenantEntity.apiKey = tenant.apiKey;\n\t\ttenantEntity.dateCreated = new Date(Date.now()).toISOString();\n\t\ttenantEntity.label = tenant.label;\n\t\ttenantEntity.dateCreated = new Date(Date.now()).toISOString();\n\t\ttenantEntity.publicOrigin = publicOrigin;\n\t\ttenantEntity.isNodeTenant = tenant.isNodeTenant;\n\n\t\tawait this._entityStorageConnector.set(tenantEntity);\n\t}\n\n\t/**\n\t * Remove a tenant by its id.\n\t * @param tenantId The id of the tenant.\n\t * @returns Nothing.\n\t */\n\tpublic async remove(tenantId: string): Promise<void> {\n\t\tGuards.stringHexLength(TenantAdminService.CLASS_NAME, nameof(tenantId), tenantId, 32);\n\n\t\treturn this._entityStorageConnector.remove(tenantId);\n\t}\n\n\t/**\n\t * Query tenants with pagination.\n\t * @param options Optional query options.\n\t * @param options.isNodeTenant Whether to filter for node admin tenants.\n\t * @param cursor The cursor to start from.\n\t * @param limit The maximum number of tenants to return.\n\t * @returns The tenants and the next cursor if more tenants are available.\n\t */\n\tpublic async query(\n\t\toptions?: { isNodeTenant?: boolean },\n\t\tcursor?: string,\n\t\tlimit?: number\n\t): Promise<{ tenants: ITenant[]; cursor?: string }> {\n\t\tconst conditions = [];\n\n\t\tif (Is.boolean(options?.isNodeTenant)) {\n\t\t\tconditions.push({\n\t\t\t\tproperty: \"isNodeTenant\",\n\t\t\t\tvalue: options.isNodeTenant,\n\t\t\t\tcomparison: ComparisonOperator.Equals\n\t\t\t});\n\t\t}\n\n\t\tconst result = await this._entityStorageConnector.query(\n\t\t\tconditions.length > 0 ? { conditions } : undefined,\n\t\t\tundefined,\n\t\t\tundefined,\n\t\t\tcursor,\n\t\t\tlimit\n\t\t);\n\n\t\treturn {\n\t\t\ttenants: result.entities as ITenant[],\n\t\t\tcursor: result.cursor\n\t\t};\n\t}\n}\n"]}
|
|
@@ -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,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;
|
|
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;wBACjD,IAAI,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;4BAC7C,cAAc,CAAC,YAAY,GAAG,UAAU,CAAC,YAAY,CAAC;wBACvD,CAAC;oBACF,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\tif (Is.stringValue(nodeTenant.publicOrigin)) {\n\t\t\t\t\t\t\tprocessorState.publicOrigin = nodeTenant.publicOrigin;\n\t\t\t\t\t\t}\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"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Copyright 2025 IOTA Stiftung.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0.
|
|
3
|
-
import {
|
|
3
|
+
import { RandomHelper } from "@twin.org/core";
|
|
4
4
|
/**
|
|
5
5
|
* Helper class for tenant id related operations.
|
|
6
6
|
*/
|
|
@@ -10,14 +10,14 @@ export class TenantIdHelper {
|
|
|
10
10
|
* @returns A new tenant ID.
|
|
11
11
|
*/
|
|
12
12
|
static generateTenantId() {
|
|
13
|
-
return
|
|
13
|
+
return RandomHelper.generateUuidV7("compact");
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
16
|
* Generates a new API Key.
|
|
17
17
|
* @returns A new API Key.
|
|
18
18
|
*/
|
|
19
19
|
static generateApiKey() {
|
|
20
|
-
return
|
|
20
|
+
return RandomHelper.generateUuidV7("compact");
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
//# sourceMappingURL=tenantIdHelper.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenantIdHelper.js","sourceRoot":"","sources":["../../../src/utils/tenantIdHelper.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"tenantIdHelper.js","sourceRoot":"","sources":["../../../src/utils/tenantIdHelper.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C;;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 \"@twin.org/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"]}
|
|
@@ -18,4 +18,12 @@ export declare class Tenant {
|
|
|
18
18
|
* The date the tenant was created.
|
|
19
19
|
*/
|
|
20
20
|
dateCreated: string;
|
|
21
|
+
/**
|
|
22
|
+
* The origin available to the public for accessing the API.
|
|
23
|
+
*/
|
|
24
|
+
publicOrigin?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Indicates whether the tenant is the node tenant.
|
|
27
|
+
*/
|
|
28
|
+
isNodeTenant: boolean;
|
|
21
29
|
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
export * from "./entities/tenant.js";
|
|
2
|
-
export * from "./models/ITenant.js";
|
|
3
|
-
export * from "./models/ITenantAdminComponent.js";
|
|
4
2
|
export * from "./models/ITenantAdminServiceConfig.js";
|
|
5
3
|
export * from "./models/ITenantAdminServiceConstructorOptions.js";
|
|
6
4
|
export * from "./models/ITenantProcessorConfig.js";
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { ITenant } from "
|
|
2
|
-
import type { ITenantAdminComponent } from "./models/ITenantAdminComponent.js";
|
|
1
|
+
import type { ITenantAdminComponent, ITenant } from "@twin.org/api-models";
|
|
3
2
|
import type { ITenantAdminServiceConstructorOptions } from "./models/ITenantAdminServiceConstructorOptions.js";
|
|
4
3
|
/**
|
|
5
4
|
* Service for performing email messaging operations to a connector.
|
|
@@ -31,6 +30,12 @@ export declare class TenantAdminService implements ITenantAdminComponent {
|
|
|
31
30
|
* @returns The tenant or undefined if not found.
|
|
32
31
|
*/
|
|
33
32
|
getByApiKey(apiKey: string): Promise<ITenant | undefined>;
|
|
33
|
+
/**
|
|
34
|
+
* Get a tenant by its public origin.
|
|
35
|
+
* @param publicOrigin The public origin of the tenant.
|
|
36
|
+
* @returns The tenant or undefined if not found.
|
|
37
|
+
*/
|
|
38
|
+
getByPublicOrigin(publicOrigin: string): Promise<ITenant | undefined>;
|
|
34
39
|
/**
|
|
35
40
|
* Set a tenant.
|
|
36
41
|
* @param tenant The tenant to store.
|
|
@@ -45,11 +50,15 @@ export declare class TenantAdminService implements ITenantAdminComponent {
|
|
|
45
50
|
remove(tenantId: string): Promise<void>;
|
|
46
51
|
/**
|
|
47
52
|
* Query tenants with pagination.
|
|
53
|
+
* @param options Optional query options.
|
|
54
|
+
* @param options.isNodeTenant Whether to filter for node admin tenants.
|
|
48
55
|
* @param cursor The cursor to start from.
|
|
49
56
|
* @param limit The maximum number of tenants to return.
|
|
50
57
|
* @returns The tenants and the next cursor if more tenants are available.
|
|
51
58
|
*/
|
|
52
|
-
query(
|
|
59
|
+
query(options?: {
|
|
60
|
+
isNodeTenant?: boolean;
|
|
61
|
+
}, cursor?: string, limit?: number): Promise<{
|
|
53
62
|
tenants: ITenant[];
|
|
54
63
|
cursor?: string;
|
|
55
64
|
}>;
|
package/docs/changelog.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.0.3-next.16](https://github.com/twinfoundation/api/compare/api-tenant-processor-v0.0.3-next.15...api-tenant-processor-v0.0.3-next.16) (2026-01-26)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* public base url ([#70](https://github.com/twinfoundation/api/issues/70)) ([5b958cd](https://github.com/twinfoundation/api/commit/5b958cd91e8a38cdae2835ff5f2356c7e48d37c3))
|
|
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.15 to 0.0.3-next.16
|
|
16
|
+
|
|
3
17
|
## [0.0.3-next.15](https://github.com/twinfoundation/api/compare/api-tenant-processor-v0.0.3-next.14...api-tenant-processor-v0.0.3-next.15) (2026-01-22)
|
|
4
18
|
|
|
5
19
|
|
|
@@ -43,3 +43,19 @@ The label of the tenant.
|
|
|
43
43
|
> **dateCreated**: `string`
|
|
44
44
|
|
|
45
45
|
The date the tenant was created.
|
|
46
|
+
|
|
47
|
+
***
|
|
48
|
+
|
|
49
|
+
### publicOrigin?
|
|
50
|
+
|
|
51
|
+
> `optional` **publicOrigin**: `string`
|
|
52
|
+
|
|
53
|
+
The origin available to the public for accessing the API.
|
|
54
|
+
|
|
55
|
+
***
|
|
56
|
+
|
|
57
|
+
### isNodeTenant
|
|
58
|
+
|
|
59
|
+
> **isNodeTenant**: `boolean`
|
|
60
|
+
|
|
61
|
+
Indicates whether the tenant is the node tenant.
|
|
@@ -4,7 +4,7 @@ Service for performing email messaging operations to a connector.
|
|
|
4
4
|
|
|
5
5
|
## Implements
|
|
6
6
|
|
|
7
|
-
-
|
|
7
|
+
- `ITenantAdminComponent`
|
|
8
8
|
|
|
9
9
|
## Constructors
|
|
10
10
|
|
|
@@ -56,7 +56,7 @@ The class name of the component.
|
|
|
56
56
|
|
|
57
57
|
### get()
|
|
58
58
|
|
|
59
|
-
> **get**(`tenantId`): `Promise
|
|
59
|
+
> **get**(`tenantId`): `Promise`\<`ITenant` \| `undefined`\>
|
|
60
60
|
|
|
61
61
|
Get a tenant by its id.
|
|
62
62
|
|
|
@@ -70,19 +70,19 @@ The id of the tenant.
|
|
|
70
70
|
|
|
71
71
|
#### Returns
|
|
72
72
|
|
|
73
|
-
`Promise
|
|
73
|
+
`Promise`\<`ITenant` \| `undefined`\>
|
|
74
74
|
|
|
75
75
|
The tenant or undefined if not found.
|
|
76
76
|
|
|
77
77
|
#### Implementation of
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
`ITenantAdminComponent.get`
|
|
80
80
|
|
|
81
81
|
***
|
|
82
82
|
|
|
83
83
|
### getByApiKey()
|
|
84
84
|
|
|
85
|
-
> **getByApiKey**(`apiKey`): `Promise
|
|
85
|
+
> **getByApiKey**(`apiKey`): `Promise`\<`ITenant` \| `undefined`\>
|
|
86
86
|
|
|
87
87
|
Get a tenant by its api key.
|
|
88
88
|
|
|
@@ -96,13 +96,39 @@ The api key of the tenant.
|
|
|
96
96
|
|
|
97
97
|
#### Returns
|
|
98
98
|
|
|
99
|
-
`Promise
|
|
99
|
+
`Promise`\<`ITenant` \| `undefined`\>
|
|
100
100
|
|
|
101
101
|
The tenant or undefined if not found.
|
|
102
102
|
|
|
103
103
|
#### Implementation of
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
`ITenantAdminComponent.getByApiKey`
|
|
106
|
+
|
|
107
|
+
***
|
|
108
|
+
|
|
109
|
+
### getByPublicOrigin()
|
|
110
|
+
|
|
111
|
+
> **getByPublicOrigin**(`publicOrigin`): `Promise`\<`ITenant` \| `undefined`\>
|
|
112
|
+
|
|
113
|
+
Get a tenant by its public origin.
|
|
114
|
+
|
|
115
|
+
#### Parameters
|
|
116
|
+
|
|
117
|
+
##### publicOrigin
|
|
118
|
+
|
|
119
|
+
`string`
|
|
120
|
+
|
|
121
|
+
The public origin of the tenant.
|
|
122
|
+
|
|
123
|
+
#### Returns
|
|
124
|
+
|
|
125
|
+
`Promise`\<`ITenant` \| `undefined`\>
|
|
126
|
+
|
|
127
|
+
The tenant or undefined if not found.
|
|
128
|
+
|
|
129
|
+
#### Implementation of
|
|
130
|
+
|
|
131
|
+
`ITenantAdminComponent.getByPublicOrigin`
|
|
106
132
|
|
|
107
133
|
***
|
|
108
134
|
|
|
@@ -116,7 +142,7 @@ Set a tenant.
|
|
|
116
142
|
|
|
117
143
|
##### tenant
|
|
118
144
|
|
|
119
|
-
|
|
145
|
+
`ITenant`
|
|
120
146
|
|
|
121
147
|
The tenant to store.
|
|
122
148
|
|
|
@@ -128,7 +154,7 @@ Nothing.
|
|
|
128
154
|
|
|
129
155
|
#### Implementation of
|
|
130
156
|
|
|
131
|
-
|
|
157
|
+
`ITenantAdminComponent.set`
|
|
132
158
|
|
|
133
159
|
***
|
|
134
160
|
|
|
@@ -154,18 +180,28 @@ Nothing.
|
|
|
154
180
|
|
|
155
181
|
#### Implementation of
|
|
156
182
|
|
|
157
|
-
|
|
183
|
+
`ITenantAdminComponent.remove`
|
|
158
184
|
|
|
159
185
|
***
|
|
160
186
|
|
|
161
187
|
### query()
|
|
162
188
|
|
|
163
|
-
> **query**(`cursor?`, `limit?`): `Promise`\<\{ `tenants`:
|
|
189
|
+
> **query**(`options?`, `cursor?`, `limit?`): `Promise`\<\{ `tenants`: `ITenant`[]; `cursor?`: `string`; \}\>
|
|
164
190
|
|
|
165
191
|
Query tenants with pagination.
|
|
166
192
|
|
|
167
193
|
#### Parameters
|
|
168
194
|
|
|
195
|
+
##### options?
|
|
196
|
+
|
|
197
|
+
Optional query options.
|
|
198
|
+
|
|
199
|
+
###### isNodeTenant?
|
|
200
|
+
|
|
201
|
+
`boolean`
|
|
202
|
+
|
|
203
|
+
Whether to filter for node admin tenants.
|
|
204
|
+
|
|
169
205
|
##### cursor?
|
|
170
206
|
|
|
171
207
|
`string`
|
|
@@ -180,10 +216,10 @@ The maximum number of tenants to return.
|
|
|
180
216
|
|
|
181
217
|
#### Returns
|
|
182
218
|
|
|
183
|
-
`Promise`\<\{ `tenants`:
|
|
219
|
+
`Promise`\<\{ `tenants`: `ITenant`[]; `cursor?`: `string`; \}\>
|
|
184
220
|
|
|
185
221
|
The tenants and the next cursor if more tenants are available.
|
|
186
222
|
|
|
187
223
|
#### Implementation of
|
|
188
224
|
|
|
189
|
-
|
|
225
|
+
`ITenantAdminComponent.query`
|
package/docs/reference/index.md
CHANGED
|
@@ -10,8 +10,6 @@
|
|
|
10
10
|
|
|
11
11
|
## Interfaces
|
|
12
12
|
|
|
13
|
-
- [ITenant](interfaces/ITenant.md)
|
|
14
|
-
- [ITenantAdminComponent](interfaces/ITenantAdminComponent.md)
|
|
15
13
|
- [ITenantAdminServiceConfig](interfaces/ITenantAdminServiceConfig.md)
|
|
16
14
|
- [ITenantAdminServiceConstructorOptions](interfaces/ITenantAdminServiceConstructorOptions.md)
|
|
17
15
|
- [ITenantProcessorConfig](interfaces/ITenantProcessorConfig.md)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@twin.org/api-tenant-processor",
|
|
3
|
-
"version": "0.0.3-next.
|
|
3
|
+
"version": "0.0.3-next.16",
|
|
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.
|
|
17
|
+
"@twin.org/api-models": "0.0.3-next.16",
|
|
18
18
|
"@twin.org/context": "next",
|
|
19
19
|
"@twin.org/core": "next",
|
|
20
20
|
"@twin.org/entity": "next",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ITenant.js","sourceRoot":"","sources":["../../../src/models/ITenant.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2025 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Model defining the tenant.\n */\nexport interface ITenant {\n\t/**\n\t * The unique identifier for the tenant.\n\t */\n\tid: string;\n\n\t/**\n\t * The api key for the tenant.\n\t */\n\tapiKey: string;\n\n\t/**\n\t * The label of the tenant.\n\t */\n\tlabel: string;\n\n\t/**\n\t * The date the tenant was created.\n\t */\n\tdateCreated: string;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ITenantAdminComponent.js","sourceRoot":"","sources":["../../../src/models/ITenantAdminComponent.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2025 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { IComponent } from \"@twin.org/core\";\nimport type { ITenant } from \"./ITenant.js\";\n\n/**\n * Configuration for the tenant admin component\n */\nexport interface ITenantAdminComponent extends IComponent {\n\t/**\n\t * Get a tenant by its id.\n\t * @param tenantId The id of the tenant.\n\t * @returns The tenant or undefined if not found.\n\t */\n\tget(tenantId: string): Promise<ITenant | undefined>;\n\n\t/**\n\t * Get a tenant by its api key.\n\t * @param apiKey The api key of the tenant.\n\t * @returns The tenant or undefined if not found.\n\t */\n\tgetByApiKey(apiKey: string): Promise<ITenant | undefined>;\n\n\t/**\n\t * Set a tenant.\n\t * @param tenant The tenant to store.\n\t * @returns Nothing.\n\t */\n\tset(tenant: ITenant): Promise<void>;\n\n\t/**\n\t * Remove a tenant by its id.\n\t * @param tenantId The id of the tenant.\n\t * @returns Nothing.\n\t */\n\tremove(tenantId: string): Promise<void>;\n\n\t/**\n\t * Query tenants with pagination.\n\t * @param cursor The cursor to start from.\n\t * @param limit The maximum number of tenants to return.\n\t * @returns The tenants and the next cursor if more tenants are available.\n\t */\n\tquery(cursor?: string, limit?: number): Promise<{ tenants: ITenant[]; cursor?: string }>;\n}\n"]}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Model defining the tenant.
|
|
3
|
-
*/
|
|
4
|
-
export interface ITenant {
|
|
5
|
-
/**
|
|
6
|
-
* The unique identifier for the tenant.
|
|
7
|
-
*/
|
|
8
|
-
id: string;
|
|
9
|
-
/**
|
|
10
|
-
* The api key for the tenant.
|
|
11
|
-
*/
|
|
12
|
-
apiKey: string;
|
|
13
|
-
/**
|
|
14
|
-
* The label of the tenant.
|
|
15
|
-
*/
|
|
16
|
-
label: string;
|
|
17
|
-
/**
|
|
18
|
-
* The date the tenant was created.
|
|
19
|
-
*/
|
|
20
|
-
dateCreated: string;
|
|
21
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import type { IComponent } from "@twin.org/core";
|
|
2
|
-
import type { ITenant } from "./ITenant.js";
|
|
3
|
-
/**
|
|
4
|
-
* Configuration for the tenant admin component
|
|
5
|
-
*/
|
|
6
|
-
export interface ITenantAdminComponent extends IComponent {
|
|
7
|
-
/**
|
|
8
|
-
* Get a tenant by its id.
|
|
9
|
-
* @param tenantId The id of the tenant.
|
|
10
|
-
* @returns The tenant or undefined if not found.
|
|
11
|
-
*/
|
|
12
|
-
get(tenantId: string): Promise<ITenant | undefined>;
|
|
13
|
-
/**
|
|
14
|
-
* Get a tenant by its api key.
|
|
15
|
-
* @param apiKey The api key of the tenant.
|
|
16
|
-
* @returns The tenant or undefined if not found.
|
|
17
|
-
*/
|
|
18
|
-
getByApiKey(apiKey: string): Promise<ITenant | undefined>;
|
|
19
|
-
/**
|
|
20
|
-
* Set a tenant.
|
|
21
|
-
* @param tenant The tenant to store.
|
|
22
|
-
* @returns Nothing.
|
|
23
|
-
*/
|
|
24
|
-
set(tenant: ITenant): Promise<void>;
|
|
25
|
-
/**
|
|
26
|
-
* Remove a tenant by its id.
|
|
27
|
-
* @param tenantId The id of the tenant.
|
|
28
|
-
* @returns Nothing.
|
|
29
|
-
*/
|
|
30
|
-
remove(tenantId: string): Promise<void>;
|
|
31
|
-
/**
|
|
32
|
-
* Query tenants with pagination.
|
|
33
|
-
* @param cursor The cursor to start from.
|
|
34
|
-
* @param limit The maximum number of tenants to return.
|
|
35
|
-
* @returns The tenants and the next cursor if more tenants are available.
|
|
36
|
-
*/
|
|
37
|
-
query(cursor?: string, limit?: number): Promise<{
|
|
38
|
-
tenants: ITenant[];
|
|
39
|
-
cursor?: string;
|
|
40
|
-
}>;
|
|
41
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# Interface: ITenant
|
|
2
|
-
|
|
3
|
-
Model defining the tenant.
|
|
4
|
-
|
|
5
|
-
## Properties
|
|
6
|
-
|
|
7
|
-
### id
|
|
8
|
-
|
|
9
|
-
> **id**: `string`
|
|
10
|
-
|
|
11
|
-
The unique identifier for the tenant.
|
|
12
|
-
|
|
13
|
-
***
|
|
14
|
-
|
|
15
|
-
### apiKey
|
|
16
|
-
|
|
17
|
-
> **apiKey**: `string`
|
|
18
|
-
|
|
19
|
-
The api key for the tenant.
|
|
20
|
-
|
|
21
|
-
***
|
|
22
|
-
|
|
23
|
-
### label
|
|
24
|
-
|
|
25
|
-
> **label**: `string`
|
|
26
|
-
|
|
27
|
-
The label of the tenant.
|
|
28
|
-
|
|
29
|
-
***
|
|
30
|
-
|
|
31
|
-
### dateCreated
|
|
32
|
-
|
|
33
|
-
> **dateCreated**: `string`
|
|
34
|
-
|
|
35
|
-
The date the tenant was created.
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
# Interface: ITenantAdminComponent
|
|
2
|
-
|
|
3
|
-
Configuration for the tenant admin component
|
|
4
|
-
|
|
5
|
-
## Extends
|
|
6
|
-
|
|
7
|
-
- `IComponent`
|
|
8
|
-
|
|
9
|
-
## Methods
|
|
10
|
-
|
|
11
|
-
### get()
|
|
12
|
-
|
|
13
|
-
> **get**(`tenantId`): `Promise`\<[`ITenant`](ITenant.md) \| `undefined`\>
|
|
14
|
-
|
|
15
|
-
Get a tenant by its id.
|
|
16
|
-
|
|
17
|
-
#### Parameters
|
|
18
|
-
|
|
19
|
-
##### tenantId
|
|
20
|
-
|
|
21
|
-
`string`
|
|
22
|
-
|
|
23
|
-
The id of the tenant.
|
|
24
|
-
|
|
25
|
-
#### Returns
|
|
26
|
-
|
|
27
|
-
`Promise`\<[`ITenant`](ITenant.md) \| `undefined`\>
|
|
28
|
-
|
|
29
|
-
The tenant or undefined if not found.
|
|
30
|
-
|
|
31
|
-
***
|
|
32
|
-
|
|
33
|
-
### getByApiKey()
|
|
34
|
-
|
|
35
|
-
> **getByApiKey**(`apiKey`): `Promise`\<[`ITenant`](ITenant.md) \| `undefined`\>
|
|
36
|
-
|
|
37
|
-
Get a tenant by its api key.
|
|
38
|
-
|
|
39
|
-
#### Parameters
|
|
40
|
-
|
|
41
|
-
##### apiKey
|
|
42
|
-
|
|
43
|
-
`string`
|
|
44
|
-
|
|
45
|
-
The api key of the tenant.
|
|
46
|
-
|
|
47
|
-
#### Returns
|
|
48
|
-
|
|
49
|
-
`Promise`\<[`ITenant`](ITenant.md) \| `undefined`\>
|
|
50
|
-
|
|
51
|
-
The tenant or undefined if not found.
|
|
52
|
-
|
|
53
|
-
***
|
|
54
|
-
|
|
55
|
-
### set()
|
|
56
|
-
|
|
57
|
-
> **set**(`tenant`): `Promise`\<`void`\>
|
|
58
|
-
|
|
59
|
-
Set a tenant.
|
|
60
|
-
|
|
61
|
-
#### Parameters
|
|
62
|
-
|
|
63
|
-
##### tenant
|
|
64
|
-
|
|
65
|
-
[`ITenant`](ITenant.md)
|
|
66
|
-
|
|
67
|
-
The tenant to store.
|
|
68
|
-
|
|
69
|
-
#### Returns
|
|
70
|
-
|
|
71
|
-
`Promise`\<`void`\>
|
|
72
|
-
|
|
73
|
-
Nothing.
|
|
74
|
-
|
|
75
|
-
***
|
|
76
|
-
|
|
77
|
-
### remove()
|
|
78
|
-
|
|
79
|
-
> **remove**(`tenantId`): `Promise`\<`void`\>
|
|
80
|
-
|
|
81
|
-
Remove a tenant by its id.
|
|
82
|
-
|
|
83
|
-
#### Parameters
|
|
84
|
-
|
|
85
|
-
##### tenantId
|
|
86
|
-
|
|
87
|
-
`string`
|
|
88
|
-
|
|
89
|
-
The id of the tenant.
|
|
90
|
-
|
|
91
|
-
#### Returns
|
|
92
|
-
|
|
93
|
-
`Promise`\<`void`\>
|
|
94
|
-
|
|
95
|
-
Nothing.
|
|
96
|
-
|
|
97
|
-
***
|
|
98
|
-
|
|
99
|
-
### query()
|
|
100
|
-
|
|
101
|
-
> **query**(`cursor?`, `limit?`): `Promise`\<\{ `tenants`: [`ITenant`](ITenant.md)[]; `cursor?`: `string`; \}\>
|
|
102
|
-
|
|
103
|
-
Query tenants with pagination.
|
|
104
|
-
|
|
105
|
-
#### Parameters
|
|
106
|
-
|
|
107
|
-
##### cursor?
|
|
108
|
-
|
|
109
|
-
`string`
|
|
110
|
-
|
|
111
|
-
The cursor to start from.
|
|
112
|
-
|
|
113
|
-
##### limit?
|
|
114
|
-
|
|
115
|
-
`number`
|
|
116
|
-
|
|
117
|
-
The maximum number of tenants to return.
|
|
118
|
-
|
|
119
|
-
#### Returns
|
|
120
|
-
|
|
121
|
-
`Promise`\<\{ `tenants`: [`ITenant`](ITenant.md)[]; `cursor?`: `string`; \}\>
|
|
122
|
-
|
|
123
|
-
The tenants and the next cursor if more tenants are available.
|