@twin.org/api-auth-entity-storage-service 0.0.1-next.2 → 0.0.1-next.20

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.
@@ -120,12 +120,13 @@ class TokenHelper {
120
120
  * @returns The token if found.
121
121
  */
122
122
  static extractTokenFromHeaders(headers, cookieName) {
123
- const cookiesHeader = headers?.cookie;
124
- let token;
125
- let location;
126
- if (core.Is.string(headers?.authorization) && headers.authorization.startsWith("Bearer ")) {
127
- token = headers.authorization.slice(7).trim();
128
- location = "authorization";
123
+ const authHeader = headers?.[web.HeaderTypes.Authorization];
124
+ const cookiesHeader = headers?.[web.HeaderTypes.Cookie];
125
+ if (core.Is.string(authHeader) && authHeader.startsWith("Bearer ")) {
126
+ return {
127
+ token: authHeader.slice(7).trim(),
128
+ location: "authorization"
129
+ };
129
130
  }
130
131
  else if (core.Is.notEmpty(cookiesHeader) && core.Is.stringValue(cookieName)) {
131
132
  const cookies = core.Is.arrayValue(cookiesHeader) ? cookiesHeader : [cookiesHeader];
@@ -136,17 +137,14 @@ class TokenHelper {
136
137
  .map(c => c.trim())
137
138
  .find(c => c.startsWith(cookieName));
138
139
  if (core.Is.stringValue(accessTokenCookie)) {
139
- token = accessTokenCookie.slice(cookieName.length + 1).trim();
140
- location = "cookie";
141
- break;
140
+ return {
141
+ token: accessTokenCookie.slice(cookieName.length + 1).trim(),
142
+ location: "cookie"
143
+ };
142
144
  }
143
145
  }
144
146
  }
145
147
  }
146
- return {
147
- token,
148
- location
149
- };
150
148
  }
151
149
  }
152
150
 
@@ -218,10 +216,10 @@ class AuthHeaderProcessor {
218
216
  if (!core.Is.empty(route) && !(route.skipAuth ?? false)) {
219
217
  try {
220
218
  const tokenAndLocation = TokenHelper.extractTokenFromHeaders(request.headers, this._cookieName);
221
- const headerAndPayload = await TokenHelper.verify(this._vaultConnector, `${this._nodeIdentity}/${this._signingKeyName}`, tokenAndLocation.token);
219
+ const headerAndPayload = await TokenHelper.verify(this._vaultConnector, `${this._nodeIdentity}/${this._signingKeyName}`, tokenAndLocation?.token);
222
220
  requestIdentity.userIdentity = headerAndPayload.payload?.sub;
223
- processorState.authToken = tokenAndLocation.token;
224
- processorState.authTokenLocation = tokenAndLocation.location;
221
+ processorState.authToken = tokenAndLocation?.token;
222
+ processorState.authTokenLocation = tokenAndLocation?.location;
225
223
  }
226
224
  catch (err) {
227
225
  const error = core.BaseError.fromError(err);
@@ -246,13 +244,13 @@ class AuthHeaderProcessor {
246
244
  if ((responseAuthOperation === "login" || responseAuthOperation === "refresh") &&
247
245
  core.Is.stringValue(response.body?.token)) {
248
246
  response.headers ??= {};
249
- response.headers["Set-Cookie"] =
247
+ response.headers[web.HeaderTypes.SetCookie] =
250
248
  `${this._cookieName}=${response.body.token}; Secure; HttpOnly; SameSite=None; Path=/`;
251
249
  delete response.body.token;
252
250
  }
253
251
  else if (responseAuthOperation === "logout") {
254
252
  response.headers ??= {};
255
- response.headers["Set-Cookie"] =
253
+ response.headers[web.HeaderTypes.SetCookie] =
256
254
  `${this._cookieName}=; Max-Age=0; Secure; HttpOnly; SameSite=None; Path=/`;
257
255
  }
258
256
  }
@@ -504,6 +502,10 @@ class PasswordHelper {
504
502
  * Implementation of the authentication component using entity storage.
505
503
  */
506
504
  class EntityStorageAuthenticationService {
505
+ /**
506
+ * The namespace supported by the authentication service.
507
+ */
508
+ static NAMESPACE = "authentication-entity-storage";
507
509
  /**
508
510
  * Default TTL in minutes.
509
511
  * @internal
@@ -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, HttpStatusCode } from '@twin.org/web';
5
+ import { Jwt, JwtAlgorithms, 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
 
@@ -118,12 +118,13 @@ class TokenHelper {
118
118
  * @returns The token if found.
119
119
  */
120
120
  static extractTokenFromHeaders(headers, cookieName) {
121
- const cookiesHeader = headers?.cookie;
122
- let token;
123
- let location;
124
- if (Is.string(headers?.authorization) && headers.authorization.startsWith("Bearer ")) {
125
- token = headers.authorization.slice(7).trim();
126
- location = "authorization";
121
+ const authHeader = headers?.[HeaderTypes.Authorization];
122
+ const cookiesHeader = headers?.[HeaderTypes.Cookie];
123
+ if (Is.string(authHeader) && authHeader.startsWith("Bearer ")) {
124
+ return {
125
+ token: authHeader.slice(7).trim(),
126
+ location: "authorization"
127
+ };
127
128
  }
128
129
  else if (Is.notEmpty(cookiesHeader) && Is.stringValue(cookieName)) {
129
130
  const cookies = Is.arrayValue(cookiesHeader) ? cookiesHeader : [cookiesHeader];
@@ -134,17 +135,14 @@ class TokenHelper {
134
135
  .map(c => c.trim())
135
136
  .find(c => c.startsWith(cookieName));
136
137
  if (Is.stringValue(accessTokenCookie)) {
137
- token = accessTokenCookie.slice(cookieName.length + 1).trim();
138
- location = "cookie";
139
- break;
138
+ return {
139
+ token: accessTokenCookie.slice(cookieName.length + 1).trim(),
140
+ location: "cookie"
141
+ };
140
142
  }
141
143
  }
142
144
  }
143
145
  }
144
- return {
145
- token,
146
- location
147
- };
148
146
  }
149
147
  }
150
148
 
@@ -216,10 +214,10 @@ class AuthHeaderProcessor {
216
214
  if (!Is.empty(route) && !(route.skipAuth ?? false)) {
217
215
  try {
218
216
  const tokenAndLocation = TokenHelper.extractTokenFromHeaders(request.headers, this._cookieName);
219
- const headerAndPayload = await TokenHelper.verify(this._vaultConnector, `${this._nodeIdentity}/${this._signingKeyName}`, tokenAndLocation.token);
217
+ const headerAndPayload = await TokenHelper.verify(this._vaultConnector, `${this._nodeIdentity}/${this._signingKeyName}`, tokenAndLocation?.token);
220
218
  requestIdentity.userIdentity = headerAndPayload.payload?.sub;
221
- processorState.authToken = tokenAndLocation.token;
222
- processorState.authTokenLocation = tokenAndLocation.location;
219
+ processorState.authToken = tokenAndLocation?.token;
220
+ processorState.authTokenLocation = tokenAndLocation?.location;
223
221
  }
224
222
  catch (err) {
225
223
  const error = BaseError.fromError(err);
@@ -244,13 +242,13 @@ class AuthHeaderProcessor {
244
242
  if ((responseAuthOperation === "login" || responseAuthOperation === "refresh") &&
245
243
  Is.stringValue(response.body?.token)) {
246
244
  response.headers ??= {};
247
- response.headers["Set-Cookie"] =
245
+ response.headers[HeaderTypes.SetCookie] =
248
246
  `${this._cookieName}=${response.body.token}; Secure; HttpOnly; SameSite=None; Path=/`;
249
247
  delete response.body.token;
250
248
  }
251
249
  else if (responseAuthOperation === "logout") {
252
250
  response.headers ??= {};
253
- response.headers["Set-Cookie"] =
251
+ response.headers[HeaderTypes.SetCookie] =
254
252
  `${this._cookieName}=; Max-Age=0; Secure; HttpOnly; SameSite=None; Path=/`;
255
253
  }
256
254
  }
@@ -502,6 +500,10 @@ class PasswordHelper {
502
500
  * Implementation of the authentication component using entity storage.
503
501
  */
504
502
  class EntityStorageAuthenticationService {
503
+ /**
504
+ * The namespace supported by the authentication service.
505
+ */
506
+ static NAMESPACE = "authentication-entity-storage";
505
507
  /**
506
508
  * Default TTL in minutes.
507
509
  * @internal
@@ -1,9 +1,9 @@
1
- import { type IHttpRequestIdentity, type IHttpResponse, type IHttpRestRouteProcessor, type IHttpServerRequest, type IRestRoute } from "@twin.org/api-models";
1
+ import { type IBaseRoute, type IBaseRouteProcessor, type IHttpRequestIdentity, type IHttpResponse, type IHttpServerRequest } from "@twin.org/api-models";
2
2
  import type { IAuthHeaderProcessorConfig } from "../models/IAuthHeaderProcessorConfig";
3
3
  /**
4
4
  * Handle a JWT token in the authorization header or cookies and validate it to populate request context identity.
5
5
  */
6
- export declare class AuthHeaderProcessor implements IHttpRestRouteProcessor {
6
+ export declare class AuthHeaderProcessor implements IBaseRouteProcessor {
7
7
  /**
8
8
  * Runtime name for the class.
9
9
  */
@@ -33,7 +33,7 @@ export declare class AuthHeaderProcessor implements IHttpRestRouteProcessor {
33
33
  * @param requestIdentity The identity context for the request.
34
34
  * @param processorState The state handed through the processors.
35
35
  */
36
- pre(request: IHttpServerRequest, response: IHttpResponse, route: IRestRoute | undefined, requestIdentity: IHttpRequestIdentity, processorState: {
36
+ pre(request: IHttpServerRequest, response: IHttpResponse, route: IBaseRoute | undefined, requestIdentity: IHttpRequestIdentity, processorState: {
37
37
  [id: string]: unknown;
38
38
  }): Promise<void>;
39
39
  /**
@@ -44,7 +44,7 @@ export declare class AuthHeaderProcessor implements IHttpRestRouteProcessor {
44
44
  * @param requestIdentity The identity context for the request.
45
45
  * @param processorState The state handed through the processors.
46
46
  */
47
- post(request: IHttpServerRequest, response: IHttpResponse, route: IRestRoute | undefined, requestIdentity: IHttpRequestIdentity, processorState: {
47
+ post(request: IHttpServerRequest, response: IHttpResponse, route: IBaseRoute | undefined, requestIdentity: IHttpRequestIdentity, processorState: {
48
48
  [id: string]: unknown;
49
49
  }): Promise<void>;
50
50
  }
@@ -4,6 +4,10 @@ import type { IEntityStorageAuthenticationServiceConfig } from "../models/IEntit
4
4
  * Implementation of the authentication component using entity storage.
5
5
  */
6
6
  export declare class EntityStorageAuthenticationService implements IAuthenticationComponent {
7
+ /**
8
+ * The namespace supported by the authentication service.
9
+ */
10
+ static readonly NAMESPACE: string;
7
11
  /**
8
12
  * Runtime name for the class.
9
13
  */
@@ -35,7 +35,7 @@ export declare class TokenHelper {
35
35
  * @returns The token if found.
36
36
  */
37
37
  static extractTokenFromHeaders(headers?: IHttpHeaders, cookieName?: string): {
38
- token: string | undefined;
39
- location: "authorization" | "cookie" | undefined;
40
- };
38
+ token: string;
39
+ location: "authorization" | "cookie";
40
+ } | undefined;
41
41
  }
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.2
3
+ ## v0.0.1-next.20
4
4
 
5
5
  - Initial Release
@@ -4,7 +4,7 @@ Handle a JWT token in the authorization header or cookies and validate it to pop
4
4
 
5
5
  ## Implements
6
6
 
7
- - `IHttpRestRouteProcessor`
7
+ - `IBaseRouteProcessor`
8
8
 
9
9
  ## Constructors
10
10
 
@@ -42,7 +42,7 @@ Runtime name for the class.
42
42
 
43
43
  #### Implementation of
44
44
 
45
- `IHttpRestRouteProcessor.CLASS_NAME`
45
+ `IBaseRouteProcessor.CLASS_NAME`
46
46
 
47
47
  ## Methods
48
48
 
@@ -70,7 +70,7 @@ Nothing.
70
70
 
71
71
  #### Implementation of
72
72
 
73
- `IHttpRestRouteProcessor.start`
73
+ `IBaseRouteProcessor.start`
74
74
 
75
75
  ***
76
76
 
@@ -90,7 +90,7 @@ The incoming request.
90
90
 
91
91
  The outgoing response.
92
92
 
93
- • **route**: `undefined` \| `IRestRoute`\<`any`, `any`\>
93
+ • **route**: `undefined` \| `IBaseRoute`
94
94
 
95
95
  The route to process.
96
96
 
@@ -108,7 +108,7 @@ The state handed through the processors.
108
108
 
109
109
  #### Implementation of
110
110
 
111
- `IHttpRestRouteProcessor.pre`
111
+ `IBaseRouteProcessor.pre`
112
112
 
113
113
  ***
114
114
 
@@ -128,7 +128,7 @@ The incoming request.
128
128
 
129
129
  The outgoing response.
130
130
 
131
- • **route**: `undefined` \| `IRestRoute`\<`any`, `any`\>
131
+ • **route**: `undefined` \| `IBaseRoute`
132
132
 
133
133
  The route to process.
134
134
 
@@ -146,4 +146,4 @@ The state handed through the processors.
146
146
 
147
147
  #### Implementation of
148
148
 
149
- `IHttpRestRouteProcessor.post`
149
+ `IBaseRouteProcessor.post`
@@ -38,6 +38,14 @@ The configuration for the authentication.
38
38
 
39
39
  ## Properties
40
40
 
41
+ ### NAMESPACE
42
+
43
+ > `readonly` `static` **NAMESPACE**: `string` = `"authentication-entity-storage"`
44
+
45
+ The namespace supported by the authentication service.
46
+
47
+ ***
48
+
41
49
  ### CLASS\_NAME
42
50
 
43
51
  > `readonly` **CLASS\_NAME**: `string`
@@ -96,7 +96,7 @@ UnauthorizedError if the token is missing, invalid or expired.
96
96
 
97
97
  ### extractTokenFromHeaders()
98
98
 
99
- > `static` **extractTokenFromHeaders**(`headers`?, `cookieName`?): `object`
99
+ > `static` **extractTokenFromHeaders**(`headers`?, `cookieName`?): `undefined` \| `object`
100
100
 
101
101
  Extract the auth token from the headers, either from the authorization header or the cookie header.
102
102
 
@@ -112,14 +112,6 @@ The name of the cookie to extract the token from.
112
112
 
113
113
  #### Returns
114
114
 
115
- `object`
115
+ `undefined` \| `object`
116
116
 
117
117
  The token if found.
118
-
119
- ##### token
120
-
121
- > **token**: `undefined` \| `string`
122
-
123
- ##### location
124
-
125
- > **location**: `undefined` \| `"authorization"` \| `"cookie"`
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.2",
3
+ "version": "0.0.1-next.20",
4
4
  "description": "Auth Entity Storage contract implementation and REST endpoint definitions",
5
5
  "repository": {
6
6
  "type": "git",
@@ -13,23 +13,10 @@
13
13
  "engines": {
14
14
  "node": ">=20.0.0"
15
15
  },
16
- "scripts": {
17
- "clean": "rimraf dist coverage",
18
- "build": "tspc",
19
- "test": "vitest --run --config ./vitest.config.ts --no-cache",
20
- "coverage": "vitest --run --coverage --config ./vitest.config.ts --no-cache",
21
- "bundle:esm": "rollup --config rollup.config.mjs --environment MODULE:esm",
22
- "bundle:cjs": "rollup --config rollup.config.mjs --environment MODULE:cjs",
23
- "bundle": "npm run bundle:esm && npm run bundle:cjs",
24
- "docs:clean": "rimraf docs/reference",
25
- "docs:generate": "typedoc",
26
- "docs": "npm run docs:clean && npm run docs:generate",
27
- "dist": "npm run clean && npm run build && npm run test && npm run bundle && npm run docs"
28
- },
29
16
  "dependencies": {
30
- "@twin.org/api-auth-entity-storage-models": "0.0.1-next.2",
31
- "@twin.org/api-core": "0.0.1-next.2",
32
- "@twin.org/api-models": "0.0.1-next.2",
17
+ "@twin.org/api-auth-entity-storage-models": "0.0.1-next.20",
18
+ "@twin.org/api-core": "0.0.1-next.20",
19
+ "@twin.org/api-models": "0.0.1-next.20",
33
20
  "@twin.org/core": "next",
34
21
  "@twin.org/crypto": "next",
35
22
  "@twin.org/entity": "next",
@@ -39,20 +26,6 @@
39
26
  "@twin.org/vault-models": "next",
40
27
  "@twin.org/web": "next"
41
28
  },
42
- "devDependencies": {
43
- "@twin.org/nameof-transformer": "next",
44
- "@vitest/coverage-v8": "2.1.1",
45
- "@types/node": "22.5.5",
46
- "copyfiles": "2.4.1",
47
- "rimraf": "6.0.1",
48
- "rollup": "4.21.3",
49
- "rollup-plugin-typescript2": "0.36.0",
50
- "ts-patch": "3.2.1",
51
- "typedoc": "0.26.7",
52
- "typedoc-plugin-markdown": "4.2.7",
53
- "typescript": "5.6.2",
54
- "vitest": "2.1.1"
55
- },
56
29
  "main": "./dist/cjs/index.cjs",
57
30
  "module": "./dist/esm/index.mjs",
58
31
  "types": "./dist/types/index.d.ts",