@classic-homes/auth 1.41.0 → 1.42.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.
@@ -1,3 +1,3 @@
1
- export { authActions, authStore, currentUser, isAuthenticated } from './chunk-HMZRBRIU.js';
2
- import './chunk-QLEEAHJJ.js';
1
+ export { authActions, authStore, currentUser, isAuthenticated } from './chunk-MBVOLE5U.js';
2
+ import './chunk-7AQYLLTA.js';
3
3
  import './chunk-K6TV3ZVS.js';
@@ -1,4 +1,4 @@
1
- import { isInitialized, getConfig, getUserRoles, getStorage, isTokenExpired, getFetch, isValidRedirectUrl } from './chunk-K6TV3ZVS.js';
1
+ import { isInitialized, getConfig, getUserRoles, getStorage, isTokenExpired, getFetch, isValidRedirectUrl, decodeJWT } from './chunk-K6TV3ZVS.js';
2
2
 
3
3
  // src/core/sso-state.ts
4
4
  var SSO_CLIENT_STATE_PARAM = "client_state";
@@ -96,6 +96,18 @@ var InvalidAuthResponseError = class _InvalidAuthResponseError extends Error {
96
96
  }
97
97
  }
98
98
  };
99
+ var SessionChangedError = class _SessionChangedError extends Error {
100
+ constructor(message = "The session changed while this request was in flight; it was not retried.") {
101
+ super(message);
102
+ this.name = "SessionChangedError";
103
+ if (Error.captureStackTrace) {
104
+ Error.captureStackTrace(this, _SessionChangedError);
105
+ }
106
+ }
107
+ };
108
+ function isSessionChangedError(error) {
109
+ return error instanceof SessionChangedError || error?.name === "SessionChangedError";
110
+ }
99
111
  var MFAChallengeEmailError = class _MFAChallengeEmailError extends Error {
100
112
  constructor(message, status, retryAfterSeconds) {
101
113
  super(message);
@@ -108,6 +120,46 @@ var MFAChallengeEmailError = class _MFAChallengeEmailError extends Error {
108
120
  }
109
121
  };
110
122
 
123
+ // src/core/session.ts
124
+ var generation = 0;
125
+ function bumpSessionGeneration() {
126
+ generation += 1;
127
+ }
128
+ function readIdentity() {
129
+ let parsed = {};
130
+ try {
131
+ const raw = getStorage().getItem(getConfig().storageKey ?? "classic_auth");
132
+ if (raw) parsed = JSON.parse(raw) ?? {};
133
+ } catch {
134
+ }
135
+ const accessToken = typeof parsed.accessToken === "string" ? parsed.accessToken : "";
136
+ const refreshToken = typeof parsed.refreshToken === "string" ? parsed.refreshToken : "";
137
+ const sub = accessToken ? decodeJWT(accessToken)?.sub : void 0;
138
+ const userId = parsed.user?.id;
139
+ return {
140
+ signedIn: accessToken !== "" || refreshToken !== "",
141
+ sub: typeof sub === "string" || typeof sub === "number" ? String(sub) : void 0,
142
+ userId: typeof userId === "string" || typeof userId === "number" ? String(userId) : void 0
143
+ };
144
+ }
145
+ function captureSession() {
146
+ return { generation, identity: readIdentity() };
147
+ }
148
+ function getSessionGeneration() {
149
+ return generation;
150
+ }
151
+ function isCurrentSession(snapshot) {
152
+ if (snapshot.generation !== generation) return false;
153
+ const then = snapshot.identity;
154
+ const now = readIdentity();
155
+ if (then.signedIn !== now.signedIn) return false;
156
+ if (then.sub !== void 0 && now.sub !== void 0 && then.sub !== now.sub) return false;
157
+ if (then.userId !== void 0 && now.userId !== void 0 && then.userId !== now.userId) {
158
+ return false;
159
+ }
160
+ return true;
161
+ }
162
+
111
163
  // src/core/client.ts
112
164
  var DEFAULT_REFRESH_RETRY_DELAYS = [1e3, 3e3];
113
165
  var refreshInflight = null;
@@ -166,7 +218,7 @@ function writeStoredTokens(accessToken, refreshToken) {
166
218
  }
167
219
  async function syncSvelteStore(apply) {
168
220
  try {
169
- const { authStore } = await import('./auth.svelte-DSE2NZMP.js');
221
+ const { authStore } = await import('./auth.svelte-XY4FQFZQ.js');
170
222
  apply(authStore);
171
223
  } catch {
172
224
  }
@@ -176,6 +228,7 @@ function clearStoredAuth() {
176
228
  const storage = getStorage();
177
229
  storage.removeItem(config.storageKey ?? "classic_auth");
178
230
  storage.removeItem(getSessionTokenKey());
231
+ bumpSessionGeneration();
179
232
  }
180
233
  async function expireSession() {
181
234
  clearStoredAuth();
@@ -245,6 +298,8 @@ function refreshSession(options = {}) {
245
298
  return refreshInflight;
246
299
  }
247
300
  async function runRefresh(options) {
301
+ const generation2 = getSessionGeneration();
302
+ const sameGeneration = () => generation2 === getSessionGeneration();
248
303
  const presented = getRefreshToken();
249
304
  if (!presented) {
250
305
  await expireSession();
@@ -254,6 +309,7 @@ async function runRefresh(options) {
254
309
  const current = getRefreshToken();
255
310
  if (current !== presented) {
256
311
  if (!current) {
312
+ if (!sameGeneration()) return "rejected";
257
313
  await expireSession();
258
314
  return "rejected";
259
315
  }
@@ -278,6 +334,7 @@ async function runRefresh(options) {
278
334
  await syncSvelteStore((authStore) => authStore.rehydrate());
279
335
  return "refreshed";
280
336
  }
337
+ if (!sameGeneration()) return "rejected";
281
338
  await writeStoredTokens(attempt.accessToken, attempt.refreshToken);
282
339
  return "refreshed";
283
340
  }
@@ -287,6 +344,7 @@ async function runRefresh(options) {
287
344
  await syncSvelteStore((authStore) => authStore.rehydrate());
288
345
  return "refreshed";
289
346
  }
347
+ if (!sameGeneration()) return "rejected";
290
348
  await expireSession();
291
349
  return "rejected";
292
350
  }
@@ -316,7 +374,7 @@ function isApiOrigin(url, baseUrl) {
316
374
  function apiRequest(endpoint, options = {}) {
317
375
  return apiRequestInternal(endpoint, options, false);
318
376
  }
319
- async function apiRequestInternal(endpoint, options, isRetry) {
377
+ async function apiRequestInternal(endpoint, options, isRetry, startedIn) {
320
378
  const {
321
379
  authenticated: wantsAuth = false,
322
380
  customFetch,
@@ -331,6 +389,14 @@ async function apiRequestInternal(endpoint, options, isRetry) {
331
389
  const isAbsolute = /^https?:\/\//i.test(endpoint);
332
390
  const url = isAbsolute ? endpoint : `${config.baseUrl}${endpoint}`;
333
391
  const authenticated = wantsAuth && (!isAbsolute || isApiOrigin(url, config.baseUrl));
392
+ const session = startedIn ?? captureSession();
393
+ const assertSameSession = async () => {
394
+ if (isCurrentSession(session)) return;
395
+ if (session.generation === getSessionGeneration()) {
396
+ await syncSvelteStore((authStore) => authStore.rehydrate());
397
+ }
398
+ throw new SessionChangedError();
399
+ };
334
400
  if (authenticated && noAuthRetry && !isRetry && typeof window !== "undefined") {
335
401
  const accessToken = getAccessToken();
336
402
  if (accessToken && isTokenExpired(accessToken)) {
@@ -338,6 +404,7 @@ async function apiRequestInternal(endpoint, options, isRetry) {
338
404
  if (outcome === "rejected") {
339
405
  throw new Error("Authentication failed. Please sign in again.");
340
406
  }
407
+ if (authenticated) await assertSameSession();
341
408
  }
342
409
  }
343
410
  const timeoutMs = timeout ?? config.requestTimeout ?? 3e4;
@@ -374,13 +441,15 @@ async function apiRequestInternal(endpoint, options, isRetry) {
374
441
  });
375
442
  clearTimeout(timeoutId);
376
443
  if (response.status === 401 && authenticated && !noAuthRetry && typeof window !== "undefined") {
444
+ await assertSameSession();
377
445
  if (isRetry) {
378
446
  await expireSession();
379
447
  throw new Error("Authentication failed. Please sign in again.");
380
448
  }
381
449
  const outcome = await refreshSession();
382
450
  if (outcome === "refreshed") {
383
- return apiRequestInternal(endpoint, options, true);
451
+ await assertSameSession();
452
+ return apiRequestInternal(endpoint, options, true, session);
384
453
  }
385
454
  if (outcome === "rejected") {
386
455
  throw new Error("Authentication failed. Please sign in again.");
@@ -1012,4 +1081,4 @@ var authApi = {
1012
1081
  }
1013
1082
  };
1014
1083
 
1015
- export { InvalidAuthResponseError, MFAChallengeEmailError, RoleDeniedError, SSO_CLIENT_STATE_PARAM, SSO_CLIENT_STATE_TTL_MS, api, apiRequest, authApi, clearStoredAuth, consumeSsoClientState, createSsoClientState, extractData, getAccessToken, getRefreshToken, getSessionToken, initCrossTabSync, isRoleDeniedError, refreshSession, updateStoredTokens, verifySsoClientState };
1084
+ export { InvalidAuthResponseError, MFAChallengeEmailError, RoleDeniedError, SSO_CLIENT_STATE_PARAM, SSO_CLIENT_STATE_TTL_MS, SessionChangedError, api, apiRequest, authApi, bumpSessionGeneration, clearStoredAuth, consumeSsoClientState, createSsoClientState, extractData, getAccessToken, getRefreshToken, getSessionToken, initCrossTabSync, isRoleDeniedError, isSessionChangedError, refreshSession, updateStoredTokens, verifySsoClientState };
@@ -1,5 +1,5 @@
1
- import { authService } from './chunk-BMCGFHVM.js';
2
- import { authStore, currentUser, isAuthenticated, authActions } from './chunk-HMZRBRIU.js';
1
+ import { authService } from './chunk-LPQKZRPC.js';
2
+ import { authStore, currentUser, isAuthenticated, authActions } from './chunk-MBVOLE5U.js';
3
3
  import { isInitialized, initAuth, getUserRoles } from './chunk-K6TV3ZVS.js';
4
4
 
5
5
  // src/svelte/guards/auth-guard.ts
@@ -1,4 +1,4 @@
1
- import { authApi, InvalidAuthResponseError, RoleDeniedError } from './chunk-QLEEAHJJ.js';
1
+ import { authApi, InvalidAuthResponseError, RoleDeniedError } from './chunk-7AQYLLTA.js';
2
2
  import { hasAnyRole, getUserRoles } from './chunk-K6TV3ZVS.js';
3
3
 
4
4
  // src/core/guards.ts
@@ -19,7 +19,7 @@ function getAvailableMethods(response) {
19
19
  async function setStoreAuth(response) {
20
20
  let store;
21
21
  try {
22
- store = (await import('./auth.svelte-DSE2NZMP.js')).authStore;
22
+ store = (await import('./auth.svelte-XY4FQFZQ.js')).authStore;
23
23
  } catch {
24
24
  return;
25
25
  }
@@ -1,4 +1,4 @@
1
- import { InvalidAuthResponseError, authApi } from './chunk-QLEEAHJJ.js';
1
+ import { InvalidAuthResponseError, bumpSessionGeneration, authApi } from './chunk-7AQYLLTA.js';
2
2
  import { isInitialized, getConfig, isValidSSOLogoutUrl, hasRole, hasAnyRole, hasAllRoles, decodeJWT, getStorage, getDefaultStorage } from './chunk-K6TV3ZVS.js';
3
3
 
4
4
  // src/svelte/stores/auth.svelte.ts
@@ -111,6 +111,7 @@ var AuthStore = class {
111
111
  throw new InvalidAuthResponseError("setAuth requires an access token and a user");
112
112
  }
113
113
  const userWithPermissions = normalizeUser(user, accessToken);
114
+ bumpSessionGeneration();
114
115
  this.state = {
115
116
  accessToken,
116
117
  refreshToken,
@@ -174,6 +175,7 @@ var AuthStore = class {
174
175
  * Clear auth state (logout).
175
176
  */
176
177
  logout() {
178
+ bumpSessionGeneration();
177
179
  this.state = {
178
180
  accessToken: null,
179
181
  refreshToken: null,
@@ -222,6 +224,7 @@ var AuthStore = class {
222
224
  */
223
225
  handleSessionExpired() {
224
226
  const currentPath = typeof window !== "undefined" ? window.location.pathname : "/";
227
+ bumpSessionGeneration();
225
228
  this.state = {
226
229
  accessToken: null,
227
230
  refreshToken: null,
@@ -303,6 +306,7 @@ var AuthStore = class {
303
306
  * ```
304
307
  */
305
308
  reset() {
309
+ bumpSessionGeneration();
306
310
  this.state = {
307
311
  accessToken: null,
308
312
  refreshToken: null,
@@ -1,6 +1,6 @@
1
1
  import { e as LoginCredentials, f as LoginResponse, g as LogoutResponse, R as RegisterData, l as RegisterResponse, q as User, k as ProfileUpdateData, C as ChangePasswordData, o as Session, A as ApiKey, c as CreateApiKeyRequest, d as CreateApiKeyResponse, U as UpdateApiKeyRequest, j as MFAStatus, i as MFASetupResponse, M as MFAChallengeData, h as MFAChallengeEmailResponse, D as Device, r as UserPreferences, L as LinkedAccount, n as SecurityEvent, P as Pagination, s as UserRolesResponse } from '../types-DF5Ny2IA.js';
2
2
  export { a as AuthConfig, b as AuthState, m as ResetPasswordData, S as SSOConfig, p as StorageAdapter, t as createMemoryStorage, u as createSessionStorage, v as getConfig, w as getDefaultStorage, x as getFetch, y as getStorage, z as initAuth, B as isInitialized, E as resetConfig } from '../types-DF5Ny2IA.js';
3
- export { A as AuthService, I as InvalidAuthResponseError, L as LoginOptions, M as MFAChallengeEmailError, a as MFAVerifyOptions, R as RoleDeniedError, b as authService, f as formatUserRoles, g as getAvatarFallback, c as getDisplayName, d as getGreeting, e as getUserEmail, h as getUserInitials, i as isRoleDeniedError } from '../user-utils-B6BNJzF2.js';
3
+ export { A as AuthService, I as InvalidAuthResponseError, L as LoginOptions, M as MFAChallengeEmailError, a as MFAVerifyOptions, R as RoleDeniedError, S as SessionChangedError, b as authService, f as formatUserRoles, g as getAvatarFallback, c as getDisplayName, d as getGreeting, e as getUserEmail, h as getUserInitials, i as isRoleDeniedError, j as isSessionChangedError } from '../user-utils-Bo3lMsuT.js';
4
4
 
5
5
  /**
6
6
  * SSO client state
@@ -1,3 +1,3 @@
1
- export { AuthService, authService, formatUserRoles, getAvailableMethods, getAvatarFallback, getDisplayName, getGreeting, getMfaToken, getUserEmail, getUserInitials, isLoginSuccessResponse, isMfaChallengeResponse } from '../chunk-BMCGFHVM.js';
2
- export { InvalidAuthResponseError, MFAChallengeEmailError, RoleDeniedError, SSO_CLIENT_STATE_PARAM, SSO_CLIENT_STATE_TTL_MS, api, apiRequest, authApi, clearStoredAuth, consumeSsoClientState, createSsoClientState, extractData, getAccessToken, getRefreshToken, getSessionToken, initCrossTabSync, isRoleDeniedError, refreshSession, updateStoredTokens, verifySsoClientState } from '../chunk-QLEEAHJJ.js';
1
+ export { AuthService, authService, formatUserRoles, getAvailableMethods, getAvatarFallback, getDisplayName, getGreeting, getMfaToken, getUserEmail, getUserInitials, isLoginSuccessResponse, isMfaChallengeResponse } from '../chunk-LPQKZRPC.js';
2
+ export { InvalidAuthResponseError, MFAChallengeEmailError, RoleDeniedError, SSO_CLIENT_STATE_PARAM, SSO_CLIENT_STATE_TTL_MS, SessionChangedError, api, apiRequest, authApi, clearStoredAuth, consumeSsoClientState, createSsoClientState, extractData, getAccessToken, getRefreshToken, getSessionToken, initCrossTabSync, isRoleDeniedError, isSessionChangedError, refreshSession, updateStoredTokens, verifySsoClientState } from '../chunk-7AQYLLTA.js';
3
3
  export { ROLE_HIERARCHY, ROLE_NAMES, computePrimaryRole, createMemoryStorage, createSessionStorage, decodeJWT, extractClaims, getConfig, getDefaultStorage, getEffectiveLevel, getFetch, getStorage, getTokenExpiration, getTokenRemainingTime, getUserRoles, hasAllRoles, hasAnyRole, hasRole, initAuth, isInitialized, isTokenExpired, resetConfig } from '../chunk-K6TV3ZVS.js';
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { A as ApiKey, a as AuthConfig, b as AuthState, C as ChangePasswordData, c as CreateApiKeyRequest, d as CreateApiKeyResponse, D as Device, L as LinkedAccount, e as LoginCredentials, f as LoginResponse, g as LogoutResponse, M as MFAChallengeData, h as MFAChallengeEmailResponse, i as MFASetupResponse, j as MFAStatus, P as Pagination, k as ProfileUpdateData, R as RegisterData, l as RegisterResponse, m as ResetPasswordData, S as SSOConfig, n as SecurityEvent, o as Session, p as StorageAdapter, U as UpdateApiKeyRequest, q as User, r as UserPreferences, s as UserRolesResponse, t as createMemoryStorage, u as createSessionStorage, v as getConfig, w as getDefaultStorage, x as getFetch, y as getStorage, z as initAuth, B as isInitialized, E as resetConfig } from './types-DF5Ny2IA.js';
2
2
  export { ApiRequestOptions, ApiResponse, JWTPayload, ROLE_HIERARCHY, ROLE_NAMES, RefreshOutcome, RefreshSessionOptions, RoleName, SSO_CLIENT_STATE_PARAM, SSO_CLIENT_STATE_TTL_MS, SsoClientStateResult, SsoClientStateVerification, api, apiRequest, authApi, clearStoredAuth, computePrimaryRole, consumeSsoClientState, createSsoClientState, decodeJWT, extractClaims, extractData, getAccessToken, getAvailableMethods, getEffectiveLevel, getMfaToken, getRefreshToken, getSessionToken, getTokenExpiration, getTokenRemainingTime, getUserRoles, hasAllRoles, hasAnyRole, hasRole, initCrossTabSync, isLoginSuccessResponse, isMfaChallengeResponse, isTokenExpired, refreshSession, updateStoredTokens, verifySsoClientState } from './core/index.js';
3
- export { A as AuthService, I as InvalidAuthResponseError, L as LoginOptions, M as MFAChallengeEmailError, a as MFAVerifyOptions, R as RoleDeniedError, b as authService, f as formatUserRoles, g as getAvatarFallback, c as getDisplayName, d as getGreeting, e as getUserEmail, h as getUserInitials, i as isRoleDeniedError } from './user-utils-B6BNJzF2.js';
3
+ export { A as AuthService, I as InvalidAuthResponseError, L as LoginOptions, M as MFAChallengeEmailError, a as MFAVerifyOptions, R as RoleDeniedError, S as SessionChangedError, b as authService, f as formatUserRoles, g as getAvatarFallback, c as getDisplayName, d as getGreeting, e as getUserEmail, h as getUserInitials, i as isRoleDeniedError, j as isSessionChangedError } from './user-utils-Bo3lMsuT.js';
4
4
  export { AuthClient, AuthGuardOptions, AuthGuardResult, AuthHookOptions, CreateAuthClientOptions, NavFilterOptions, RoleRestrictedItem, authActions, authStore, canAccess, checkAuth, createAuthClient, createAuthGuard, createAuthHook, createNavFilter, currentUser, filterByAccess, filterNavSections, isAuthenticated, matchesRoute, protectedLoad, requireAuth, requirePermission, requireRole, routePatterns } from './svelte/index.js';
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- export { canAccess, checkAuth, createAuthClient, createAuthGuard, createAuthHook, createNavFilter, filterByAccess, filterNavSections, matchesRoute, protectedLoad, requireAuth, requirePermission, requireRole, routePatterns } from './chunk-5SZT7GKG.js';
2
- export { AuthService, authService, formatUserRoles, getAvailableMethods, getAvatarFallback, getDisplayName, getGreeting, getMfaToken, getUserEmail, getUserInitials, isLoginSuccessResponse, isMfaChallengeResponse } from './chunk-BMCGFHVM.js';
3
- export { authActions, authStore, currentUser, isAuthenticated } from './chunk-HMZRBRIU.js';
4
- export { InvalidAuthResponseError, MFAChallengeEmailError, RoleDeniedError, SSO_CLIENT_STATE_PARAM, SSO_CLIENT_STATE_TTL_MS, api, apiRequest, authApi, clearStoredAuth, consumeSsoClientState, createSsoClientState, extractData, getAccessToken, getRefreshToken, getSessionToken, initCrossTabSync, isRoleDeniedError, refreshSession, updateStoredTokens, verifySsoClientState } from './chunk-QLEEAHJJ.js';
1
+ export { canAccess, checkAuth, createAuthClient, createAuthGuard, createAuthHook, createNavFilter, filterByAccess, filterNavSections, matchesRoute, protectedLoad, requireAuth, requirePermission, requireRole, routePatterns } from './chunk-7JLCFRUU.js';
2
+ export { AuthService, authService, formatUserRoles, getAvailableMethods, getAvatarFallback, getDisplayName, getGreeting, getMfaToken, getUserEmail, getUserInitials, isLoginSuccessResponse, isMfaChallengeResponse } from './chunk-LPQKZRPC.js';
3
+ export { authActions, authStore, currentUser, isAuthenticated } from './chunk-MBVOLE5U.js';
4
+ export { InvalidAuthResponseError, MFAChallengeEmailError, RoleDeniedError, SSO_CLIENT_STATE_PARAM, SSO_CLIENT_STATE_TTL_MS, SessionChangedError, api, apiRequest, authApi, clearStoredAuth, consumeSsoClientState, createSsoClientState, extractData, getAccessToken, getRefreshToken, getSessionToken, initCrossTabSync, isRoleDeniedError, isSessionChangedError, refreshSession, updateStoredTokens, verifySsoClientState } from './chunk-7AQYLLTA.js';
5
5
  export { ROLE_HIERARCHY, ROLE_NAMES, computePrimaryRole, createMemoryStorage, createSessionStorage, decodeJWT, extractClaims, getConfig, getDefaultStorage, getEffectiveLevel, getFetch, getStorage, getTokenExpiration, getTokenRemainingTime, getUserRoles, hasAllRoles, hasAnyRole, hasRole, initAuth, isInitialized, isTokenExpired, resetConfig } from './chunk-K6TV3ZVS.js';
@@ -1,7 +1,7 @@
1
1
  import { b as AuthState, q as User, a as AuthConfig } from '../types-DF5Ny2IA.js';
2
2
  export { z as initAuth, B as isInitialized } from '../types-DF5Ny2IA.js';
3
- import { b as authService } from '../user-utils-B6BNJzF2.js';
4
- export { I as InvalidAuthResponseError, R as RoleDeniedError, f as formatUserRoles, g as getAvatarFallback, c as getDisplayName, d as getGreeting, e as getUserEmail, h as getUserInitials, i as isRoleDeniedError } from '../user-utils-B6BNJzF2.js';
3
+ import { b as authService } from '../user-utils-Bo3lMsuT.js';
4
+ export { I as InvalidAuthResponseError, R as RoleDeniedError, S as SessionChangedError, f as formatUserRoles, g as getAvatarFallback, c as getDisplayName, d as getGreeting, e as getUserEmail, h as getUserInitials, i as isRoleDeniedError, j as isSessionChangedError } from '../user-utils-Bo3lMsuT.js';
5
5
 
6
6
  /**
7
7
  * Auth Store
@@ -1,5 +1,5 @@
1
- export { canAccess, checkAuth, createAuthClient, createAuthGuard, createAuthHook, createNavFilter, filterByAccess, filterNavSections, matchesRoute, protectedLoad, requireAuth, requirePermission, requireRole, routePatterns } from '../chunk-5SZT7GKG.js';
2
- export { formatUserRoles, getAvatarFallback, getDisplayName, getGreeting, getUserEmail, getUserInitials } from '../chunk-BMCGFHVM.js';
3
- export { authActions, authStore, currentUser, isAuthenticated } from '../chunk-HMZRBRIU.js';
4
- export { InvalidAuthResponseError, RoleDeniedError, isRoleDeniedError } from '../chunk-QLEEAHJJ.js';
1
+ export { canAccess, checkAuth, createAuthClient, createAuthGuard, createAuthHook, createNavFilter, filterByAccess, filterNavSections, matchesRoute, protectedLoad, requireAuth, requirePermission, requireRole, routePatterns } from '../chunk-7JLCFRUU.js';
2
+ export { formatUserRoles, getAvatarFallback, getDisplayName, getGreeting, getUserEmail, getUserInitials } from '../chunk-LPQKZRPC.js';
3
+ export { authActions, authStore, currentUser, isAuthenticated } from '../chunk-MBVOLE5U.js';
4
+ export { InvalidAuthResponseError, RoleDeniedError, SessionChangedError, isRoleDeniedError, isSessionChangedError } from '../chunk-7AQYLLTA.js';
5
5
  export { initAuth, isInitialized } from '../chunk-K6TV3ZVS.js';
@@ -326,6 +326,22 @@ declare class InvalidAuthResponseError extends Error {
326
326
  readonly name = "InvalidAuthResponseError";
327
327
  constructor(message?: string);
328
328
  }
329
+ /**
330
+ * Error thrown when the session changed (logout, login as another account,
331
+ * expiry) while a request was in flight, and the request needed the session
332
+ * to continue (a 401 that would have been refreshed and retried). The request
333
+ * is not refreshed, retried or allowed to expire the new session: replaying it
334
+ * would send the previous account's request with the next account's
335
+ * credentials.
336
+ */
337
+ declare class SessionChangedError extends Error {
338
+ readonly name = "SessionChangedError";
339
+ constructor(message?: string);
340
+ }
341
+ /**
342
+ * Type guard to check if an error is a SessionChangedError.
343
+ */
344
+ declare function isSessionChangedError(error: unknown): error is SessionChangedError;
329
345
  /**
330
346
  * Error thrown when CHAPI won't send an MFA challenge email code: the
331
347
  * challenge token is invalid or expired (401), the account has no email MFA
@@ -444,4 +460,4 @@ declare function formatUserRoles(user: User | null | undefined, options?: {
444
460
  capitalize?: boolean;
445
461
  }): string;
446
462
 
447
- export { AuthService as A, InvalidAuthResponseError as I, type LoginOptions as L, MFAChallengeEmailError as M, RoleDeniedError as R, type MFAVerifyOptions as a, authService as b, getDisplayName as c, getGreeting as d, getUserEmail as e, formatUserRoles as f, getAvatarFallback as g, getUserInitials as h, isRoleDeniedError as i };
463
+ export { AuthService as A, InvalidAuthResponseError as I, type LoginOptions as L, MFAChallengeEmailError as M, RoleDeniedError as R, SessionChangedError as S, type MFAVerifyOptions as a, authService as b, getDisplayName as c, getGreeting as d, getUserEmail as e, formatUserRoles as f, getAvatarFallback as g, getUserInitials as h, isRoleDeniedError as i, isSessionChangedError as j };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classic-homes/auth",
3
- "version": "1.41.0",
3
+ "version": "1.42.0",
4
4
  "description": "Authentication services and Svelte bindings for Classic Theme apps",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",