@owlmeans/web-oidc-rp 0.1.2 → 0.1.4

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 (39) hide show
  1. package/README.md +39 -477
  2. package/build/@/components/ui/progress.d.ts +5 -0
  3. package/build/@/components/ui/progress.d.ts.map +1 -0
  4. package/build/@/components/ui/progress.js +11 -0
  5. package/build/@/components/ui/progress.js.map +1 -0
  6. package/build/@/lib/utils.d.ts +3 -0
  7. package/build/@/lib/utils.d.ts.map +1 -0
  8. package/build/@/lib/utils.js +6 -0
  9. package/build/@/lib/utils.js.map +1 -0
  10. package/build/auth/plugins/google-client.d.ts +3 -0
  11. package/build/auth/plugins/google-client.d.ts.map +1 -0
  12. package/build/auth/plugins/google-client.js +71 -0
  13. package/build/auth/plugins/google-client.js.map +1 -0
  14. package/build/auth/plugins/helpers.d.ts +16 -0
  15. package/build/auth/plugins/helpers.d.ts.map +1 -0
  16. package/build/auth/plugins/helpers.js +31 -0
  17. package/build/auth/plugins/helpers.js.map +1 -0
  18. package/build/auth/plugins/index.d.ts.map +1 -1
  19. package/build/auth/plugins/index.js +3 -1
  20. package/build/auth/plugins/index.js.map +1 -1
  21. package/build/auth/plugins/oidc-client.js +2 -2
  22. package/build/auth/plugins/oidc-client.js.map +1 -1
  23. package/build/guard.d.ts +2 -2
  24. package/build/guard.d.ts.map +1 -1
  25. package/build/guard.js.map +1 -1
  26. package/components.json +21 -0
  27. package/package.json +39 -19
  28. package/src/@/components/ui/progress.tsx +44 -0
  29. package/src/@/globals.css +17 -0
  30. package/src/@/lib/utils.ts +6 -0
  31. package/src/auth/plugins/google-client.tsx +94 -0
  32. package/src/auth/plugins/helpers.ts +39 -0
  33. package/src/auth/plugins/index.ts +3 -1
  34. package/src/auth/plugins/oidc-client.tsx +2 -2
  35. package/src/guard.ts +2 -2
  36. package/tests/context.ts +16 -0
  37. package/tests/google-client.spec.ts +64 -0
  38. package/tests/tsconfig.json +12 -0
  39. package/tsconfig.json +9 -11
package/README.md CHANGED
@@ -1,515 +1,77 @@
1
1
  # @owlmeans/web-oidc-rp
2
2
 
3
- The **@owlmeans/web-oidc-rp** package provides web client-side OpenID Connect Relying Party (RP) functionality for OwlMeans Common Libraries, enabling secure authentication and authorization through OIDC protocols in React-based frontend applications.
3
+ Browser-side OIDC relying party — guard, auth service, and React components for OIDC login flows.
4
4
 
5
- ## Purpose
5
+ ## Overview
6
6
 
7
- This package serves as a comprehensive OIDC client implementation for web applications, specifically designed for:
8
-
9
- - **Frontend OIDC Authentication**: Handle OIDC authentication flows in React applications
10
- - **Flow Integration**: Integrate with OwlMeans flow system for complex authentication workflows
11
- - **Automatic Token Management**: Handle OIDC authentication callbacks and token processing
12
- - **React Components**: Provide ready-to-use React components for OIDC integration
13
- - **Server Communication**: Coordinate with server-side OIDC relying party implementation
14
- - **Authentication State Management**: Manage authentication state across the application
15
-
16
- ## Key Concepts
17
-
18
- ### Web-based OIDC Relying Party
19
- This package implements the client-side portion of OIDC authentication, handling redirects, callbacks, and token management in web browsers.
20
-
21
- ### Flow-based Authentication
22
- Integrates with the OwlMeans flow system to support complex authentication workflows that may involve multiple steps and decision points.
23
-
24
- ### Server-Client Coordination
25
- Works in tandem with `@owlmeans/server-oidc-rp` to provide a complete OIDC solution where the server handles sensitive operations and the client manages user interactions.
26
-
27
- ### Authentication Dispatcher
28
- Provides a dispatcher component that automatically handles OIDC callbacks and coordinates authentication state.
7
+ - `appendOidcGuard(context)` — registers the OIDC guard on a web context
8
+ - `setupOidcGuard(modules, coguards?, extras?)` — attaches the guard onto module declarations
9
+ - `makeOidcAuthService(alias?)` — browser-side OIDC auth service (built on `oidc-client-ts`)
10
+ - React components for login and callback handling
11
+ - `OidcAuthPurposes` enum — `Unknown` | `Subscribe` | `Login`
29
12
 
30
13
  ## Installation
31
14
 
32
15
  ```bash
33
- npm install @owlmeans/web-oidc-rp
16
+ bun add @owlmeans/web-oidc-rp
34
17
  ```
35
18
 
36
- ## API Reference
37
-
38
- ### Types
19
+ ## Usage
39
20
 
40
- #### `OidcAuthService`
41
- Main service interface for web-based OIDC operations.
21
+ Register the guard in your web context:
42
22
 
43
23
  ```typescript
44
- interface OidcAuthService extends InitializedService {
45
- dispatch(params: Record<string, string>): Promise<boolean>
46
- authenticate(flow: FlowModel, params: OIDCAuthInitParams): Promise<string | null>
47
- proceedToRedirectUrl(extras: OidcAuthRedirectExtras): Promise<string>
48
- dispatchClientOnly(): Promise<void>
49
- }
50
- ```
51
-
52
- #### `OidcAuthRedirectExtras`
53
- Configuration for OIDC redirect operations.
54
-
55
- ```typescript
56
- interface OidcAuthRedirectExtras extends FlowPayload {
57
- purpose: OidcAuthPurposes
58
- uid?: string
59
- alias?: string
60
- }
61
- ```
62
-
63
- #### `OidcInteraction`
64
- Resource record for storing OIDC interaction data.
24
+ import { appendOidcGuard } from '@owlmeans/web-oidc-rp'
25
+ import { makeContext as makeBasicContext } from '@owlmeans/mui-panel'
65
26
 
66
- ```typescript
67
- interface OidcInteraction extends ResourceRecord {
68
- authUrl: string
27
+ export const makeContext = <C extends Config, T extends Context<C>>(cfg: C): T => {
28
+ const context = makeBasicContext<C, T>(cfg) as T
29
+ appendOidcGuard<C, T>(context)
30
+ return context
69
31
  }
70
32
  ```
71
33
 
72
- #### `Config`
73
- Configuration interface extending AppConfig.
34
+ Wire OIDC onto module declarations:
74
35
 
75
36
  ```typescript
76
- interface Config extends AppConfig, WithSharedConfig { }
77
- ```
37
+ import { setupOidcGuard } from '@owlmeans/web-oidc-rp'
78
38
 
79
- #### `Context`
80
- Context interface for web applications.
81
-
82
- ```typescript
83
- interface Context<C extends Config = Config> extends AppContext<C> { }
39
+ setupOidcGuard(modules, undefined, { payload: { simplified: true } })
84
40
  ```
85
41
 
86
- ### Enums
87
-
88
- #### `OidcAuthPurposes`
89
- Enumeration of OIDC authentication purposes.
90
-
91
- ```typescript
92
- enum OidcAuthPurposes {
93
- Unknown = 'unknown',
94
- Subscribe = 'subscribe',
95
- Login = 'login'
96
- }
97
- ```
98
-
99
- ### Factory Functions
100
-
101
- #### `makeOidcAuthService(alias?: string): OidcAuthService`
42
+ ## API
102
43
 
103
- Creates an OIDC authentication service instance for web applications.
44
+ ### `appendOidcGuard<C, T>(context): T`
104
45
 
105
- **Parameters:**
106
- - `alias`: Service alias (defaults to 'oidc-rp')
46
+ Registers the OIDC guard service on the web context.
107
47
 
108
- **Returns:** OidcAuthService instance
48
+ ### `setupOidcGuard(modules, coguards?, extras?)`
109
49
 
110
- ```typescript
111
- import { makeOidcAuthService } from '@owlmeans/web-oidc-rp'
112
-
113
- const oidcService = makeOidcAuthService('web-oidc-auth')
114
- ```
115
-
116
- ### React Components
50
+ Attaches the OIDC guard to the given module declarations. `coguards` lets you compose with another guard alias; `extras` overrides the parametrised props (e.g., `payload.simplified`).
117
51
 
118
- #### `Dispatcher`
119
- Higher-order component that handles OIDC authentication callbacks and token processing.
120
-
121
- ```typescript
122
- const Dispatcher = DispatcherHOC(({ provideToken, navigate }) => {
123
- // Component implementation handles OIDC callback processing
124
- })
125
- ```
52
+ ### `makeOidcAuthService(alias?): OidcAuthService`
126
53
 
127
- **Props:**
128
- - `provideToken`: Function to provide authentication tokens
129
- - `navigate`: Function to handle navigation after authentication
54
+ Creates the browser OIDC auth service. `alias` defaults to `DEFAULT_ALIAS` (`'oidc-rp'`).
130
55
 
131
56
  ### Constants
132
57
 
133
- #### Service Configuration
134
- ```typescript
135
- const DEFAULT_ALIAS = 'oidc-rp'
136
- ```
137
-
138
- ## Usage Examples
139
-
140
- ### Basic Setup
141
-
142
- ```typescript
143
- import { makeOidcAuthService } from '@owlmeans/web-oidc-rp'
144
- import { makeAppContext, makeAppConfig } from '@owlmeans/web-client'
145
-
146
- // Create app context with OIDC configuration
147
- const config = makeAppConfig('web-app', {
148
- oidc: {
149
- // OIDC configuration shared with server
150
- }
151
- })
152
-
153
- const context = makeAppContext(config)
154
-
155
- // Create and register OIDC service
156
- const oidcService = makeOidcAuthService()
157
- context.registerService(oidcService)
158
-
159
- // Initialize context
160
- await context.configure().init()
161
- ```
162
-
163
- ### React Application Integration
164
-
165
- ```typescript
166
- import React from 'react'
167
- import { BrowserRouter, Routes, Route } from 'react-router-dom'
168
- import { Dispatcher } from '@owlmeans/web-oidc-rp'
169
-
170
- function App() {
171
- return (
172
- <BrowserRouter>
173
- <Routes>
174
- <Route path="/auth/callback" element={<Dispatcher />} />
175
- <Route path="/login" element={<LoginPage />} />
176
- <Route path="/dashboard" element={<Dashboard />} />
177
- </Routes>
178
- </BrowserRouter>
179
- )
180
- }
181
-
182
- function LoginPage() {
183
- const context = useContext()
184
- const oidcService = context.service<OidcAuthService>('oidc-rp')
185
-
186
- const handleOidcLogin = async () => {
187
- const flow = await context.service<FlowService>('flow').createFlow('oidc-auth')
188
- const redirectUrl = await oidcService.authenticate(flow, {
189
- entity: 'my-organization',
190
- profile: 'user-profile'
191
- })
192
-
193
- if (redirectUrl) {
194
- window.location.href = redirectUrl
195
- }
196
- }
197
-
198
- return (
199
- <div>
200
- <button onClick={handleOidcLogin}>
201
- Login with OIDC
202
- </button>
203
- </div>
204
- )
205
- }
206
- ```
207
-
208
- ### OIDC Authentication Flow
209
-
210
- ```typescript
211
- import { useFlow } from '@owlmeans/web-flow'
212
- import { useContext } from '@owlmeans/web-client'
213
- import { OidcAuthService } from '@owlmeans/web-oidc-rp'
214
-
215
- function useOidcAuth() {
216
- const context = useContext()
217
- const flowClient = useFlow()
218
- const oidcService = context.service<OidcAuthService>('oidc-rp')
219
-
220
- const initiateAuth = async (entityId: string, profileId?: string) => {
221
- if (!flowClient) return null
222
-
223
- const flow = flowClient.flow()
224
- const redirectUrl = await oidcService.authenticate(flow, {
225
- entity: entityId,
226
- profile: profileId
227
- })
228
-
229
- return redirectUrl
230
- }
231
-
232
- const handleCallback = async (urlParams: URLSearchParams) => {
233
- const params: Record<string, string> = {}
234
- urlParams.forEach((value, key) => {
235
- params[key] = value
236
- })
237
-
238
- return await oidcService.dispatch(params)
239
- }
240
-
241
- return { initiateAuth, handleCallback }
242
- }
243
- ```
244
-
245
- ### Custom Dispatcher Implementation
246
-
247
- ```typescript
248
- import { useSearchParams } from 'react-router-dom'
249
- import { useEffect, useState } from 'react'
250
- import { useContext } from '@owlmeans/web-client'
251
- import { OidcAuthService } from '@owlmeans/web-oidc-rp'
252
-
253
- function CustomOidcDispatcher() {
254
- const [searchParams] = useSearchParams()
255
- const [status, setStatus] = useState<'loading' | 'success' | 'error'>('loading')
256
- const context = useContext()
257
-
258
- useEffect(() => {
259
- const processCallback = async () => {
260
- try {
261
- const oidcService = context.service<OidcAuthService>('oidc-rp')
262
-
263
- const params: Record<string, string> = {}
264
- searchParams.forEach((value, key) => {
265
- params[key] = value
266
- })
267
-
268
- const success = await oidcService.dispatch(params)
269
-
270
- if (success) {
271
- setStatus('success')
272
- // Redirect to intended destination
273
- window.location.href = '/dashboard'
274
- } else {
275
- setStatus('error')
276
- }
277
- } catch (error) {
278
- console.error('OIDC callback processing failed:', error)
279
- setStatus('error')
280
- }
281
- }
282
-
283
- processCallback()
284
- }, [searchParams])
285
-
286
- return (
287
- <div>
288
- {status === 'loading' && <div>Processing authentication...</div>}
289
- {status === 'success' && <div>Authentication successful, redirecting...</div>}
290
- {status === 'error' && <div>Authentication failed. Please try again.</div>}
291
- </div>
292
- )
293
- }
294
- ```
295
-
296
- ### Flow-based Authentication
297
-
298
- ```typescript
299
- import { FlowModel } from '@owlmeans/flow'
300
- import { OIDCAuthInitParams } from '@owlmeans/oidc'
301
-
302
- function FlowBasedAuth() {
303
- const context = useContext()
304
- const oidcService = context.service<OidcAuthService>('oidc-rp')
305
-
306
- const startAuthFlow = async () => {
307
- // Create or get current flow
308
- const flowService = context.service<FlowService>('flow')
309
- const flow = await flowService.createFlow('oidc-authentication')
310
-
311
- // Configure OIDC parameters
312
- const params: OIDCAuthInitParams = {
313
- entity: 'my-organization',
314
- profile: 'default',
315
- purpose: 'login'
316
- }
317
-
318
- // Start authentication
319
- const redirectUrl = await oidcService.authenticate(flow, params)
320
-
321
- if (redirectUrl) {
322
- // Store flow state before redirect
323
- await flowService.persistFlow()
324
-
325
- // Redirect to OIDC provider
326
- window.location.href = redirectUrl
327
- }
328
- }
329
-
330
- return (
331
- <button onClick={startAuthFlow}>
332
- Start Secure Login Flow
333
- </button>
334
- )
335
- }
336
- ```
337
-
338
- ### Advanced Redirect Handling
339
-
340
- ```typescript
341
- import { OidcAuthRedirectExtras, OidcAuthPurposes } from '@owlmeans/web-oidc-rp'
342
-
343
- async function handleComplexRedirect(
344
- oidcService: OidcAuthService,
345
- purpose: OidcAuthPurposes,
346
- userId?: string
347
- ) {
348
- const extras: OidcAuthRedirectExtras = {
349
- purpose,
350
- uid: userId,
351
- alias: 'dashboard'
352
- }
353
-
354
- try {
355
- const finalUrl = await oidcService.proceedToRedirectUrl(extras)
356
- window.location.href = finalUrl
357
- } catch (error) {
358
- console.error('Redirect processing failed:', error)
359
- // Handle error appropriately
360
- }
361
- }
362
- ```
363
-
364
- ### Integration with Authentication Guards
365
-
366
- ```typescript
367
- import { useAuth } from '@owlmeans/client-auth'
368
- import { Navigate } from 'react-router-dom'
369
-
370
- function ProtectedRoute({ children }: { children: React.ReactNode }) {
371
- const auth = useAuth()
372
- const context = useContext()
373
- const oidcService = context.service<OidcAuthService>('oidc-rp')
374
-
375
- useEffect(() => {
376
- const checkAuth = async () => {
377
- const token = await auth.authenticated()
378
- if (!token) {
379
- // Initiate OIDC authentication
380
- const flow = await context.service<FlowService>('flow').createFlow('auth')
381
- const redirectUrl = await oidcService.authenticate(flow, {
382
- entity: 'default'
383
- })
384
-
385
- if (redirectUrl) {
386
- window.location.href = redirectUrl
387
- }
388
- }
389
- }
390
-
391
- checkAuth()
392
- }, [])
393
-
394
- const isAuthenticated = auth.isAuthenticated()
395
-
396
- if (!isAuthenticated) {
397
- return <Navigate to="/login" replace />
398
- }
399
-
400
- return <>{children}</>
401
- }
402
- ```
403
-
404
- ## Error Handling
405
-
406
- ```typescript
407
- import { useEffect, useState } from 'react'
408
- import { OidcAuthService } from '@owlmeans/web-oidc-rp'
409
-
410
- function useOidcErrorHandling() {
411
- const [error, setError] = useState<string | null>(null)
412
- const context = useContext()
413
-
414
- const handleOidcOperation = async (operation: () => Promise<any>) => {
415
- try {
416
- setError(null)
417
- return await operation()
418
- } catch (err) {
419
- const errorMessage = err instanceof Error ? err.message : 'OIDC operation failed'
420
- setError(errorMessage)
421
-
422
- // Log error for debugging
423
- console.error('OIDC Error:', err)
424
-
425
- // Could also send to error reporting service
426
- return null
427
- }
428
- }
429
-
430
- return { error, handleOidcOperation }
431
- }
432
- ```
433
-
434
- ## Integration Patterns
435
-
436
- ### Routing Integration
437
-
438
- ```typescript
439
- import { Routes, Route } from 'react-router-dom'
440
- import { Dispatcher } from '@owlmeans/web-oidc-rp'
441
-
442
- function AppRoutes() {
443
- return (
444
- <Routes>
445
- {/* OIDC callback route */}
446
- <Route path="/auth/oidc/callback" element={<Dispatcher />} />
447
-
448
- {/* Other application routes */}
449
- <Route path="/" element={<HomePage />} />
450
- <Route path="/dashboard" element={<ProtectedDashboard />} />
451
- </Routes>
452
- )
453
- }
454
- ```
455
-
456
- ### State Management Integration
457
-
458
- ```typescript
459
- import { createContext, useContext as useReactContext } from 'react'
460
- import { OidcAuthService } from '@owlmeans/web-oidc-rp'
461
-
462
- const OidcContext = createContext<OidcAuthService | null>(null)
463
-
464
- export function OidcProvider({ children }: { children: React.ReactNode }) {
465
- const context = useContext()
466
- const oidcService = context.service<OidcAuthService>('oidc-rp')
467
-
468
- return (
469
- <OidcContext.Provider value={oidcService}>
470
- {children}
471
- </OidcContext.Provider>
472
- )
473
- }
474
-
475
- export function useOidc() {
476
- const oidcService = useReactContext(OidcContext)
477
- if (!oidcService) {
478
- throw new Error('useOidc must be used within OidcProvider')
479
- }
480
- return oidcService
481
- }
482
- ```
58
+ - `DEFAULT_ALIAS` — `'oidc-rp'`
59
+ - `OidcAuthPurposes` enum: `Unknown`, `Subscribe`, `Login`
483
60
 
484
- ## Best Practices
61
+ ### Components
485
62
 
486
- 1. **Secure Redirects**: Always validate redirect URLs and use HTTPS in production
487
- 2. **State Management**: Properly manage authentication state across page reloads
488
- 3. **Error Handling**: Implement comprehensive error handling for network and authentication failures
489
- 4. **Flow Integration**: Use flows for complex authentication scenarios
490
- 5. **Token Security**: Never expose sensitive tokens in client-side storage
491
- 6. **PKCE Support**: Use PKCE (Proof Key for Code Exchange) for enhanced security
492
- 7. **Callback Validation**: Always validate OIDC callback parameters before processing
63
+ Login and callback React components exported from `./components` (re-exported at root).
493
64
 
494
- ## Dependencies
65
+ ## Product-Viable Integration Notes
495
66
 
496
- This package depends on:
497
- - `@owlmeans/auth` - Authentication framework
498
- - `@owlmeans/client` - Client framework
499
- - `@owlmeans/client-auth` - Client authentication
500
- - `@owlmeans/client-flow` - Client flow management
501
- - `@owlmeans/flow` - Flow system
502
- - `@owlmeans/oidc` - Core OIDC functionality
503
- - `@owlmeans/web-client` - Web client framework
504
- - `@owlmeans/web-flow` - Web flow integration
505
- - `oidc-client-ts` - TypeScript OIDC client library
506
- - `react` - React framework
507
- - `react-router-dom` - React routing
67
+ - Import `@owlmeans/web-oidc-rp/auth/plugins` for side effects to register `OIDC_CLIENT_AUTH` and `GOOGLE_CLIENT_AUTH` with `@owlmeans/client-auth`.
68
+ - The Google plugin uses `useValue`, persists auth control state before redirect, restores it on return, and submits URL query params as `AuthCredentials`.
69
+ - The browser starts login; the server exchanges provider code, links local identity, and returns a normal bearer token.
70
+ - Keep product authorization server-side through module gates and identity profile scopes.
508
71
 
509
72
  ## Related Packages
510
73
 
511
- - [`@owlmeans/server-oidc-rp`](../server-oidc-rp) - Server-side OIDC Relying Party
512
- - [`@owlmeans/oidc`](../oidc) - Core OIDC functionality
513
- - [`@owlmeans/client-auth`](../client-auth) - Client authentication framework
514
- - [`@owlmeans/web-client`](../web-client) - Web client framework
515
- - [`@owlmeans/web-flow`](../web-flow) - Web flow management
74
+ - [`@owlmeans/oidc`](../oidc) — shared `OIDC_GATE`, `OIDC_GUARD`, dispatcher modules
75
+ - [`@owlmeans/web-client`](../web-client) — base web context this guard plugs into
76
+ - [`@owlmeans/mui-panel`](../mui-panel) — `makeContext` typically used as the base
77
+ - [`@owlmeans/client-auth`](../client-auth) — auth manager primitives the guard interacts with
@@ -0,0 +1,5 @@
1
+ import * as React from 'react';
2
+ import * as ProgressPrimitive from '@radix-ui/react-progress';
3
+ declare function Progress({ className, value, ...props }: React.ComponentProps<typeof ProgressPrimitive.Root>): import("react/jsx-runtime").JSX.Element;
4
+ export { Progress };
5
+ //# sourceMappingURL=progress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../../../src/@/components/ui/progress.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,iBAAiB,MAAM,0BAA0B,CAAA;AAI7D,iBAAS,QAAQ,CAAC,EAChB,SAAS,EACT,KAAK,EACL,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,iBAAiB,CAAC,IAAI,CAAC,2CA4BrD;AAED,OAAO,EAAE,QAAQ,EAAE,CAAA"}
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import * as ProgressPrimitive from '@radix-ui/react-progress';
3
+ import { cn } from '@/lib/utils';
4
+ function Progress({ className, value, ...props }) {
5
+ const indeterminate = value == null;
6
+ return (_jsx(ProgressPrimitive.Root, { "data-slot": "progress", className: cn("bg-primary/20 relative h-2 w-full overflow-hidden rounded-full", className), value: indeterminate ? undefined : value, ...props, children: _jsx(ProgressPrimitive.Indicator, { "data-slot": "progress-indicator", "data-state": indeterminate ? 'indeterminate' : 'determinate', className: cn("bg-primary h-full w-full flex-1 transition-all", indeterminate && "absolute inset-y-0 left-0 w-1/3 animate-[progress-indeterminate_1.5s_linear_infinite]"), style: indeterminate
7
+ ? undefined
8
+ : { transform: `translateX(-${100 - (value || 0)}%)` } }) }));
9
+ }
10
+ export { Progress };
11
+ //# sourceMappingURL=progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.js","sourceRoot":"","sources":["../../../../src/@/components/ui/progress.tsx"],"names":[],"mappings":";AAKA,OAAO,KAAK,iBAAiB,MAAM,0BAA0B,CAAA;AAE7D,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AAEhC,SAAS,QAAQ,CAAC,EAChB,SAAS,EACT,KAAK,EACL,GAAG,KAAK,EAC4C;IACpD,MAAM,aAAa,GAAG,KAAK,IAAI,IAAI,CAAA;IAEnC,OAAO,CACL,KAAC,iBAAiB,CAAC,IAAI,iBACX,UAAU,EACpB,SAAS,EAAE,EAAE,CACX,gEAAgE,EAChE,SAAS,CACV,EACD,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,KACpC,KAAK,YAET,KAAC,iBAAiB,CAAC,SAAS,iBAChB,oBAAoB,gBAClB,aAAa,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,aAAa,EAC3D,SAAS,EAAE,EAAE,CACX,gDAAgD,EAChD,aAAa,IAAI,uFAAuF,CACzG,EACD,KAAK,EACH,aAAa;gBACX,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,EAAE,SAAS,EAAE,eAAe,GAAG,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,EAAE,GAE1D,GACqB,CAC1B,CAAA;AACH,CAAC;AAED,OAAO,EAAE,QAAQ,EAAE,CAAA"}
@@ -0,0 +1,3 @@
1
+ import { type ClassValue } from 'clsx';
2
+ export declare function cn(...inputs: ClassValue[]): string;
3
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/@/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAA;AAG5C,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,UAEzC"}
@@ -0,0 +1,6 @@
1
+ import { clsx } from 'clsx';
2
+ import { twMerge } from 'tailwind-merge';
3
+ export function cn(...inputs) {
4
+ return twMerge(clsx(inputs));
5
+ }
6
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/@/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,MAAM,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAExC,MAAM,UAAU,EAAE,CAAC,GAAG,MAAoB;IACxC,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;AAC9B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { AuthenticationPlugin } from '@owlmeans/client-auth/manager/plugins';
2
+ export declare const googleClientPlugin: AuthenticationPlugin;
3
+ //# sourceMappingURL=google-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google-client.d.ts","sourceRoot":"","sources":["../../../src/auth/plugins/google-client.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAA;AAYjF,eAAO,MAAM,kBAAkB,EAAE,oBAgFhC,CAAA"}
@@ -0,0 +1,71 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { AuthenticationStage, CAUTHEN_AUTHEN_TYPED } from '@owlmeans/auth';
3
+ import { DEFAULT_ALIAS as AUTH_SERVICE } from '@owlmeans/client-auth';
4
+ import { GOOGLE_CLIENT_AUTH } from '@owlmeans/oidc';
5
+ import { useContext, useValue } from '@owlmeans/client';
6
+ import { HOME } from '@owlmeans/web-client';
7
+ import { Progress } from '@/components/ui/progress';
8
+ import { extractGoogleUrl, buildCallbackCredentials } from './helpers.js';
9
+ export const googleClientPlugin = {
10
+ type: GOOGLE_CLIENT_AUTH,
11
+ Implementation: Renderer => ({ type, stage, control }) => {
12
+ const context = useContext();
13
+ Renderer = Renderer ?? googleClientPlugin.Renderer;
14
+ useValue(async (cancel) => {
15
+ switch (control.stage) {
16
+ case AuthenticationStage.Init: {
17
+ const hasState = await control.hasPersistentState();
18
+ if (cancel?.current)
19
+ return;
20
+ // Returning from Google redirect — restore state and authenticate
21
+ if (hasState) {
22
+ await control.restore();
23
+ await control.cleanUpState();
24
+ const url = new URL(window.location.href);
25
+ const code = url.searchParams.get('code');
26
+ if (code != null) {
27
+ const auth = buildCallbackCredentials(url.searchParams.toString(), type, control.allowance?.challenge ?? '');
28
+ const token = await control.authenticate(auth);
29
+ if (token.token !== '') {
30
+ const authService = context.service(AUTH_SERVICE);
31
+ await authService.authenticate(token);
32
+ }
33
+ // Navigate to app root after successful authentication
34
+ const [homeUrl] = await context.module(HOME).call({ full: true }) ?? [];
35
+ window.location.href = homeUrl ?? window.location.origin;
36
+ return;
37
+ }
38
+ }
39
+ // Initial request — ask server for Google auth URL
40
+ const [source] = await context.module(CAUTHEN_AUTHEN_TYPED).call({
41
+ full: true, params: { type }
42
+ }) ?? [];
43
+ await control.requestAllowence({ type, source: source ?? '' });
44
+ break;
45
+ }
46
+ case AuthenticationStage.Authenticate: {
47
+ if (cancel?.current)
48
+ return;
49
+ if (control.allowance?.challenge != null) {
50
+ // The server wraps challenge as "source:googleUrl" — extract the URL part
51
+ const [source] = await context.module(CAUTHEN_AUTHEN_TYPED).call({
52
+ full: true, params: { type }
53
+ }) ?? [];
54
+ const url = extractGoogleUrl(control.allowance.challenge, source ?? '');
55
+ // Persist control state before redirect
56
+ await control.persist();
57
+ // Redirect to Google
58
+ document.location.href = url;
59
+ }
60
+ break;
61
+ }
62
+ }
63
+ }, [type, stage]);
64
+ if (Renderer == null) {
65
+ throw new SyntaxError('Renderer is not defined for Google plugin');
66
+ }
67
+ return _jsx(Renderer, { type: type, stage: stage, control: control, params: {} });
68
+ },
69
+ Renderer: () => _jsx(Progress, {})
70
+ };
71
+ //# sourceMappingURL=google-client.js.map