@owlmeans/web-oidc-rp 0.1.1 → 0.1.3
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.
- package/LICENSE +1 -1
- package/README.md +39 -477
- package/build/@/components/ui/progress.d.ts +5 -0
- package/build/@/components/ui/progress.d.ts.map +1 -0
- package/build/@/components/ui/progress.js +11 -0
- package/build/@/components/ui/progress.js.map +1 -0
- package/build/@/lib/utils.d.ts +3 -0
- package/build/@/lib/utils.d.ts.map +1 -0
- package/build/@/lib/utils.js +6 -0
- package/build/@/lib/utils.js.map +1 -0
- package/build/auth/plugins/google-client.d.ts +3 -0
- package/build/auth/plugins/google-client.d.ts.map +1 -0
- package/build/auth/plugins/google-client.js +71 -0
- package/build/auth/plugins/google-client.js.map +1 -0
- package/build/auth/plugins/helpers.d.ts +16 -0
- package/build/auth/plugins/helpers.d.ts.map +1 -0
- package/build/auth/plugins/helpers.js +31 -0
- package/build/auth/plugins/helpers.js.map +1 -0
- package/build/auth/plugins/index.d.ts.map +1 -1
- package/build/auth/plugins/index.js +3 -1
- package/build/auth/plugins/index.js.map +1 -1
- package/build/auth/plugins/oidc-client.d.ts.map +1 -1
- package/build/auth/plugins/oidc-client.js +6 -2
- package/build/auth/plugins/oidc-client.js.map +1 -1
- package/build/guard.d.ts +3 -2
- package/build/guard.d.ts.map +1 -1
- package/build/guard.js +5 -4
- package/build/guard.js.map +1 -1
- package/build/service.d.ts.map +1 -1
- package/build/service.js +12 -3
- package/build/service.js.map +1 -1
- package/build/types.d.ts +6 -0
- package/build/types.d.ts.map +1 -1
- package/components.json +21 -0
- package/package.json +40 -19
- package/src/@/components/ui/progress.tsx +44 -0
- package/src/@/globals.css +17 -0
- package/src/@/lib/utils.ts +6 -0
- package/src/auth/plugins/google-client.tsx +94 -0
- package/src/auth/plugins/helpers.ts +39 -0
- package/src/auth/plugins/index.ts +3 -1
- package/src/auth/plugins/oidc-client.tsx +6 -2
- package/src/guard.ts +13 -10
- package/src/service.ts +13 -3
- package/src/types.ts +7 -0
- package/tests/context.ts +16 -0
- package/tests/google-client.spec.ts +64 -0
- package/tests/tsconfig.json +12 -0
- package/tsconfig.json +9 -11
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2026 OwlMeans Common — Fullstack typescript framework
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -1,515 +1,77 @@
|
|
|
1
1
|
# @owlmeans/web-oidc-rp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Browser-side OIDC relying party — guard, auth service, and React components for OIDC login flows.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Overview
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
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
|
-
|
|
16
|
+
bun add @owlmeans/web-oidc-rp
|
|
34
17
|
```
|
|
35
18
|
|
|
36
|
-
##
|
|
37
|
-
|
|
38
|
-
### Types
|
|
19
|
+
## Usage
|
|
39
20
|
|
|
40
|
-
|
|
41
|
-
Main service interface for web-based OIDC operations.
|
|
21
|
+
Register the guard in your web context:
|
|
42
22
|
|
|
43
23
|
```typescript
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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
|
-
|
|
73
|
-
Configuration interface extending AppConfig.
|
|
34
|
+
Wire OIDC onto module declarations:
|
|
74
35
|
|
|
75
36
|
```typescript
|
|
76
|
-
|
|
77
|
-
```
|
|
37
|
+
import { setupOidcGuard } from '@owlmeans/web-oidc-rp'
|
|
78
38
|
|
|
79
|
-
|
|
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
|
-
|
|
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
|
-
|
|
44
|
+
### `appendOidcGuard<C, T>(context): T`
|
|
104
45
|
|
|
105
|
-
|
|
106
|
-
- `alias`: Service alias (defaults to 'oidc-rp')
|
|
46
|
+
Registers the OIDC guard service on the web context.
|
|
107
47
|
|
|
108
|
-
|
|
48
|
+
### `setupOidcGuard(modules, coguards?, extras?)`
|
|
109
49
|
|
|
110
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
134
|
-
|
|
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
|
-
|
|
61
|
+
### Components
|
|
485
62
|
|
|
486
|
-
|
|
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
|
-
##
|
|
65
|
+
## Product-Viable Integration Notes
|
|
495
66
|
|
|
496
|
-
|
|
497
|
-
-
|
|
498
|
-
-
|
|
499
|
-
-
|
|
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/
|
|
512
|
-
- [`@owlmeans/
|
|
513
|
-
- [`@owlmeans/
|
|
514
|
-
- [`@owlmeans/
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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"}
|