@owlmeans/auth-common 0.1.0

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 (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +318 -0
  3. package/build/consts.d.ts +9 -0
  4. package/build/consts.d.ts.map +1 -0
  5. package/build/consts.js +9 -0
  6. package/build/consts.js.map +1 -0
  7. package/build/guards/basic-ed25519/consts.d.ts +6 -0
  8. package/build/guards/basic-ed25519/consts.d.ts.map +1 -0
  9. package/build/guards/basic-ed25519/consts.js +7 -0
  10. package/build/guards/basic-ed25519/consts.js.map +1 -0
  11. package/build/guards/basic-ed25519/index.d.ts +4 -0
  12. package/build/guards/basic-ed25519/index.d.ts.map +1 -0
  13. package/build/guards/basic-ed25519/index.js +3 -0
  14. package/build/guards/basic-ed25519/index.js.map +1 -0
  15. package/build/guards/basic-ed25519/service.d.ts +8 -0
  16. package/build/guards/basic-ed25519/service.d.ts.map +1 -0
  17. package/build/guards/basic-ed25519/service.js +110 -0
  18. package/build/guards/basic-ed25519/service.js.map +1 -0
  19. package/build/guards/basic-ed25519/types.d.ts +7 -0
  20. package/build/guards/basic-ed25519/types.d.ts.map +1 -0
  21. package/build/guards/basic-ed25519/types.js +2 -0
  22. package/build/guards/basic-ed25519/types.js.map +1 -0
  23. package/build/guards/index.d.ts +2 -0
  24. package/build/guards/index.d.ts.map +1 -0
  25. package/build/guards/index.js +2 -0
  26. package/build/guards/index.js.map +1 -0
  27. package/build/index.d.ts +6 -0
  28. package/build/index.d.ts.map +1 -0
  29. package/build/index.js +5 -0
  30. package/build/index.js.map +1 -0
  31. package/build/middleware.d.ts +3 -0
  32. package/build/middleware.d.ts.map +1 -0
  33. package/build/middleware.js +39 -0
  34. package/build/middleware.js.map +1 -0
  35. package/build/modules.d.ts +2 -0
  36. package/build/modules.d.ts.map +1 -0
  37. package/build/modules.js +32 -0
  38. package/build/modules.js.map +1 -0
  39. package/build/types.d.ts +28 -0
  40. package/build/types.d.ts.map +1 -0
  41. package/build/types.js +2 -0
  42. package/build/types.js.map +1 -0
  43. package/build/utils/header.d.ts +3 -0
  44. package/build/utils/header.d.ts.map +1 -0
  45. package/build/utils/header.js +16 -0
  46. package/build/utils/header.js.map +1 -0
  47. package/build/utils/index.d.ts +4 -0
  48. package/build/utils/index.d.ts.map +1 -0
  49. package/build/utils/index.js +3 -0
  50. package/build/utils/index.js.map +1 -0
  51. package/build/utils/trusted.d.ts +7 -0
  52. package/build/utils/trusted.d.ts.map +1 -0
  53. package/build/utils/trusted.js +11 -0
  54. package/build/utils/trusted.js.map +1 -0
  55. package/build/utils/types.d.ts +6 -0
  56. package/build/utils/types.d.ts.map +1 -0
  57. package/build/utils/types.js +2 -0
  58. package/build/utils/types.js.map +1 -0
  59. package/package.json +49 -0
  60. package/src/consts.ts +16 -0
  61. package/src/guards/basic-ed25519/consts.ts +10 -0
  62. package/src/guards/basic-ed25519/index.ts +4 -0
  63. package/src/guards/basic-ed25519/service.ts +142 -0
  64. package/src/guards/basic-ed25519/types.ts +9 -0
  65. package/src/guards/index.ts +2 -0
  66. package/src/index.ts +6 -0
  67. package/src/middleware.ts +50 -0
  68. package/src/modules.ts +40 -0
  69. package/src/types.ts +38 -0
  70. package/src/utils/header.ts +24 -0
  71. package/src/utils/index.ts +4 -0
  72. package/src/utils/trusted.ts +17 -0
  73. package/src/utils/types.ts +6 -0
  74. package/tsconfig.json +15 -0
  75. package/tsconfig.tsbuildinfo +1 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 OwlMeans Common — Fullstack typescript framework
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,318 @@
1
+ # @owlmeans/auth-common
2
+
3
+ Common authentication components and modules for OwlMeans Common libraries. This package provides shared authentication infrastructure that bridges the core `@owlmeans/auth` package with client and server implementations, focusing on authentication modules, guards, middleware, and common types used across fullstack applications.
4
+
5
+ ## Overview
6
+
7
+ The `@owlmeans/auth-common` package serves as a foundational layer for authentication in the OwlMeans ecosystem, providing:
8
+
9
+ - **Authentication Modules**: Predefined URL units for authentication flows including login, initialization, and rely functionality
10
+ - **Guard Services**: Authentication and authorization guard implementations for route protection
11
+ - **Common Types**: Shared interfaces and types used across client and server authentication implementations
12
+ - **Middleware**: Authentication middleware for request processing and token validation
13
+ - **Utility Functions**: Helper functions for authentication workflows and token management
14
+
15
+ This package follows the OwlMeans "quadra" pattern, providing common functionality that can be used by both server and client implementations.
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install @owlmeans/auth-common
21
+ ```
22
+
23
+ ## Core Concepts
24
+
25
+ ### Authentication Modules
26
+
27
+ In the OwlMeans ecosystem, modules represent URL units that define authentication routes and their behavior. The auth-common package provides standardized authentication modules for:
28
+
29
+ - **Backend Authentication**: Server-side authentication endpoints
30
+ - **Frontend Authentication**: Client-side authentication routes
31
+ - **Socket Authentication**: WebSocket authentication channels
32
+ - **Dispatcher Routes**: Authentication flow management and redirection
33
+
34
+ ### Guards and Services
35
+
36
+ The package defines standard service interfaces for authentication and authorization:
37
+
38
+ - **AuthService**: Core authentication service with token validation and user management
39
+ - **AuthorizationService**: Permission-based authorization service
40
+ - **GuardService**: Route protection and access control
41
+
42
+ ## API Reference
43
+
44
+ ### Types
45
+
46
+ #### `AuthRequest`
47
+ Extended request interface with authentication token in query parameters.
48
+
49
+ ```typescript
50
+ interface AuthRequest extends AbstractRequest {
51
+ query: AuthToken
52
+ }
53
+ ```
54
+
55
+ #### `AuthUIParams`
56
+ Parameters for authentication UI components.
57
+
58
+ ```typescript
59
+ interface AuthUIParams {
60
+ type?: string // Authentication type identifier
61
+ }
62
+ ```
63
+
64
+ #### `AuthService`
65
+ Core authentication service interface extending GuardService.
66
+
67
+ ```typescript
68
+ interface AuthService extends GuardService {
69
+ auth?: Auth // Current authentication state
70
+ authenticate: (token: AuthToken) => Promise<void> // Authenticate with token (throws AuthenFailed)
71
+ update: (token: string | undefined) => Promise<void> // Update authentication token
72
+ user: () => Auth // Get current authenticated user
73
+ store: <T extends ResourceRecord = ResourceRecord>() => Resource<T> // Get authentication storage resource
74
+ }
75
+ ```
76
+
77
+ **Methods:**
78
+ - **`authenticate(token: AuthToken): Promise<void>`**: Validates and sets authentication token. Throws `AuthenFailed` on invalid token.
79
+ - **`update(token: string | undefined): Promise<void>`**: Updates the current authentication token, useful for token refresh.
80
+ - **`user(): Auth`**: Returns the current authenticated user object.
81
+ - **`store<T>(): Resource<T>`**: Provides access to the authentication storage resource for persistence.
82
+
83
+ #### `AuthorizationService`
84
+ Service interface for permission-based authorization.
85
+
86
+ ```typescript
87
+ interface AuthorizationService extends InitializedService {
88
+ isAllowed: (permissions: string | string[] | PermissionSet | PermissionSet[], token?: string | AuthToken | null, thr?: boolean) => Promise<boolean>
89
+ update: (token?: string | AuthToken, thr?: boolean) => Promise<AuthToken | null>
90
+ }
91
+ ```
92
+
93
+ **Methods:**
94
+ - **`isAllowed(permissions, token?, thr?): Promise<boolean>`**: Checks if given permissions are allowed for the token. Can throw on error if `thr` is true.
95
+ - **`update(token?, thr?): Promise<AuthToken | null>`**: Updates authorization context with new token and returns validated token.
96
+
97
+ #### `TrustedRecord`
98
+ Configuration record for trusted authentication entities.
99
+
100
+ ```typescript
101
+ interface TrustedRecord extends ConfigRecord, Partial<Omit<Profile, "permissions" | "attributes">> {
102
+ id: string // Unique identifier for the trusted entity
103
+ }
104
+ ```
105
+
106
+ ### Modules
107
+
108
+ The package exports a standardized set of authentication modules through the `modules` array:
109
+
110
+ #### Backend Modules
111
+ - **`AUTHEN`**: Base authentication endpoint (`/authentication`)
112
+ - **`AUTHEN_INIT`**: Authentication initialization (`/init`) - POST with AllowanceRequestSchema
113
+ - **`AUTHEN_AUTHEN`**: Authentication execution (`/authenticate`) - POST with AuthCredentialsSchema
114
+ - **`AUTHEN_RELY`**: WebSocket authentication rely (`/rely`) - with OptionalAuthTokenSchema
115
+
116
+ #### Frontend Modules
117
+ - **`CAUTHEN`**: Base client authentication (`/authentication`)
118
+ - **`CAUTHEN_AUTHEN`**: Client login page (`/login`)
119
+ - **`CAUTHEN_AUTHEN_DEFAULT`**: Default client auth route (`/`)
120
+ - **`CAUTHEN_AUTHEN_TYPED`**: Typed authentication (`/:type`)
121
+ - **`CAUTHEN_FLOW_ENTER`**: Authentication flow entry point (`/`)
122
+
123
+ #### Dispatcher Modules
124
+ - **`DISPATCHER`**: Authentication dispatcher (`/dispatcher`) - sticky module with AuthTokenSchema
125
+ - **`DISPATCHER_AUTHEN`**: Dispatcher authentication endpoint (`/authenticate`) - POST with AuthTokenSchema
126
+
127
+ ```typescript
128
+ import { modules } from '@owlmeans/auth-common'
129
+
130
+ // All authentication modules are available in the modules array
131
+ console.log(modules.length) // 11 predefined authentication modules
132
+ ```
133
+
134
+ ### Constants
135
+
136
+ #### Rely Constants
137
+ ```typescript
138
+ const RELY_PIN_PERFIX = 'rely-pin:' // Prefix for rely PIN tokens
139
+ const RELY_TOKEN_PREFIX = 'rely-token:' // Prefix for rely tokens
140
+ const RELY_CALL_TIMEOUT = 120 // Rely call timeout in seconds
141
+ const RELY_ACTION_TIMEOUT = 600 // Rely action timeout in seconds
142
+ ```
143
+
144
+ #### Service Constants
145
+ ```typescript
146
+ const DISPATCHER_PATH = '/dispatcher' // Default dispatcher route path
147
+ const DEF_AUTH_SRV = 'auth' // Default authentication service name
148
+ const DEFAULT_GUARD = DEF_AUTH_SRV // Default guard service name
149
+ const TOKEN_UPDATE = 'auth-token-refresh' // Token update event name
150
+ ```
151
+
152
+ ### Guards
153
+
154
+ The package provides authentication guard implementations in the `/guards` subpackage:
155
+
156
+ #### Basic Ed25519 Guard
157
+ Authentication guard implementation for Ed25519 signature-based authentication.
158
+
159
+ ```typescript
160
+ import { basicEd25519Guard } from '@owlmeans/auth-common/guards'
161
+ ```
162
+
163
+ ### Utilities
164
+
165
+ Authentication utility functions are available in the `/utils` subpackage:
166
+
167
+ #### Header Utilities
168
+ Functions for managing authentication headers in HTTP requests.
169
+
170
+ #### Trusted Entity Utilities
171
+ Functions for managing trusted authentication entities and their validation.
172
+
173
+ ```typescript
174
+ import { /* utility functions */ } from '@owlmeans/auth-common/utils'
175
+ ```
176
+
177
+ ## Usage Examples
178
+
179
+ ### Using Authentication Modules
180
+
181
+ ```typescript
182
+ import { modules } from '@owlmeans/auth-common'
183
+ import { makeBasicContext } from '@owlmeans/context'
184
+
185
+ const context = makeBasicContext(config)
186
+
187
+ // Register all authentication modules
188
+ modules.forEach(module => {
189
+ context.registerModule(module)
190
+ })
191
+
192
+ await context.configure().init()
193
+
194
+ // Access specific authentication modules
195
+ const loginModule = context.module('cauthen-authen')
196
+ const authModule = context.module('authen')
197
+ ```
198
+
199
+ ### Implementing AuthService
200
+
201
+ ```typescript
202
+ import type { AuthService } from '@owlmeans/auth-common'
203
+ import { createService } from '@owlmeans/context'
204
+
205
+ const authService = createService<AuthService>('auth', {
206
+ auth: undefined,
207
+
208
+ async authenticate(token) {
209
+ // Validate token and set auth
210
+ const validatedAuth = await validateToken(token)
211
+ this.auth = validatedAuth
212
+ },
213
+
214
+ async update(token) {
215
+ if (token) {
216
+ await this.authenticate({ token })
217
+ }
218
+ },
219
+
220
+ user() {
221
+ if (!this.auth) {
222
+ throw new Error('No authenticated user')
223
+ }
224
+ return this.auth
225
+ },
226
+
227
+ store() {
228
+ // Return authentication storage resource
229
+ return authStorageResource
230
+ }
231
+ })
232
+ ```
233
+
234
+ ### Permission Checking
235
+
236
+ ```typescript
237
+ import type { AuthorizationService } from '@owlmeans/auth-common'
238
+
239
+ const authzService: AuthorizationService = context.service('authorization')
240
+
241
+ // Check single permission
242
+ const canRead = await authzService.isAllowed('read', userToken)
243
+
244
+ // Check multiple permissions
245
+ const canReadWrite = await authzService.isAllowed(['read', 'write'], userToken)
246
+
247
+ // Check with permission sets
248
+ const canAccess = await authzService.isAllowed([{
249
+ scope: 'documents',
250
+ permissions: { read: true, write: true }
251
+ }], userToken)
252
+ ```
253
+
254
+ ### Using Constants
255
+
256
+ ```typescript
257
+ import { DEF_AUTH_SRV, DISPATCHER_PATH, RELY_CALL_TIMEOUT } from '@owlmeans/auth-common'
258
+
259
+ // Configure authentication service
260
+ const authServiceName = DEF_AUTH_SRV
261
+
262
+ // Set up dispatcher route
263
+ const dispatcherRoute = DISPATCHER_PATH
264
+
265
+ // Configure rely timeout
266
+ const relyTimeout = RELY_CALL_TIMEOUT * 1000 // Convert to milliseconds
267
+ ```
268
+
269
+ ## Integration with OwlMeans Ecosystem
270
+
271
+ The auth-common package integrates with other OwlMeans packages:
272
+
273
+ - **@owlmeans/auth**: Core authentication types and validation
274
+ - **@owlmeans/basic-keys**: Cryptographic key management for signatures
275
+ - **@owlmeans/context**: Dependency injection and service registration
276
+ - **@owlmeans/module**: Module system and route definitions
277
+ - **@owlmeans/resource**: Data persistence and resource management
278
+ - **@owlmeans/route**: URL and routing infrastructure
279
+
280
+ ## Package Structure
281
+
282
+ The authentication common library follows the OwlMeans package structure:
283
+
284
+ - **types**: TypeScript interfaces and type definitions
285
+ - **modules**: Predefined authentication modules for common flows
286
+ - **consts**: Static values and configuration constants
287
+ - **guards/**: Authentication guard implementations
288
+ - **utils/**: Internal utility functions for authentication workflows
289
+ - **middleware**: Authentication middleware for request processing
290
+
291
+ ## Related Packages
292
+
293
+ This package serves as the foundation for:
294
+
295
+ - **@owlmeans/server-auth**: Server-side authentication implementation
296
+ - **@owlmeans/client-auth**: Client-side authentication implementation
297
+ - **@owlmeans/web-oidc-provider**: OpenID Connect provider implementation
298
+ - **@owlmeans/web-oidc-rp**: OpenID Connect relying party implementation
299
+
300
+ ## Error Handling
301
+
302
+ The package leverages the error types from `@owlmeans/auth`:
303
+
304
+ - **AuthenFailed**: Thrown by `authenticate()` method on authentication failure
305
+ - **AuthForbidden**: Thrown by authorization services on access denial
306
+ - **AuthError**: Base authentication error for general failures
307
+
308
+ Always handle authentication errors appropriately in your application:
309
+
310
+ ```typescript
311
+ try {
312
+ await authService.authenticate(token)
313
+ } catch (error) {
314
+ if (error instanceof AuthenFailed) {
315
+ // Handle authentication failure
316
+ }
317
+ }
318
+ ```
@@ -0,0 +1,9 @@
1
+ export declare const RELY_PIN_PERFIX = "rely-pin:";
2
+ export declare const RELY_TOKEN_PREFIX = "rely-token:";
3
+ export declare const RELY_CALL_TIMEOUT = 120;
4
+ export declare const RELY_ACTION_TIMEOUT = 600;
5
+ export declare const DISPATCHER_PATH = "/dispatcher";
6
+ export declare const DEF_AUTH_SRV = "auth";
7
+ export declare const DEFAULT_GUARD = "auth";
8
+ export declare const TOKEN_UPDATE = "auth-token-refresh";
9
+ //# sourceMappingURL=consts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,cAAc,CAAA;AAE1C,eAAO,MAAM,iBAAiB,gBAAgB,CAAA;AAE9C,eAAO,MAAM,iBAAiB,MAAM,CAAA;AAEpC,eAAO,MAAM,mBAAmB,MAAM,CAAA;AAEtC,eAAO,MAAM,eAAe,gBAAgB,CAAA;AAE5C,eAAO,MAAM,YAAY,SAAS,CAAA;AAElC,eAAO,MAAM,aAAa,SAAe,CAAA;AAEzC,eAAO,MAAM,YAAY,uBAAuB,CAAA"}
@@ -0,0 +1,9 @@
1
+ export const RELY_PIN_PERFIX = 'rely-pin:';
2
+ export const RELY_TOKEN_PREFIX = 'rely-token:';
3
+ export const RELY_CALL_TIMEOUT = 120;
4
+ export const RELY_ACTION_TIMEOUT = 600;
5
+ export const DISPATCHER_PATH = '/dispatcher';
6
+ export const DEF_AUTH_SRV = 'auth';
7
+ export const DEFAULT_GUARD = DEF_AUTH_SRV;
8
+ export const TOKEN_UPDATE = 'auth-token-refresh';
9
+ //# sourceMappingURL=consts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,WAAW,CAAA;AAE1C,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAA;AAE9C,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;AAEpC,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAA;AAEtC,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAAA;AAE5C,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAA;AAElC,MAAM,CAAC,MAAM,aAAa,GAAG,YAAY,CAAA;AAEzC,MAAM,CAAC,MAAM,YAAY,GAAG,oBAAoB,CAAA"}
@@ -0,0 +1,6 @@
1
+ export declare const GUARD_ED25519 = "guard:ed25519-basic-signature";
2
+ export declare const BED255_TIME_HEADER = "X-Auth-Time";
3
+ export declare const BED255_NONCE_HEADER = "X-Auth-Nonce";
4
+ export declare const BED255_SIG_TTL: number;
5
+ export declare const BED255_CASHE_RESOURCE = "basic-ed25519-nonce-cache";
6
+ //# sourceMappingURL=consts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../../../src/guards/basic-ed25519/consts.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,kCAAqD,CAAA;AAE/E,eAAO,MAAM,kBAAkB,gBAAgB,CAAA;AAC/C,eAAO,MAAM,mBAAmB,iBAAiB,CAAA;AAEjD,eAAO,MAAM,cAAc,QAAY,CAAA;AAEvC,eAAO,MAAM,qBAAqB,8BAA8B,CAAA"}
@@ -0,0 +1,7 @@
1
+ import { AuthroizationType } from '@owlmeans/auth';
2
+ export const GUARD_ED25519 = `guard:${AuthroizationType.Ed25519BasicSignature}`;
3
+ export const BED255_TIME_HEADER = 'X-Auth-Time';
4
+ export const BED255_NONCE_HEADER = 'X-Auth-Nonce';
5
+ export const BED255_SIG_TTL = 60 * 1000;
6
+ export const BED255_CASHE_RESOURCE = 'basic-ed25519-nonce-cache';
7
+ //# sourceMappingURL=consts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../../../src/guards/basic-ed25519/consts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAElD,MAAM,CAAC,MAAM,aAAa,GAAG,SAAS,iBAAiB,CAAC,qBAAqB,EAAE,CAAA;AAE/E,MAAM,CAAC,MAAM,kBAAkB,GAAG,aAAa,CAAA;AAC/C,MAAM,CAAC,MAAM,mBAAmB,GAAG,cAAc,CAAA;AAEjD,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,GAAG,IAAI,CAAA;AAEvC,MAAM,CAAC,MAAM,qBAAqB,GAAG,2BAA2B,CAAA"}
@@ -0,0 +1,4 @@
1
+ export type * from './types.js';
2
+ export * from './consts.js';
3
+ export * from './service.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/guards/basic-ed25519/index.ts"],"names":[],"mappings":"AACA,mBAAmB,YAAY,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA"}
@@ -0,0 +1,3 @@
1
+ export * from './consts.js';
2
+ export * from './service.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/guards/basic-ed25519/index.ts"],"names":[],"mappings":"AAEA,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA"}
@@ -0,0 +1,8 @@
1
+ import type { BasicEd25519Guard, BasicEd25519GuardOptions } from './types.js';
2
+ /**
3
+ * Proper configuration:
4
+ * - One needs to specify opts.cache as a redis resource that stores nonces for a while to
5
+ * avoid requests duplication.
6
+ */
7
+ export declare const makeBasicEd25519Guard: (resource: string, opts?: BasicEd25519GuardOptions) => BasicEd25519Guard;
8
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/guards/basic-ed25519/service.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAA;AAU7E;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,aAAc,MAAM,SAAS,wBAAwB,KAAG,iBAqHzF,CAAA"}
@@ -0,0 +1,110 @@
1
+ import { createService } from '@owlmeans/context';
2
+ import { assertContext } from '@owlmeans/context';
3
+ import { BED255_NONCE_HEADER, BED255_TIME_HEADER, BED255_CASHE_RESOURCE, GUARD_ED25519, BED255_SIG_TTL } from './consts.js';
4
+ import { trust } from '../../utils/trusted.js';
5
+ import { AuthenPayloadError, AuthroizationType, AuthRole } from '@owlmeans/auth';
6
+ import { createIdOfLength } from '@owlmeans/basic-ids';
7
+ import { extractAuthToken } from '@owlmeans/auth-common/utils';
8
+ const timeKey = BED255_TIME_HEADER.toLocaleLowerCase();
9
+ const nonceKey = BED255_NONCE_HEADER.toLocaleLowerCase();
10
+ /**
11
+ * Proper configuration:
12
+ * - One needs to specify opts.cache as a redis resource that stores nonces for a while to
13
+ * avoid requests duplication.
14
+ */
15
+ export const makeBasicEd25519Guard = (resource, opts) => {
16
+ const cache = (context) => context.hasResource(opts?.cache ?? BED255_CASHE_RESOURCE)
17
+ ? context.resource(opts?.cache ?? BED255_CASHE_RESOURCE)
18
+ : null;
19
+ const guard = createService(GUARD_ED25519, {
20
+ authenticated: async (req) => {
21
+ const context = assertContext(guard.ctx);
22
+ const truested = await trust(context, resource, context.cfg.alias ?? context.cfg.service);
23
+ // req?.body != null
24
+ if (req != null && truested.user.secret != null) {
25
+ if (req.headers == null) {
26
+ req.headers = {};
27
+ }
28
+ req.headers[timeKey] = new Date().toISOString();
29
+ req.headers[nonceKey] = createIdOfLength(16);
30
+ const payload = {
31
+ body: req.body ?? {},
32
+ headers: { [timeKey]: req.headers[timeKey], [nonceKey]: req.headers[nonceKey] }
33
+ };
34
+ const token = [
35
+ AuthroizationType.Ed25519BasicSignature.toUpperCase(),
36
+ ['Credential', truested.user.id],
37
+ ['Signature', await truested.key.sign(payload)]
38
+ ];
39
+ return token.map(item => Array.isArray(item) ? item.join('=') : item).join(' ');
40
+ }
41
+ return null;
42
+ },
43
+ match: async (req) => extractAuthToken(req, AuthroizationType.Ed25519BasicSignature) != null,
44
+ handle: async (req, res) => {
45
+ const context = assertContext(guard.ctx);
46
+ const authorization = extractAuthToken(req, AuthroizationType.Ed25519BasicSignature);
47
+ if (authorization == null) {
48
+ return false;
49
+ }
50
+ const signature = authorization.split(' ', 3).reduce((result, pair) => {
51
+ if (!pair.includes('=')) {
52
+ return result;
53
+ }
54
+ const [key, value] = pair.split('=', 2);
55
+ return { ...result, [key.toLowerCase()]: value };
56
+ }, {});
57
+ const trusted = await trust(context, resource, signature.credential, "id");
58
+ if (trusted.user.credential == null) {
59
+ return false;
60
+ }
61
+ const payload = {
62
+ body: req.body ?? {},
63
+ headers: { [timeKey]: req.headers[timeKey], [nonceKey]: req.headers[nonceKey] }
64
+ };
65
+ if (!await trusted.key.verify(payload, signature.signature)) {
66
+ return false;
67
+ }
68
+ if (typeof req.headers[timeKey] !== 'string') {
69
+ throw new AuthenPayloadError('timestamp');
70
+ }
71
+ const createdAt = new Date(req.headers[timeKey]);
72
+ if (createdAt.getTime() + BED255_SIG_TTL < Date.now()) {
73
+ throw new AuthenPayloadError('expired');
74
+ }
75
+ const nonce = req.headers[nonceKey];
76
+ if (typeof nonce !== 'string') {
77
+ throw new AuthenPayloadError('nonce');
78
+ }
79
+ try {
80
+ const tried = cache(context);
81
+ if (tried != null) {
82
+ await tried.create({ id: nonce }, { ttl: BED255_SIG_TTL / 1000 });
83
+ }
84
+ }
85
+ catch {
86
+ throw new AuthenPayloadError('nonce');
87
+ }
88
+ res.resolve({
89
+ token: authorization,
90
+ userId: trusted.user.id,
91
+ profileId: trusted.user.id,
92
+ entityId: trusted.user.entityId,
93
+ scopes: trusted.user.name != null ? [trusted.user.name] : [],
94
+ type: AuthroizationType.Ed25519BasicSignature,
95
+ source: context.cfg.service,
96
+ /**
97
+ * @TODO actually it's not always the case (that the the role is the service)
98
+ */
99
+ role: AuthRole.Service,
100
+ isUser: false,
101
+ createdAt: new Date()
102
+ });
103
+ return true;
104
+ }
105
+ }, guard => async () => {
106
+ guard.initialized = true;
107
+ });
108
+ return guard;
109
+ };
110
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/guards/basic-ed25519/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { GuardService } from '@owlmeans/module';
2
+ export interface BasicEd25519Guard extends GuardService {
3
+ }
4
+ export interface BasicEd25519GuardOptions {
5
+ cache?: string;
6
+ }
7
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/guards/basic-ed25519/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEpD,MAAM,WAAW,iBAAkB,SAAQ,YAAY;CACtD;AAED,MAAM,WAAW,wBAAwB;IACvC,KAAK,CAAC,EAAE,MAAM,CAAA;CACf"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/guards/basic-ed25519/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export * from './basic-ed25519/index.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/guards/index.ts"],"names":[],"mappings":"AACA,cAAc,0BAA0B,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from './basic-ed25519/index.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/guards/index.ts"],"names":[],"mappings":"AACA,cAAc,0BAA0B,CAAA"}
@@ -0,0 +1,6 @@
1
+ export type * from './types.js';
2
+ export * from './modules.js';
3
+ export * from './consts.js';
4
+ export * from './middleware.js';
5
+ export * from './guards/index.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,YAAY,CAAA;AAE/B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,mBAAmB,CAAA"}
package/build/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export * from './modules.js';
2
+ export * from './consts.js';
3
+ export * from './middleware.js';
4
+ export * from './guards/index.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,mBAAmB,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { Middleware } from '@owlmeans/context';
2
+ export declare const authMiddleware: Middleware;
3
+ //# sourceMappingURL=middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAOnD,eAAO,MAAM,cAAc,EAAE,UAsC5B,CAAA"}
@@ -0,0 +1,39 @@
1
+ import { MiddlewareType, MiddlewareStage, AppType } from '@owlmeans/context';
2
+ import { provideRequest } from '@owlmeans/client-module';
3
+ import { AUTH_HEADER } from '@owlmeans/auth';
4
+ export const authMiddleware = {
5
+ type: MiddlewareType.Context,
6
+ stage: MiddlewareStage.Loading,
7
+ apply: async (context) => {
8
+ context.modules().forEach(module => {
9
+ if (module.route.route.type === AppType.Backend && module.call != null) {
10
+ const guards = module.getGuards();
11
+ if (guards.length > 0) {
12
+ if (module._auth_common_middleware_applied === true) {
13
+ return;
14
+ }
15
+ module._auth_common_middleware_applied = true;
16
+ // const auth = context.service<GuardService>(service)
17
+ const call = module.call;
18
+ module.call = async (req, res) => {
19
+ // @TODO Actually we may use multiple authentication headers with the same name
20
+ // As I learnt its not always the case
21
+ const [token] = (await Promise.all(guards.map(guard => context.service(guard).authenticated(req)))).filter(token => token != null).reverse();
22
+ if (token != null) {
23
+ await module.resolve();
24
+ const _req = req ?? provideRequest(module.getAlias(), module.getPath());
25
+ const headers = (_req.headers ?? {});
26
+ if (headers[AUTH_HEADER] == null) {
27
+ headers[AUTH_HEADER] = token;
28
+ _req.headers = headers;
29
+ req = _req;
30
+ }
31
+ }
32
+ return call(req, res);
33
+ };
34
+ }
35
+ }
36
+ });
37
+ }
38
+ };
39
+ //# sourceMappingURL=middleware.js.map