@twin.org/api-auth-entity-storage-service 0.0.1-next.26 → 0.0.1-next.28

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.
@@ -71,13 +71,16 @@ class TokenHelper {
71
71
  * @returns The new token and its expiry date.
72
72
  */
73
73
  static async createToken(vaultConnector, signingKeyName, subject, ttlMinutes) {
74
- // Verify was a success so we can now generate a new token.
75
74
  const nowSeconds = Math.trunc(Date.now() / 1000);
76
75
  const ttlSeconds = ttlMinutes * 60;
77
- const jwt = await web.Jwt.encodeWithSigner({ alg: web.JwtAlgorithms.EdDSA }, {
76
+ const jwt = await web.Jwt.encodeWithSigner({ alg: "EdDSA" }, {
78
77
  sub: subject,
79
78
  exp: nowSeconds + ttlSeconds
80
- }, async (alg, key, payload) => vaultConnector.sign(signingKeyName, payload));
79
+ }, async (header, payload) => {
80
+ const signingBytes = web.Jwt.toSigningBytes(header, payload);
81
+ const signatureBytes = await vaultConnector.sign(signingKeyName, signingBytes);
82
+ return web.Jwt.tokenFromBytes(signingBytes, signatureBytes);
83
+ });
81
84
  return {
82
85
  token: jwt,
83
86
  expiry: (nowSeconds + ttlSeconds) * 1000
@@ -95,14 +98,18 @@ class TokenHelper {
95
98
  if (!core.Is.stringValue(token)) {
96
99
  throw new core.UnauthorizedError(this._CLASS_NAME, "missing");
97
100
  }
98
- const decoded = await web.Jwt.verifyWithVerifier(token, async (alg, key, payload, signature) => vaultConnector.verify(signingKeyName, payload, signature));
101
+ const decoded = await web.Jwt.verifyWithVerifier(token, async (t) => {
102
+ const { signingBytes, signature } = web.Jwt.tokenToBytes(t);
103
+ const verified = await vaultConnector.verify(signingKeyName, signingBytes, signature);
104
+ if (!verified) {
105
+ throw new core.UnauthorizedError(this._CLASS_NAME, "invalidSignature");
106
+ }
107
+ return web.Jwt.fromSigningBytes(signingBytes);
108
+ });
99
109
  // If the signature validation failed or some of the header/payload data
100
110
  // is not properly populated then it is unauthorized.
101
- if (!decoded.verified ||
102
- !core.Is.object(decoded.header) ||
103
- !core.Is.object(decoded.payload) ||
104
- !core.Is.stringValue(decoded.payload.sub)) {
105
- throw new core.UnauthorizedError(this._CLASS_NAME, "invalidToken");
111
+ if (!core.Is.stringValue(decoded.payload.sub)) {
112
+ throw new core.UnauthorizedError(this._CLASS_NAME, "payloadMissingSubject");
106
113
  }
107
114
  else if (!core.Is.empty(decoded.payload?.exp) &&
108
115
  decoded.payload.exp < Math.trunc(Date.now() / 1000)) {
@@ -2,7 +2,7 @@ import { property, entity, EntitySchemaFactory, EntitySchemaHelper } from '@twin
2
2
  import { HttpErrorHelper } from '@twin.org/api-models';
3
3
  import { Is, UnauthorizedError, Guards, BaseError, ComponentFactory, Converter, GeneralError } from '@twin.org/core';
4
4
  import { VaultConnectorFactory } from '@twin.org/vault-models';
5
- import { Jwt, JwtAlgorithms, HeaderTypes, HttpStatusCode } from '@twin.org/web';
5
+ import { Jwt, HeaderTypes, HttpStatusCode } from '@twin.org/web';
6
6
  import { EntityStorageConnectorFactory } from '@twin.org/entity-storage-models';
7
7
  import { Blake2b } from '@twin.org/crypto';
8
8
 
@@ -69,13 +69,16 @@ class TokenHelper {
69
69
  * @returns The new token and its expiry date.
70
70
  */
71
71
  static async createToken(vaultConnector, signingKeyName, subject, ttlMinutes) {
72
- // Verify was a success so we can now generate a new token.
73
72
  const nowSeconds = Math.trunc(Date.now() / 1000);
74
73
  const ttlSeconds = ttlMinutes * 60;
75
- const jwt = await Jwt.encodeWithSigner({ alg: JwtAlgorithms.EdDSA }, {
74
+ const jwt = await Jwt.encodeWithSigner({ alg: "EdDSA" }, {
76
75
  sub: subject,
77
76
  exp: nowSeconds + ttlSeconds
78
- }, async (alg, key, payload) => vaultConnector.sign(signingKeyName, payload));
77
+ }, async (header, payload) => {
78
+ const signingBytes = Jwt.toSigningBytes(header, payload);
79
+ const signatureBytes = await vaultConnector.sign(signingKeyName, signingBytes);
80
+ return Jwt.tokenFromBytes(signingBytes, signatureBytes);
81
+ });
79
82
  return {
80
83
  token: jwt,
81
84
  expiry: (nowSeconds + ttlSeconds) * 1000
@@ -93,14 +96,18 @@ class TokenHelper {
93
96
  if (!Is.stringValue(token)) {
94
97
  throw new UnauthorizedError(this._CLASS_NAME, "missing");
95
98
  }
96
- const decoded = await Jwt.verifyWithVerifier(token, async (alg, key, payload, signature) => vaultConnector.verify(signingKeyName, payload, signature));
99
+ const decoded = await Jwt.verifyWithVerifier(token, async (t) => {
100
+ const { signingBytes, signature } = Jwt.tokenToBytes(t);
101
+ const verified = await vaultConnector.verify(signingKeyName, signingBytes, signature);
102
+ if (!verified) {
103
+ throw new UnauthorizedError(this._CLASS_NAME, "invalidSignature");
104
+ }
105
+ return Jwt.fromSigningBytes(signingBytes);
106
+ });
97
107
  // If the signature validation failed or some of the header/payload data
98
108
  // is not properly populated then it is unauthorized.
99
- if (!decoded.verified ||
100
- !Is.object(decoded.header) ||
101
- !Is.object(decoded.payload) ||
102
- !Is.stringValue(decoded.payload.sub)) {
103
- throw new UnauthorizedError(this._CLASS_NAME, "invalidToken");
109
+ if (!Is.stringValue(decoded.payload.sub)) {
110
+ throw new UnauthorizedError(this._CLASS_NAME, "payloadMissingSubject");
104
111
  }
105
112
  else if (!Is.empty(decoded.payload?.exp) &&
106
113
  decoded.payload.exp < Math.trunc(Date.now() / 1000)) {
package/docs/changelog.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # @twin.org/api-auth-entity-storage-service - Changelog
2
2
 
3
- ## v0.0.1-next.26
3
+ ## v0.0.1-next.28
4
4
 
5
5
  - Initial Release
package/locales/en.json CHANGED
@@ -11,7 +11,8 @@
11
11
  },
12
12
  "tokenHelper": {
13
13
  "missing": "The JSON Web token could not be found in the authorization header",
14
- "invalid": "The JSON Web token signature could not be validated",
14
+ "invalidSignature": "The JSON Web token signature could not be validated",
15
+ "payloadMissingSubject": "The JSON Web token payload does not contain a subject",
15
16
  "expired": "The JSON Web token has expired"
16
17
  }
17
18
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/api-auth-entity-storage-service",
3
- "version": "0.0.1-next.26",
3
+ "version": "0.0.1-next.28",
4
4
  "description": "Auth Entity Storage contract implementation and REST endpoint definitions",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,9 +14,9 @@
14
14
  "node": ">=20.0.0"
15
15
  },
16
16
  "dependencies": {
17
- "@twin.org/api-auth-entity-storage-models": "0.0.1-next.26",
18
- "@twin.org/api-core": "0.0.1-next.26",
19
- "@twin.org/api-models": "0.0.1-next.26",
17
+ "@twin.org/api-auth-entity-storage-models": "0.0.1-next.28",
18
+ "@twin.org/api-core": "0.0.1-next.28",
19
+ "@twin.org/api-models": "0.0.1-next.28",
20
20
  "@twin.org/core": "next",
21
21
  "@twin.org/crypto": "next",
22
22
  "@twin.org/entity": "next",
@@ -31,9 +31,9 @@
31
31
  "types": "./dist/types/index.d.ts",
32
32
  "exports": {
33
33
  ".": {
34
+ "types": "./dist/types/index.d.ts",
34
35
  "require": "./dist/cjs/index.cjs",
35
- "import": "./dist/esm/index.mjs",
36
- "types": "./dist/types/index.d.ts"
36
+ "import": "./dist/esm/index.mjs"
37
37
  }
38
38
  },
39
39
  "files": [