@owlmeans/client-auth 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 (162) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +526 -0
  3. package/build/.gitkeep +0 -0
  4. package/build/components/dispatcher/component.d.ts +3 -0
  5. package/build/components/dispatcher/component.d.ts.map +1 -0
  6. package/build/components/dispatcher/component.js +70 -0
  7. package/build/components/dispatcher/component.js.map +1 -0
  8. package/build/components/dispatcher/index.d.ts +3 -0
  9. package/build/components/dispatcher/index.d.ts.map +1 -0
  10. package/build/components/dispatcher/index.js +3 -0
  11. package/build/components/dispatcher/index.js.map +1 -0
  12. package/build/components/dispatcher/types.d.ts +21 -0
  13. package/build/components/dispatcher/types.d.ts.map +1 -0
  14. package/build/components/dispatcher/types.js +2 -0
  15. package/build/components/dispatcher/types.js.map +1 -0
  16. package/build/components/index.d.ts +2 -0
  17. package/build/components/index.d.ts.map +1 -0
  18. package/build/components/index.js +2 -0
  19. package/build/components/index.js.map +1 -0
  20. package/build/consts.d.ts +4 -0
  21. package/build/consts.d.ts.map +1 -0
  22. package/build/consts.js +4 -0
  23. package/build/consts.js.map +1 -0
  24. package/build/helper.d.ts +4 -0
  25. package/build/helper.d.ts.map +1 -0
  26. package/build/helper.js +28 -0
  27. package/build/helper.js.map +1 -0
  28. package/build/index.d.ts +7 -0
  29. package/build/index.d.ts.map +1 -0
  30. package/build/index.js +6 -0
  31. package/build/index.js.map +1 -0
  32. package/build/manager/components/authentication/component.d.ts +3 -0
  33. package/build/manager/components/authentication/component.d.ts.map +1 -0
  34. package/build/manager/components/authentication/component.js +28 -0
  35. package/build/manager/components/authentication/component.js.map +1 -0
  36. package/build/manager/components/authentication/consts.d.ts +2 -0
  37. package/build/manager/components/authentication/consts.d.ts.map +1 -0
  38. package/build/manager/components/authentication/consts.js +2 -0
  39. package/build/manager/components/authentication/consts.js.map +1 -0
  40. package/build/manager/components/authentication/control.d.ts +6 -0
  41. package/build/manager/components/authentication/control.d.ts.map +1 -0
  42. package/build/manager/components/authentication/control.js +146 -0
  43. package/build/manager/components/authentication/control.js.map +1 -0
  44. package/build/manager/components/authentication/index.d.ts +4 -0
  45. package/build/manager/components/authentication/index.d.ts.map +1 -0
  46. package/build/manager/components/authentication/index.js +4 -0
  47. package/build/manager/components/authentication/index.js.map +1 -0
  48. package/build/manager/components/authentication/types.d.ts +57 -0
  49. package/build/manager/components/authentication/types.d.ts.map +1 -0
  50. package/build/manager/components/authentication/types.js +2 -0
  51. package/build/manager/components/authentication/types.js.map +1 -0
  52. package/build/manager/components/index.d.ts +4 -0
  53. package/build/manager/components/index.d.ts.map +1 -0
  54. package/build/manager/components/index.js +3 -0
  55. package/build/manager/components/index.js.map +1 -0
  56. package/build/manager/components/tunnel-consumer.d.ts +4 -0
  57. package/build/manager/components/tunnel-consumer.d.ts.map +1 -0
  58. package/build/manager/components/tunnel-consumer.js +11 -0
  59. package/build/manager/components/tunnel-consumer.js.map +1 -0
  60. package/build/manager/components/types.d.ts +10 -0
  61. package/build/manager/components/types.d.ts.map +1 -0
  62. package/build/manager/components/types.js +2 -0
  63. package/build/manager/components/types.js.map +1 -0
  64. package/build/manager/errors.d.ts +6 -0
  65. package/build/manager/errors.d.ts.map +1 -0
  66. package/build/manager/errors.js +11 -0
  67. package/build/manager/errors.js.map +1 -0
  68. package/build/manager/index.d.ts +4 -0
  69. package/build/manager/index.d.ts.map +1 -0
  70. package/build/manager/index.js +4 -0
  71. package/build/manager/index.js.map +1 -0
  72. package/build/manager/modules.d.ts +2 -0
  73. package/build/manager/modules.d.ts.map +1 -0
  74. package/build/manager/modules.js +16 -0
  75. package/build/manager/modules.js.map +1 -0
  76. package/build/manager/plugins/basic-ed25519.d.ts +3 -0
  77. package/build/manager/plugins/basic-ed25519.d.ts.map +1 -0
  78. package/build/manager/plugins/basic-ed25519.js +33 -0
  79. package/build/manager/plugins/basic-ed25519.js.map +1 -0
  80. package/build/manager/plugins/exports.d.ts +6 -0
  81. package/build/manager/plugins/exports.d.ts.map +1 -0
  82. package/build/manager/plugins/exports.js +5 -0
  83. package/build/manager/plugins/exports.js.map +1 -0
  84. package/build/manager/plugins/index.d.ts +6 -0
  85. package/build/manager/plugins/index.d.ts.map +1 -0
  86. package/build/manager/plugins/index.js +9 -0
  87. package/build/manager/plugins/index.js.map +1 -0
  88. package/build/manager/plugins/re-captcha.d.ts +3 -0
  89. package/build/manager/plugins/re-captcha.d.ts.map +1 -0
  90. package/build/manager/plugins/re-captcha.js +26 -0
  91. package/build/manager/plugins/re-captcha.js.map +1 -0
  92. package/build/manager/plugins/tunnel/consts.d.ts +4 -0
  93. package/build/manager/plugins/tunnel/consts.d.ts.map +1 -0
  94. package/build/manager/plugins/tunnel/consts.js +9 -0
  95. package/build/manager/plugins/tunnel/consts.js.map +1 -0
  96. package/build/manager/plugins/tunnel/index.d.ts +4 -0
  97. package/build/manager/plugins/tunnel/index.d.ts.map +1 -0
  98. package/build/manager/plugins/tunnel/index.js +3 -0
  99. package/build/manager/plugins/tunnel/index.js.map +1 -0
  100. package/build/manager/plugins/tunnel/types.d.ts +13 -0
  101. package/build/manager/plugins/tunnel/types.d.ts.map +1 -0
  102. package/build/manager/plugins/tunnel/types.js +2 -0
  103. package/build/manager/plugins/tunnel/types.js.map +1 -0
  104. package/build/manager/plugins/tunnel/wallet.d.ts +4 -0
  105. package/build/manager/plugins/tunnel/wallet.d.ts.map +1 -0
  106. package/build/manager/plugins/tunnel/wallet.js +32 -0
  107. package/build/manager/plugins/tunnel/wallet.js.map +1 -0
  108. package/build/manager/plugins/tunnel-consumer.d.ts +3 -0
  109. package/build/manager/plugins/tunnel-consumer.d.ts.map +1 -0
  110. package/build/manager/plugins/tunnel-consumer.js +81 -0
  111. package/build/manager/plugins/tunnel-consumer.js.map +1 -0
  112. package/build/manager/plugins/types.d.ts +11 -0
  113. package/build/manager/plugins/types.d.ts.map +1 -0
  114. package/build/manager/plugins/types.js +2 -0
  115. package/build/manager/plugins/types.js.map +1 -0
  116. package/build/modules.d.ts +4 -0
  117. package/build/modules.d.ts.map +1 -0
  118. package/build/modules.js +9 -0
  119. package/build/modules.js.map +1 -0
  120. package/build/service.d.ts +6 -0
  121. package/build/service.d.ts.map +1 -0
  122. package/build/service.js +71 -0
  123. package/build/service.js.map +1 -0
  124. package/build/types.d.ts +13 -0
  125. package/build/types.d.ts.map +1 -0
  126. package/build/types.js +2 -0
  127. package/build/types.js.map +1 -0
  128. package/package.json +79 -0
  129. package/src/components/dispatcher/component.tsx +84 -0
  130. package/src/components/dispatcher/index.ts +3 -0
  131. package/src/components/dispatcher/types.ts +24 -0
  132. package/src/components/index.ts +2 -0
  133. package/src/consts.ts +6 -0
  134. package/src/helper.ts +39 -0
  135. package/src/index.ts +7 -0
  136. package/src/manager/README.md +463 -0
  137. package/src/manager/components/authentication/component.tsx +34 -0
  138. package/src/manager/components/authentication/consts.ts +2 -0
  139. package/src/manager/components/authentication/control.ts +193 -0
  140. package/src/manager/components/authentication/index.ts +4 -0
  141. package/src/manager/components/authentication/types.ts +74 -0
  142. package/src/manager/components/index.ts +4 -0
  143. package/src/manager/components/tunnel-consumer.tsx +15 -0
  144. package/src/manager/components/types.ts +11 -0
  145. package/src/manager/errors.ts +14 -0
  146. package/src/manager/index.ts +4 -0
  147. package/src/manager/modules.ts +18 -0
  148. package/src/manager/plugins/basic-ed25519.tsx +42 -0
  149. package/src/manager/plugins/exports.ts +5 -0
  150. package/src/manager/plugins/index.ts +13 -0
  151. package/src/manager/plugins/re-captcha.tsx +31 -0
  152. package/src/manager/plugins/tunnel/consts.ts +12 -0
  153. package/src/manager/plugins/tunnel/index.ts +5 -0
  154. package/src/manager/plugins/tunnel/types.ts +15 -0
  155. package/src/manager/plugins/tunnel/wallet.ts +43 -0
  156. package/src/manager/plugins/tunnel-consumer.tsx +100 -0
  157. package/src/manager/plugins/types.ts +14 -0
  158. package/src/modules.ts +13 -0
  159. package/src/service.ts +106 -0
  160. package/src/types.ts +15 -0
  161. package/tsconfig.json +15 -0
  162. 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,526 @@
1
+ # @owlmeans/client-auth
2
+
3
+ Client-side authentication library for OwlMeans Common applications. This package provides comprehensive authentication capabilities for React-based frontend applications, including token management, session persistence, and integration with the OwlMeans authentication subsystem.
4
+
5
+ ## Overview
6
+
7
+ The `@owlmeans/client-auth` package extends the base `@owlmeans/auth` and `@owlmeans/auth-common` packages with client-specific functionality. It provides:
8
+
9
+ - **Token Management**: Secure storage and retrieval of authentication tokens
10
+ - **Session Persistence**: Client-side session management across browser sessions
11
+ - **Authentication Service**: Centralized authentication logic for client applications
12
+ - **React Components**: Pre-built authentication UI components
13
+ - **Module Integration**: Authentication modules for client-side routing and API calls
14
+ - **Manager Components**: Authentication manager UI for administrative interfaces
15
+
16
+ This package is part of the OwlMeans authentication quadra:
17
+ - **@owlmeans/auth**: Common authentication declarations and utilities
18
+ - **@owlmeans/auth-common**: Shared authentication logic
19
+ - **@owlmeans/client-auth**: Client-side authentication implementation *(this package)*
20
+ - **@owlmeans/server-auth**: Server-side authentication implementation
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ npm install @owlmeans/client-auth
26
+ ```
27
+
28
+ ## Core Concepts
29
+
30
+ ### Authentication Service
31
+ The authentication service manages the client-side authentication state, including token storage, validation, and user session management.
32
+
33
+ ### Token Management
34
+ Client-side tokens are securely stored using the resource system and automatically attached to API requests for authentication.
35
+
36
+ ### Resource-based Storage
37
+ Authentication data is persisted using the OwlMeans resource system, allowing for consistent data management across the application.
38
+
39
+ ## API Reference
40
+
41
+ ### Factory Functions
42
+
43
+ #### `makeAuthService(alias?: string): AuthService`
44
+
45
+ Creates a client-side authentication service instance.
46
+
47
+ ```typescript
48
+ import { makeAuthService } from '@owlmeans/client-auth'
49
+
50
+ const authService = makeAuthService('main-auth')
51
+ ```
52
+
53
+ **Parameters:**
54
+ - `alias`: string (optional) - Service alias for registration, defaults to 'auth'
55
+
56
+ **Returns:** AuthService instance with client-specific capabilities
57
+
58
+ ### Core Interfaces
59
+
60
+ #### `AuthService`
61
+
62
+ Main authentication service interface that extends the base AuthService from `@owlmeans/auth-common`.
63
+
64
+ ```typescript
65
+ interface AuthService extends InitializedService {
66
+ token?: string
67
+ auth?: Auth
68
+
69
+ // Authentication methods
70
+ authenticated(): Promise<string | null>
71
+ authenticate(token: AuthToken): Promise<void>
72
+ update(token?: string): Promise<void>
73
+
74
+ // Guard and handler methods
75
+ match(): Promise<boolean>
76
+ handle<T>(): Promise<T | void>
77
+ }
78
+ ```
79
+
80
+ #### `ClientAuthRecord`
81
+
82
+ Interface for authentication data stored in client resources.
83
+
84
+ ```typescript
85
+ interface ClientAuthRecord extends ResourceRecord {
86
+ token: string // Authentication token
87
+ profileId?: string // Optional profile identifier
88
+ }
89
+ ```
90
+
91
+ #### `ClientAuthResource`
92
+
93
+ Resource interface for managing authentication data persistence.
94
+
95
+ ```typescript
96
+ interface ClientAuthResource extends ClientResource<ClientAuthRecord> {
97
+ // Inherits standard resource methods for CRUD operations
98
+ }
99
+ ```
100
+
101
+ #### `AuthServiceAppend`
102
+
103
+ Interface for services that need authentication capabilities.
104
+
105
+ ```typescript
106
+ interface AuthServiceAppend {
107
+ auth(): AuthService
108
+ }
109
+ ```
110
+
111
+ ### Authentication Service Methods
112
+
113
+ #### `authenticated(): Promise<string | null>`
114
+
115
+ **Purpose**: Checks if the current session is authenticated and returns the auth token
116
+
117
+ **Behavior**:
118
+ - Checks for existing token in memory
119
+ - Falls back to loading token from persistent storage
120
+ - Validates token format and expiration
121
+ - Returns null if no valid authentication found
122
+
123
+ **Usage**: Primary method for checking authentication status
124
+
125
+ **Returns**: Promise that resolves to auth token string or null
126
+
127
+ ```typescript
128
+ const authService = makeAuthService()
129
+
130
+ const token = await authService.authenticated()
131
+ if (token) {
132
+ console.log('User is authenticated')
133
+ } else {
134
+ console.log('User needs to authenticate')
135
+ }
136
+ ```
137
+
138
+ #### `authenticate(token: AuthToken): Promise<void>`
139
+
140
+ **Purpose**: Authenticates the user with the provided token
141
+
142
+ **Behavior**:
143
+ - Calls the authentication dispatcher module with the token
144
+ - Stores the received authentication token
145
+ - Updates the authentication state
146
+ - Persists authentication data for future sessions
147
+
148
+ **Usage**: Called after successful login to establish authentication
149
+
150
+ **Parameters**:
151
+ - `token`: AuthToken - Authentication token received from login process
152
+
153
+ **Throws**: `AuthorizationError` if authentication fails
154
+
155
+ ```typescript
156
+ try {
157
+ await authService.authenticate(loginToken)
158
+ console.log('Authentication successful')
159
+ } catch (error) {
160
+ console.error('Authentication failed:', error.message)
161
+ }
162
+ ```
163
+
164
+ #### `update(token?: string): Promise<void>`
165
+
166
+ **Purpose**: Updates the authentication state with a new token
167
+
168
+ **Behavior**:
169
+ - If token is provided, stores it and updates authentication state
170
+ - If token is null/undefined, clears authentication state
171
+ - Updates persistent storage accordingly
172
+ - Parses token to extract Auth payload
173
+
174
+ **Usage**: Called to refresh authentication or clear session
175
+
176
+ **Parameters**:
177
+ - `token`: string (optional) - New authentication token, or undefined to clear
178
+
179
+ ```typescript
180
+ // Update with new token
181
+ await authService.update('Bearer new-auth-token')
182
+
183
+ // Clear authentication
184
+ await authService.update()
185
+ ```
186
+
187
+ #### `match(): Promise<boolean>`
188
+
189
+ **Purpose**: Guard method that checks if authentication requirements are met
190
+
191
+ **Behavior**: Returns true if user is authenticated, false otherwise
192
+
193
+ **Usage**: Used by routing and module systems for access control
194
+
195
+ **Returns**: Promise that resolves to boolean indicating authentication status
196
+
197
+ ```typescript
198
+ const canAccess = await authService.match()
199
+ if (canAccess) {
200
+ // Allow access to protected resource
201
+ }
202
+ ```
203
+
204
+ #### `handle<T>(): Promise<T | void>`
205
+
206
+ **Purpose**: Handler method for processing authenticated requests
207
+
208
+ **Behavior**: Currently returns undefined, can be extended for custom handling
209
+
210
+ **Usage**: Used by module system for request processing
211
+
212
+ **Returns**: Promise that resolves to undefined or custom result
213
+
214
+ ### Module Functions
215
+
216
+ #### `elevate(modules: ClientModule[], alias: string): void`
217
+
218
+ Elevates authentication modules to client-side modules with enhanced capabilities.
219
+
220
+ ```typescript
221
+ import { elevate } from '@owlmeans/client-auth'
222
+
223
+ elevate(authModules, 'dispatcher-auth')
224
+ ```
225
+
226
+ #### `setupExternalAuthentication(service: string): void`
227
+
228
+ Configures external authentication flow for a specific service.
229
+
230
+ ```typescript
231
+ import { setupExternalAuthentication } from '@owlmeans/client-auth'
232
+
233
+ setupExternalAuthentication('oauth-provider')
234
+ ```
235
+
236
+ ### Constants
237
+
238
+ #### Authentication Configuration
239
+ ```typescript
240
+ const DEFAULT_ALIAS = 'auth' // Default service alias
241
+ const AUTH_RESOURCE = 'auth' // Resource identifier for auth data
242
+ const USER_ID = 'user' // Default user identifier
243
+ ```
244
+
245
+ ### Components
246
+
247
+ The package provides React components for authentication UI:
248
+
249
+ #### Authentication Dispatcher
250
+ Located in `./components/dispatcher`, provides components for handling authentication flows.
251
+
252
+ #### Manager Components
253
+ Located in `./manager/components`, provides administrative interfaces for authentication management.
254
+
255
+ **Import paths:**
256
+ ```typescript
257
+ import { /* components */ } from '@owlmeans/client-auth'
258
+ import { /* manager components */ } from '@owlmeans/client-auth/manager'
259
+ ```
260
+
261
+ ### Manager Functionality
262
+
263
+ The package includes a manager subsystem accessible via `/manager` export:
264
+
265
+ ```typescript
266
+ import { /* manager functions */ } from '@owlmeans/client-auth/manager'
267
+ import { /* manager modules */ } from '@owlmeans/client-auth/manager/modules'
268
+ import { /* manager plugins */ } from '@owlmeans/client-auth/manager/plugins'
269
+ ```
270
+
271
+ The manager provides:
272
+ - Administrative authentication interfaces
273
+ - User management components
274
+ - Authentication flow configuration
275
+ - Plugin system for extending authentication capabilities
276
+
277
+ ## Usage Examples
278
+
279
+ ### Basic Authentication Setup
280
+
281
+ ```typescript
282
+ import { makeAuthService } from '@owlmeans/client-auth'
283
+ import { makeClientContext } from '@owlmeans/client-context'
284
+
285
+ // Create context and auth service
286
+ const context = makeClientContext(config)
287
+ const authService = makeAuthService()
288
+
289
+ // Register the service
290
+ context.registerService(authService)
291
+
292
+ // Initialize context
293
+ await context.configure().init()
294
+
295
+ // Check authentication status
296
+ const isAuthenticated = await authService.authenticated()
297
+ console.log('Authenticated:', isAuthenticated != null)
298
+ ```
299
+
300
+ ### Authentication Flow
301
+
302
+ ```typescript
303
+ import { makeAuthService } from '@owlmeans/client-auth'
304
+
305
+ const authService = makeAuthService()
306
+
307
+ // Authenticate with token from login
308
+ const loginToken = { /* token from login process */ }
309
+ try {
310
+ await authService.authenticate(loginToken)
311
+ console.log('Successfully authenticated')
312
+ } catch (error) {
313
+ console.error('Authentication failed:', error)
314
+ }
315
+
316
+ // Check authentication status
317
+ const token = await authService.authenticated()
318
+ if (token) {
319
+ console.log('User is authenticated with token:', token)
320
+ }
321
+
322
+ // Clear authentication
323
+ await authService.update()
324
+ console.log('Authentication cleared')
325
+ ```
326
+
327
+ ### Module Integration
328
+
329
+ ```typescript
330
+ import { modules, setupExternalAuthentication } from '@owlmeans/client-auth'
331
+ import { makeClientContext } from '@owlmeans/client-context'
332
+
333
+ const context = makeClientContext(config)
334
+
335
+ // Register authentication modules
336
+ context.registerModules(modules)
337
+
338
+ // Setup external authentication
339
+ setupExternalAuthentication('google-oauth')
340
+
341
+ // Initialize context
342
+ await context.configure().init()
343
+ ```
344
+
345
+ ### Protected Resource Access
346
+
347
+ ```typescript
348
+ import { makeAuthService } from '@owlmeans/client-auth'
349
+
350
+ const authService = makeAuthService()
351
+
352
+ // Guard for protected resources
353
+ const canAccess = await authService.match()
354
+ if (!canAccess) {
355
+ throw new Error('Authentication required')
356
+ }
357
+
358
+ // Access protected resource
359
+ const protectedData = await api.getProtectedData()
360
+ ```
361
+
362
+ ### React Component Integration
363
+
364
+ ```typescript
365
+ import React from 'react'
366
+ import { useContext } from 'react'
367
+ import { makeAuthService } from '@owlmeans/client-auth'
368
+
369
+ const AuthProvider = ({ children }) => {
370
+ const authService = makeAuthService()
371
+
372
+ const login = async (credentials) => {
373
+ try {
374
+ await authService.authenticate(credentials)
375
+ // Redirect to dashboard
376
+ } catch (error) {
377
+ // Handle login error
378
+ }
379
+ }
380
+
381
+ const logout = async () => {
382
+ await authService.update() // Clear authentication
383
+ // Redirect to login
384
+ }
385
+
386
+ return (
387
+ <AuthContext.Provider value={{ authService, login, logout }}>
388
+ {children}
389
+ </AuthContext.Provider>
390
+ )
391
+ }
392
+ ```
393
+
394
+ ## Error Handling
395
+
396
+ The package uses the OwlMeans error system and may throw the following errors:
397
+
398
+ ### `AuthorizationError`
399
+ Thrown when authentication fails or access is denied.
400
+
401
+ ```typescript
402
+ import { AuthorizationError } from '@owlmeans/auth'
403
+
404
+ try {
405
+ await authService.authenticate(invalidToken)
406
+ } catch (error) {
407
+ if (error instanceof AuthorizationError) {
408
+ console.error('Authentication failed:', error.message)
409
+ }
410
+ }
411
+ ```
412
+
413
+ Common scenarios:
414
+ - Invalid authentication token
415
+ - Expired token
416
+ - Insufficient permissions
417
+ - Network errors during authentication
418
+
419
+ ## Resource Management
420
+
421
+ Authentication data is managed through the OwlMeans resource system:
422
+
423
+ ```typescript
424
+ // Access the auth resource directly
425
+ const authResource = context.resource<ClientAuthResource>('auth')
426
+
427
+ // Load stored authentication data
428
+ const authRecord = await authResource.load('user')
429
+
430
+ // Save authentication data
431
+ await authResource.save({
432
+ id: 'user',
433
+ token: 'Bearer auth-token-here',
434
+ profileId: 'user-profile-123'
435
+ })
436
+
437
+ // Clear authentication data
438
+ await authResource.delete('user')
439
+ ```
440
+
441
+ ## Integration with Other Packages
442
+
443
+ ### Authentication Quadra Integration
444
+
445
+ ```typescript
446
+ // Common authentication (shared)
447
+ import { AuthRole, AuthenticationType } from '@owlmeans/auth'
448
+
449
+ // Shared authentication logic
450
+ import { authMiddleware } from '@owlmeans/auth-common'
451
+
452
+ // Client authentication (this package)
453
+ import { makeAuthService } from '@owlmeans/client-auth'
454
+
455
+ // Server authentication (backend)
456
+ import { makeServerAuthService } from '@owlmeans/server-auth'
457
+ ```
458
+
459
+ ### Context Integration
460
+
461
+ ```typescript
462
+ import { makeClientContext } from '@owlmeans/client-context'
463
+ import { makeAuthService } from '@owlmeans/client-auth'
464
+
465
+ const context = makeClientContext(config)
466
+ const authService = makeAuthService()
467
+
468
+ context.registerService(authService)
469
+ ```
470
+
471
+ ### Module Integration
472
+
473
+ ```typescript
474
+ import { modules } from '@owlmeans/client-auth'
475
+ import { makeClientContext } from '@owlmeans/client-context'
476
+
477
+ const context = makeClientContext(config)
478
+ context.registerModules(modules)
479
+ ```
480
+
481
+ ### Flow Integration
482
+
483
+ ```typescript
484
+ import { makeAuthService } from '@owlmeans/client-auth'
485
+ import { FlowService } from '@owlmeans/client-flow'
486
+
487
+ // Authentication can be integrated with user flows
488
+ const authService = makeAuthService()
489
+ const flowService = context.service<FlowService>('flow')
490
+
491
+ // Use authentication in flow steps
492
+ await flowService.addStep('authenticate', async () => {
493
+ const isAuth = await authService.authenticated()
494
+ if (!isAuth) {
495
+ throw new Error('Authentication required')
496
+ }
497
+ })
498
+ ```
499
+
500
+ ## Best Practices
501
+
502
+ 1. **Single Authentication Service**: Use one primary authentication service per application
503
+ 2. **Context Registration**: Always register the authentication service with the application context
504
+ 3. **Error Handling**: Implement proper error handling for authentication failures
505
+ 4. **Token Security**: Let the service handle token storage and validation
506
+ 5. **Module Integration**: Use provided modules for consistent authentication flows
507
+ 6. **Manager Access**: Use manager components for administrative authentication features
508
+
509
+ ## Dependencies
510
+
511
+ This package depends on:
512
+ - `@owlmeans/auth` - Core authentication types and constants
513
+ - `@owlmeans/auth-common` - Shared authentication logic
514
+ - `@owlmeans/client-context` - Client-side context management
515
+ - `@owlmeans/client-module` - Client-side module system
516
+ - `@owlmeans/client-resource` - Client-side resource management
517
+ - `@owlmeans/basic-envelope` - Token envelope handling
518
+ - `@owlmeans/context` - Core context system
519
+
520
+ ## Related Packages
521
+
522
+ - [`@owlmeans/auth`](../auth) - Core authentication declarations
523
+ - [`@owlmeans/auth-common`](../auth-common) - Shared authentication logic
524
+ - [`@owlmeans/server-auth`](../server-auth) - Server-side authentication
525
+ - [`@owlmeans/client-context`](../client-context) - Client context management
526
+ - [`@owlmeans/client-module`](../client-module) - Client module system
package/build/.gitkeep ADDED
File without changes
@@ -0,0 +1,3 @@
1
+ import type { TDispatcherHOC } from './types.js';
2
+ export declare const DispatcherHOC: TDispatcherHOC;
3
+ //# sourceMappingURL=component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../../src/components/dispatcher/component.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA2B,cAAc,EAAE,MAAM,YAAY,CAAA;AAczE,eAAO,MAAM,aAAa,EAAE,cA+D3B,CAAA"}
@@ -0,0 +1,70 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useState } from 'react';
3
+ import { AUTH_QUERY, DISPATCHER } from '@owlmeans/auth';
4
+ import { HOME } from '@owlmeans/context';
5
+ import { DEFAULT_ALIAS } from '../../consts.js';
6
+ import { useNavigate } from '@owlmeans/client';
7
+ import { DEFAULT_ALIAS as FLOW_SERVICE } from '@owlmeans/client-flow';
8
+ import { STD_OIDC_FLOW } from '@owlmeans/flow';
9
+ import { SERVICE_PARAM } from '@owlmeans/web-flow';
10
+ export const DispatcherHOC = Renderer => ({ context, params, alias, query }) => {
11
+ const [forwarding, setForwarding] = useState();
12
+ const navigator = useNavigate();
13
+ const navigate = useCallback(async () => {
14
+ alias = alias == null || alias === DISPATCHER ? HOME : alias;
15
+ const module = context.module(alias);
16
+ if (alias === HOME) {
17
+ params = {};
18
+ query = {};
19
+ }
20
+ else {
21
+ query = { ...forwarding?.query, ...query };
22
+ if (query != null && AUTH_QUERY in query) {
23
+ delete query[AUTH_QUERY];
24
+ }
25
+ }
26
+ await navigator.navigate(module, { params, query });
27
+ }, [forwarding]);
28
+ useEffect(() => {
29
+ if (forwarding?.token != null) {
30
+ if (forwarding.token.token === '') {
31
+ const flow = context.service(FLOW_SERVICE);
32
+ // @TODO: Make sure that the provided flow is compatible with OIDC flow or provide custom from step
33
+ flow.ready().then(async () => {
34
+ // We do nothing if we are in the middle of a flow
35
+ if (await flow.supplied) {
36
+ const state = await flow.state();
37
+ // If the flow we are in already has a targe, it means this is some flow
38
+ // that is really happening and we do not need to override it with our own.
39
+ // It's MAY BE required on the auth manager service side, cause this
40
+ // component is actually reused by both service and identity providers of OwlMeans.
41
+ if (state?.state().service !== '') {
42
+ return;
43
+ }
44
+ }
45
+ const cfg = context.cfg.security?.auth;
46
+ const model = await flow.begin(cfg?.flow ?? STD_OIDC_FLOW, cfg?.enter);
47
+ const target = (SERVICE_PARAM in params ? params[SERVICE_PARAM] : context.cfg.shortAlias);
48
+ if (target != null) {
49
+ model.target(target);
50
+ }
51
+ await flow.proceed();
52
+ });
53
+ }
54
+ else {
55
+ const auth = context.service(DEFAULT_ALIAS);
56
+ auth.authenticate(forwarding.token).then(async () => {
57
+ return await navigate();
58
+ }).catch((e) => {
59
+ // @TODO Show error on the component
60
+ console.error(e);
61
+ });
62
+ }
63
+ }
64
+ }, [forwarding?.token]);
65
+ const provideToken = useCallback((token, query) => {
66
+ setForwarding({ token, query });
67
+ }, []);
68
+ return _jsx(Renderer, { provideToken: provideToken, navigate: navigate });
69
+ };
70
+ //# sourceMappingURL=component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component.js","sourceRoot":"","sources":["../../../src/components/dispatcher/component.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export * from './component.js';
2
+ export * from './types.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/dispatcher/index.ts"],"names":[],"mappings":"AACA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,YAAY,CAAA"}
@@ -0,0 +1,3 @@
1
+ export * from './component.js';
2
+ export * from './types.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/dispatcher/index.ts"],"names":[],"mappings":"AACA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,YAAY,CAAA"}
@@ -0,0 +1,21 @@
1
+ import type { FC, PropsWithChildren } from 'react';
2
+ import type { RoutedComponent } from '@owlmeans/client';
3
+ import type { AuthToken } from '@owlmeans/auth';
4
+ import type { ClientContext, ClientConfig } from '@owlmeans/client-context';
5
+ import type { AbstractRequest } from '@owlmeans/module';
6
+ export interface DispatcherProps {
7
+ alias: string;
8
+ params: AbstractRequest['params'];
9
+ query?: AbstractRequest['query'];
10
+ context: ClientContext<ClientConfig>;
11
+ }
12
+ export interface TDispatcherHOC {
13
+ (Renderer: DispatcherRenderer): RoutedComponent<DispatcherProps>;
14
+ }
15
+ export interface DispatcherRenderer extends FC<DispatcherRendererProps> {
16
+ }
17
+ export interface DispatcherRendererProps extends PropsWithChildren {
18
+ provideToken: (token: AuthToken, query?: AbstractRequest['params']) => void;
19
+ navigate: () => Promise<void>;
20
+ }
21
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/dispatcher/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAA;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAEvD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAA;IACjC,KAAK,CAAC,EAAE,eAAe,CAAC,OAAO,CAAC,CAAA;IAChC,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,CAAA;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,CAAC,QAAQ,EAAE,kBAAkB,GAAG,eAAe,CAAC,eAAe,CAAC,CAAA;CACjE;AAED,MAAM,WAAW,kBAAmB,SAAQ,EAAE,CAAC,uBAAuB,CAAC;CACtE;AAED,MAAM,WAAW,uBAAwB,SAAQ,iBAAiB;IAChE,YAAY,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,eAAe,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAA;IAC3E,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC9B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/components/dispatcher/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export * from './dispatcher/index.js';
2
+ //# sourceMappingURL=index.d.ts.map