@dloizides/auth-client 2.0.0 → 2.1.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,68 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.1.0 (2026-05-17)
4
+
5
+ Additive release. Lays the groundwork for the "shrink identity service"
6
+ migration by extracting the OIDC primitives that three apps (BaseClient,
7
+ `apps/erevna-web`, `apps/katalogos-web`) had each duplicated in their own
8
+ `useKeycloakExchange.ts` files. No breaking changes — v2.0 callers continue
9
+ to work unchanged.
10
+
11
+ ### Added
12
+
13
+ #### New `/oidc` sub-path entry
14
+
15
+ - `@dloizides/auth-client/oidc` — Pure OIDC primitives (no React, no hooks).
16
+ Lets non-React consumers tree-shake the `AuthClient` class away entirely.
17
+
18
+ #### OIDC primitives (also re-exported from the main entry)
19
+
20
+ - `fetchDiscoveryDocument({ issuerUrl, http })` — Fetches
21
+ `{issuer}/.well-known/openid-configuration` and caches the result per
22
+ issuer URL for the lifetime of the process. Throws on non-2xx or invalid
23
+ metadata. Cache cleared with `clearDiscoveryCache()` (test-only).
24
+ - `generateCodeVerifier(length?)` — RFC 7636-compliant PKCE verifier
25
+ generator. Defaults to 64 chars; enforces the 43..128 band.
26
+ - `deriveCodeChallenge(verifier)` — `BASE64URL(SHA256(verifier))` via
27
+ `crypto.subtle` (browser + Node 16+). Matches the RFC 7636 Appendix B
28
+ test vector.
29
+ - `generatePkcePair(length?)` — Convenience: fresh verifier + matching S256
30
+ challenge in one call.
31
+ - `exchangeAuthorizationCode({ http, baseUrl, realm, clientId, code,
32
+ redirectUri, codeVerifier })` — POSTs `grant_type=authorization_code` to
33
+ the realm's token endpoint. Returns a normalised `TokenResponse`.
34
+ - `refreshAccessToken({ http, baseUrl, realm, clientId, refreshToken })` —
35
+ POSTs `grant_type=refresh_token`. Same return shape.
36
+
37
+ #### `AuthClient` v2.1 surface
38
+
39
+ - `useDirectKcAuth?: boolean` config flag. Default `false`. When `true`,
40
+ apps can route their PKCE flow through the shared `exchangeAuthorizationCode`
41
+ primitive instead of the proxied identity-api `/auth/login` flow. The
42
+ flag is read-only at runtime via `AuthClient.isDirectMode()` so apps can
43
+ render conditionally on whether they've opted in.
44
+ - `acceptDirectKcTokens(response)` — Persists a `TokenResponse` produced by
45
+ the direct-KC flow into the configured storage, marks the inactivity
46
+ tracker active, and fires `onTokenAcquired`. Use this from the app's
47
+ `useKeycloakExchange.ts` hook after `exchangeAuthorizationCode()` resolves.
48
+ - `acceptDirectKcRefresh(response)` — Same as above but fires
49
+ `onTokenRefreshed` instead. Use after `refreshAccessToken()` swaps.
50
+ - `onTokenAcquired?: (tokens) => void` collaborator — fires after any login
51
+ path (OTP, password, direct-KC) successfully persists a fresh token
52
+ bundle. For app-side analytics/logging only — NOT designed for BFF
53
+ integration (Phase 2 designs that fresh).
54
+ - `onTokenRefreshed?: (tokens) => void` collaborator — fires after any
55
+ refresh (interceptor or direct-KC) persists a fresh bundle.
56
+
57
+ ### Notes
58
+
59
+ - The `useDirectKcAuth` flag is the dormant-path flip mechanism. After v2.1
60
+ ships, apps still default to the proxied path. Per-app cutover (flipping
61
+ the flag to `true`) happens in subsequent steps of the
62
+ shrink-identity-to-tenant-service migration.
63
+ - The proxied `/auth/login`, `/auth/refresh`, `/auth/refresh-cookie` methods
64
+ on `AuthApiClient` are unchanged — production apps still call them.
65
+
3
66
  ## 2.0.0 (2026-05-07)
4
67
 
5
68
  Major release. Extends the realm-aware OIDC core into a single source of truth for every auth surface in the dloizides.com portfolio: web cookies, mobile secure storage, biometric gating, silent token refresh with single-flight, inactivity enforcement, password reset, and sessions management.
@@ -1,3 +1,5 @@
1
+ import { H as HttpClient, T as TokenResponse } from './TokenResponse-CY1CaU2l.mjs';
2
+
1
3
  /**
2
4
  * Tiny dependency-free event emitter for auth lifecycle events.
3
5
  *
@@ -19,39 +21,6 @@ declare class AuthEventEmitter {
19
21
  clear(): void;
20
22
  }
21
23
 
22
- /**
23
- * Minimal HTTP transport the package depends on.
24
- *
25
- * `AuthClient` orchestrates token-related HTTP calls (login, refresh, logout,
26
- * password reset) but doesn't import `fetch` directly — keeping the package
27
- * runtime-agnostic. Consumers wire native fetch, axios, ky, or whatever their
28
- * platform exposes.
29
- */
30
- interface HttpRequest {
31
- url: string;
32
- method: 'GET' | 'POST' | 'DELETE';
33
- headers?: Record<string, string>;
34
- /** When set, body is sent as the request body; serialization is the caller's job. */
35
- body?: string;
36
- /** Browser fetch only — pass through `credentials: 'include'` for cookie auth. */
37
- credentials?: 'include' | 'same-origin' | 'omit';
38
- }
39
- interface HttpResponse {
40
- status: number;
41
- ok: boolean;
42
- /** Parsed body (already JSON-decoded). `undefined` for 204 / empty bodies. */
43
- data?: unknown;
44
- }
45
- type HttpClient = (request: HttpRequest) => Promise<HttpResponse>;
46
- /**
47
- * Wrap the platform's native `fetch` into the package's `HttpClient` shape.
48
- * Decoded JSON when `Content-Type` is JSON, otherwise leaves data undefined.
49
- *
50
- * Errors thrown by `fetch` (network / abort) are NOT swallowed — callers
51
- * decide whether to treat them as session-ending.
52
- */
53
- declare function createFetchHttpClient(fetchImpl: typeof fetch): HttpClient;
54
-
55
24
  /**
56
25
  * Backend session record returned by `GET /me/sessions`.
57
26
  *
@@ -328,6 +297,34 @@ interface AuthClientCollaborators {
328
297
  interceptor?: RefreshInterceptor;
329
298
  inactivityTracker?: InactivityTracker;
330
299
  events?: AuthEventEmitter;
300
+ /**
301
+ * Observability hook fired when a fresh token bundle has been acquired
302
+ * (any login path: OTP, password, or direct-KC PKCE). For app-side
303
+ * analytics/logging only — NOT for BFF integration (Phase 2 designs that
304
+ * fresh).
305
+ */
306
+ onTokenAcquired?: (tokens: AuthTokens) => void;
307
+ /**
308
+ * Observability hook fired when an existing token bundle has been
309
+ * refreshed. For app-side analytics/logging only.
310
+ */
311
+ onTokenRefreshed?: (tokens: AuthTokens) => void;
312
+ }
313
+ /**
314
+ * Direct-to-KC (PKCE) routing flag added in v2.1.0.
315
+ *
316
+ * When `true`, `AuthClient` consumers can route their PKCE auth code through
317
+ * the shared OIDC primitives (`exchangeAuthorizationCodeViaOidc`,
318
+ * `refreshTokensViaOidc`) instead of the proxied identity-api `/auth/login`
319
+ * + `/auth/refresh` flow.
320
+ *
321
+ * Default `false` — v2.0 behavior unchanged.
322
+ *
323
+ * The flag is read-only at runtime (`isDirectMode()`) so apps can render
324
+ * conditionally on whether they've opted in.
325
+ */
326
+ interface DirectKcOptions {
327
+ useDirectKcAuth?: boolean;
331
328
  }
332
329
  interface LoginOptions {
333
330
  /** When true, request `offline_access` scope so the IdP issues a long-lived refresh token. */
@@ -339,15 +336,45 @@ interface LogoutOptions {
339
336
  }
340
337
  declare class AuthClient {
341
338
  private readonly config;
339
+ private readonly directKcAuth;
342
340
  private readonly tokenStorage;
343
341
  private readonly api;
344
342
  private readonly interceptor;
345
343
  private readonly inactivityTracker;
346
344
  private readonly events;
345
+ private readonly onTokenAcquired;
346
+ private readonly onTokenRefreshed;
347
347
  /**
348
348
  * @throws Error when `baseUrl`, `realm`, or `clientId` is missing or empty.
349
349
  */
350
- constructor(config: AuthClientConfig, storage: TokenStorage, collaborators?: AuthClientCollaborators);
350
+ constructor(config: AuthClientConfig & DirectKcOptions, storage: TokenStorage, collaborators?: AuthClientCollaborators);
351
+ /**
352
+ * Whether this client is configured to route auth flows directly to
353
+ * Keycloak (v2.1.0 direct-KC path) instead of through the proxied
354
+ * identity-api `/auth/*` endpoints.
355
+ *
356
+ * Apps can render conditionally on this — e.g. to swap a login form for
357
+ * a "Sign in with Keycloak" redirect button.
358
+ */
359
+ isDirectMode(): boolean;
360
+ /**
361
+ * Persist a token bundle produced by an external flow (e.g. the
362
+ * app-side `useKeycloakExchange` hook that consumes the shared
363
+ * `exchangeAuthorizationCode` primitive). Fires `onTokenAcquired` after
364
+ * persistence and marks the inactivity tracker active.
365
+ *
366
+ * Designed for the v2.1.0 direct-KC path where the PKCE code exchange
367
+ * happens in the app's React-Query hook (which needs `useDispatch`/etc.)
368
+ * but the token persistence + observability should still flow through
369
+ * the shared client.
370
+ */
371
+ acceptDirectKcTokens(response: TokenResponse): Promise<AuthTokens>;
372
+ /**
373
+ * Same as {@link acceptDirectKcTokens} but fires `onTokenRefreshed`.
374
+ * Use after a `refreshAccessToken()` swap to keep observability counts
375
+ * separated between "fresh login" and "silent refresh".
376
+ */
377
+ acceptDirectKcRefresh(response: TokenResponse): Promise<AuthTokens>;
351
378
  /**
352
379
  * Build an {@link AuthClient} from a standalone issuer URL by parsing the
353
380
  * realm and base URL. Useful when migrating from the legacy
@@ -430,4 +457,4 @@ declare class AuthClient {
430
457
  private resolveScope;
431
458
  }
432
459
 
433
- export { type AuthTokens as A, type ForgotPasswordRequest as F, type HttpClient as H, type InactivityStore as I, type LoginOptions as L, type OtpLoginRequest as O, type PasswordLoginRequest as P, type RawAuthLoginResponse as R, type TokenStorage as T, AuthApiClient as a, type AuthApiClientOptions as b, AuthClient as c, type AuthClientCollaborators as d, type AuthClientConfig as e, type AuthClientFromIssuerInput as f, AuthEventEmitter as g, type AuthEventListener as h, type AuthEventName as i, type AuthEventUnsubscribe as j, type AuthSessionInfo as k, type HttpRequest as l, type HttpResponse as m, InactivityTracker as n, type InactivityTrackerOptions as o, type LogoutOptions as p, type RefreshFn as q, RefreshInterceptor as r, type RefreshInterceptorOptions as s, type ResetPasswordRequest as t, createFetchHttpClient as u };
460
+ export { AuthApiClient as A, type DirectKcOptions as D, type ForgotPasswordRequest as F, type InactivityStore as I, type LoginOptions as L, type OtpLoginRequest as O, type PasswordLoginRequest as P, type ResetPasswordRequest as R, type TokenStorage as T, type AuthSessionInfo as a, AuthClient as b, type AuthTokens as c, type AuthApiClientOptions as d, type AuthClientCollaborators as e, type AuthClientConfig as f, type AuthClientFromIssuerInput as g, AuthEventEmitter as h, type AuthEventListener as i, type AuthEventName as j, type AuthEventUnsubscribe as k, InactivityTracker as l, type InactivityTrackerOptions as m, type LogoutOptions as n, type RawAuthLoginResponse as o, type RefreshFn as p, RefreshInterceptor as q, type RefreshInterceptorOptions as r };
@@ -1,3 +1,5 @@
1
+ import { H as HttpClient, T as TokenResponse } from './TokenResponse-CY1CaU2l.js';
2
+
1
3
  /**
2
4
  * Tiny dependency-free event emitter for auth lifecycle events.
3
5
  *
@@ -19,39 +21,6 @@ declare class AuthEventEmitter {
19
21
  clear(): void;
20
22
  }
21
23
 
22
- /**
23
- * Minimal HTTP transport the package depends on.
24
- *
25
- * `AuthClient` orchestrates token-related HTTP calls (login, refresh, logout,
26
- * password reset) but doesn't import `fetch` directly — keeping the package
27
- * runtime-agnostic. Consumers wire native fetch, axios, ky, or whatever their
28
- * platform exposes.
29
- */
30
- interface HttpRequest {
31
- url: string;
32
- method: 'GET' | 'POST' | 'DELETE';
33
- headers?: Record<string, string>;
34
- /** When set, body is sent as the request body; serialization is the caller's job. */
35
- body?: string;
36
- /** Browser fetch only — pass through `credentials: 'include'` for cookie auth. */
37
- credentials?: 'include' | 'same-origin' | 'omit';
38
- }
39
- interface HttpResponse {
40
- status: number;
41
- ok: boolean;
42
- /** Parsed body (already JSON-decoded). `undefined` for 204 / empty bodies. */
43
- data?: unknown;
44
- }
45
- type HttpClient = (request: HttpRequest) => Promise<HttpResponse>;
46
- /**
47
- * Wrap the platform's native `fetch` into the package's `HttpClient` shape.
48
- * Decoded JSON when `Content-Type` is JSON, otherwise leaves data undefined.
49
- *
50
- * Errors thrown by `fetch` (network / abort) are NOT swallowed — callers
51
- * decide whether to treat them as session-ending.
52
- */
53
- declare function createFetchHttpClient(fetchImpl: typeof fetch): HttpClient;
54
-
55
24
  /**
56
25
  * Backend session record returned by `GET /me/sessions`.
57
26
  *
@@ -328,6 +297,34 @@ interface AuthClientCollaborators {
328
297
  interceptor?: RefreshInterceptor;
329
298
  inactivityTracker?: InactivityTracker;
330
299
  events?: AuthEventEmitter;
300
+ /**
301
+ * Observability hook fired when a fresh token bundle has been acquired
302
+ * (any login path: OTP, password, or direct-KC PKCE). For app-side
303
+ * analytics/logging only — NOT for BFF integration (Phase 2 designs that
304
+ * fresh).
305
+ */
306
+ onTokenAcquired?: (tokens: AuthTokens) => void;
307
+ /**
308
+ * Observability hook fired when an existing token bundle has been
309
+ * refreshed. For app-side analytics/logging only.
310
+ */
311
+ onTokenRefreshed?: (tokens: AuthTokens) => void;
312
+ }
313
+ /**
314
+ * Direct-to-KC (PKCE) routing flag added in v2.1.0.
315
+ *
316
+ * When `true`, `AuthClient` consumers can route their PKCE auth code through
317
+ * the shared OIDC primitives (`exchangeAuthorizationCodeViaOidc`,
318
+ * `refreshTokensViaOidc`) instead of the proxied identity-api `/auth/login`
319
+ * + `/auth/refresh` flow.
320
+ *
321
+ * Default `false` — v2.0 behavior unchanged.
322
+ *
323
+ * The flag is read-only at runtime (`isDirectMode()`) so apps can render
324
+ * conditionally on whether they've opted in.
325
+ */
326
+ interface DirectKcOptions {
327
+ useDirectKcAuth?: boolean;
331
328
  }
332
329
  interface LoginOptions {
333
330
  /** When true, request `offline_access` scope so the IdP issues a long-lived refresh token. */
@@ -339,15 +336,45 @@ interface LogoutOptions {
339
336
  }
340
337
  declare class AuthClient {
341
338
  private readonly config;
339
+ private readonly directKcAuth;
342
340
  private readonly tokenStorage;
343
341
  private readonly api;
344
342
  private readonly interceptor;
345
343
  private readonly inactivityTracker;
346
344
  private readonly events;
345
+ private readonly onTokenAcquired;
346
+ private readonly onTokenRefreshed;
347
347
  /**
348
348
  * @throws Error when `baseUrl`, `realm`, or `clientId` is missing or empty.
349
349
  */
350
- constructor(config: AuthClientConfig, storage: TokenStorage, collaborators?: AuthClientCollaborators);
350
+ constructor(config: AuthClientConfig & DirectKcOptions, storage: TokenStorage, collaborators?: AuthClientCollaborators);
351
+ /**
352
+ * Whether this client is configured to route auth flows directly to
353
+ * Keycloak (v2.1.0 direct-KC path) instead of through the proxied
354
+ * identity-api `/auth/*` endpoints.
355
+ *
356
+ * Apps can render conditionally on this — e.g. to swap a login form for
357
+ * a "Sign in with Keycloak" redirect button.
358
+ */
359
+ isDirectMode(): boolean;
360
+ /**
361
+ * Persist a token bundle produced by an external flow (e.g. the
362
+ * app-side `useKeycloakExchange` hook that consumes the shared
363
+ * `exchangeAuthorizationCode` primitive). Fires `onTokenAcquired` after
364
+ * persistence and marks the inactivity tracker active.
365
+ *
366
+ * Designed for the v2.1.0 direct-KC path where the PKCE code exchange
367
+ * happens in the app's React-Query hook (which needs `useDispatch`/etc.)
368
+ * but the token persistence + observability should still flow through
369
+ * the shared client.
370
+ */
371
+ acceptDirectKcTokens(response: TokenResponse): Promise<AuthTokens>;
372
+ /**
373
+ * Same as {@link acceptDirectKcTokens} but fires `onTokenRefreshed`.
374
+ * Use after a `refreshAccessToken()` swap to keep observability counts
375
+ * separated between "fresh login" and "silent refresh".
376
+ */
377
+ acceptDirectKcRefresh(response: TokenResponse): Promise<AuthTokens>;
351
378
  /**
352
379
  * Build an {@link AuthClient} from a standalone issuer URL by parsing the
353
380
  * realm and base URL. Useful when migrating from the legacy
@@ -430,4 +457,4 @@ declare class AuthClient {
430
457
  private resolveScope;
431
458
  }
432
459
 
433
- export { type AuthTokens as A, type ForgotPasswordRequest as F, type HttpClient as H, type InactivityStore as I, type LoginOptions as L, type OtpLoginRequest as O, type PasswordLoginRequest as P, type RawAuthLoginResponse as R, type TokenStorage as T, AuthApiClient as a, type AuthApiClientOptions as b, AuthClient as c, type AuthClientCollaborators as d, type AuthClientConfig as e, type AuthClientFromIssuerInput as f, AuthEventEmitter as g, type AuthEventListener as h, type AuthEventName as i, type AuthEventUnsubscribe as j, type AuthSessionInfo as k, type HttpRequest as l, type HttpResponse as m, InactivityTracker as n, type InactivityTrackerOptions as o, type LogoutOptions as p, type RefreshFn as q, RefreshInterceptor as r, type RefreshInterceptorOptions as s, type ResetPasswordRequest as t, createFetchHttpClient as u };
460
+ export { AuthApiClient as A, type DirectKcOptions as D, type ForgotPasswordRequest as F, type InactivityStore as I, type LoginOptions as L, type OtpLoginRequest as O, type PasswordLoginRequest as P, type ResetPasswordRequest as R, type TokenStorage as T, type AuthSessionInfo as a, AuthClient as b, type AuthTokens as c, type AuthApiClientOptions as d, type AuthClientCollaborators as e, type AuthClientConfig as f, type AuthClientFromIssuerInput as g, AuthEventEmitter as h, type AuthEventListener as i, type AuthEventName as j, type AuthEventUnsubscribe as k, InactivityTracker as l, type InactivityTrackerOptions as m, type LogoutOptions as n, type RawAuthLoginResponse as o, type RefreshFn as p, RefreshInterceptor as q, type RefreshInterceptorOptions as r };
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Minimal HTTP transport the package depends on.
3
+ *
4
+ * `AuthClient` orchestrates token-related HTTP calls (login, refresh, logout,
5
+ * password reset) but doesn't import `fetch` directly — keeping the package
6
+ * runtime-agnostic. Consumers wire native fetch, axios, ky, or whatever their
7
+ * platform exposes.
8
+ */
9
+ interface HttpRequest {
10
+ url: string;
11
+ method: 'GET' | 'POST' | 'DELETE';
12
+ headers?: Record<string, string>;
13
+ /** When set, body is sent as the request body; serialization is the caller's job. */
14
+ body?: string;
15
+ /** Browser fetch only — pass through `credentials: 'include'` for cookie auth. */
16
+ credentials?: 'include' | 'same-origin' | 'omit';
17
+ }
18
+ interface HttpResponse {
19
+ status: number;
20
+ ok: boolean;
21
+ /** Parsed body (already JSON-decoded). `undefined` for 204 / empty bodies. */
22
+ data?: unknown;
23
+ }
24
+ type HttpClient = (request: HttpRequest) => Promise<HttpResponse>;
25
+ /**
26
+ * Wrap the platform's native `fetch` into the package's `HttpClient` shape.
27
+ * Decoded JSON when `Content-Type` is JSON, otherwise leaves data undefined.
28
+ *
29
+ * Errors thrown by `fetch` (network / abort) are NOT swallowed — callers
30
+ * decide whether to treat them as session-ending.
31
+ */
32
+ declare function createFetchHttpClient(fetchImpl: typeof fetch): HttpClient;
33
+
34
+ /**
35
+ * Raw token endpoint response (snake_case, OIDC standard).
36
+ */
37
+ interface RawTokenResponse {
38
+ access_token: string;
39
+ refresh_token?: string;
40
+ id_token?: string;
41
+ expires_in?: number;
42
+ token_type?: string;
43
+ scope?: string;
44
+ [key: string]: unknown;
45
+ }
46
+ /**
47
+ * Application-friendly camelCase view of a token endpoint response.
48
+ */
49
+ interface TokenResponse {
50
+ accessToken: string;
51
+ refreshToken?: string;
52
+ idToken?: string;
53
+ /** Seconds until expiry, as returned by Keycloak. */
54
+ expiresIn?: number;
55
+ tokenType?: string;
56
+ scope?: string;
57
+ }
58
+
59
+ export { type HttpClient as H, type RawTokenResponse as R, type TokenResponse as T, type HttpRequest as a, type HttpResponse as b, createFetchHttpClient as c };
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Minimal HTTP transport the package depends on.
3
+ *
4
+ * `AuthClient` orchestrates token-related HTTP calls (login, refresh, logout,
5
+ * password reset) but doesn't import `fetch` directly — keeping the package
6
+ * runtime-agnostic. Consumers wire native fetch, axios, ky, or whatever their
7
+ * platform exposes.
8
+ */
9
+ interface HttpRequest {
10
+ url: string;
11
+ method: 'GET' | 'POST' | 'DELETE';
12
+ headers?: Record<string, string>;
13
+ /** When set, body is sent as the request body; serialization is the caller's job. */
14
+ body?: string;
15
+ /** Browser fetch only — pass through `credentials: 'include'` for cookie auth. */
16
+ credentials?: 'include' | 'same-origin' | 'omit';
17
+ }
18
+ interface HttpResponse {
19
+ status: number;
20
+ ok: boolean;
21
+ /** Parsed body (already JSON-decoded). `undefined` for 204 / empty bodies. */
22
+ data?: unknown;
23
+ }
24
+ type HttpClient = (request: HttpRequest) => Promise<HttpResponse>;
25
+ /**
26
+ * Wrap the platform's native `fetch` into the package's `HttpClient` shape.
27
+ * Decoded JSON when `Content-Type` is JSON, otherwise leaves data undefined.
28
+ *
29
+ * Errors thrown by `fetch` (network / abort) are NOT swallowed — callers
30
+ * decide whether to treat them as session-ending.
31
+ */
32
+ declare function createFetchHttpClient(fetchImpl: typeof fetch): HttpClient;
33
+
34
+ /**
35
+ * Raw token endpoint response (snake_case, OIDC standard).
36
+ */
37
+ interface RawTokenResponse {
38
+ access_token: string;
39
+ refresh_token?: string;
40
+ id_token?: string;
41
+ expires_in?: number;
42
+ token_type?: string;
43
+ scope?: string;
44
+ [key: string]: unknown;
45
+ }
46
+ /**
47
+ * Application-friendly camelCase view of a token endpoint response.
48
+ */
49
+ interface TokenResponse {
50
+ accessToken: string;
51
+ refreshToken?: string;
52
+ idToken?: string;
53
+ /** Seconds until expiry, as returned by Keycloak. */
54
+ expiresIn?: number;
55
+ tokenType?: string;
56
+ scope?: string;
57
+ }
58
+
59
+ export { type HttpClient as H, type RawTokenResponse as R, type TokenResponse as T, type HttpRequest as a, type HttpResponse as b, createFetchHttpClient as c };
package/dist/index.d.mts CHANGED
@@ -1,5 +1,8 @@
1
- import { T as TokenStorage, A as AuthTokens } from './AuthClient-Dim7HPRz.mjs';
2
- export { a as AuthApiClient, b as AuthApiClientOptions, c as AuthClient, d as AuthClientCollaborators, e as AuthClientConfig, f as AuthClientFromIssuerInput, g as AuthEventEmitter, h as AuthEventListener, i as AuthEventName, j as AuthEventUnsubscribe, k as AuthSessionInfo, F as ForgotPasswordRequest, H as HttpClient, l as HttpRequest, m as HttpResponse, I as InactivityStore, n as InactivityTracker, o as InactivityTrackerOptions, L as LoginOptions, p as LogoutOptions, O as OtpLoginRequest, P as PasswordLoginRequest, R as RawAuthLoginResponse, q as RefreshFn, r as RefreshInterceptor, s as RefreshInterceptorOptions, t as ResetPasswordRequest, u as createFetchHttpClient } from './AuthClient-Dim7HPRz.mjs';
1
+ import { T as TokenStorage, c as AuthTokens } from './AuthClient-BGr8L03W.mjs';
2
+ export { A as AuthApiClient, d as AuthApiClientOptions, b as AuthClient, e as AuthClientCollaborators, f as AuthClientConfig, g as AuthClientFromIssuerInput, h as AuthEventEmitter, i as AuthEventListener, j as AuthEventName, k as AuthEventUnsubscribe, a as AuthSessionInfo, D as DirectKcOptions, F as ForgotPasswordRequest, I as InactivityStore, l as InactivityTracker, m as InactivityTrackerOptions, L as LoginOptions, n as LogoutOptions, O as OtpLoginRequest, P as PasswordLoginRequest, o as RawAuthLoginResponse, p as RefreshFn, q as RefreshInterceptor, r as RefreshInterceptorOptions, R as ResetPasswordRequest } from './AuthClient-BGr8L03W.mjs';
3
+ export { ExchangeAuthorizationCodeInput, FetchDiscoveryDocumentInput, OidcDiscoveryDocument, PkcePair, RefreshAccessTokenInput, clearDiscoveryCache, deriveCodeChallenge, exchangeAuthorizationCode, fetchDiscoveryDocument, generateCodeVerifier, generatePkcePair, refreshAccessToken } from './oidc/index.mjs';
4
+ import { R as RawTokenResponse, T as TokenResponse } from './TokenResponse-CY1CaU2l.mjs';
5
+ export { H as HttpClient, a as HttpRequest, b as HttpResponse, c as createFetchHttpClient } from './TokenResponse-CY1CaU2l.mjs';
3
6
 
4
7
  /**
5
8
  * Roles emitted by Keycloak realms in the dloizides.com portfolio.
@@ -65,31 +68,6 @@ interface NormalizedUser {
65
68
  raw?: KeycloakUserInfo;
66
69
  }
67
70
 
68
- /**
69
- * Raw token endpoint response (snake_case, OIDC standard).
70
- */
71
- interface RawTokenResponse {
72
- access_token: string;
73
- refresh_token?: string;
74
- id_token?: string;
75
- expires_in?: number;
76
- token_type?: string;
77
- scope?: string;
78
- [key: string]: unknown;
79
- }
80
- /**
81
- * Application-friendly camelCase view of a token endpoint response.
82
- */
83
- interface TokenResponse {
84
- accessToken: string;
85
- refreshToken?: string;
86
- idToken?: string;
87
- /** Seconds until expiry, as returned by Keycloak. */
88
- expiresIn?: number;
89
- tokenType?: string;
90
- scope?: string;
91
- }
92
-
93
71
  /**
94
72
  * Subset of `Storage` we actually use. Lets callers inject `localStorage`,
95
73
  * `sessionStorage`, or any compatible polyfill.
@@ -510,4 +488,4 @@ declare function normalizeTokenResponse(raw: RawTokenResponse): TokenResponse;
510
488
  */
511
489
  declare function tokenResponseToAuthTokens(response: TokenResponse, now?: number): AuthTokens;
512
490
 
513
- export { AuthTokens, type AuthorizationCodeBodyInput, type AuthorizationResponseLike, type AuthorizationUrlInput, type BiometricFlagStore, BiometricGate, type BiometricGateLike, type BiometricGateOptions, BrowserStorageTokenStorage, type BrowserStorageTokenStorageOptions, CookieTokenStorage, InMemoryTokenStorage, KeycloakRoles, type KeycloakUserInfo, type LocalAuthLike, type NormalizedUser, type RawTokenResponse, type RefreshTokenBodyInput, type SecureStoreLike, SecureStoreTokenStorage, type SecureStoreTokenStorageOptions, type StorageLike, type TokenResponse, TokenStorage, buildAuthorizationCodeBody, buildAuthorizationEndpoint, buildAuthorizationUrl, buildIssuerUrl, buildLogoutEndpoint, buildRefreshTokenBody, buildTokenEndpoint, buildUserInfoEndpoint, computeExpiresAt, decodeJwt, extractAuthCode, isKeycloakRole, isTokenExpired, normalizeKeycloakUser, normalizeTokenResponse, parseBaseUrlFromIssuer, parseRealmFromIssuer, tokenResponseToAuthTokens };
491
+ export { AuthTokens, type AuthorizationCodeBodyInput, type AuthorizationResponseLike, type AuthorizationUrlInput, type BiometricFlagStore, BiometricGate, type BiometricGateLike, type BiometricGateOptions, BrowserStorageTokenStorage, type BrowserStorageTokenStorageOptions, CookieTokenStorage, InMemoryTokenStorage, KeycloakRoles, type KeycloakUserInfo, type LocalAuthLike, type NormalizedUser, RawTokenResponse, type RefreshTokenBodyInput, type SecureStoreLike, SecureStoreTokenStorage, type SecureStoreTokenStorageOptions, type StorageLike, TokenResponse, TokenStorage, buildAuthorizationCodeBody, buildAuthorizationEndpoint, buildAuthorizationUrl, buildIssuerUrl, buildLogoutEndpoint, buildRefreshTokenBody, buildTokenEndpoint, buildUserInfoEndpoint, computeExpiresAt, decodeJwt, extractAuthCode, isKeycloakRole, isTokenExpired, normalizeKeycloakUser, normalizeTokenResponse, parseBaseUrlFromIssuer, parseRealmFromIssuer, tokenResponseToAuthTokens };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,8 @@
1
- import { T as TokenStorage, A as AuthTokens } from './AuthClient-Dim7HPRz.js';
2
- export { a as AuthApiClient, b as AuthApiClientOptions, c as AuthClient, d as AuthClientCollaborators, e as AuthClientConfig, f as AuthClientFromIssuerInput, g as AuthEventEmitter, h as AuthEventListener, i as AuthEventName, j as AuthEventUnsubscribe, k as AuthSessionInfo, F as ForgotPasswordRequest, H as HttpClient, l as HttpRequest, m as HttpResponse, I as InactivityStore, n as InactivityTracker, o as InactivityTrackerOptions, L as LoginOptions, p as LogoutOptions, O as OtpLoginRequest, P as PasswordLoginRequest, R as RawAuthLoginResponse, q as RefreshFn, r as RefreshInterceptor, s as RefreshInterceptorOptions, t as ResetPasswordRequest, u as createFetchHttpClient } from './AuthClient-Dim7HPRz.js';
1
+ import { T as TokenStorage, c as AuthTokens } from './AuthClient-D95OMajD.js';
2
+ export { A as AuthApiClient, d as AuthApiClientOptions, b as AuthClient, e as AuthClientCollaborators, f as AuthClientConfig, g as AuthClientFromIssuerInput, h as AuthEventEmitter, i as AuthEventListener, j as AuthEventName, k as AuthEventUnsubscribe, a as AuthSessionInfo, D as DirectKcOptions, F as ForgotPasswordRequest, I as InactivityStore, l as InactivityTracker, m as InactivityTrackerOptions, L as LoginOptions, n as LogoutOptions, O as OtpLoginRequest, P as PasswordLoginRequest, o as RawAuthLoginResponse, p as RefreshFn, q as RefreshInterceptor, r as RefreshInterceptorOptions, R as ResetPasswordRequest } from './AuthClient-D95OMajD.js';
3
+ export { ExchangeAuthorizationCodeInput, FetchDiscoveryDocumentInput, OidcDiscoveryDocument, PkcePair, RefreshAccessTokenInput, clearDiscoveryCache, deriveCodeChallenge, exchangeAuthorizationCode, fetchDiscoveryDocument, generateCodeVerifier, generatePkcePair, refreshAccessToken } from './oidc/index.js';
4
+ import { R as RawTokenResponse, T as TokenResponse } from './TokenResponse-CY1CaU2l.js';
5
+ export { H as HttpClient, a as HttpRequest, b as HttpResponse, c as createFetchHttpClient } from './TokenResponse-CY1CaU2l.js';
3
6
 
4
7
  /**
5
8
  * Roles emitted by Keycloak realms in the dloizides.com portfolio.
@@ -65,31 +68,6 @@ interface NormalizedUser {
65
68
  raw?: KeycloakUserInfo;
66
69
  }
67
70
 
68
- /**
69
- * Raw token endpoint response (snake_case, OIDC standard).
70
- */
71
- interface RawTokenResponse {
72
- access_token: string;
73
- refresh_token?: string;
74
- id_token?: string;
75
- expires_in?: number;
76
- token_type?: string;
77
- scope?: string;
78
- [key: string]: unknown;
79
- }
80
- /**
81
- * Application-friendly camelCase view of a token endpoint response.
82
- */
83
- interface TokenResponse {
84
- accessToken: string;
85
- refreshToken?: string;
86
- idToken?: string;
87
- /** Seconds until expiry, as returned by Keycloak. */
88
- expiresIn?: number;
89
- tokenType?: string;
90
- scope?: string;
91
- }
92
-
93
71
  /**
94
72
  * Subset of `Storage` we actually use. Lets callers inject `localStorage`,
95
73
  * `sessionStorage`, or any compatible polyfill.
@@ -510,4 +488,4 @@ declare function normalizeTokenResponse(raw: RawTokenResponse): TokenResponse;
510
488
  */
511
489
  declare function tokenResponseToAuthTokens(response: TokenResponse, now?: number): AuthTokens;
512
490
 
513
- export { AuthTokens, type AuthorizationCodeBodyInput, type AuthorizationResponseLike, type AuthorizationUrlInput, type BiometricFlagStore, BiometricGate, type BiometricGateLike, type BiometricGateOptions, BrowserStorageTokenStorage, type BrowserStorageTokenStorageOptions, CookieTokenStorage, InMemoryTokenStorage, KeycloakRoles, type KeycloakUserInfo, type LocalAuthLike, type NormalizedUser, type RawTokenResponse, type RefreshTokenBodyInput, type SecureStoreLike, SecureStoreTokenStorage, type SecureStoreTokenStorageOptions, type StorageLike, type TokenResponse, TokenStorage, buildAuthorizationCodeBody, buildAuthorizationEndpoint, buildAuthorizationUrl, buildIssuerUrl, buildLogoutEndpoint, buildRefreshTokenBody, buildTokenEndpoint, buildUserInfoEndpoint, computeExpiresAt, decodeJwt, extractAuthCode, isKeycloakRole, isTokenExpired, normalizeKeycloakUser, normalizeTokenResponse, parseBaseUrlFromIssuer, parseRealmFromIssuer, tokenResponseToAuthTokens };
491
+ export { AuthTokens, type AuthorizationCodeBodyInput, type AuthorizationResponseLike, type AuthorizationUrlInput, type BiometricFlagStore, BiometricGate, type BiometricGateLike, type BiometricGateOptions, BrowserStorageTokenStorage, type BrowserStorageTokenStorageOptions, CookieTokenStorage, InMemoryTokenStorage, KeycloakRoles, type KeycloakUserInfo, type LocalAuthLike, type NormalizedUser, RawTokenResponse, type RefreshTokenBodyInput, type SecureStoreLike, SecureStoreTokenStorage, type SecureStoreTokenStorageOptions, type StorageLike, TokenResponse, TokenStorage, buildAuthorizationCodeBody, buildAuthorizationEndpoint, buildAuthorizationUrl, buildIssuerUrl, buildLogoutEndpoint, buildRefreshTokenBody, buildTokenEndpoint, buildUserInfoEndpoint, computeExpiresAt, decodeJwt, extractAuthCode, isKeycloakRole, isTokenExpired, normalizeKeycloakUser, normalizeTokenResponse, parseBaseUrlFromIssuer, parseRealmFromIssuer, tokenResponseToAuthTokens };