docpouch-client 1.1.4 → 1.2.1
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/.github/dependabot.yml +7 -0
- package/README.md +162 -3
- package/coverage/lcov-report/index.html +20 -20
- package/coverage/lcov.info +410 -234
- package/dist/index.d.ts +118 -0
- package/dist/index.js +275 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,6 +12,9 @@ Supports JWT and OIDC (OpenID Connect) authentication.
|
|
|
12
12
|
- [JWT Authentication](#jwt-authentication)
|
|
13
13
|
- [OIDC Authentication](#oidc-authentication)
|
|
14
14
|
- [OIDC Dynamic Client Registration](#oidc-dynamic-client-registration)
|
|
15
|
+
- [Session Management & Auth State](#session-management--auth-state)
|
|
16
|
+
- [Event-Driven Logout](#event-driven-logout)
|
|
17
|
+
- [Convenience OIDC Methods](#convenience-oidc-methods)
|
|
15
18
|
- [User Management](#user-management)
|
|
16
19
|
- [Document Management](#document-management)
|
|
17
20
|
- [Data Structure Management](#data-structure-management)
|
|
@@ -87,6 +90,13 @@ await client.loginWithOidc({
|
|
|
87
90
|
scopes: ['openid', 'profile', 'email']
|
|
88
91
|
});
|
|
89
92
|
|
|
93
|
+
// Set OIDC config after a page reload (before handling the callback)
|
|
94
|
+
client.setOidcConfig({
|
|
95
|
+
issuer: 'https://your-oidc-provider.com',
|
|
96
|
+
clientId: 'your-client-id',
|
|
97
|
+
redirectUri: 'https://yourapp.com/callback'
|
|
98
|
+
});
|
|
99
|
+
|
|
90
100
|
// Handle the OIDC callback on your redirect page
|
|
91
101
|
const handled = await client.handleOidcCallback();
|
|
92
102
|
if (handled) {
|
|
@@ -96,8 +106,22 @@ if (handled) {
|
|
|
96
106
|
// The access token is automatically refreshed when needed
|
|
97
107
|
const validToken = await client.ensureValidOidcToken();
|
|
98
108
|
|
|
99
|
-
// Log out (
|
|
109
|
+
// Log out (for OIDC, redirects to the end-session endpoint)
|
|
100
110
|
await client.logout();
|
|
111
|
+
|
|
112
|
+
// Log out with custom redirect URI and ID token hint
|
|
113
|
+
await client.logout({
|
|
114
|
+
redirectUri: 'https://yourapp.com/logged-out',
|
|
115
|
+
idTokenHint: 'id-token-from-login'
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// Explicit OIDC logout (throws if not authenticated via OIDC)
|
|
119
|
+
await client.logoutOidc({
|
|
120
|
+
redirectUri: 'https://yourapp.com/logged-out'
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// Client-side-only JWT logout (throws if not authenticated via JWT)
|
|
124
|
+
await client.logoutJwt();
|
|
101
125
|
```
|
|
102
126
|
|
|
103
127
|
### OIDC Dynamic Client Registration
|
|
@@ -125,6 +149,88 @@ await client.updateOidcClient('client-id', {
|
|
|
125
149
|
await client.deleteOidcClient('client-id');
|
|
126
150
|
```
|
|
127
151
|
|
|
152
|
+
### Session Management & Auth State
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
// On page load, restore the authentication state automatically.
|
|
156
|
+
// This is the recommended entry point for applications:
|
|
157
|
+
const authState = await client.initAuth();
|
|
158
|
+
// authState: { method: 'jwt' | 'oidc' | 'none', token: string | null, isAdmin: boolean, userName: string }
|
|
159
|
+
|
|
160
|
+
if (authState.method === 'none') {
|
|
161
|
+
// No active session — show login page
|
|
162
|
+
} else {
|
|
163
|
+
// Session restored — proceed with authenticated UI
|
|
164
|
+
console.log(`Authenticated via ${authState.method}`);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Manually persist the current auth method to localStorage
|
|
168
|
+
client.persistAuthMethod('oidc');
|
|
169
|
+
|
|
170
|
+
// Clear all local auth state without redirecting to an OIDC end-session endpoint
|
|
171
|
+
client.clearAuth();
|
|
172
|
+
|
|
173
|
+
// Check whether the user just returned from an OIDC logout redirect
|
|
174
|
+
if (client.wasJustLoggedOut()) {
|
|
175
|
+
console.log('User logged out via OIDC provider');
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Manually restore an OIDC session from localStorage
|
|
179
|
+
const restored = client.restoreOidcSession();
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Event-Driven Logout
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
// Listen for any logout event (JWT or OIDC)
|
|
186
|
+
client.onLogout(() => {
|
|
187
|
+
console.log('User logged out');
|
|
188
|
+
// Redirect to login page, update UI, etc.
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
// Listen specifically for OIDC logout
|
|
192
|
+
client.onOidcLogout(() => {
|
|
193
|
+
console.log('OIDC session ended');
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// Listen specifically for JWT logout
|
|
197
|
+
client.onJwtLogout(() => {
|
|
198
|
+
console.log('JWT session ended');
|
|
199
|
+
});
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Convenience OIDC Methods
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
// Fetch the OIDC client config from the server
|
|
206
|
+
const config = await client.fetchOidcClientConfig();
|
|
207
|
+
if (config) {
|
|
208
|
+
console.log(`OIDC available at ${config.issuer}`);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Fetch the currently authenticated user's profile
|
|
212
|
+
const user = await client.getCurrentUser();
|
|
213
|
+
if (user) {
|
|
214
|
+
console.log(`Hello, ${user.name}`);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Ensure an OIDC client is registered (auto-registers if needed)
|
|
218
|
+
const clientId = await client.ensureOidcClient(
|
|
219
|
+
'https://yourapp.com/callback',
|
|
220
|
+
undefined, // optional registration token
|
|
221
|
+
{ clientName: 'My App', postLogoutRedirectUri: 'https://yourapp.com/' }
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
// One-call OIDC login: fetches config (or registers client) and redirects
|
|
225
|
+
await client.startOidcLogin('optional-registration-token');
|
|
226
|
+
|
|
227
|
+
// Derive the OIDC issuer from the client's baseUrl
|
|
228
|
+
const issuer = client.getOidcIssuer();
|
|
229
|
+
|
|
230
|
+
// Get the post-logout redirect URI stored in localStorage
|
|
231
|
+
const uri = client.getPostLogoutRedirectUri();
|
|
232
|
+
```
|
|
233
|
+
|
|
128
234
|
### User Management
|
|
129
235
|
|
|
130
236
|
```typescript
|
|
@@ -177,7 +283,7 @@ const anonymousDocument = await client.createDocument({
|
|
|
177
283
|
public: false,
|
|
178
284
|
anonymous: true // Document will be owned by admin user
|
|
179
285
|
});
|
|
180
|
-
```
|
|
286
|
+
```
|
|
181
287
|
|
|
182
288
|
### Data Structure Management
|
|
183
289
|
|
|
@@ -263,7 +369,10 @@ Authentication failures (HTTP 401/403) automatically clear the stored JWT token.
|
|
|
263
369
|
- `getToken(): string | null` — Returns the active token (JWT or OIDC)
|
|
264
370
|
- `getAuthMethod(): 'jwt' | 'oidc' | 'none'` — Returns current auth method
|
|
265
371
|
- `isAuthenticated(): boolean` — Checks if the client is authenticated
|
|
266
|
-
- `logout(): Promise<void>` — Clears all tokens and disconnects WebSocket
|
|
372
|
+
- `logout(options?: LogoutOptions): Promise<void>` — Clears all tokens and disconnects WebSocket; for OIDC, redirects to
|
|
373
|
+
the end-session endpoint
|
|
374
|
+
- `logoutOidc(options?: LogoutOptions): Promise<void>` — Explicit OIDC logout (redirects to /end_session)
|
|
375
|
+
- `logoutJwt(): Promise<void>` — Client-side-only JWT logout
|
|
267
376
|
- `getVersion(): string` — Returns the package version
|
|
268
377
|
|
|
269
378
|
**OIDC Authentication**
|
|
@@ -271,6 +380,31 @@ Authentication failures (HTTP 401/403) automatically clear the stored JWT token.
|
|
|
271
380
|
- `loginWithOidc(config: I_OidcConfig): Promise<void>` — Initiates OIDC authorization code flow (PKCE)
|
|
272
381
|
- `handleOidcCallback(): Promise<boolean>` — Handles the OIDC redirect callback
|
|
273
382
|
- `ensureValidOidcToken(): Promise<string>` — Returns a valid OIDC access token, refreshing if needed
|
|
383
|
+
- `setOidcConfig(config: I_OidcConfig): void` — Sets the OIDC configuration for callback handling (use after page
|
|
384
|
+
reload)
|
|
385
|
+
- `fetchOidcClientConfig(): Promise<I_OidcClientConfig | null>` — Fetches OIDC client config from the server
|
|
386
|
+
-
|
|
387
|
+
`ensureOidcClient(redirectUri: string, registrationToken?: string, options?: { clientName?: string; postLogoutRedirectUri?: string }): Promise<string>` —
|
|
388
|
+
Auto-registers or updates an OIDC client
|
|
389
|
+
- `startOidcLogin(registrationToken?: string): Promise<void>` — Convenience method: fetches config and initiates OIDC
|
|
390
|
+
login
|
|
391
|
+
- `getOidcIssuer(): string` — Derives the OIDC issuer URL from the client's baseUrl
|
|
392
|
+
- `getPostLogoutRedirectUri(): string | null` — Returns the stored post-logout redirect URI
|
|
393
|
+
|
|
394
|
+
**Session Management**
|
|
395
|
+
|
|
396
|
+
- `initAuth(): Promise<I_AuthState>` — Restores authentication state (JWT/OIDC) on page load; recommended entry point
|
|
397
|
+
- `clearAuth(): void` — Clears all local auth state without OIDC redirect
|
|
398
|
+
- `restoreOidcSession(): boolean` — Restores OIDC session from localStorage
|
|
399
|
+
- `wasJustLoggedOut(): boolean` — Checks if user just returned from an OIDC logout redirect
|
|
400
|
+
- `persistAuthMethod(method: 'jwt' | 'oidc'): void` — Persists auth method to localStorage
|
|
401
|
+
- `clearPersistedAuthState(): void` — Removes all docpouch localStorage keys
|
|
402
|
+
|
|
403
|
+
**Event-Driven Logout**
|
|
404
|
+
|
|
405
|
+
- `onLogout(callback: () => void): void` — Listen for any logout event
|
|
406
|
+
- `onOidcLogout(callback: () => void): void` — Listen for OIDC-specific logout
|
|
407
|
+
- `onJwtLogout(callback: () => void): void` — Listen for JWT-specific logout
|
|
274
408
|
|
|
275
409
|
**OIDC Dynamic Client Registration**
|
|
276
410
|
|
|
@@ -387,8 +521,31 @@ Authentication failures (HTTP 401/403) automatically clear the stored JWT token.
|
|
|
387
521
|
issuer: string;
|
|
388
522
|
clientId: string;
|
|
389
523
|
redirectUri: string;
|
|
524
|
+
scope?: string;
|
|
390
525
|
scopes?: string[];
|
|
391
526
|
clientSecret?: string;
|
|
527
|
+
postLogoutRedirectUri?: string;
|
|
528
|
+
}
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
### I_OidcClientConfig
|
|
532
|
+
|
|
533
|
+
Extends `I_OidcConfig` with:
|
|
534
|
+
|
|
535
|
+
```typescript
|
|
536
|
+
{
|
|
537
|
+
...I_OidcConfig;
|
|
538
|
+
configured?: boolean;
|
|
539
|
+
apiBaseUrl?: string;
|
|
540
|
+
}
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
### LogoutOptions
|
|
544
|
+
|
|
545
|
+
```typescript
|
|
546
|
+
{
|
|
547
|
+
redirectUri?: string; // Where to redirect after OIDC logout (default: app root)
|
|
548
|
+
idTokenHint?: string; // Optional ID token hint for logout confirmation
|
|
392
549
|
}
|
|
393
550
|
```
|
|
394
551
|
|
|
@@ -421,6 +578,7 @@ Authentication failures (HTTP 401/403) automatically clear the stored JWT token.
|
|
|
421
578
|
{
|
|
422
579
|
client_name: string;
|
|
423
580
|
redirect_uris: string[];
|
|
581
|
+
post_logout_redirect_uris?: string[];
|
|
424
582
|
grant_types?: string[];
|
|
425
583
|
response_types?: string[];
|
|
426
584
|
scope?: string;
|
|
@@ -445,6 +603,7 @@ Authentication failures (HTTP 401/403) automatically clear the stored JWT token.
|
|
|
445
603
|
registration_client_uri?: string;
|
|
446
604
|
client_name?: string;
|
|
447
605
|
redirect_uris?: string[];
|
|
606
|
+
post_logout_redirect_uris?: string[];
|
|
448
607
|
grant_types?: string[];
|
|
449
608
|
response_types?: string[];
|
|
450
609
|
scope?: string;
|
|
@@ -23,30 +23,30 @@
|
|
|
23
23
|
<div class='clearfix'>
|
|
24
24
|
|
|
25
25
|
<div class='fl pad1y space-right2'>
|
|
26
|
-
<span class="strong">
|
|
26
|
+
<span class="strong">56.74% </span>
|
|
27
27
|
<span class="quiet">Statements</span>
|
|
28
|
-
<span class='fraction'>446/
|
|
28
|
+
<span class='fraction'>446/786</span>
|
|
29
29
|
</div>
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
<div class='fl pad1y space-right2'>
|
|
33
|
-
<span class="strong">
|
|
33
|
+
<span class="strong">42.16% </span>
|
|
34
34
|
<span class="quiet">Branches</span>
|
|
35
|
-
<span class='fraction'>234/
|
|
35
|
+
<span class='fraction'>234/555</span>
|
|
36
36
|
</div>
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
<div class='fl pad1y space-right2'>
|
|
40
|
-
<span class="strong">
|
|
40
|
+
<span class="strong">74.59% </span>
|
|
41
41
|
<span class="quiet">Functions</span>
|
|
42
|
-
<span class='fraction'>91/
|
|
42
|
+
<span class='fraction'>91/122</span>
|
|
43
43
|
</div>
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
<div class='fl pad1y space-right2'>
|
|
47
|
-
<span class="strong">
|
|
47
|
+
<span class="strong">59.25% </span>
|
|
48
48
|
<span class="quiet">Lines</span>
|
|
49
|
-
<span class='fraction'>432/
|
|
49
|
+
<span class='fraction'>432/729</span>
|
|
50
50
|
</div>
|
|
51
51
|
|
|
52
52
|
|
|
@@ -79,18 +79,18 @@
|
|
|
79
79
|
</tr>
|
|
80
80
|
</thead>
|
|
81
81
|
<tbody><tr>
|
|
82
|
-
<td class="file
|
|
83
|
-
<td data-value="
|
|
84
|
-
<div class="chart"><div class="cover-fill" style="width:
|
|
82
|
+
<td class="file low" data-value="src"><a href="src/index.html">src</a></td>
|
|
83
|
+
<td data-value="43.13" class="pic low">
|
|
84
|
+
<div class="chart"><div class="cover-fill" style="width: 43%"></div><div class="cover-empty" style="width: 57%"></div></div>
|
|
85
85
|
</td>
|
|
86
|
-
<td data-value="
|
|
87
|
-
<td data-value="
|
|
88
|
-
<td data-value="
|
|
89
|
-
<td data-value="
|
|
90
|
-
<td data-value="
|
|
91
|
-
<td data-value="
|
|
92
|
-
<td data-value="
|
|
93
|
-
<td data-value="
|
|
86
|
+
<td data-value="43.13" class="pct low">43.13%</td>
|
|
87
|
+
<td data-value="466" class="abs low">201/466</td>
|
|
88
|
+
<td data-value="33.9" class="pct low">33.9%</td>
|
|
89
|
+
<td data-value="348" class="abs low">118/348</td>
|
|
90
|
+
<td data-value="66.66" class="pct medium">66.66%</td>
|
|
91
|
+
<td data-value="72" class="abs medium">48/72</td>
|
|
92
|
+
<td data-value="43.4" class="pct low">43.4%</td>
|
|
93
|
+
<td data-value="447" class="abs low">194/447</td>
|
|
94
94
|
</tr>
|
|
95
95
|
|
|
96
96
|
<tr>
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
117
117
|
Code coverage generated by
|
|
118
118
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
119
|
-
at 2026-
|
|
119
|
+
at 2026-07-05T08:03:42.223Z
|
|
120
120
|
</div>
|
|
121
121
|
<script src="prettify.js"></script>
|
|
122
122
|
<script>
|