@twin.org/identity-authentication 0.0.3-next.5 → 0.0.3-next.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +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"]}
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 id of the identity method to use when creating/verifying tokens.\n\t */\n\tverificationMethodId: string;\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { ContextIdKeys } from "@twin.org/context";
2
- import { GeneralError, Is } from "@twin.org/core";
2
+ import { Is, UnauthorizedError } from "@twin.org/core";
3
3
  import { IdentityConnectorFactory } from "@twin.org/identity-models";
4
4
  import { VerifiableCredentialHelper } from "@twin.org/standards-w3c-did";
5
5
  import { HeaderHelper, HeaderTypes } from "@twin.org/web";
@@ -55,54 +55,58 @@ export class VerifiableCredentialAuthenticationProcessor {
55
55
  * @returns Nothing
56
56
  */
57
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;
58
+ // Only process if the route has the verifiableCredential feature
59
+ if (Is.arrayValue(route?.processorFeatures) &&
60
+ route?.processorFeatures.includes("verifiableCredential")) {
61
+ const token = HeaderHelper.extractBearer(request.headers?.[HeaderTypes.Authorization]);
62
+ if (!Is.stringValue(token)) {
63
+ throw new UnauthorizedError(VerifiableCredentialAuthenticationProcessor.CLASS_NAME, "tokenMissing");
102
64
  }
103
- }
104
- catch (err) {
105
- throw new GeneralError(VerifiableCredentialAuthenticationProcessor.CLASS_NAME, "tokenFailed", undefined, err);
65
+ let verificationResult;
66
+ try {
67
+ verificationResult = await this._identityConnector.checkVerifiableCredential(token);
68
+ }
69
+ catch (error) {
70
+ throw new UnauthorizedError(VerifiableCredentialAuthenticationProcessor.CLASS_NAME, "tokenVerificationFailed", undefined, error);
71
+ }
72
+ const verifiableCredential = verificationResult.verifiableCredential;
73
+ if (Is.empty(verifiableCredential)) {
74
+ throw new UnauthorizedError(VerifiableCredentialAuthenticationProcessor.CLASS_NAME, "tokenMissingCredential");
75
+ }
76
+ const issuer = Is.stringValue(verifiableCredential.issuer)
77
+ ? verifiableCredential.issuer
78
+ : undefined;
79
+ if (Is.empty(issuer)) {
80
+ throw new UnauthorizedError(VerifiableCredentialAuthenticationProcessor.CLASS_NAME, "tokenMissingIssuer");
81
+ }
82
+ const issuanceDate = VerifiableCredentialHelper.getValidFrom(verifiableCredential);
83
+ if (Is.empty(issuanceDate)) {
84
+ throw new UnauthorizedError(VerifiableCredentialAuthenticationProcessor.CLASS_NAME, "tokenMissingIssuanceDate", {
85
+ issuer
86
+ });
87
+ }
88
+ const tokenCreated = new Date(issuanceDate);
89
+ const now = Date.now();
90
+ const tokenTtlInMs = this._tokenTtlInSeconds * 1000;
91
+ // If the token has expired then we should reject it
92
+ if (tokenCreated.getTime() + tokenTtlInMs < now) {
93
+ throw new UnauthorizedError(VerifiableCredentialAuthenticationProcessor.CLASS_NAME, "tokenExpired", {
94
+ issuer
95
+ });
96
+ }
97
+ const subject = verifiableCredential.credentialSubject;
98
+ if (Is.empty(subject)) {
99
+ throw new UnauthorizedError(VerifiableCredentialAuthenticationProcessor.CLASS_NAME, "tokenMissingSubject", {
100
+ issuer
101
+ });
102
+ }
103
+ let contextId = ContextIdKeys.Organization;
104
+ if (Is.object(processorState?.verifiableCredential)) {
105
+ contextId = processorState.verifiableCredential.contextId ?? contextId;
106
+ }
107
+ contextIds[contextId] = issuer;
108
+ processorState.verifiableCredentialJsonLd = verifiableCredential;
109
+ processorState.verifiableCredentialSubject = subject;
106
110
  }
107
111
  }
108
112
  }
@@ -1 +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
+ {"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 { Is, UnauthorizedError } 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\t// Only process if the route has the verifiableCredential feature\n\t\tif (\n\t\t\tIs.arrayValue(route?.processorFeatures) &&\n\t\t\troute?.processorFeatures.includes(\"verifiableCredential\")\n\t\t) {\n\t\t\tconst token = HeaderHelper.extractBearer(request.headers?.[HeaderTypes.Authorization]);\n\n\t\t\tif (!Is.stringValue(token)) {\n\t\t\t\tthrow new UnauthorizedError(\n\t\t\t\t\tVerifiableCredentialAuthenticationProcessor.CLASS_NAME,\n\t\t\t\t\t\"tokenMissing\"\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlet verificationResult;\n\t\t\ttry {\n\t\t\t\tverificationResult = await this._identityConnector.checkVerifiableCredential(token);\n\t\t\t} catch (error) {\n\t\t\t\tthrow new UnauthorizedError(\n\t\t\t\t\tVerifiableCredentialAuthenticationProcessor.CLASS_NAME,\n\t\t\t\t\t\"tokenVerificationFailed\",\n\t\t\t\t\tundefined,\n\t\t\t\t\terror\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst verifiableCredential = verificationResult.verifiableCredential;\n\t\t\tif (Is.empty(verifiableCredential)) {\n\t\t\t\tthrow new UnauthorizedError(\n\t\t\t\t\tVerifiableCredentialAuthenticationProcessor.CLASS_NAME,\n\t\t\t\t\t\"tokenMissingCredential\"\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst issuer: string | undefined = Is.stringValue(verifiableCredential.issuer)\n\t\t\t\t? verifiableCredential.issuer\n\t\t\t\t: undefined;\n\t\t\tif (Is.empty(issuer)) {\n\t\t\t\tthrow new UnauthorizedError(\n\t\t\t\t\tVerifiableCredentialAuthenticationProcessor.CLASS_NAME,\n\t\t\t\t\t\"tokenMissingIssuer\"\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst issuanceDate = VerifiableCredentialHelper.getValidFrom(verifiableCredential);\n\t\t\tif (Is.empty(issuanceDate)) {\n\t\t\t\tthrow new UnauthorizedError(\n\t\t\t\t\tVerifiableCredentialAuthenticationProcessor.CLASS_NAME,\n\t\t\t\t\t\"tokenMissingIssuanceDate\",\n\t\t\t\t\t{\n\t\t\t\t\t\tissuer\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst tokenCreated = new Date(issuanceDate);\n\t\t\tconst now = Date.now();\n\t\t\tconst tokenTtlInMs = this._tokenTtlInSeconds * 1000;\n\n\t\t\t// If the token has expired then we should reject it\n\t\t\tif (tokenCreated.getTime() + tokenTtlInMs < now) {\n\t\t\t\tthrow new UnauthorizedError(\n\t\t\t\t\tVerifiableCredentialAuthenticationProcessor.CLASS_NAME,\n\t\t\t\t\t\"tokenExpired\",\n\t\t\t\t\t{\n\t\t\t\t\t\tissuer\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst subject = verifiableCredential.credentialSubject;\n\t\t\tif (Is.empty(subject)) {\n\t\t\t\tthrow new UnauthorizedError(\n\t\t\t\t\tVerifiableCredentialAuthenticationProcessor.CLASS_NAME,\n\t\t\t\t\t\"tokenMissingSubject\",\n\t\t\t\t\t{\n\t\t\t\t\t\tissuer\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlet contextId: string = ContextIdKeys.Organization;\n\t\t\tif (Is.object<{ contextId?: string }>(processorState?.verifiableCredential)) {\n\t\t\t\tcontextId = processorState.verifiableCredential.contextId ?? contextId;\n\t\t\t}\n\n\t\t\tcontextIds[contextId] = issuer;\n\t\t\tprocessorState.verifiableCredentialJsonLd = verifiableCredential;\n\t\t\tprocessorState.verifiableCredentialSubject = subject;\n\t\t}\n\t}\n}\n"]}
@@ -7,11 +7,6 @@ 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;
15
10
  /**
16
11
  * The id of the identity method to use when creating/verifying tokens.
17
12
  */
package/docs/changelog.md CHANGED
@@ -1,5 +1,42 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.0.3-next.7](https://github.com/twinfoundation/identity/compare/identity-authentication-v0.0.3-next.6...identity-authentication-v0.0.3-next.7) (2026-01-13)
4
+
5
+
6
+ ### Features
7
+
8
+ * remove unused config property ([672e61f](https://github.com/twinfoundation/identity/commit/672e61f83925e9fe5cd188af30bc2d45d75d2882))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * associate vault keys with document not controller ([#86](https://github.com/twinfoundation/identity/issues/86)) ([6430f4b](https://github.com/twinfoundation/identity/commit/6430f4b559315a1fe99b60c6db1c661d317bc243))
14
+
15
+
16
+ ### Dependencies
17
+
18
+ * The following workspace dependencies were updated
19
+ * dependencies
20
+ * @twin.org/identity-models bumped from 0.0.3-next.6 to 0.0.3-next.7
21
+ * devDependencies
22
+ * @twin.org/identity-connector-entity-storage bumped from 0.0.3-next.6 to 0.0.3-next.7
23
+
24
+ ## [0.0.3-next.6](https://github.com/twinfoundation/identity/compare/identity-authentication-v0.0.3-next.5...identity-authentication-v0.0.3-next.6) (2025-11-26)
25
+
26
+
27
+ ### Bug Fixes
28
+
29
+ * use correct error types for vc auth processor ([fcd54fb](https://github.com/twinfoundation/identity/commit/fcd54fbe59e747b7a1d84eac70451e7f6ea5930b))
30
+
31
+
32
+ ### Dependencies
33
+
34
+ * The following workspace dependencies were updated
35
+ * dependencies
36
+ * @twin.org/identity-models bumped from 0.0.3-next.5 to 0.0.3-next.6
37
+ * devDependencies
38
+ * @twin.org/identity-connector-entity-storage bumped from 0.0.3-next.5 to 0.0.3-next.6
39
+
3
40
  ## [0.0.3-next.5](https://github.com/twinfoundation/identity/compare/identity-authentication-v0.0.3-next.4...identity-authentication-v0.0.3-next.5) (2025-11-20)
4
41
 
5
42
 
@@ -18,20 +18,6 @@ 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
-
35
21
  ### verificationMethodId
36
22
 
37
23
  > **verificationMethodId**: `string`
package/locales/en.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "error": {
3
3
  "verifiableCredentialAuthenticationProcessor": {
4
- "tokenFailed": "Failed to verify token",
5
- "tokenNoCredential": "The token does not contain a verifiable credential",
6
- "tokenNoIssuer": "The token does not contain an issuer",
4
+ "tokenMissing": "No token provided",
5
+ "tokenVerificationFailed": "The token could not be verified",
6
+ "tokenMissingCredential": "The token does not contain a verifiable credential",
7
+ "tokenMissingIssuer": "The token does not contain an issuer",
7
8
  "tokenMissingIssuanceDate": "The token is missing the 'issuanceDate' field for issuer \"{issuer}\"",
8
9
  "tokenExpired": "The token has expired for issuer \"{issuer}\"",
9
10
  "tokenMissingSubject": "The token is missing the 'credentialSubject' field for issuer \"{issuer}\""
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/identity-authentication",
3
- "version": "0.0.3-next.5",
3
+ "version": "0.0.3-next.7",
4
4
  "description": "Authentication components implemented using identity",
5
5
  "repository": {
6
6
  "type": "git",
@@ -19,7 +19,7 @@
19
19
  "@twin.org/core": "next",
20
20
  "@twin.org/crypto": "next",
21
21
  "@twin.org/data-json-ld": "next",
22
- "@twin.org/identity-models": "0.0.3-next.5",
22
+ "@twin.org/identity-models": "0.0.3-next.7",
23
23
  "@twin.org/standards-w3c-did": "next",
24
24
  "@twin.org/web": "next"
25
25
  },