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.
@@ -0,0 +1,7 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "npm"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ open-pull-requests-limit: 10
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 (clears tokens, disconnects WebSocket, cleans up URL params)
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">63.89% </span>
26
+ <span class="strong">56.74% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>446/698</span>
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">48.54% </span>
33
+ <span class="strong">42.16% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>234/482</span>
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">80.53% </span>
40
+ <span class="strong">74.59% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>91/113</span>
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">67.08% </span>
47
+ <span class="strong">59.25% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>432/644</span>
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 medium" data-value="src"><a href="src/index.html">src</a></td>
83
- <td data-value="53.17" class="pic medium">
84
- <div class="chart"><div class="cover-fill" style="width: 53%"></div><div class="cover-empty" style="width: 47%"></div></div>
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="53.17" class="pct medium">53.17%</td>
87
- <td data-value="378" class="abs medium">201/378</td>
88
- <td data-value="42.9" class="pct low">42.9%</td>
89
- <td data-value="275" class="abs low">118/275</td>
90
- <td data-value="76.19" class="pct medium">76.19%</td>
91
- <td data-value="63" class="abs medium">48/63</td>
92
- <td data-value="53.59" class="pct medium">53.59%</td>
93
- <td data-value="362" class="abs medium">194/362</td>
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-06-08T21:00:52.221Z
119
+ at 2026-07-05T08:03:42.223Z
120
120
  </div>
121
121
  <script src="prettify.js"></script>
122
122
  <script>