keycloak-api-manager 6.0.1 → 6.0.2

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.
@@ -7,10 +7,7 @@ Core API methods for initializing and managing the Keycloak Admin Client connect
7
7
  - [configure()](#configure)
8
8
  - [setConfig()](#setconfig)
9
9
  - [getToken()](#gettoken)
10
- - [login()](#login)
11
- - [generateAuthorizationUrl()](#generateauthorizationurl)
12
- - [loginPKCE()](#loginpkce)
13
- - [auth()](#auth)
10
+ - [Deprecated OIDC Methods](#deprecated-oidc-methods)
14
11
  - [stop()](#stop)
15
12
 
16
13
  ---
@@ -39,7 +36,7 @@ Authentication configuration object.
39
36
  | `username` | string | 📋 Conditional | Required for `password` grant type |
40
37
  | `password` | string | 📋 Conditional | Required for `password` grant type |
41
38
  | `clientSecret` | string | 📋 Conditional | Required for `client_credentials` grant type |
42
- | `tokenLifeSpan` | number | 📋 Optional | Token refresh interval in seconds (default: 60) |
39
+ | `tokenLifeSpan` | number | 📋 Optional | Token lifespan hint in seconds used to schedule refresh (`tokenLifeSpan / 2`) |
43
40
  | `scope` | string | 📋 Optional | OAuth2 scope (e.g., `'offline_access'` for refresh tokens) |
44
41
 
45
42
  ### Returns
@@ -53,6 +50,7 @@ Authentication configuration object.
53
50
  ```javascript
54
51
  const KeycloakManager = require('keycloak-api-manager');
55
52
 
53
+ // Bootstrap admin session once at startup.
56
54
  await KeycloakManager.configure({
57
55
  baseUrl: 'https://keycloak.example.com:8443',
58
56
  realmName: 'master',
@@ -63,6 +61,7 @@ await KeycloakManager.configure({
63
61
  tokenLifeSpan: 60
64
62
  });
65
63
 
64
+ // All handler calls below reuse the authenticated admin context.
66
65
  console.log('Authenticated successfully');
67
66
  ```
68
67
 
@@ -96,7 +95,10 @@ await KeycloakManager.configure({
96
95
 
97
96
  ### Automatic Token Refresh
98
97
 
99
- When `tokenLifeSpan` is set, the client automatically refreshes the access token before expiration using an internal timer. The refresh happens at `tokenLifeSpan` seconds interval.
98
+ The client automatically refreshes the access token using an internal timer.
99
+
100
+ - If `tokenLifeSpan` is provided and valid, refresh runs at half that interval (`tokenLifeSpan / 2`).
101
+ - If `tokenLifeSpan` is omitted/invalid, a safe fallback interval of 30 seconds is used.
100
102
 
101
103
  ### Error Handling
102
104
 
@@ -139,7 +141,8 @@ Configuration overrides object.
139
141
  | Property | Type | Required | Description |
140
142
  |----------|------|----------|-------------|
141
143
  | `realmName` | string | 📋 Optional | Switch to a different realm context |
142
- | `requestConfig` | object | 📋 Optional | Axios request configuration overrides |
144
+ | `baseUrl` | string | 📋 Optional | Override Keycloak base URL for subsequent calls |
145
+ | `requestConfig` | object | 📋 Optional | HTTP client request overrides forwarded to `@keycloak/keycloak-admin-client` internals (typically Axios). Supported keys depend on the installed admin client version |
143
146
 
144
147
  ### Returns
145
148
 
@@ -170,6 +173,7 @@ const users = await KeycloakManager.users.find({ max: 100 });
170
173
  #### Custom Request Configuration
171
174
 
172
175
  ```javascript
176
+ // Runtime realm switch is immediate and affects subsequent API calls.
173
177
  KeycloakManager.setConfig({
174
178
  realmName: 'my-realm',
175
179
  requestConfig: {
@@ -185,6 +189,7 @@ KeycloakManager.setConfig({
185
189
 
186
190
  - `setConfig()` does NOT perform token/login calls. It only updates the runtime context.
187
191
  - Changing `realmName` affects all subsequent API calls until changed again.
192
+ - Changing `baseUrl` updates the runtime target URL and is normalized (trailing slash removed).
188
193
  - The access token remains valid across realm switches (as long as the authenticated user/service account has permissions).
189
194
 
190
195
  ---
@@ -195,7 +200,7 @@ Retrieve the current access token. Useful for debugging or passing the token to
195
200
 
196
201
  **Syntax:**
197
202
  ```javascript
198
- const token = await KeycloakManager.getToken()
203
+ const { accessToken, refreshToken } = KeycloakManager.getToken()
199
204
  ```
200
205
 
201
206
  ### Parameters
@@ -204,7 +209,7 @@ None
204
209
 
205
210
  ### Returns
206
211
 
207
- **Promise\<string\>** - The current access token (JWT)
212
+ **{ accessToken: string, refreshToken: string }** - Current token pair managed by the client
208
213
 
209
214
  ### Examples
210
215
 
@@ -218,14 +223,15 @@ await KeycloakManager.configure({
218
223
  clientId: 'admin-cli'
219
224
  });
220
225
 
221
- const token = await KeycloakManager.getToken();
222
- console.log('Access Token:', token);
226
+ // Reads token currently managed by the internal refresh loop.
227
+ const { accessToken } = KeycloakManager.getToken();
228
+ console.log('Access Token:', accessToken);
223
229
 
224
230
  // Use token with custom HTTP client
225
231
  const axios = require('axios');
226
232
  const response = await axios.get('https://keycloak.example.com/admin/realms/master', {
227
233
  headers: {
228
- 'Authorization': `Bearer ${token}`
234
+ 'Authorization': `Bearer ${accessToken}`
229
235
  }
230
236
  });
231
237
  ```
@@ -233,382 +239,28 @@ const response = await axios.get('https://keycloak.example.com/admin/realms/mast
233
239
  ### Notes
234
240
 
235
241
  - The returned token is automatically refreshed by the internal timer (if `tokenLifeSpan` was configured).
236
- - Token format is JWT (JSON Web Token).
237
-
238
- ---
239
-
240
- ## auth()
241
-
242
- ⚠️ **DEPRECATED (v6.0.0)** - Use [`keycloak-express-middleware.login()`](https://github.com/smartenv-crs4/keycloak-express-middleware) instead.
243
-
244
- This method will be removed in v7.0.0. For user authentication flows, use `keycloak-express-middleware` v6.1.0+.
245
-
246
- See: [Migration Guide](../guides/PKCE-Login-Flow.md#-migration-to-keycloak-express-middleware-recommended)
247
-
248
- ---
249
-
250
- **Legacy Note:** Backward-compatible alias of `login()`. Use `login()` instead (also deprecated).
251
-
252
- **Syntax:**
253
- ```javascript
254
- await KeycloakManager.auth(credentials)
255
- ```
256
-
257
- ### Returns
258
-
259
- **Promise\<Object\>** - Same response as `login()`
260
-
261
- ---
262
-
263
- ## login()
264
-
265
- ⚠️ **DEPRECATED (v6.0.0)** - Use [`keycloak-express-middleware.login()`](https://github.com/smartenv-crs4/keycloak-express-middleware) instead.
266
-
267
- This method will be removed in v7.0.0. For user authentication flows, use `keycloak-express-middleware` v6.1.0+.
268
-
269
- See: [Migration Guide](../guides/PKCE-Login-Flow.md#-migration-to-keycloak-express-middleware-recommended)
242
+ - `accessToken` is JWT (JSON Web Token). `refreshToken` may be undefined depending on grant/scope.
270
243
 
271
244
  ---
272
245
 
273
- Request tokens from Keycloak via the OIDC token endpoint.
274
-
275
- This method is intended for application-level login/token flows (for users, service clients, or third-party integrations) using this package as a wrapper.
276
-
277
- It does **not** reconfigure or replace the internal admin session created by `configure()`.
278
-
279
- **Syntax:**
280
- ```javascript
281
- await KeycloakManager.login(credentials)
282
- ```
283
-
284
- ### Parameters
285
-
286
- #### credentials (Object) ⚠️ Required
287
-
288
- Form parameters sent to `/protocol/openid-connect/token`.
289
-
290
- Common fields:
246
+ ## Deprecated OIDC Methods
291
247
 
292
- | Property | Type | Required | Description |
293
- |----------|------|----------|-------------|
294
- | `grant_type` | string | ⚠️ Yes | OAuth2 grant type (`password`, `client_credentials`, `refresh_token`, `authorization_code`) |
295
- | `username` | string | 📋 Conditional | Required for `password` grant |
296
- | `password` | string | 📋 Conditional | Required for `password` grant |
297
- | `client_id` | string | 📋 Optional | If omitted, runtime `clientId` from `configure()` is used |
298
- | `client_secret` | string | 📋 Optional | If omitted, runtime `clientSecret` from `configure()` is used |
299
- | `refresh_token` | string | 📋 Conditional | Required for `refresh_token` grant |
300
- | `scope` | string | 📋 Optional | OAuth scopes (e.g. `openid profile email offline_access`) |
301
- | `code` | string | 📋 Conditional | Required for `authorization_code` grant |
302
- | `redirect_uri` | string | 📋 Conditional | Required for `authorization_code` grant |
248
+ The following methods are still available only for backward compatibility and are deprecated since v6.0.0:
303
249
 
304
- ### Returns
250
+ - `auth(credentials)`
251
+ - `login(credentials)`
252
+ - `generateAuthorizationUrl(options)`
253
+ - `loginPKCE(credentials)`
305
254
 
306
- **Promise\<Object\>** - Token payload returned by Keycloak (e.g. `access_token`, `refresh_token`, `expires_in`, `token_type`)
255
+ These methods will be removed in v7.0.0.
307
256
 
308
- ### Examples
257
+ For all user authentication flows (including Authorization Code + PKCE), use keycloak-express-middleware:
309
258
 
310
- #### Resource Owner Password Login
259
+ - https://github.com/smartenv-crs4/keycloak-express-middleware
311
260
 
312
- ```javascript
313
- // Admin setup for wrapper/handlers
314
- await KeycloakManager.configure({
315
- baseUrl: 'https://keycloak.example.com',
316
- realmName: 'master',
317
- username: 'admin',
318
- password: 'admin',
319
- grantType: 'password',
320
- clientId: 'admin-cli'
321
- });
322
-
323
- // Application login/token request for an end-user
324
- const tokenResponse = await KeycloakManager.login({
325
- grant_type: 'password',
326
- username: 'end-user',
327
- password: 'user-password',
328
- scope: 'openid profile email'
329
- });
330
-
331
- console.log(tokenResponse.access_token);
332
- ```
333
-
334
- #### Client Credentials Login
335
-
336
- ```javascript
337
- const tokenResponse = await KeycloakManager.login({
338
- grant_type: 'client_credentials',
339
- client_id: 'my-public-api',
340
- client_secret: process.env.API_CLIENT_SECRET
341
- });
342
-
343
- console.log(tokenResponse.access_token);
344
- ```
345
-
346
- #### Refresh Token Flow
347
-
348
- ```javascript
349
- const refreshed = await KeycloakManager.login({
350
- grant_type: 'refresh_token',
351
- refresh_token: oldRefreshToken
352
- });
353
-
354
- console.log(refreshed.access_token);
355
- ```
356
-
357
- ### Notes
358
-
359
- - `login()` posts to `${baseUrl}/realms/${realmName}/protocol/openid-connect/token`.
360
- - `login()` returns raw token endpoint payload and throws on non-2xx responses.
361
- - `login()`/`auth()` do not change handler wiring, runtime config, or the internal admin refresh timer.
362
- - Runtime `clientId`/`clientSecret` are appended automatically if configured and not overridden in request payload.
363
-
364
- ---
365
-
366
- ## generateAuthorizationUrl()
367
-
368
- ⚠️ **DEPRECATED (v6.0.0)** - Use [`keycloak-express-middleware.generateAuthorizationUrl()`](https://github.com/smartenv-crs4/keycloak-express-middleware) instead.
369
-
370
- This method will be removed in v7.0.0. For PKCE authentication flows, use `keycloak-express-middleware` v6.1.0+.
371
-
372
- See: [Migration Guide](../guides/PKCE-Login-Flow.md#-migration-to-keycloak-express-middleware-recommended)
373
-
374
- ---
375
-
376
- Generate OAuth2 Authorization Code + PKCE flow initialization. Returns a ready-to-use authorization URL and PKCE pair for server-side session storage.
377
-
378
- This helper simplifies the first step of PKCE login: generating the authorization URL with PKCE challenge and state parameter.
379
-
380
- **Syntax:**
381
- ```javascript
382
- const pkceFlow = KeycloakManager.generateAuthorizationUrl(options)
383
- ```
384
-
385
- ### Parameters
386
-
387
- #### options (Object) ⚠️ Required
388
-
389
- | Property | Type | Required | Description |
390
- |----------|------|----------|-------------|
391
- | `redirect_uri` | string | ⚠️ Yes* | Redirect URI where user returns after login |
392
- | `redirectUri` | string | ⚠️ Yes* | CamelCase alias of `redirect_uri` |
393
- | `scope` | string | 📋 Optional | Space-separated scopes (default: `'openid profile email'`) |
394
- | `state` | string | 📋 Optional | Custom state value (auto-generated if not provided) |
395
-
396
- `*` required with either snake_case or camelCase form.
397
-
398
- ### Returns
399
-
400
- **Object** - PKCE flow initialization data:
401
-
402
- ```javascript
403
- {
404
- authUrl: 'https://keycloak.example.com/realms/my-realm/protocol/openid-connect/auth?...',
405
- state: 'random_state_string',
406
- codeVerifier: 'random_code_verifier_string'
407
- }
408
- ```
409
-
410
- - `authUrl`: Ready-to-use authorization URL to redirect user to
411
- - `state`: CSRF token to validate in callback (store in session)
412
- - `codeVerifier`: PKCE proof to exchange for code in callback (store in session, **never expose to client**)
413
-
414
- ### Example
415
-
416
- ```javascript
417
- // Step 1: Generate authorization URL
418
- app.get('/auth/login', (req, res) => {
419
- const pkceFlow = KeycloakManager.generateAuthorizationUrl({
420
- redirect_uri: `${process.env.APP_URL}/auth/callback`,
421
- scope: 'openid profile email'
422
- });
423
-
424
- // Store in session server-side
425
- req.session.pkce_state = pkceFlow.state;
426
- req.session.pkce_verifier = pkceFlow.codeVerifier;
427
-
428
- // Redirect user to Keycloak
429
- res.redirect(pkceFlow.authUrl);
430
- });
431
-
432
- // Step 2: In callback, recover verifier and exchange code
433
- app.get('/auth/callback', async (req, res) => {
434
- const { code, state } = req.query;
435
-
436
- // Validate state
437
- if (state !== req.session.pkce_state) {
438
- return res.status(400).send('CSRF attack detected');
439
- }
440
-
441
- // Exchange code for token
442
- const tokens = await KeycloakManager.loginPKCE({
443
- code,
444
- redirect_uri: `${process.env.APP_URL}/auth/callback`,
445
- code_verifier: req.session.pkce_verifier
446
- });
447
-
448
- // Use tokens...
449
- });
450
- ```
451
-
452
- ### Notes
453
-
454
- - `generateAuthorizationUrl()` does **not** call Keycloak; it generates URLs and PKCE values locally.
455
- - `state` and `codeVerifier` must be stored **server-side only** in session storage, never in cookies or local storage.
456
- - `codeVerifier` must be kept secret and never exposed to the browser.
457
- - `state` provides CSRF protection and must be validated in the callback.
458
- - Uses cryptographically secure random generation for `codeVerifier` and `state`.
459
- - Code challenge is SHA256-hashed (S256 method), not plain text.
460
-
461
- ---
462
-
463
- ## loginPKCE()
464
-
465
- ⚠️ **DEPRECATED (v6.0.0)** - Use [`keycloak-express-middleware.loginPKCE()`](https://github.com/smartenv-crs4/keycloak-express-middleware) instead.
466
-
467
- This method will be removed in v7.0.0. For PKCE authentication flows, use `keycloak-express-middleware` v6.1.0+.
468
-
469
- See: [Migration Guide](../guides/PKCE-Login-Flow.md#-migration-to-keycloak-express-middleware-recommended)
470
-
471
- ---
472
-
473
- Perform Authorization Code + PKCE token exchange.
474
-
475
- This helper is intended for the callback step after user login on Keycloak, where your backend receives an authorization `code` and exchanges it with `code_verifier`.
476
-
477
- > **📖 For a complete step-by-step guide on implementing PKCE flow in your application, see [PKCE Login Flow Guide](../guides/PKCE-Login-Flow.md#-migration-to-keycloak-express-middleware-recommended)**
478
-
479
- **Syntax:**
480
- ```javascript
481
- await KeycloakManager.loginPKCE(credentials)
482
- ```
483
-
484
- ### Parameters
485
-
486
- #### credentials (Object) ⚠️ Required
487
-
488
- | Property | Type | Required | Description |
489
- |----------|------|----------|-------------|
490
- | `code` | string | ⚠️ Yes | Authorization code returned by Keycloak |
491
- | `redirect_uri` | string | ⚠️ Yes* | Redirect URI used in authorize request |
492
- | `redirectUri` | string | ⚠️ Yes* | CamelCase alias of `redirect_uri` |
493
- | `code_verifier` | string | ⚠️ Yes* | PKCE code verifier |
494
- | `codeVerifier` | string | ⚠️ Yes* | CamelCase alias of `code_verifier` |
495
- | `client_id` | string | 📋 Optional | Overrides runtime `clientId` |
496
- | `clientId` | string | 📋 Optional | CamelCase alias of `client_id` |
497
- | `client_secret` | string | 📋 Optional | Overrides runtime `clientSecret` |
498
- | `clientSecret` | string | 📋 Optional | CamelCase alias of `client_secret` |
499
- | `scope` | string | 📋 Optional | Additional scope string |
500
-
501
- `*` required with either snake_case or camelCase form.
502
-
503
- ### Returns
504
-
505
- **Promise\<Object\>** - Token payload returned by Keycloak (`access_token`, `refresh_token`, `id_token`, `expires_in`, ...)
506
-
507
- ### Complete End-to-End Example (Express)
508
-
509
- ```javascript
510
- const crypto = require('crypto');
511
- const express = require('express');
512
- const KeycloakManager = require('keycloak-api-manager');
513
-
514
- const app = express();
515
-
516
- const KEYCLOAK_BASE_URL = 'https://keycloak.example.com';
517
- const REALM = 'my-realm';
518
- const CLIENT_ID = 'my-confidential-client';
519
- const CLIENT_SECRET = process.env.KC_CLIENT_SECRET;
520
- const REDIRECT_URI = 'https://my-app.example.com/auth/callback';
521
-
522
- // Demo in-memory store. In production, use Redis/session storage.
523
- const pkceStore = new Map();
524
-
525
- function base64url(buffer) {
526
- return buffer
527
- .toString('base64')
528
- .replace(/\+/g, '-')
529
- .replace(/\//g, '_')
530
- .replace(/=+$/, '');
531
- }
532
-
533
- function createPkcePair() {
534
- const codeVerifier = base64url(crypto.randomBytes(32));
535
- const codeChallenge = base64url(
536
- crypto.createHash('sha256').update(codeVerifier).digest()
537
- );
538
- const state = base64url(crypto.randomBytes(16));
539
- return { codeVerifier, codeChallenge, state };
540
- }
541
-
542
- async function bootstrap() {
543
- // Configure runtime context so loginPKCE can reuse baseUrl/realm/client credentials
544
- await KeycloakManager.configure({
545
- baseUrl: KEYCLOAK_BASE_URL,
546
- realmName: REALM,
547
- grantType: 'client_credentials',
548
- clientId: CLIENT_ID,
549
- clientSecret: CLIENT_SECRET
550
- });
551
- }
552
-
553
- // 1) Start login flow: generate PKCE and redirect to Keycloak /auth endpoint
554
- app.get('/auth/login', (req, res) => {
555
- const { codeVerifier, codeChallenge, state } = createPkcePair();
556
- pkceStore.set(state, codeVerifier);
557
-
558
- const authorizeUrl =
559
- `${KEYCLOAK_BASE_URL}/realms/${REALM}/protocol/openid-connect/auth` +
560
- `?client_id=${encodeURIComponent(CLIENT_ID)}` +
561
- `&response_type=code` +
562
- `&scope=${encodeURIComponent('openid profile email')}` +
563
- `&redirect_uri=${encodeURIComponent(REDIRECT_URI)}` +
564
- `&code_challenge=${encodeURIComponent(codeChallenge)}` +
565
- `&code_challenge_method=S256` +
566
- `&state=${encodeURIComponent(state)}`;
567
-
568
- res.redirect(authorizeUrl);
569
- });
570
-
571
- // 2) Callback: receive code+state, recover verifier, exchange code for tokens
572
- app.get('/auth/callback', async (req, res) => {
573
- const { code, state } = req.query;
574
- const codeVerifier = pkceStore.get(state);
575
- pkceStore.delete(state);
576
-
577
- if (!code || !state || !codeVerifier) {
578
- return res.status(400).json({ error: 'Invalid PKCE callback parameters' });
579
- }
580
-
581
- try {
582
- const tokenResponse = await KeycloakManager.loginPKCE({
583
- code,
584
- redirectUri: REDIRECT_URI,
585
- codeVerifier
586
- });
587
-
588
- // Usually you create your own app session/JWT here, instead of returning raw tokens
589
- return res.json({
590
- access_token: tokenResponse.access_token,
591
- refresh_token: tokenResponse.refresh_token,
592
- expires_in: tokenResponse.expires_in
593
- });
594
- } catch (error) {
595
- return res.status(401).json({ error: error.message });
596
- }
597
- });
598
-
599
- bootstrap()
600
- .then(() => app.listen(3000, () => console.log('Listening on :3000')))
601
- .catch((error) => {
602
- console.error('Startup error:', error.message);
603
- process.exit(1);
604
- });
605
- ```
606
-
607
- ### Notes
261
+ Migration notes:
608
262
 
609
- - `loginPKCE()` forces `grant_type=authorization_code`.
610
- - If `client_id/client_secret` are omitted, runtime values from `configure()` are used.
611
- - `loginPKCE()` does not generate authorize URLs, `state`, or PKCE challenge; it only performs token exchange.
263
+ - [OIDC Migration Plan](../../OIDC_MIGRATION_PLAN.md)
612
264
 
613
265
  ---
614
266
 
@@ -698,7 +350,7 @@ const KeycloakManager = require('keycloak-api-manager');
698
350
 
699
351
  async function keycloakWorkflow() {
700
352
  try {
701
- // 1. Configure and authenticate
353
+ // 1) Configure and authenticate once.
702
354
  await KeycloakManager.configure({
703
355
  baseUrl: 'https://keycloak.example.com:8443',
704
356
  realmName: 'master',
@@ -710,27 +362,28 @@ async function keycloakWorkflow() {
710
362
  });
711
363
  console.log('✓ Authenticated');
712
364
 
713
- // 2. Work in master realm
365
+ // 2) Run operations in the current realm context.
714
366
  const masterRealms = await KeycloakManager.realms.find();
715
367
  console.log(`✓ Found ${masterRealms.length} realms`);
716
368
 
717
- // 3. Switch to application realm
369
+ // 3) Switch realm context for following API calls.
718
370
  KeycloakManager.setConfig({ realmName: 'my-app' });
719
371
  console.log('✓ Switched to my-app realm');
720
372
 
721
- // 4. Perform operations
373
+ // 4) Execute admin operations in the target realm.
722
374
  const users = await KeycloakManager.users.find({ max: 100 });
723
375
  console.log(`✓ Found ${users.length} users in my-app`);
724
376
 
725
- // 5. Get current token for debugging
726
- const token = await KeycloakManager.getToken();
727
- console.log('✓ Current token:', token.substring(0, 50) + '...');
377
+ // 5) Optionally inspect the token for debugging/integration checks.
378
+ const { accessToken } = KeycloakManager.getToken();
379
+ console.log('✓ Current token:', accessToken.substring(0, 50) + '...');
728
380
 
729
- // 6. Cleanup
381
+ // 6) Always stop refresh timer before process exit.
730
382
  KeycloakManager.stop();
731
383
  console.log('✓ Stopped token refresh');
732
384
 
733
385
  } catch (error) {
386
+ // Ensure timer cleanup also happens on failures.
734
387
  console.error('✗ Error:', error.message);
735
388
  KeycloakManager.stop();
736
389
  process.exit(1);
@@ -4,8 +4,8 @@ Complete API documentation for keycloak-api-manager.
4
4
 
5
5
  ## Table of Contents
6
6
 
7
- ### Guides (Practical Implementation)
8
- - [PKCE Login Flow Guide](guides/PKCE-Login-Flow.md) - Step-by-step OAuth2 Authorization Code + PKCE implementation guide
7
+ ### Guides
8
+ - [OIDC Migration Plan](../OIDC_MIGRATION_PLAN.md) - Deprecation status and migration notes to keycloak-express-middleware
9
9
 
10
10
  ### Core API
11
11
  - [Configuration & Authentication](api/configuration.md) - Setup, authentication, and lifecycle management
@@ -78,11 +78,11 @@ KeycloakManager.stop();
78
78
  |-----------|-------------|--------|
79
79
  | `configure()` | Authentication and setup | Core |
80
80
  | `setConfig()` | Runtime configuration | Core |
81
- | `getToken()` | Get current access token | Core |
82
- | `login()` | Preferred OIDC token grant/login endpoint wrapper | Core |
83
- | `generateAuthorizationUrl()` | Generate PKCE authorization URL and verifier pair | Core |
84
- | `loginPKCE()` | Authorization Code + PKCE token exchange helper | Core |
85
- | `auth()` | Backward-compatible alias of `login()` | Core |
81
+ | `getToken()` | Get current access/refresh token pair | Core |
82
+ | `login()` | Deprecated OIDC token endpoint wrapper (moved to keycloak-express-middleware) | Core |
83
+ | `generateAuthorizationUrl()` | Deprecated PKCE helper (moved to keycloak-express-middleware) | Core |
84
+ | `loginPKCE()` | Deprecated PKCE token exchange helper (moved to keycloak-express-middleware) | Core |
85
+ | `auth()` | Deprecated backward-compatible alias of `login()` | Core |
86
86
  | `stop()` | Stop token refresh timer | Core |
87
87
  | `realms` | Realm management | realmsHandler |
88
88
  | `users` | User management | usersHandler |