@dloizides/auth-client 2.0.0 → 3.0.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/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 { H as HttpClient, R as RawTokenResponse, T as TokenResponse } from './TokenResponse-CY1CaU2l.mjs';
5
+ export { 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.
@@ -337,6 +315,109 @@ declare class BiometricGate {
337
315
  unlock(): Promise<void>;
338
316
  }
339
317
 
318
+ /** Credentials posted to `POST /bff/login`. */
319
+ interface BffLoginRequest {
320
+ username: string;
321
+ password: string;
322
+ }
323
+ /** Payload for `POST /bff/register` — proxied by the BFF to TenantService. */
324
+ interface BffRegisterRequest {
325
+ firstName: string;
326
+ lastName: string;
327
+ username: string;
328
+ email: string;
329
+ password: string;
330
+ tenantName: string;
331
+ [key: string]: unknown;
332
+ }
333
+ /** Payload for `POST /bff/forgot-password` — proxied to TenantService. */
334
+ interface BffForgotPasswordRequest {
335
+ email: string;
336
+ /** Full URL with a `{token}` placeholder; the backend substitutes the token. */
337
+ resetUrlTemplate?: string;
338
+ [key: string]: unknown;
339
+ }
340
+ /** Payload for `POST /bff/reset-password` — proxied to TenantService. */
341
+ interface BffResetPasswordRequest {
342
+ token: string;
343
+ newPassword: string;
344
+ }
345
+ /**
346
+ * The user object returned by `GET /bff/me` and `POST /bff/login`. The BFF
347
+ * returns the sanitised KC claims under a `user` envelope and **never** a
348
+ * token. Kept permissive so server-added claims flow through without a bump.
349
+ */
350
+ interface BffUser {
351
+ sub?: string;
352
+ email?: string;
353
+ email_verified?: boolean;
354
+ name?: string;
355
+ preferred_username?: string;
356
+ given_name?: string;
357
+ family_name?: string;
358
+ tenantId?: string;
359
+ roles?: string[];
360
+ [key: string]: unknown;
361
+ }
362
+ interface BffAuthClientOptions {
363
+ /** Runtime-agnostic HTTP transport (wrap native `fetch` with `createFetchHttpClient`). */
364
+ http: HttpClient;
365
+ /**
366
+ * BFF origin. Defaults to `''` (same-origin) — the production wiring. An
367
+ * explicit origin is only useful for tests or a non-same-origin BFF.
368
+ */
369
+ baseUrl?: string;
370
+ }
371
+ /**
372
+ * Same-origin client for a per-app BFF.
373
+ *
374
+ * No token storage, no refresh logic, no realm awareness — the BFF owns all of
375
+ * that server-side. The browser's only auth artefact is the httpOnly cookie.
376
+ */
377
+ declare class BffAuthClient {
378
+ private readonly http;
379
+ private readonly baseUrl;
380
+ constructor(options: BffAuthClientOptions);
381
+ /**
382
+ * `POST /bff/login` — the BFF does ROPC against Keycloak server-side, stores
383
+ * the tokens in its Redis vault, and sets the httpOnly session cookie.
384
+ * Returns the sanitised user. Throws on a non-2xx response.
385
+ */
386
+ login(request: BffLoginRequest): Promise<BffUser>;
387
+ /**
388
+ * `POST /bff/logout` — the BFF calls KC end-session, deletes the Redis
389
+ * session, and clears the cookie. Non-fatal: a failed logout still leaves
390
+ * the SPA logged out client-side. Throws only on a non-2xx response.
391
+ */
392
+ logout(): Promise<void>;
393
+ /**
394
+ * `GET /bff/me` — the live session's sanitised user, or `null` when there is
395
+ * no session (the BFF answers `401`). Used at app load to bootstrap auth
396
+ * state in place of the old token-in-storage check.
397
+ */
398
+ getCurrentUser(): Promise<BffUser | null>;
399
+ /**
400
+ * `POST /bff/register` — the BFF proxies registration to TenantService and,
401
+ * on success, establishes a session exactly like `login`. Returns the user.
402
+ */
403
+ register(request: BffRegisterRequest): Promise<BffUser>;
404
+ /**
405
+ * `POST /bff/forgot-password` — proxied to TenantService. The backend
406
+ * returns 200 unconditionally (no email enumeration); anything else throws.
407
+ */
408
+ forgotPassword(request: BffForgotPasswordRequest): Promise<void>;
409
+ /**
410
+ * `POST /bff/reset-password` — proxied to TenantService. Throws on a non-2xx
411
+ * response (e.g. `400` for an invalid / expired token).
412
+ */
413
+ resetPassword(request: BffResetPasswordRequest): Promise<void>;
414
+ /**
415
+ * Shared POST for every state-changing `/bff/*` call: same-origin, cookie
416
+ * included, `X-BFF-Csrf` header attached. Throws a labelled error on non-2xx.
417
+ */
418
+ private postState;
419
+ }
420
+
340
421
  /**
341
422
  * Convert a Keycloak `/userinfo` payload into a flat, app-friendly user object.
342
423
  *
@@ -510,4 +591,4 @@ declare function normalizeTokenResponse(raw: RawTokenResponse): TokenResponse;
510
591
  */
511
592
  declare function tokenResponseToAuthTokens(response: TokenResponse, now?: number): AuthTokens;
512
593
 
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 };
594
+ export { AuthTokens, type AuthorizationCodeBodyInput, type AuthorizationResponseLike, type AuthorizationUrlInput, BffAuthClient, type BffAuthClientOptions, type BffForgotPasswordRequest, type BffLoginRequest, type BffRegisterRequest, type BffResetPasswordRequest, type BffUser, type BiometricFlagStore, BiometricGate, type BiometricGateLike, type BiometricGateOptions, BrowserStorageTokenStorage, type BrowserStorageTokenStorageOptions, CookieTokenStorage, HttpClient, 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 { H as HttpClient, R as RawTokenResponse, T as TokenResponse } from './TokenResponse-CY1CaU2l.js';
5
+ export { 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.
@@ -337,6 +315,109 @@ declare class BiometricGate {
337
315
  unlock(): Promise<void>;
338
316
  }
339
317
 
318
+ /** Credentials posted to `POST /bff/login`. */
319
+ interface BffLoginRequest {
320
+ username: string;
321
+ password: string;
322
+ }
323
+ /** Payload for `POST /bff/register` — proxied by the BFF to TenantService. */
324
+ interface BffRegisterRequest {
325
+ firstName: string;
326
+ lastName: string;
327
+ username: string;
328
+ email: string;
329
+ password: string;
330
+ tenantName: string;
331
+ [key: string]: unknown;
332
+ }
333
+ /** Payload for `POST /bff/forgot-password` — proxied to TenantService. */
334
+ interface BffForgotPasswordRequest {
335
+ email: string;
336
+ /** Full URL with a `{token}` placeholder; the backend substitutes the token. */
337
+ resetUrlTemplate?: string;
338
+ [key: string]: unknown;
339
+ }
340
+ /** Payload for `POST /bff/reset-password` — proxied to TenantService. */
341
+ interface BffResetPasswordRequest {
342
+ token: string;
343
+ newPassword: string;
344
+ }
345
+ /**
346
+ * The user object returned by `GET /bff/me` and `POST /bff/login`. The BFF
347
+ * returns the sanitised KC claims under a `user` envelope and **never** a
348
+ * token. Kept permissive so server-added claims flow through without a bump.
349
+ */
350
+ interface BffUser {
351
+ sub?: string;
352
+ email?: string;
353
+ email_verified?: boolean;
354
+ name?: string;
355
+ preferred_username?: string;
356
+ given_name?: string;
357
+ family_name?: string;
358
+ tenantId?: string;
359
+ roles?: string[];
360
+ [key: string]: unknown;
361
+ }
362
+ interface BffAuthClientOptions {
363
+ /** Runtime-agnostic HTTP transport (wrap native `fetch` with `createFetchHttpClient`). */
364
+ http: HttpClient;
365
+ /**
366
+ * BFF origin. Defaults to `''` (same-origin) — the production wiring. An
367
+ * explicit origin is only useful for tests or a non-same-origin BFF.
368
+ */
369
+ baseUrl?: string;
370
+ }
371
+ /**
372
+ * Same-origin client for a per-app BFF.
373
+ *
374
+ * No token storage, no refresh logic, no realm awareness — the BFF owns all of
375
+ * that server-side. The browser's only auth artefact is the httpOnly cookie.
376
+ */
377
+ declare class BffAuthClient {
378
+ private readonly http;
379
+ private readonly baseUrl;
380
+ constructor(options: BffAuthClientOptions);
381
+ /**
382
+ * `POST /bff/login` — the BFF does ROPC against Keycloak server-side, stores
383
+ * the tokens in its Redis vault, and sets the httpOnly session cookie.
384
+ * Returns the sanitised user. Throws on a non-2xx response.
385
+ */
386
+ login(request: BffLoginRequest): Promise<BffUser>;
387
+ /**
388
+ * `POST /bff/logout` — the BFF calls KC end-session, deletes the Redis
389
+ * session, and clears the cookie. Non-fatal: a failed logout still leaves
390
+ * the SPA logged out client-side. Throws only on a non-2xx response.
391
+ */
392
+ logout(): Promise<void>;
393
+ /**
394
+ * `GET /bff/me` — the live session's sanitised user, or `null` when there is
395
+ * no session (the BFF answers `401`). Used at app load to bootstrap auth
396
+ * state in place of the old token-in-storage check.
397
+ */
398
+ getCurrentUser(): Promise<BffUser | null>;
399
+ /**
400
+ * `POST /bff/register` — the BFF proxies registration to TenantService and,
401
+ * on success, establishes a session exactly like `login`. Returns the user.
402
+ */
403
+ register(request: BffRegisterRequest): Promise<BffUser>;
404
+ /**
405
+ * `POST /bff/forgot-password` — proxied to TenantService. The backend
406
+ * returns 200 unconditionally (no email enumeration); anything else throws.
407
+ */
408
+ forgotPassword(request: BffForgotPasswordRequest): Promise<void>;
409
+ /**
410
+ * `POST /bff/reset-password` — proxied to TenantService. Throws on a non-2xx
411
+ * response (e.g. `400` for an invalid / expired token).
412
+ */
413
+ resetPassword(request: BffResetPasswordRequest): Promise<void>;
414
+ /**
415
+ * Shared POST for every state-changing `/bff/*` call: same-origin, cookie
416
+ * included, `X-BFF-Csrf` header attached. Throws a labelled error on non-2xx.
417
+ */
418
+ private postState;
419
+ }
420
+
340
421
  /**
341
422
  * Convert a Keycloak `/userinfo` payload into a flat, app-friendly user object.
342
423
  *
@@ -510,4 +591,4 @@ declare function normalizeTokenResponse(raw: RawTokenResponse): TokenResponse;
510
591
  */
511
592
  declare function tokenResponseToAuthTokens(response: TokenResponse, now?: number): AuthTokens;
512
593
 
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 };
594
+ export { AuthTokens, type AuthorizationCodeBodyInput, type AuthorizationResponseLike, type AuthorizationUrlInput, BffAuthClient, type BffAuthClientOptions, type BffForgotPasswordRequest, type BffLoginRequest, type BffRegisterRequest, type BffResetPasswordRequest, type BffUser, type BiometricFlagStore, BiometricGate, type BiometricGateLike, type BiometricGateOptions, BrowserStorageTokenStorage, type BrowserStorageTokenStorageOptions, CookieTokenStorage, HttpClient, 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 };