@twin.org/identity-authentication 0.0.2-next.8 → 0.0.3-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.
Files changed (35) hide show
  1. package/dist/es/index.js +12 -0
  2. package/dist/es/index.js.map +1 -0
  3. package/dist/es/models/IIdentityAuthenticationActionRequest.js +2 -0
  4. package/dist/es/models/IIdentityAuthenticationActionRequest.js.map +1 -0
  5. package/dist/es/models/IVerifiableCredentialAuthenticationGeneratorConfig.js +4 -0
  6. package/dist/es/models/IVerifiableCredentialAuthenticationGeneratorConfig.js.map +1 -0
  7. package/dist/es/models/IVerifiableCredentialAuthenticationGeneratorConstructorOptions.js +2 -0
  8. package/dist/es/models/IVerifiableCredentialAuthenticationGeneratorConstructorOptions.js.map +1 -0
  9. package/dist/es/models/IVerifiableCredentialAuthenticationProcessorConfig.js +4 -0
  10. package/dist/es/models/IVerifiableCredentialAuthenticationProcessorConfig.js.map +1 -0
  11. package/dist/es/models/IVerifiableCredentialAuthenticationProcessorConstructorOptions.js +2 -0
  12. package/dist/es/models/IVerifiableCredentialAuthenticationProcessorConstructorOptions.js.map +1 -0
  13. package/dist/es/models/identityAuthenticationContexts.js +13 -0
  14. package/dist/es/models/identityAuthenticationContexts.js.map +1 -0
  15. package/dist/es/models/identityAuthenticationTypes.js +13 -0
  16. package/dist/es/models/identityAuthenticationTypes.js.map +1 -0
  17. package/dist/es/verifiableCredentialAuthenticationGenerator.js +67 -0
  18. package/dist/es/verifiableCredentialAuthenticationGenerator.js.map +1 -0
  19. package/dist/es/verifiableCredentialAuthenticationProcessor.js +109 -0
  20. package/dist/es/verifiableCredentialAuthenticationProcessor.js.map +1 -0
  21. package/dist/types/index.d.ts +9 -9
  22. package/dist/types/models/IIdentityAuthenticationActionRequest.d.ts +2 -2
  23. package/dist/types/models/IVerifiableCredentialAuthenticationGeneratorConfig.d.ts +5 -0
  24. package/dist/types/models/IVerifiableCredentialAuthenticationGeneratorConstructorOptions.d.ts +1 -1
  25. package/dist/types/models/IVerifiableCredentialAuthenticationProcessorConstructorOptions.d.ts +1 -1
  26. package/dist/types/verifiableCredentialAuthenticationGenerator.d.ts +11 -8
  27. package/dist/types/verifiableCredentialAuthenticationProcessor.d.ts +11 -5
  28. package/docs/changelog.md +51 -0
  29. package/docs/reference/classes/VerifiableCredentialAuthenticationGenerator.md +18 -26
  30. package/docs/reference/classes/VerifiableCredentialAuthenticationProcessor.md +22 -8
  31. package/docs/reference/interfaces/IVerifiableCredentialAuthenticationGeneratorConfig.md +14 -0
  32. package/locales/en.json +0 -3
  33. package/package.json +23 -9
  34. package/dist/cjs/index.cjs +0 -198
  35. package/dist/esm/index.mjs +0 -193
@@ -0,0 +1,12 @@
1
+ // Copyright 2024 IOTA Stiftung.
2
+ // SPDX-License-Identifier: Apache-2.0.
3
+ export * from "./models/identityAuthenticationContexts.js";
4
+ export * from "./models/identityAuthenticationTypes.js";
5
+ export * from "./models/IIdentityAuthenticationActionRequest.js";
6
+ export * from "./models/IVerifiableCredentialAuthenticationGeneratorConfig.js";
7
+ export * from "./models/IVerifiableCredentialAuthenticationGeneratorConstructorOptions.js";
8
+ export * from "./models/IVerifiableCredentialAuthenticationProcessorConfig.js";
9
+ export * from "./models/IVerifiableCredentialAuthenticationProcessorConstructorOptions.js";
10
+ export * from "./verifiableCredentialAuthenticationGenerator.js";
11
+ export * from "./verifiableCredentialAuthenticationProcessor.js";
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,cAAc,4CAA4C,CAAC;AAC3D,cAAc,yCAAyC,CAAC;AACxD,cAAc,kDAAkD,CAAC;AACjE,cAAc,gEAAgE,CAAC;AAC/E,cAAc,4EAA4E,CAAC;AAC3F,cAAc,gEAAgE,CAAC;AAC/E,cAAc,4EAA4E,CAAC;AAC3F,cAAc,kDAAkD,CAAC;AACjE,cAAc,kDAAkD,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nexport * from \"./models/identityAuthenticationContexts.js\";\nexport * from \"./models/identityAuthenticationTypes.js\";\nexport * from \"./models/IIdentityAuthenticationActionRequest.js\";\nexport * from \"./models/IVerifiableCredentialAuthenticationGeneratorConfig.js\";\nexport * from \"./models/IVerifiableCredentialAuthenticationGeneratorConstructorOptions.js\";\nexport * from \"./models/IVerifiableCredentialAuthenticationProcessorConfig.js\";\nexport * from \"./models/IVerifiableCredentialAuthenticationProcessorConstructorOptions.js\";\nexport * from \"./verifiableCredentialAuthenticationGenerator.js\";\nexport * from \"./verifiableCredentialAuthenticationProcessor.js\";\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=IIdentityAuthenticationActionRequest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IIdentityAuthenticationActionRequest.js","sourceRoot":"","sources":["../../../src/models/IIdentityAuthenticationActionRequest.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { IdentityAuthenticationContexts } from \"./identityAuthenticationContexts.js\";\nimport type { IdentityAuthenticationTypes } from \"./identityAuthenticationTypes.js\";\n\n/**\n * The JSON-LD definition for a action request.\n */\nexport interface IIdentityAuthenticationActionRequest {\n\t/**\n\t * The JSON-LD context.\n\t */\n\t\"@context\": typeof IdentityAuthenticationContexts.ContextRoot;\n\n\t/**\n\t * The type of the request.\n\t */\n\ttype: typeof IdentityAuthenticationTypes.ActionRequest;\n\n\t/**\n\t * The identity of the entity making the request.\n\t */\n\trequester: string;\n\n\t/**\n\t * The action which can be checked to make sure it matches the specific operation.\n\t */\n\taction?: string;\n\n\t/**\n\t * Additional data for the action request, can be customised per request.\n\t */\n\tdata?: unknown;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ // Copyright 2024 IOTA Stiftung.
2
+ // SPDX-License-Identifier: Apache-2.0.
3
+ export {};
4
+ //# sourceMappingURL=IVerifiableCredentialAuthenticationGeneratorConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IVerifiableCredentialAuthenticationGeneratorConfig.js","sourceRoot":"","sources":["../../../src/models/IVerifiableCredentialAuthenticationGeneratorConfig.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Configuration for the Verifiable Credential Authentication Generator.\n */\nexport interface IVerifiableCredentialAuthenticationGeneratorConfig {\n\t/**\n\t * The time-to-live (TTL) for token in seconds.\n\t * @default 60 (1 minute)\n\t */\n\ttokenTtlInSeconds?: number;\n\n\t/**\n\t * The context id to use as the base for the verification method e.g. node/organization.\n\t * @default node\n\t */\n\tcontextId?: string;\n\n\t/**\n\t * The id of the identity method to use when creating/verifying tokens.\n\t */\n\tverificationMethodId: string;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=IVerifiableCredentialAuthenticationGeneratorConstructorOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IVerifiableCredentialAuthenticationGeneratorConstructorOptions.js","sourceRoot":"","sources":["../../../src/models/IVerifiableCredentialAuthenticationGeneratorConstructorOptions.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { IVerifiableCredentialAuthenticationGeneratorConfig } from \"./IVerifiableCredentialAuthenticationGeneratorConfig.js\";\n\n/**\n * Options for the verifiable credential authentication generator constructor.\n */\nexport interface IVerifiableCredentialAuthenticationGeneratorConstructorOptions {\n\t/**\n\t * The type of identity connector to use.\n\t * @default identity\n\t */\n\tidentityConnectorType?: string;\n\n\t/**\n\t * The type of logging component to use.\n\t * @default logging\n\t */\n\tloggingComponentType?: string;\n\n\t/**\n\t * The configuration for the verifiable credential authentication generator.\n\t */\n\tconfig: IVerifiableCredentialAuthenticationGeneratorConfig;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ // Copyright 2024 IOTA Stiftung.
2
+ // SPDX-License-Identifier: Apache-2.0.
3
+ export {};
4
+ //# sourceMappingURL=IVerifiableCredentialAuthenticationProcessorConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IVerifiableCredentialAuthenticationProcessorConfig.js","sourceRoot":"","sources":["../../../src/models/IVerifiableCredentialAuthenticationProcessorConfig.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Configuration for the Verifiable Credential Authentication Processor.\n */\nexport interface IVerifiableCredentialAuthenticationProcessorConfig {\n\t/**\n\t * The time-to-live (TTL) for token in seconds.\n\t * @default 60 (1 minute)\n\t */\n\ttokenTtlInSeconds?: number;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=IVerifiableCredentialAuthenticationProcessorConstructorOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IVerifiableCredentialAuthenticationProcessorConstructorOptions.js","sourceRoot":"","sources":["../../../src/models/IVerifiableCredentialAuthenticationProcessorConstructorOptions.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { IVerifiableCredentialAuthenticationProcessorConfig } from \"./IVerifiableCredentialAuthenticationProcessorConfig.js\";\n\n/**\n * Options for the verifiable credential authentication processor constructor.\n */\nexport interface IVerifiableCredentialAuthenticationProcessorConstructorOptions {\n\t/**\n\t * The type of identity connector to use.\n\t * @default identity\n\t */\n\tidentityConnectorType?: string;\n\n\t/**\n\t * The type of logging component to use.\n\t * @default logging\n\t */\n\tloggingComponentType?: string;\n\n\t/**\n\t * The configuration for the verifiable credential authentication processor.\n\t */\n\tconfig?: IVerifiableCredentialAuthenticationProcessorConfig;\n}\n"]}
@@ -0,0 +1,13 @@
1
+ // Copyright 2024 IOTA Stiftung.
2
+ // SPDX-License-Identifier: Apache-2.0.
3
+ /**
4
+ * The LD Contexts concerning Identity Authentication.
5
+ */
6
+ // eslint-disable-next-line @typescript-eslint/naming-convention
7
+ export const IdentityAuthenticationContexts = {
8
+ /**
9
+ * The Identity Authentication LD Context.
10
+ */
11
+ ContextRoot: "https://schema.twindev.org/identity-authentication"
12
+ };
13
+ //# sourceMappingURL=identityAuthenticationContexts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identityAuthenticationContexts.js","sourceRoot":"","sources":["../../../src/models/identityAuthenticationContexts.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AAEvC;;GAEG;AACH,gEAAgE;AAChE,MAAM,CAAC,MAAM,8BAA8B,GAAG;IAC7C;;OAEG;IACH,WAAW,EAAE,oDAAoD;CACxD,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * The LD Contexts concerning Identity Authentication.\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport const IdentityAuthenticationContexts = {\n\t/**\n\t * The Identity Authentication LD Context.\n\t */\n\tContextRoot: \"https://schema.twindev.org/identity-authentication\"\n} as const;\n\n/**\n * The LD Contexts concerning Identity Authentication.\n */\nexport type IdentityAuthenticationContexts =\n\t(typeof IdentityAuthenticationContexts)[keyof typeof IdentityAuthenticationContexts];\n"]}
@@ -0,0 +1,13 @@
1
+ // Copyright 2024 IOTA Stiftung.
2
+ // SPDX-License-Identifier: Apache-2.0.
3
+ /**
4
+ * The types of Identity Authentication data.
5
+ */
6
+ // eslint-disable-next-line @typescript-eslint/naming-convention
7
+ export const IdentityAuthenticationTypes = {
8
+ /**
9
+ * Represents action request.
10
+ */
11
+ ActionRequest: "ActionRequest"
12
+ };
13
+ //# sourceMappingURL=identityAuthenticationTypes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identityAuthenticationTypes.js","sourceRoot":"","sources":["../../../src/models/identityAuthenticationTypes.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AAEvC;;GAEG;AACH,gEAAgE;AAChE,MAAM,CAAC,MAAM,2BAA2B,GAAG;IAC1C;;OAEG;IACH,aAAa,EAAE,eAAe;CACrB,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * The types of Identity Authentication data.\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport const IdentityAuthenticationTypes = {\n\t/**\n\t * Represents action request.\n\t */\n\tActionRequest: \"ActionRequest\"\n} as const;\n\n/**\n * The types of Identity Authentication data.\n */\nexport type IdentityAuthenticationTypes =\n\t(typeof IdentityAuthenticationTypes)[keyof typeof IdentityAuthenticationTypes];\n"]}
@@ -0,0 +1,67 @@
1
+ import { ContextIdHelper, ContextIdStore } from "@twin.org/context";
2
+ import { Guards } from "@twin.org/core";
3
+ import { DocumentHelper, IdentityConnectorFactory } from "@twin.org/identity-models";
4
+ import { HeaderHelper, HeaderTypes } from "@twin.org/web";
5
+ /**
6
+ * Class performing verifiable credential authentication generation.
7
+ */
8
+ export class VerifiableCredentialAuthenticationGenerator {
9
+ /**
10
+ * Runtime name for the class.
11
+ */
12
+ static CLASS_NAME = "VerifiableCredentialAuthenticationGenerator";
13
+ /**
14
+ * Connector for identity operations.
15
+ * @internal
16
+ */
17
+ _identityConnector;
18
+ /**
19
+ * The verification method ID for the connector to use.
20
+ * @internal
21
+ */
22
+ _verificationMethodId;
23
+ /**
24
+ * The time-to-live (TTL) for token in seconds.
25
+ * @internal
26
+ */
27
+ _tokenTtlInSeconds;
28
+ /**
29
+ * Create a new instance of VerifiableCredentialAuthenticationGenerator.
30
+ * @param options The options for the service.
31
+ */
32
+ constructor(options) {
33
+ Guards.object(VerifiableCredentialAuthenticationGenerator.CLASS_NAME, "options", options);
34
+ Guards.object(VerifiableCredentialAuthenticationGenerator.CLASS_NAME, "options.config", options.config);
35
+ Guards.stringValue(VerifiableCredentialAuthenticationGenerator.CLASS_NAME, "options.config.verificationMethodId", options.config.verificationMethodId);
36
+ this._identityConnector = IdentityConnectorFactory.get(options?.identityConnectorType ?? "identity");
37
+ this._verificationMethodId = options.config.verificationMethodId;
38
+ this._tokenTtlInSeconds = options.config.tokenTtlInSeconds ?? 60;
39
+ }
40
+ /**
41
+ * Returns the class name of the component.
42
+ * @returns The class name of the component.
43
+ */
44
+ className() {
45
+ return VerifiableCredentialAuthenticationGenerator.CLASS_NAME;
46
+ }
47
+ /**
48
+ * Adds authentication information to the request headers.
49
+ * @param requestHeaders The request headers to add authentication information to.
50
+ * @param authData Optional authentication data passed from the request.
51
+ * @param authData.contextId The context ID for the authentication.
52
+ * @param authData.subject The subject for the authentication.
53
+ * @returns A promise that resolves when the authentication information has been added.
54
+ */
55
+ async addAuthentication(requestHeaders, authData) {
56
+ Guards.object(VerifiableCredentialAuthenticationGenerator.CLASS_NAME, "requestHeaders", requestHeaders);
57
+ const contextIds = await ContextIdStore.getContextIds();
58
+ ContextIdHelper.guard(contextIds, authData.contextId);
59
+ const contextId = contextIds[authData.contextId];
60
+ const ttlMs = this._tokenTtlInSeconds * 1000;
61
+ const credential = await this._identityConnector.createVerifiableCredential(contextId, DocumentHelper.joinId(contextId, this._verificationMethodId), undefined, authData.subject ?? {}, {
62
+ expirationDate: new Date(Date.now() + ttlMs)
63
+ });
64
+ requestHeaders[HeaderTypes.Authorization] = HeaderHelper.createBearer(credential.jwt);
65
+ }
66
+ }
67
+ //# sourceMappingURL=verifiableCredentialAuthenticationGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifiableCredentialAuthenticationGenerator.js","sourceRoot":"","sources":["../../src/verifiableCredentialAuthenticationGenerator.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,OAAO,EACN,cAAc,EACd,wBAAwB,EAExB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAqB,MAAM,eAAe,CAAC;AAI7E;;GAEG;AACH,MAAM,OAAO,2CAA2C;IACvD;;OAEG;IACI,MAAM,CAAU,UAAU,iDAAiE;IAElG;;;OAGG;IACc,kBAAkB,CAAqB;IAExD;;;OAGG;IACc,qBAAqB,CAAS;IAE/C;;;OAGG;IACc,kBAAkB,CAAS;IAE5C;;;OAGG;IACH,YAAY,OAAuE;QAClF,MAAM,CAAC,MAAM,CACZ,2CAA2C,CAAC,UAAU,aAEtD,OAAO,CACP,CAAC;QACF,MAAM,CAAC,MAAM,CACZ,2CAA2C,CAAC,UAAU,oBAEtD,OAAO,CAAC,MAAM,CACd,CAAC;QACF,MAAM,CAAC,WAAW,CACjB,2CAA2C,CAAC,UAAU,yCAEtD,OAAO,CAAC,MAAM,CAAC,oBAAoB,CACnC,CAAC;QAEF,IAAI,CAAC,kBAAkB,GAAG,wBAAwB,CAAC,GAAG,CACrD,OAAO,EAAE,qBAAqB,IAAI,UAAU,CAC5C,CAAC;QAEF,IAAI,CAAC,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAC;QACjE,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,iBAAiB,IAAI,EAAE,CAAC;IAClE,CAAC;IAED;;;OAGG;IACI,SAAS;QACf,OAAO,2CAA2C,CAAC,UAAU,CAAC;IAC/D,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,iBAAiB,CAC7B,cAA4B,EAC5B,QAGC;QAED,MAAM,CAAC,MAAM,CACZ,2CAA2C,CAAC,UAAU,oBAEtD,cAAc,CACd,CAAC;QAEF,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,aAAa,EAAE,CAAC;QACxD,eAAe,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;QACtD,MAAM,SAAS,GAAG,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAEjD,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAE7C,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,0BAA0B,CAC1E,SAAS,EACT,cAAc,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,qBAAqB,CAAC,EAC5D,SAAS,EACT,QAAQ,CAAC,OAAO,IAAI,EAAE,EACtB;YACC,cAAc,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;SAC5C,CACD,CAAC;QAEF,cAAc,CAAC,WAAW,CAAC,aAAa,CAAC,GAAG,YAAY,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACvF,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { IAuthenticationGenerator } from \"@twin.org/api-models\";\nimport { ContextIdHelper, ContextIdStore } from \"@twin.org/context\";\nimport { Guards } from \"@twin.org/core\";\nimport type { IJsonLdNodeObject } from \"@twin.org/data-json-ld\";\nimport {\n\tDocumentHelper,\n\tIdentityConnectorFactory,\n\ttype IIdentityConnector\n} from \"@twin.org/identity-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { HeaderHelper, HeaderTypes, type IHttpHeaders } from \"@twin.org/web\";\nimport type { IVerifiableCredentialAuthenticationGeneratorConfig } from \"./models/IVerifiableCredentialAuthenticationGeneratorConfig.js\";\nimport type { IVerifiableCredentialAuthenticationGeneratorConstructorOptions } from \"./models/IVerifiableCredentialAuthenticationGeneratorConstructorOptions.js\";\n\n/**\n * Class performing verifiable credential authentication generation.\n */\nexport class VerifiableCredentialAuthenticationGenerator implements IAuthenticationGenerator {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<VerifiableCredentialAuthenticationGenerator>();\n\n\t/**\n\t * Connector for identity operations.\n\t * @internal\n\t */\n\tprivate readonly _identityConnector: IIdentityConnector;\n\n\t/**\n\t * The verification method ID for the connector to use.\n\t * @internal\n\t */\n\tprivate readonly _verificationMethodId: string;\n\n\t/**\n\t * The time-to-live (TTL) for token in seconds.\n\t * @internal\n\t */\n\tprivate readonly _tokenTtlInSeconds: number;\n\n\t/**\n\t * Create a new instance of VerifiableCredentialAuthenticationGenerator.\n\t * @param options The options for the service.\n\t */\n\tconstructor(options: IVerifiableCredentialAuthenticationGeneratorConstructorOptions) {\n\t\tGuards.object<IVerifiableCredentialAuthenticationGeneratorConstructorOptions>(\n\t\t\tVerifiableCredentialAuthenticationGenerator.CLASS_NAME,\n\t\t\tnameof(options),\n\t\t\toptions\n\t\t);\n\t\tGuards.object<IVerifiableCredentialAuthenticationGeneratorConfig>(\n\t\t\tVerifiableCredentialAuthenticationGenerator.CLASS_NAME,\n\t\t\tnameof(options.config),\n\t\t\toptions.config\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tVerifiableCredentialAuthenticationGenerator.CLASS_NAME,\n\t\t\tnameof(options.config.verificationMethodId),\n\t\t\toptions.config.verificationMethodId\n\t\t);\n\n\t\tthis._identityConnector = IdentityConnectorFactory.get(\n\t\t\toptions?.identityConnectorType ?? \"identity\"\n\t\t);\n\n\t\tthis._verificationMethodId = options.config.verificationMethodId;\n\t\tthis._tokenTtlInSeconds = options.config.tokenTtlInSeconds ?? 60;\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 VerifiableCredentialAuthenticationGenerator.CLASS_NAME;\n\t}\n\n\t/**\n\t * Adds authentication information to the request headers.\n\t * @param requestHeaders The request headers to add authentication information to.\n\t * @param authData Optional authentication data passed from the request.\n\t * @param authData.contextId The context ID for the authentication.\n\t * @param authData.subject The subject for the authentication.\n\t * @returns A promise that resolves when the authentication information has been added.\n\t */\n\tpublic async addAuthentication(\n\t\trequestHeaders: IHttpHeaders,\n\t\tauthData: {\n\t\t\tcontextId: string;\n\t\t\tsubject?: IJsonLdNodeObject;\n\t\t}\n\t): Promise<void> {\n\t\tGuards.object<IHttpHeaders>(\n\t\t\tVerifiableCredentialAuthenticationGenerator.CLASS_NAME,\n\t\t\tnameof(requestHeaders),\n\t\t\trequestHeaders\n\t\t);\n\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tContextIdHelper.guard(contextIds, authData.contextId);\n\t\tconst contextId = contextIds[authData.contextId];\n\n\t\tconst ttlMs = this._tokenTtlInSeconds * 1000;\n\n\t\tconst credential = await this._identityConnector.createVerifiableCredential(\n\t\t\tcontextId,\n\t\t\tDocumentHelper.joinId(contextId, this._verificationMethodId),\n\t\t\tundefined,\n\t\t\tauthData.subject ?? {},\n\t\t\t{\n\t\t\t\texpirationDate: new Date(Date.now() + ttlMs)\n\t\t\t}\n\t\t);\n\n\t\trequestHeaders[HeaderTypes.Authorization] = HeaderHelper.createBearer(credential.jwt);\n\t}\n}\n"]}
@@ -0,0 +1,109 @@
1
+ import { ContextIdKeys } from "@twin.org/context";
2
+ import { GeneralError, Is } from "@twin.org/core";
3
+ import { IdentityConnectorFactory } from "@twin.org/identity-models";
4
+ import { VerifiableCredentialHelper } from "@twin.org/standards-w3c-did";
5
+ import { HeaderHelper, HeaderTypes } from "@twin.org/web";
6
+ /**
7
+ * Handle a JWT token in the authorization header and verify the credential.
8
+ */
9
+ export class VerifiableCredentialAuthenticationProcessor {
10
+ /**
11
+ * Runtime name for the class.
12
+ */
13
+ static CLASS_NAME = "VerifiableCredentialAuthenticationProcessor";
14
+ /**
15
+ * Connector for identity operations.
16
+ * @internal
17
+ */
18
+ _identityConnector;
19
+ /**
20
+ * The time-to-live (TTL) for token in seconds.
21
+ * @internal
22
+ */
23
+ _tokenTtlInSeconds;
24
+ /**
25
+ * Create a new instance of AuthCookiePreProcessor.
26
+ * @param options Options for the processor.
27
+ */
28
+ constructor(options) {
29
+ this._identityConnector = IdentityConnectorFactory.get(options?.identityConnectorType ?? "identity");
30
+ this._tokenTtlInSeconds = options?.config?.tokenTtlInSeconds ?? 60;
31
+ }
32
+ /**
33
+ * Returns the class name of the component.
34
+ * @returns The class name of the component.
35
+ */
36
+ className() {
37
+ return VerifiableCredentialAuthenticationProcessor.CLASS_NAME;
38
+ }
39
+ /**
40
+ * Features supported by this processor.
41
+ * If a route has any of these features listed, this processor will be run for that route.
42
+ * If this is not implemented, the processor will run for all routes.
43
+ * @returns The features supported by this processor.
44
+ */
45
+ features() {
46
+ return ["verifiableCredential"];
47
+ }
48
+ /**
49
+ * Pre process the REST request for the specified route.
50
+ * @param request The incoming request.
51
+ * @param response The outgoing response.
52
+ * @param route The route to process.
53
+ * @param contextIds The context IDs of the request.
54
+ * @param processorState The state handed through the processors.
55
+ * @returns Nothing
56
+ */
57
+ async pre(request, response, route, contextIds, processorState) {
58
+ try {
59
+ // Only process if the route has the verifiableCredential feature
60
+ if (Is.arrayValue(route?.processorFeatures) &&
61
+ route?.processorFeatures.includes("verifiableCredential")) {
62
+ const token = HeaderHelper.extractBearer(request.headers?.[HeaderTypes.Authorization]);
63
+ const result = await this._identityConnector.checkVerifiableCredential(token);
64
+ const verifiableCredential = result.verifiableCredential;
65
+ if (Is.empty(verifiableCredential)) {
66
+ throw new GeneralError(VerifiableCredentialAuthenticationProcessor.CLASS_NAME, "tokenNoCredential");
67
+ }
68
+ const issuer = Is.stringValue(verifiableCredential.issuer)
69
+ ? verifiableCredential.issuer
70
+ : undefined;
71
+ if (Is.empty(issuer)) {
72
+ throw new GeneralError(VerifiableCredentialAuthenticationProcessor.CLASS_NAME, "tokenNoIssuer");
73
+ }
74
+ const issuanceDate = VerifiableCredentialHelper.getValidFrom(verifiableCredential);
75
+ if (Is.empty(issuanceDate)) {
76
+ throw new GeneralError(VerifiableCredentialAuthenticationProcessor.CLASS_NAME, "tokenMissingIssuanceDate", {
77
+ issuer
78
+ });
79
+ }
80
+ const tokenCreated = new Date(issuanceDate);
81
+ const now = Date.now();
82
+ const tokenTtlInMs = this._tokenTtlInSeconds * 1000;
83
+ // If the token has expired then we should reject it
84
+ if (tokenCreated.getTime() + tokenTtlInMs < now) {
85
+ throw new GeneralError(VerifiableCredentialAuthenticationProcessor.CLASS_NAME, "tokenExpired", {
86
+ issuer
87
+ });
88
+ }
89
+ const subject = verifiableCredential.credentialSubject;
90
+ if (Is.empty(subject)) {
91
+ throw new GeneralError(VerifiableCredentialAuthenticationProcessor.CLASS_NAME, "tokenMissingSubject", {
92
+ issuer
93
+ });
94
+ }
95
+ let contextId = ContextIdKeys.Organization;
96
+ if (Is.object(processorState?.verifiableCredential)) {
97
+ contextId = processorState.verifiableCredential.contextId ?? contextId;
98
+ }
99
+ contextIds[contextId] = issuer;
100
+ processorState.verifiableCredentialJsonLd = verifiableCredential;
101
+ processorState.verifiableCredentialSubject = subject;
102
+ }
103
+ }
104
+ catch (err) {
105
+ throw new GeneralError(VerifiableCredentialAuthenticationProcessor.CLASS_NAME, "tokenFailed", undefined, err);
106
+ }
107
+ }
108
+ }
109
+ //# sourceMappingURL=verifiableCredentialAuthenticationProcessor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifiableCredentialAuthenticationProcessor.js","sourceRoot":"","sources":["../../src/verifiableCredentialAuthenticationProcessor.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type {\n\tIBaseRoute,\n\tIBaseRouteProcessor,\n\tIHttpResponse,\n\tIHttpServerRequest\n} from \"@twin.org/api-models\";\nimport { ContextIdKeys, type IContextIds } from \"@twin.org/context\";\nimport { GeneralError, Is } from \"@twin.org/core\";\nimport { IdentityConnectorFactory, type IIdentityConnector } from \"@twin.org/identity-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { VerifiableCredentialHelper } from \"@twin.org/standards-w3c-did\";\nimport { HeaderHelper, HeaderTypes } from \"@twin.org/web\";\nimport type { IVerifiableCredentialAuthenticationProcessorConstructorOptions } from \"./models/IVerifiableCredentialAuthenticationProcessorConstructorOptions.js\";\n\n/**\n * Handle a JWT token in the authorization header and verify the credential.\n */\nexport class VerifiableCredentialAuthenticationProcessor implements IBaseRouteProcessor {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<VerifiableCredentialAuthenticationProcessor>();\n\n\t/**\n\t * Connector for identity operations.\n\t * @internal\n\t */\n\tprivate readonly _identityConnector: IIdentityConnector;\n\n\t/**\n\t * The time-to-live (TTL) for token in seconds.\n\t * @internal\n\t */\n\tprivate readonly _tokenTtlInSeconds: number;\n\n\t/**\n\t * Create a new instance of AuthCookiePreProcessor.\n\t * @param options Options for the processor.\n\t */\n\tconstructor(options?: IVerifiableCredentialAuthenticationProcessorConstructorOptions) {\n\t\tthis._identityConnector = IdentityConnectorFactory.get(\n\t\t\toptions?.identityConnectorType ?? \"identity\"\n\t\t);\n\t\tthis._tokenTtlInSeconds = options?.config?.tokenTtlInSeconds ?? 60;\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 VerifiableCredentialAuthenticationProcessor.CLASS_NAME;\n\t}\n\n\t/**\n\t * Features supported by this processor.\n\t * If a route has any of these features listed, this processor will be run for that route.\n\t * If this is not implemented, the processor will run for all routes.\n\t * @returns The features supported by this processor.\n\t */\n\tpublic features(): string[] {\n\t\treturn [\"verifiableCredential\"];\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 Nothing\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\ttry {\n\t\t\t// Only process if the route has the verifiableCredential feature\n\t\t\tif (\n\t\t\t\tIs.arrayValue(route?.processorFeatures) &&\n\t\t\t\troute?.processorFeatures.includes(\"verifiableCredential\")\n\t\t\t) {\n\t\t\t\tconst token = HeaderHelper.extractBearer(request.headers?.[HeaderTypes.Authorization]);\n\n\t\t\t\tconst result = await this._identityConnector.checkVerifiableCredential(token);\n\n\t\t\t\tconst verifiableCredential = result.verifiableCredential;\n\t\t\t\tif (Is.empty(verifiableCredential)) {\n\t\t\t\t\tthrow new GeneralError(\n\t\t\t\t\t\tVerifiableCredentialAuthenticationProcessor.CLASS_NAME,\n\t\t\t\t\t\t\"tokenNoCredential\"\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst issuer: string | undefined = Is.stringValue(verifiableCredential.issuer)\n\t\t\t\t\t? verifiableCredential.issuer\n\t\t\t\t\t: undefined;\n\t\t\t\tif (Is.empty(issuer)) {\n\t\t\t\t\tthrow new GeneralError(\n\t\t\t\t\t\tVerifiableCredentialAuthenticationProcessor.CLASS_NAME,\n\t\t\t\t\t\t\"tokenNoIssuer\"\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst issuanceDate = VerifiableCredentialHelper.getValidFrom(verifiableCredential);\n\n\t\t\t\tif (Is.empty(issuanceDate)) {\n\t\t\t\t\tthrow new GeneralError(\n\t\t\t\t\t\tVerifiableCredentialAuthenticationProcessor.CLASS_NAME,\n\t\t\t\t\t\t\"tokenMissingIssuanceDate\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tissuer\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst tokenCreated = new Date(issuanceDate);\n\t\t\t\tconst now = Date.now();\n\t\t\t\tconst tokenTtlInMs = this._tokenTtlInSeconds * 1000;\n\n\t\t\t\t// If the token has expired then we should reject it\n\t\t\t\tif (tokenCreated.getTime() + tokenTtlInMs < now) {\n\t\t\t\t\tthrow new GeneralError(\n\t\t\t\t\t\tVerifiableCredentialAuthenticationProcessor.CLASS_NAME,\n\t\t\t\t\t\t\"tokenExpired\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tissuer\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst subject = verifiableCredential.credentialSubject;\n\t\t\t\tif (Is.empty(subject)) {\n\t\t\t\t\tthrow new GeneralError(\n\t\t\t\t\t\tVerifiableCredentialAuthenticationProcessor.CLASS_NAME,\n\t\t\t\t\t\t\"tokenMissingSubject\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tissuer\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tlet contextId: string = ContextIdKeys.Organization;\n\t\t\t\tif (Is.object<{ contextId?: string }>(processorState?.verifiableCredential)) {\n\t\t\t\t\tcontextId = processorState.verifiableCredential.contextId ?? contextId;\n\t\t\t\t}\n\n\t\t\t\tcontextIds[contextId] = issuer;\n\t\t\t\tprocessorState.verifiableCredentialJsonLd = verifiableCredential;\n\t\t\t\tprocessorState.verifiableCredentialSubject = subject;\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tVerifiableCredentialAuthenticationProcessor.CLASS_NAME,\n\t\t\t\t\"tokenFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n}\n"]}
@@ -1,9 +1,9 @@
1
- export * from "./models/identityAuthenticationContexts";
2
- export * from "./models/identityAuthenticationTypes";
3
- export * from "./models/IIdentityAuthenticationActionRequest";
4
- export * from "./models/IVerifiableCredentialAuthenticationGeneratorConfig";
5
- export * from "./models/IVerifiableCredentialAuthenticationGeneratorConstructorOptions";
6
- export * from "./models/IVerifiableCredentialAuthenticationProcessorConfig";
7
- export * from "./models/IVerifiableCredentialAuthenticationProcessorConstructorOptions";
8
- export * from "./verifiableCredentialAuthenticationGenerator";
9
- export * from "./verifiableCredentialAuthenticationProcessor";
1
+ export * from "./models/identityAuthenticationContexts.js";
2
+ export * from "./models/identityAuthenticationTypes.js";
3
+ export * from "./models/IIdentityAuthenticationActionRequest.js";
4
+ export * from "./models/IVerifiableCredentialAuthenticationGeneratorConfig.js";
5
+ export * from "./models/IVerifiableCredentialAuthenticationGeneratorConstructorOptions.js";
6
+ export * from "./models/IVerifiableCredentialAuthenticationProcessorConfig.js";
7
+ export * from "./models/IVerifiableCredentialAuthenticationProcessorConstructorOptions.js";
8
+ export * from "./verifiableCredentialAuthenticationGenerator.js";
9
+ export * from "./verifiableCredentialAuthenticationProcessor.js";
@@ -1,5 +1,5 @@
1
- import type { IdentityAuthenticationContexts } from "./identityAuthenticationContexts";
2
- import type { IdentityAuthenticationTypes } from "./identityAuthenticationTypes";
1
+ import type { IdentityAuthenticationContexts } from "./identityAuthenticationContexts.js";
2
+ import type { IdentityAuthenticationTypes } from "./identityAuthenticationTypes.js";
3
3
  /**
4
4
  * The JSON-LD definition for a action request.
5
5
  */
@@ -7,6 +7,11 @@ export interface IVerifiableCredentialAuthenticationGeneratorConfig {
7
7
  * @default 60 (1 minute)
8
8
  */
9
9
  tokenTtlInSeconds?: number;
10
+ /**
11
+ * The context id to use as the base for the verification method e.g. node/organization.
12
+ * @default node
13
+ */
14
+ contextId?: string;
10
15
  /**
11
16
  * The id of the identity method to use when creating/verifying tokens.
12
17
  */
@@ -1,4 +1,4 @@
1
- import type { IVerifiableCredentialAuthenticationGeneratorConfig } from "./IVerifiableCredentialAuthenticationGeneratorConfig";
1
+ import type { IVerifiableCredentialAuthenticationGeneratorConfig } from "./IVerifiableCredentialAuthenticationGeneratorConfig.js";
2
2
  /**
3
3
  * Options for the verifiable credential authentication generator constructor.
4
4
  */
@@ -1,4 +1,4 @@
1
- import type { IVerifiableCredentialAuthenticationProcessorConfig } from "./IVerifiableCredentialAuthenticationProcessorConfig";
1
+ import type { IVerifiableCredentialAuthenticationProcessorConfig } from "./IVerifiableCredentialAuthenticationProcessorConfig.js";
2
2
  /**
3
3
  * Options for the verifiable credential authentication processor constructor.
4
4
  */
@@ -1,7 +1,7 @@
1
1
  import type { IAuthenticationGenerator } from "@twin.org/api-models";
2
2
  import type { IJsonLdNodeObject } from "@twin.org/data-json-ld";
3
3
  import { type IHttpHeaders } from "@twin.org/web";
4
- import type { IVerifiableCredentialAuthenticationGeneratorConstructorOptions } from "./models/IVerifiableCredentialAuthenticationGeneratorConstructorOptions";
4
+ import type { IVerifiableCredentialAuthenticationGeneratorConstructorOptions } from "./models/IVerifiableCredentialAuthenticationGeneratorConstructorOptions.js";
5
5
  /**
6
6
  * Class performing verifiable credential authentication generation.
7
7
  */
@@ -9,24 +9,27 @@ export declare class VerifiableCredentialAuthenticationGenerator implements IAut
9
9
  /**
10
10
  * Runtime name for the class.
11
11
  */
12
- readonly CLASS_NAME: string;
12
+ static readonly CLASS_NAME: string;
13
13
  /**
14
14
  * Create a new instance of VerifiableCredentialAuthenticationGenerator.
15
15
  * @param options The options for the service.
16
16
  */
17
17
  constructor(options: IVerifiableCredentialAuthenticationGeneratorConstructorOptions);
18
18
  /**
19
- * The component needs to be started when the node is initialized.
20
- * @param nodeIdentity The identity of the node starting the component.
21
- * @param nodeLoggingComponentType The node logging component type.
22
- * @returns Nothing.
19
+ * Returns the class name of the component.
20
+ * @returns The class name of the component.
23
21
  */
24
- start(nodeIdentity: string, nodeLoggingComponentType: string | undefined): Promise<void>;
22
+ className(): string;
25
23
  /**
26
24
  * Adds authentication information to the request headers.
27
25
  * @param requestHeaders The request headers to add authentication information to.
28
26
  * @param authData Optional authentication data passed from the request.
27
+ * @param authData.contextId The context ID for the authentication.
28
+ * @param authData.subject The subject for the authentication.
29
29
  * @returns A promise that resolves when the authentication information has been added.
30
30
  */
31
- addAuthentication(requestHeaders: IHttpHeaders, authData: IJsonLdNodeObject): Promise<void>;
31
+ addAuthentication(requestHeaders: IHttpHeaders, authData: {
32
+ contextId: string;
33
+ subject?: IJsonLdNodeObject;
34
+ }): Promise<void>;
32
35
  }
@@ -1,5 +1,6 @@
1
- import type { IBaseRoute, IBaseRouteProcessor, IHttpRequestIdentity, IHttpResponse, IHttpServerRequest } from "@twin.org/api-models";
2
- import type { IVerifiableCredentialAuthenticationProcessorConstructorOptions } from "./models/IVerifiableCredentialAuthenticationProcessorConstructorOptions";
1
+ import type { IBaseRoute, IBaseRouteProcessor, IHttpResponse, IHttpServerRequest } from "@twin.org/api-models";
2
+ import { type IContextIds } from "@twin.org/context";
3
+ import type { IVerifiableCredentialAuthenticationProcessorConstructorOptions } from "./models/IVerifiableCredentialAuthenticationProcessorConstructorOptions.js";
3
4
  /**
4
5
  * Handle a JWT token in the authorization header and verify the credential.
5
6
  */
@@ -7,12 +8,17 @@ export declare class VerifiableCredentialAuthenticationProcessor implements IBas
7
8
  /**
8
9
  * Runtime name for the class.
9
10
  */
10
- readonly CLASS_NAME: string;
11
+ static readonly CLASS_NAME: string;
11
12
  /**
12
13
  * Create a new instance of AuthCookiePreProcessor.
13
14
  * @param options Options for the processor.
14
15
  */
15
16
  constructor(options?: IVerifiableCredentialAuthenticationProcessorConstructorOptions);
17
+ /**
18
+ * Returns the class name of the component.
19
+ * @returns The class name of the component.
20
+ */
21
+ className(): string;
16
22
  /**
17
23
  * Features supported by this processor.
18
24
  * If a route has any of these features listed, this processor will be run for that route.
@@ -25,11 +31,11 @@ export declare class VerifiableCredentialAuthenticationProcessor implements IBas
25
31
  * @param request The incoming request.
26
32
  * @param response The outgoing response.
27
33
  * @param route The route to process.
28
- * @param requestIdentity The identity context for the request.
34
+ * @param contextIds The context IDs of the request.
29
35
  * @param processorState The state handed through the processors.
30
36
  * @returns Nothing
31
37
  */
32
- pre(request: IHttpServerRequest, response: IHttpResponse, route: IBaseRoute | undefined, requestIdentity: IHttpRequestIdentity, processorState: {
38
+ pre(request: IHttpServerRequest, response: IHttpResponse, route: IBaseRoute | undefined, contextIds: IContextIds, processorState: {
33
39
  [id: string]: unknown;
34
40
  }): Promise<void>;
35
41
  }
package/docs/changelog.md CHANGED
@@ -1,5 +1,56 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.0.3-next.1](https://github.com/twinfoundation/identity/compare/identity-authentication-v0.0.3-next.0...identity-authentication-v0.0.3-next.1) (2025-11-11)
4
+
5
+
6
+ ### Features
7
+
8
+ * add context id features ([#62](https://github.com/twinfoundation/identity/issues/62)) ([e02ecca](https://github.com/twinfoundation/identity/commit/e02ecca9c45a849104bfbf7bc18a1f44e6eea8a1))
9
+ * add identity authentication module ([33fb5cc](https://github.com/twinfoundation/identity/commit/33fb5cc409ff11aba273b13c8d83724b0b0daa53))
10
+ * add validate-locales ([04d74b4](https://github.com/twinfoundation/identity/commit/04d74b4d1ebe42672e8ca75a7bdb8e3556afd0be))
11
+ * additional fields for IIdentityAuthenticationActionRequest ([5d7d688](https://github.com/twinfoundation/identity/commit/5d7d688f370978cd7287ce0e98dd8da82800b7ea))
12
+
13
+
14
+ ### Dependencies
15
+
16
+ * The following workspace dependencies were updated
17
+ * dependencies
18
+ * @twin.org/identity-models bumped from 0.0.3-next.0 to 0.0.3-next.1
19
+ * devDependencies
20
+ * @twin.org/identity-connector-entity-storage bumped from 0.0.3-next.0 to 0.0.3-next.1
21
+
22
+ ## [0.0.2-next.10](https://github.com/twinfoundation/identity/compare/identity-authentication-v0.0.2-next.9...identity-authentication-v0.0.2-next.10) (2025-10-27)
23
+
24
+
25
+ ### Miscellaneous Chores
26
+
27
+ * **identity-authentication:** Synchronize repo versions
28
+
29
+
30
+ ### Dependencies
31
+
32
+ * The following workspace dependencies were updated
33
+ * dependencies
34
+ * @twin.org/identity-models bumped from 0.0.2-next.9 to 0.0.2-next.10
35
+ * devDependencies
36
+ * @twin.org/identity-connector-entity-storage bumped from 0.0.2-next.9 to 0.0.2-next.10
37
+
38
+ ## [0.0.2-next.9](https://github.com/twinfoundation/identity/compare/identity-authentication-v0.0.2-next.8...identity-authentication-v0.0.2-next.9) (2025-10-09)
39
+
40
+
41
+ ### Features
42
+
43
+ * add validate-locales ([04d74b4](https://github.com/twinfoundation/identity/commit/04d74b4d1ebe42672e8ca75a7bdb8e3556afd0be))
44
+
45
+
46
+ ### Dependencies
47
+
48
+ * The following workspace dependencies were updated
49
+ * dependencies
50
+ * @twin.org/identity-models bumped from 0.0.2-next.8 to 0.0.2-next.9
51
+ * devDependencies
52
+ * @twin.org/identity-connector-entity-storage bumped from 0.0.2-next.8 to 0.0.2-next.9
53
+
3
54
  ## [0.0.2-next.8](https://github.com/twinfoundation/identity/compare/identity-authentication-v0.0.2-next.7...identity-authentication-v0.0.2-next.8) (2025-09-25)
4
55
 
5
56
 
@@ -30,45 +30,27 @@ The options for the service.
30
30
 
31
31
  ### CLASS\_NAME
32
32
 
33
- > `readonly` **CLASS\_NAME**: `string`
33
+ > `readonly` `static` **CLASS\_NAME**: `string`
34
34
 
35
35
  Runtime name for the class.
36
36
 
37
- #### Implementation of
38
-
39
- `IAuthenticationGenerator.CLASS_NAME`
40
-
41
37
  ## Methods
42
38
 
43
- ### start()
44
-
45
- > **start**(`nodeIdentity`, `nodeLoggingComponentType`): `Promise`\<`void`\>
46
-
47
- The component needs to be started when the node is initialized.
48
-
49
- #### Parameters
50
-
51
- ##### nodeIdentity
52
-
53
- `string`
54
-
55
- The identity of the node starting the component.
39
+ ### className()
56
40
 
57
- ##### nodeLoggingComponentType
41
+ > **className**(): `string`
58
42
 
59
- The node logging component type.
60
-
61
- `undefined` | `string`
43
+ Returns the class name of the component.
62
44
 
63
45
  #### Returns
64
46
 
65
- `Promise`\<`void`\>
47
+ `string`
66
48
 
67
- Nothing.
49
+ The class name of the component.
68
50
 
69
51
  #### Implementation of
70
52
 
71
- `IAuthenticationGenerator.start`
53
+ `IAuthenticationGenerator.className`
72
54
 
73
55
  ***
74
56
 
@@ -88,9 +70,19 @@ The request headers to add authentication information to.
88
70
 
89
71
  ##### authData
90
72
 
73
+ Optional authentication data passed from the request.
74
+
75
+ ###### contextId
76
+
77
+ `string`
78
+
79
+ The context ID for the authentication.
80
+
81
+ ###### subject?
82
+
91
83
  `IJsonLdNodeObject`
92
84
 
93
- Optional authentication data passed from the request.
85
+ The subject for the authentication.
94
86
 
95
87
  #### Returns
96
88
 
@@ -30,15 +30,29 @@ Options for the processor.
30
30
 
31
31
  ### CLASS\_NAME
32
32
 
33
- > `readonly` **CLASS\_NAME**: `string`
33
+ > `readonly` `static` **CLASS\_NAME**: `string`
34
34
 
35
35
  Runtime name for the class.
36
36
 
37
+ ## Methods
38
+
39
+ ### className()
40
+
41
+ > **className**(): `string`
42
+
43
+ Returns the class name of the component.
44
+
45
+ #### Returns
46
+
47
+ `string`
48
+
49
+ The class name of the component.
50
+
37
51
  #### Implementation of
38
52
 
39
- `IBaseRouteProcessor.CLASS_NAME`
53
+ `IBaseRouteProcessor.className`
40
54
 
41
- ## Methods
55
+ ***
42
56
 
43
57
  ### features()
44
58
 
@@ -62,7 +76,7 @@ The features supported by this processor.
62
76
 
63
77
  ### pre()
64
78
 
65
- > **pre**(`request`, `response`, `route`, `requestIdentity`, `processorState`): `Promise`\<`void`\>
79
+ > **pre**(`request`, `response`, `route`, `contextIds`, `processorState`): `Promise`\<`void`\>
66
80
 
67
81
  Pre process the REST request for the specified route.
68
82
 
@@ -84,13 +98,13 @@ The outgoing response.
84
98
 
85
99
  The route to process.
86
100
 
87
- `undefined` | `IBaseRoute`
101
+ `IBaseRoute` | `undefined`
88
102
 
89
- ##### requestIdentity
103
+ ##### contextIds
90
104
 
91
- `IHttpRequestIdentity`
105
+ `IContextIds`
92
106
 
93
- The identity context for the request.
107
+ The context IDs of the request.
94
108
 
95
109
  ##### processorState
96
110
 
@@ -18,6 +18,20 @@ The time-to-live (TTL) for token in seconds.
18
18
 
19
19
  ***
20
20
 
21
+ ### contextId?
22
+
23
+ > `optional` **contextId**: `string`
24
+
25
+ The context id to use as the base for the verification method e.g. node/organization.
26
+
27
+ #### Default
28
+
29
+ ```ts
30
+ node
31
+ ```
32
+
33
+ ***
34
+
21
35
  ### verificationMethodId
22
36
 
23
37
  > **verificationMethodId**: `string`
package/locales/en.json CHANGED
@@ -1,8 +1,5 @@
1
1
  {
2
2
  "error": {
3
- "verifiableCredentialAuthenticationGenerator": {
4
- "missingNodeIdentity": "The authenticator can not generate a token without a node identity"
5
- },
6
3
  "verifiableCredentialAuthenticationProcessor": {
7
4
  "tokenFailed": "Failed to verify token",
8
5
  "tokenNoCredential": "The token does not contain a verifiable credential",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/identity-authentication",
3
- "version": "0.0.2-next.8",
3
+ "version": "0.0.3-next.1",
4
4
  "description": "Authentication components implemented using identity",
5
5
  "repository": {
6
6
  "type": "git",
@@ -15,29 +15,43 @@
15
15
  },
16
16
  "dependencies": {
17
17
  "@twin.org/api-models": "next",
18
+ "@twin.org/context": "next",
18
19
  "@twin.org/core": "next",
19
20
  "@twin.org/crypto": "next",
20
21
  "@twin.org/data-json-ld": "next",
21
- "@twin.org/identity-models": "0.0.2-next.8",
22
+ "@twin.org/identity-models": "0.0.3-next.1",
22
23
  "@twin.org/standards-w3c-did": "next",
23
24
  "@twin.org/web": "next"
24
25
  },
25
- "main": "./dist/cjs/index.cjs",
26
- "module": "./dist/esm/index.mjs",
26
+ "main": "./dist/es/index.js",
27
27
  "types": "./dist/types/index.d.ts",
28
28
  "exports": {
29
29
  ".": {
30
30
  "types": "./dist/types/index.d.ts",
31
- "require": "./dist/cjs/index.cjs",
32
- "import": "./dist/esm/index.mjs"
31
+ "import": "./dist/es/index.js",
32
+ "default": "./dist/es/index.js"
33
33
  },
34
34
  "./locales/*.json": "./locales/*.json"
35
35
  },
36
36
  "files": [
37
- "dist/cjs",
38
- "dist/esm",
37
+ "dist/es",
39
38
  "dist/types",
40
39
  "locales",
41
40
  "docs"
42
- ]
41
+ ],
42
+ "keywords": [
43
+ "twin",
44
+ "trade",
45
+ "iota",
46
+ "framework",
47
+ "blockchain",
48
+ "identity",
49
+ "did",
50
+ "credentials",
51
+ "authentication"
52
+ ],
53
+ "bugs": {
54
+ "url": "git+https://github.com/twinfoundation/identity/issues"
55
+ },
56
+ "homepage": "https://twindev.org"
43
57
  }
@@ -1,198 +0,0 @@
1
- 'use strict';
2
-
3
- var core = require('@twin.org/core');
4
- var identityModels = require('@twin.org/identity-models');
5
- var web = require('@twin.org/web');
6
- var standardsW3cDid = require('@twin.org/standards-w3c-did');
7
-
8
- // Copyright 2024 IOTA Stiftung.
9
- // SPDX-License-Identifier: Apache-2.0.
10
- /**
11
- * The LD Contexts concerning Identity Authentication.
12
- */
13
- // eslint-disable-next-line @typescript-eslint/naming-convention
14
- const IdentityAuthenticationContexts = {
15
- /**
16
- * The Identity Authentication LD Context.
17
- */
18
- ContextRoot: "https://schema.twindev.org/identity-authentication"
19
- };
20
-
21
- // Copyright 2024 IOTA Stiftung.
22
- // SPDX-License-Identifier: Apache-2.0.
23
- /**
24
- * The types of Identity Authentication data.
25
- */
26
- // eslint-disable-next-line @typescript-eslint/naming-convention
27
- const IdentityAuthenticationTypes = {
28
- /**
29
- * Represents action request.
30
- */
31
- ActionRequest: "ActionRequest"
32
- };
33
-
34
- /**
35
- * Class performing verifiable credential authentication generation.
36
- */
37
- class VerifiableCredentialAuthenticationGenerator {
38
- /**
39
- * Runtime name for the class.
40
- */
41
- CLASS_NAME = "VerifiableCredentialAuthenticationGenerator";
42
- /**
43
- * Connector for identity operations.
44
- * @internal
45
- */
46
- _identityConnector;
47
- /**
48
- * The verification method ID for the connector to use.
49
- * @internal
50
- */
51
- _verificationMethodId;
52
- /**
53
- * The time-to-live (TTL) for token in seconds.
54
- * @internal
55
- */
56
- _tokenTtlInSeconds;
57
- /**
58
- * The node identity.
59
- * @internal
60
- */
61
- _nodeIdentity;
62
- /**
63
- * Create a new instance of VerifiableCredentialAuthenticationGenerator.
64
- * @param options The options for the service.
65
- */
66
- constructor(options) {
67
- core.Guards.object(this.CLASS_NAME, "options", options);
68
- core.Guards.object(this.CLASS_NAME, "options.config", options.config);
69
- core.Guards.stringValue(this.CLASS_NAME, "options.config.verificationMethodId", options.config.verificationMethodId);
70
- this._identityConnector = identityModels.IdentityConnectorFactory.get(options?.identityConnectorType ?? "identity");
71
- this._verificationMethodId = options.config.verificationMethodId;
72
- this._tokenTtlInSeconds = options.config.tokenTtlInSeconds ?? 60;
73
- }
74
- /**
75
- * The component needs to be started when the node is initialized.
76
- * @param nodeIdentity The identity of the node starting the component.
77
- * @param nodeLoggingComponentType The node logging component type.
78
- * @returns Nothing.
79
- */
80
- async start(nodeIdentity, nodeLoggingComponentType) {
81
- this._nodeIdentity = nodeIdentity;
82
- }
83
- /**
84
- * Adds authentication information to the request headers.
85
- * @param requestHeaders The request headers to add authentication information to.
86
- * @param authData Optional authentication data passed from the request.
87
- * @returns A promise that resolves when the authentication information has been added.
88
- */
89
- async addAuthentication(requestHeaders, authData) {
90
- core.Guards.object(this.CLASS_NAME, "requestHeaders", requestHeaders);
91
- if (!this._nodeIdentity) {
92
- throw new core.GeneralError(this.CLASS_NAME, "missingNodeIdentity");
93
- }
94
- const ttlMs = this._tokenTtlInSeconds * 1000;
95
- const credential = await this._identityConnector.createVerifiableCredential(this._nodeIdentity, identityModels.DocumentHelper.joinId(this._nodeIdentity, this._verificationMethodId), undefined, authData, {
96
- expirationDate: new Date(Date.now() + ttlMs)
97
- });
98
- requestHeaders[web.HeaderTypes.Authorization] = web.HeaderHelper.createBearer(credential.jwt);
99
- }
100
- }
101
-
102
- /**
103
- * Handle a JWT token in the authorization header and verify the credential.
104
- */
105
- class VerifiableCredentialAuthenticationProcessor {
106
- /**
107
- * Runtime name for the class.
108
- */
109
- CLASS_NAME = "VerifiableCredentialAuthenticationProcessor";
110
- /**
111
- * Connector for identity operations.
112
- * @internal
113
- */
114
- _identityConnector;
115
- /**
116
- * The time-to-live (TTL) for token in seconds.
117
- * @internal
118
- */
119
- _tokenTtlInSeconds;
120
- /**
121
- * Create a new instance of AuthCookiePreProcessor.
122
- * @param options Options for the processor.
123
- */
124
- constructor(options) {
125
- this._identityConnector = identityModels.IdentityConnectorFactory.get(options?.identityConnectorType ?? "identity");
126
- this._tokenTtlInSeconds = options?.config?.tokenTtlInSeconds ?? 60;
127
- }
128
- /**
129
- * Features supported by this processor.
130
- * If a route has any of these features listed, this processor will be run for that route.
131
- * If this is not implemented, the processor will run for all routes.
132
- * @returns The features supported by this processor.
133
- */
134
- features() {
135
- return ["verifiableCredential"];
136
- }
137
- /**
138
- * Pre process the REST request for the specified route.
139
- * @param request The incoming request.
140
- * @param response The outgoing response.
141
- * @param route The route to process.
142
- * @param requestIdentity The identity context for the request.
143
- * @param processorState The state handed through the processors.
144
- * @returns Nothing
145
- */
146
- async pre(request, response, route, requestIdentity, processorState) {
147
- try {
148
- // Only process if the route has the verifiableCredential feature
149
- if (core.Is.arrayValue(route?.processorFeatures) &&
150
- route?.processorFeatures.includes("verifiableCredential")) {
151
- const token = web.HeaderHelper.extractBearer(request.headers?.[web.HeaderTypes.Authorization]);
152
- const result = await this._identityConnector.checkVerifiableCredential(token);
153
- const verifiableCredential = result.verifiableCredential;
154
- if (core.Is.empty(verifiableCredential)) {
155
- throw new core.GeneralError(this.CLASS_NAME, "tokenNoCredential");
156
- }
157
- const issuer = core.Is.stringValue(verifiableCredential.issuer)
158
- ? verifiableCredential.issuer
159
- : undefined;
160
- if (core.Is.empty(issuer)) {
161
- throw new core.GeneralError(this.CLASS_NAME, "tokenNoIssuer");
162
- }
163
- const issuanceDate = standardsW3cDid.VerifiableCredentialHelper.getValidFrom(verifiableCredential);
164
- if (core.Is.empty(issuanceDate)) {
165
- throw new core.GeneralError(this.CLASS_NAME, "tokenMissingIssuanceDate", {
166
- issuer
167
- });
168
- }
169
- const tokenCreated = new Date(issuanceDate);
170
- const now = Date.now();
171
- const tokenTtlInMs = this._tokenTtlInSeconds * 1000;
172
- // If the token has expired then we should reject it
173
- if (tokenCreated.getTime() + tokenTtlInMs < now) {
174
- throw new core.GeneralError(this.CLASS_NAME, "tokenExpired", {
175
- issuer
176
- });
177
- }
178
- const subject = verifiableCredential.credentialSubject;
179
- if (core.Is.empty(subject)) {
180
- throw new core.GeneralError(this.CLASS_NAME, "tokenMissingSubject", {
181
- issuer
182
- });
183
- }
184
- processorState.verifiableCredentialIssuer = issuer;
185
- processorState.verifiableCredential = verifiableCredential;
186
- processorState.verifiableCredentialSubject = subject;
187
- }
188
- }
189
- catch (err) {
190
- throw new core.GeneralError(this.CLASS_NAME, "tokenFailed", undefined, err);
191
- }
192
- }
193
- }
194
-
195
- exports.IdentityAuthenticationContexts = IdentityAuthenticationContexts;
196
- exports.IdentityAuthenticationTypes = IdentityAuthenticationTypes;
197
- exports.VerifiableCredentialAuthenticationGenerator = VerifiableCredentialAuthenticationGenerator;
198
- exports.VerifiableCredentialAuthenticationProcessor = VerifiableCredentialAuthenticationProcessor;
@@ -1,193 +0,0 @@
1
- import { Guards, GeneralError, Is } from '@twin.org/core';
2
- import { IdentityConnectorFactory, DocumentHelper } from '@twin.org/identity-models';
3
- import { HeaderHelper, HeaderTypes } from '@twin.org/web';
4
- import { VerifiableCredentialHelper } from '@twin.org/standards-w3c-did';
5
-
6
- // Copyright 2024 IOTA Stiftung.
7
- // SPDX-License-Identifier: Apache-2.0.
8
- /**
9
- * The LD Contexts concerning Identity Authentication.
10
- */
11
- // eslint-disable-next-line @typescript-eslint/naming-convention
12
- const IdentityAuthenticationContexts = {
13
- /**
14
- * The Identity Authentication LD Context.
15
- */
16
- ContextRoot: "https://schema.twindev.org/identity-authentication"
17
- };
18
-
19
- // Copyright 2024 IOTA Stiftung.
20
- // SPDX-License-Identifier: Apache-2.0.
21
- /**
22
- * The types of Identity Authentication data.
23
- */
24
- // eslint-disable-next-line @typescript-eslint/naming-convention
25
- const IdentityAuthenticationTypes = {
26
- /**
27
- * Represents action request.
28
- */
29
- ActionRequest: "ActionRequest"
30
- };
31
-
32
- /**
33
- * Class performing verifiable credential authentication generation.
34
- */
35
- class VerifiableCredentialAuthenticationGenerator {
36
- /**
37
- * Runtime name for the class.
38
- */
39
- CLASS_NAME = "VerifiableCredentialAuthenticationGenerator";
40
- /**
41
- * Connector for identity operations.
42
- * @internal
43
- */
44
- _identityConnector;
45
- /**
46
- * The verification method ID for the connector to use.
47
- * @internal
48
- */
49
- _verificationMethodId;
50
- /**
51
- * The time-to-live (TTL) for token in seconds.
52
- * @internal
53
- */
54
- _tokenTtlInSeconds;
55
- /**
56
- * The node identity.
57
- * @internal
58
- */
59
- _nodeIdentity;
60
- /**
61
- * Create a new instance of VerifiableCredentialAuthenticationGenerator.
62
- * @param options The options for the service.
63
- */
64
- constructor(options) {
65
- Guards.object(this.CLASS_NAME, "options", options);
66
- Guards.object(this.CLASS_NAME, "options.config", options.config);
67
- Guards.stringValue(this.CLASS_NAME, "options.config.verificationMethodId", options.config.verificationMethodId);
68
- this._identityConnector = IdentityConnectorFactory.get(options?.identityConnectorType ?? "identity");
69
- this._verificationMethodId = options.config.verificationMethodId;
70
- this._tokenTtlInSeconds = options.config.tokenTtlInSeconds ?? 60;
71
- }
72
- /**
73
- * The component needs to be started when the node is initialized.
74
- * @param nodeIdentity The identity of the node starting the component.
75
- * @param nodeLoggingComponentType The node logging component type.
76
- * @returns Nothing.
77
- */
78
- async start(nodeIdentity, nodeLoggingComponentType) {
79
- this._nodeIdentity = nodeIdentity;
80
- }
81
- /**
82
- * Adds authentication information to the request headers.
83
- * @param requestHeaders The request headers to add authentication information to.
84
- * @param authData Optional authentication data passed from the request.
85
- * @returns A promise that resolves when the authentication information has been added.
86
- */
87
- async addAuthentication(requestHeaders, authData) {
88
- Guards.object(this.CLASS_NAME, "requestHeaders", requestHeaders);
89
- if (!this._nodeIdentity) {
90
- throw new GeneralError(this.CLASS_NAME, "missingNodeIdentity");
91
- }
92
- const ttlMs = this._tokenTtlInSeconds * 1000;
93
- const credential = await this._identityConnector.createVerifiableCredential(this._nodeIdentity, DocumentHelper.joinId(this._nodeIdentity, this._verificationMethodId), undefined, authData, {
94
- expirationDate: new Date(Date.now() + ttlMs)
95
- });
96
- requestHeaders[HeaderTypes.Authorization] = HeaderHelper.createBearer(credential.jwt);
97
- }
98
- }
99
-
100
- /**
101
- * Handle a JWT token in the authorization header and verify the credential.
102
- */
103
- class VerifiableCredentialAuthenticationProcessor {
104
- /**
105
- * Runtime name for the class.
106
- */
107
- CLASS_NAME = "VerifiableCredentialAuthenticationProcessor";
108
- /**
109
- * Connector for identity operations.
110
- * @internal
111
- */
112
- _identityConnector;
113
- /**
114
- * The time-to-live (TTL) for token in seconds.
115
- * @internal
116
- */
117
- _tokenTtlInSeconds;
118
- /**
119
- * Create a new instance of AuthCookiePreProcessor.
120
- * @param options Options for the processor.
121
- */
122
- constructor(options) {
123
- this._identityConnector = IdentityConnectorFactory.get(options?.identityConnectorType ?? "identity");
124
- this._tokenTtlInSeconds = options?.config?.tokenTtlInSeconds ?? 60;
125
- }
126
- /**
127
- * Features supported by this processor.
128
- * If a route has any of these features listed, this processor will be run for that route.
129
- * If this is not implemented, the processor will run for all routes.
130
- * @returns The features supported by this processor.
131
- */
132
- features() {
133
- return ["verifiableCredential"];
134
- }
135
- /**
136
- * Pre process the REST request for the specified route.
137
- * @param request The incoming request.
138
- * @param response The outgoing response.
139
- * @param route The route to process.
140
- * @param requestIdentity The identity context for the request.
141
- * @param processorState The state handed through the processors.
142
- * @returns Nothing
143
- */
144
- async pre(request, response, route, requestIdentity, processorState) {
145
- try {
146
- // Only process if the route has the verifiableCredential feature
147
- if (Is.arrayValue(route?.processorFeatures) &&
148
- route?.processorFeatures.includes("verifiableCredential")) {
149
- const token = HeaderHelper.extractBearer(request.headers?.[HeaderTypes.Authorization]);
150
- const result = await this._identityConnector.checkVerifiableCredential(token);
151
- const verifiableCredential = result.verifiableCredential;
152
- if (Is.empty(verifiableCredential)) {
153
- throw new GeneralError(this.CLASS_NAME, "tokenNoCredential");
154
- }
155
- const issuer = Is.stringValue(verifiableCredential.issuer)
156
- ? verifiableCredential.issuer
157
- : undefined;
158
- if (Is.empty(issuer)) {
159
- throw new GeneralError(this.CLASS_NAME, "tokenNoIssuer");
160
- }
161
- const issuanceDate = VerifiableCredentialHelper.getValidFrom(verifiableCredential);
162
- if (Is.empty(issuanceDate)) {
163
- throw new GeneralError(this.CLASS_NAME, "tokenMissingIssuanceDate", {
164
- issuer
165
- });
166
- }
167
- const tokenCreated = new Date(issuanceDate);
168
- const now = Date.now();
169
- const tokenTtlInMs = this._tokenTtlInSeconds * 1000;
170
- // If the token has expired then we should reject it
171
- if (tokenCreated.getTime() + tokenTtlInMs < now) {
172
- throw new GeneralError(this.CLASS_NAME, "tokenExpired", {
173
- issuer
174
- });
175
- }
176
- const subject = verifiableCredential.credentialSubject;
177
- if (Is.empty(subject)) {
178
- throw new GeneralError(this.CLASS_NAME, "tokenMissingSubject", {
179
- issuer
180
- });
181
- }
182
- processorState.verifiableCredentialIssuer = issuer;
183
- processorState.verifiableCredential = verifiableCredential;
184
- processorState.verifiableCredentialSubject = subject;
185
- }
186
- }
187
- catch (err) {
188
- throw new GeneralError(this.CLASS_NAME, "tokenFailed", undefined, err);
189
- }
190
- }
191
- }
192
-
193
- export { IdentityAuthenticationContexts, IdentityAuthenticationTypes, VerifiableCredentialAuthenticationGenerator, VerifiableCredentialAuthenticationProcessor };