@classic-homes/auth 1.22.1 → 1.23.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.
@@ -0,0 +1,3 @@
1
+ export { authActions, authStore, currentUser, isAuthenticated } from './chunk-KSOYQYUZ.js';
2
+ import './chunk-ETKDIPD2.js';
3
+ import './chunk-2CYGQUUY.js';
@@ -96,7 +96,13 @@ function isValidRedirectUrl(url) {
96
96
  return false;
97
97
  }
98
98
  } catch {
99
- return !url.includes("://") && !url.startsWith("//");
99
+ if (url.includes("://") || url.startsWith("//")) return false;
100
+ try {
101
+ const sentinel = "https://relative.invalid";
102
+ return new URL(url, sentinel).origin === sentinel;
103
+ } catch {
104
+ return false;
105
+ }
100
106
  }
101
107
  }
102
108
 
@@ -108,8 +114,9 @@ function decodeJWT(token) {
108
114
  return null;
109
115
  }
110
116
  const payload = parts[1];
111
- const decoded = atob(payload.replace(/-/g, "+").replace(/_/g, "/"));
112
- return JSON.parse(decoded);
117
+ const binary = atob(payload.replace(/-/g, "+").replace(/_/g, "/"));
118
+ const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));
119
+ return JSON.parse(new TextDecoder().decode(bytes));
113
120
  } catch {
114
121
  return null;
115
122
  }
@@ -174,6 +181,7 @@ var ROLE_NAMES = [
174
181
  "stormwater_staff",
175
182
  "warranty_staff",
176
183
  "hotsheet_editor",
184
+ "office_admin",
177
185
  "employee",
178
186
  "user",
179
187
  "vendor",
@@ -188,7 +196,8 @@ var ROLE_HIERARCHY = {
188
196
  customer: 1,
189
197
  subcontractor: 1,
190
198
  // Staff tier (2): the read-only `employee` floor, the field-app clones of
191
- // `agent`, every `<department>_staff` docs role, and `hotsheet_editor`.
199
+ // `agent`, every `<department>_staff` docs role, `hotsheet_editor` and
200
+ // `office_admin`.
192
201
  employee: 2,
193
202
  agent: 2,
194
203
  builder: 2,
@@ -209,6 +218,7 @@ var ROLE_HIERARCHY = {
209
218
  stormwater_staff: 2,
210
219
  warranty_staff: 2,
211
220
  hotsheet_editor: 2,
221
+ office_admin: 2,
212
222
  manager: 3,
213
223
  admin: 4
214
224
  };
@@ -1,5 +1,5 @@
1
- import { authApi } from './chunk-LFNG4XAP.js';
2
- import { getUserRoles, hasAnyRole } from './chunk-PYCXNOMA.js';
1
+ import { authApi } from './chunk-ETKDIPD2.js';
2
+ import { getUserRoles, hasAnyRole } from './chunk-2CYGQUUY.js';
3
3
 
4
4
  // src/core/guards.ts
5
5
  function isMfaChallengeResponse(response) {
@@ -59,7 +59,7 @@ var AuthService = class {
59
59
  }
60
60
  if (options?.autoSetAuth !== false && !isMfaChallengeResponse(response)) {
61
61
  try {
62
- const { authStore } = await import('./auth.svelte-64QCTV2B.js');
62
+ const { authStore } = await import('./auth.svelte-T4LKTTDZ.js');
63
63
  authStore.setAuth(
64
64
  response.accessToken,
65
65
  response.refreshToken,
@@ -245,7 +245,7 @@ var AuthService = class {
245
245
  }
246
246
  if (options?.autoSetAuth !== false) {
247
247
  try {
248
- const { authStore } = await import('./auth.svelte-64QCTV2B.js');
248
+ const { authStore } = await import('./auth.svelte-T4LKTTDZ.js');
249
249
  authStore.setAuth(
250
250
  response.accessToken,
251
251
  response.refreshToken,
@@ -1,4 +1,4 @@
1
- import { getConfig, getStorage, isTokenExpired, getFetch, isValidRedirectUrl } from './chunk-PYCXNOMA.js';
1
+ import { getConfig, getStorage, isTokenExpired, getFetch, isValidRedirectUrl } from './chunk-2CYGQUUY.js';
2
2
 
3
3
  // src/core/client.ts
4
4
  var DEFAULT_REFRESH_RETRY_DELAYS = [1e3, 3e3];
@@ -58,7 +58,7 @@ function writeStoredTokens(accessToken, refreshToken) {
58
58
  }
59
59
  async function syncSvelteStore(apply) {
60
60
  try {
61
- const { authStore } = await import('./auth.svelte-64QCTV2B.js');
61
+ const { authStore } = await import('./auth.svelte-T4LKTTDZ.js');
62
62
  apply(authStore);
63
63
  } catch {
64
64
  }
@@ -164,6 +164,12 @@ async function runRefresh(options) {
164
164
  attempt = await refreshOnce(current);
165
165
  }
166
166
  if (attempt.outcome === "refreshed") {
167
+ const stored = getRefreshToken();
168
+ if (stored !== current) {
169
+ if (!stored) return "rejected";
170
+ await syncSvelteStore((authStore) => authStore.rehydrate());
171
+ return "refreshed";
172
+ }
167
173
  await writeStoredTokens(attempt.accessToken, attempt.refreshToken);
168
174
  return "refreshed";
169
175
  }
@@ -202,11 +208,12 @@ async function apiRequestInternal(endpoint, options, isRetry) {
202
208
  const timeoutMs = timeout ?? config.requestTimeout ?? 3e4;
203
209
  const controller = new AbortController();
204
210
  const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
211
+ const onCallerAbort = () => controller.abort();
205
212
  if (signal) {
206
213
  if (signal.aborted) {
207
214
  controller.abort();
208
215
  } else {
209
- signal.addEventListener("abort", () => controller.abort(), { once: true });
216
+ signal.addEventListener("abort", onCallerAbort, { once: true });
210
217
  }
211
218
  }
212
219
  const headers = {
@@ -290,12 +297,15 @@ async function apiRequestInternal(endpoint, options, isRetry) {
290
297
  } catch (error) {
291
298
  clearTimeout(timeoutId);
292
299
  if (error instanceof DOMException && error.name === "AbortError") {
300
+ if (signal?.aborted) throw error;
293
301
  throw new Error(`Request timed out after ${timeoutMs}ms`);
294
302
  }
295
303
  if (error instanceof Error) {
296
304
  throw error;
297
305
  }
298
306
  throw new Error("API request failed");
307
+ } finally {
308
+ signal?.removeEventListener("abort", onCallerAbort);
299
309
  }
300
310
  }
301
311
  function initCrossTabSync() {
@@ -496,7 +506,7 @@ var authApi = {
496
506
  * Revoke a specific session.
497
507
  */
498
508
  async revokeSession(sessionId) {
499
- await api.delete(`/auth/sessions/${sessionId}`, true);
509
+ await api.delete(`/auth/sessions/${encodeURIComponent(sessionId)}`, true);
500
510
  },
501
511
  /**
502
512
  * Revoke all sessions except the current one.
@@ -525,13 +535,13 @@ var authApi = {
525
535
  * Revoke an API key.
526
536
  */
527
537
  async revokeApiKey(keyId) {
528
- await api.delete(`/auth/api-keys/${keyId}`, true);
538
+ await api.delete(`/auth/api-keys/${encodeURIComponent(keyId)}`, true);
529
539
  },
530
540
  /**
531
541
  * Update an API key's name, description, role, or permissions.
532
542
  */
533
543
  async updateApiKey(keyId, data) {
534
- await api.put(`/auth/api-keys/${keyId}`, data, true);
544
+ await api.put(`/auth/api-keys/${encodeURIComponent(keyId)}`, data, true);
535
545
  },
536
546
  // ============================================================================
537
547
  // MFA Management
@@ -616,19 +626,19 @@ var authApi = {
616
626
  * Trust a device.
617
627
  */
618
628
  async trustDevice(deviceId) {
619
- await api.put(`/auth/devices/${deviceId}/trust`, {}, true);
629
+ await api.put(`/auth/devices/${encodeURIComponent(deviceId)}/trust`, {}, true);
620
630
  },
621
631
  /**
622
632
  * Revoke device trust.
623
633
  */
624
634
  async revokeDevice(deviceId) {
625
- await api.delete(`/auth/devices/${deviceId}/revoke`, true);
635
+ await api.delete(`/auth/devices/${encodeURIComponent(deviceId)}/revoke`, true);
626
636
  },
627
637
  /**
628
638
  * Remove a device completely.
629
639
  */
630
640
  async removeDevice(deviceId) {
631
- await api.delete(`/auth/devices/${deviceId}`, true);
641
+ await api.delete(`/auth/devices/${encodeURIComponent(deviceId)}`, true);
632
642
  },
633
643
  /**
634
644
  * Approve a device with a token.
@@ -773,7 +783,7 @@ var authApi = {
773
783
  */
774
784
  async getUserRoles(userId, customFetch) {
775
785
  const response = await api.get(
776
- `/users/${userId}/roles`,
786
+ `/users/${encodeURIComponent(userId)}/roles`,
777
787
  true,
778
788
  customFetch
779
789
  );
@@ -787,7 +797,7 @@ var authApi = {
787
797
  */
788
798
  async grantUserRole(userId, role) {
789
799
  const response = await api.put(
790
- `/users/${userId}/roles/${role}`,
800
+ `/users/${encodeURIComponent(userId)}/roles/${encodeURIComponent(role)}`,
791
801
  {},
792
802
  true
793
803
  );
@@ -802,7 +812,7 @@ var authApi = {
802
812
  */
803
813
  async revokeUserRole(userId, role) {
804
814
  const response = await api.delete(
805
- `/users/${userId}/roles/${role}`,
815
+ `/users/${encodeURIComponent(userId)}/roles/${encodeURIComponent(role)}`,
806
816
  true
807
817
  );
808
818
  return extractData(response);
@@ -815,7 +825,11 @@ var authApi = {
815
825
  * Use {@link grantUserRole} / {@link revokeUserRole} for additive changes.
816
826
  */
817
827
  async setUserRoles(userId, roles) {
818
- const response = await api.put(`/users/${userId}`, { roles }, true);
828
+ const response = await api.put(
829
+ `/users/${encodeURIComponent(userId)}`,
830
+ { roles },
831
+ true
832
+ );
819
833
  return extractData(response);
820
834
  }
821
835
  };
@@ -1,5 +1,5 @@
1
- import { authApi } from './chunk-LFNG4XAP.js';
2
- import { isInitialized, getConfig, hasRole, hasAnyRole, hasAllRoles, decodeJWT, getStorage, getDefaultStorage } from './chunk-PYCXNOMA.js';
1
+ import { authApi } from './chunk-ETKDIPD2.js';
2
+ import { isInitialized, getConfig, hasRole, hasAnyRole, hasAllRoles, decodeJWT, getStorage, getDefaultStorage } from './chunk-2CYGQUUY.js';
3
3
 
4
4
  // src/svelte/stores/auth.svelte.ts
5
5
  var STORAGE_VERSION = 2;
@@ -115,8 +115,12 @@ var AuthStore = class {
115
115
  isAuthenticated: true
116
116
  };
117
117
  saveAuthToStorage(this.state);
118
- if (sessionToken && typeof window !== "undefined") {
119
- getStorageAdapter().setItem(getSessionTokenKey(), sessionToken);
118
+ if (typeof window !== "undefined") {
119
+ if (sessionToken) {
120
+ getStorageAdapter().setItem(getSessionTokenKey(), sessionToken);
121
+ } else {
122
+ getStorageAdapter().removeItem(getSessionTokenKey());
123
+ }
120
124
  }
121
125
  if (typeof window !== "undefined") {
122
126
  window.dispatchEvent(
@@ -1,6 +1,6 @@
1
- import { authService } from './chunk-S5LHUKA5.js';
2
- import { authStore, currentUser, isAuthenticated, authActions } from './chunk-B6MOGO74.js';
3
- import { isInitialized, initAuth, getUserRoles } from './chunk-PYCXNOMA.js';
1
+ import { authService } from './chunk-DFCBWKCU.js';
2
+ import { authStore, currentUser, isAuthenticated, authActions } from './chunk-KSOYQYUZ.js';
3
+ import { isInitialized, initAuth, getUserRoles } from './chunk-2CYGQUUY.js';
4
4
 
5
5
  // src/svelte/guards/auth-guard.ts
6
6
  function checkAuth(options = {}) {
@@ -170,12 +170,14 @@ function createAuthHook(options = {}) {
170
170
  onUnauthenticated,
171
171
  onAuthCheck
172
172
  } = options;
173
+ const loginPathname = new URL(loginPath, "http://localhost").pathname.replace(/(.)\/+$/, "$1");
173
174
  return async ({
174
175
  event,
175
176
  resolve
176
177
  }) => {
177
178
  const { pathname } = event.url;
178
- const isPublic = publicRoutes.some((r) => r.test(pathname));
179
+ const isLoginPage = pathname.replace(/(.)\/+$/, "$1") === loginPathname;
180
+ const isPublic = isLoginPage || publicRoutes.some((r) => r.test(pathname));
179
181
  if (isPublic) {
180
182
  return resolve(event);
181
183
  }
@@ -195,9 +197,8 @@ function createAuthHook(options = {}) {
195
197
  if (onUnauthenticated) {
196
198
  return onUnauthenticated(event);
197
199
  }
198
- const redirectUrl = encodeURIComponent(pathname + event.url.search);
199
200
  const loginUrl = new URL(loginPath, event.url.origin);
200
- loginUrl.searchParams.set(redirectParam, redirectUrl);
201
+ loginUrl.searchParams.set(redirectParam, pathname + event.url.search);
201
202
  return new Response(null, {
202
203
  status: 302,
203
204
  headers: { Location: loginUrl.pathname + loginUrl.search }
@@ -209,6 +210,9 @@ function createAuthHook(options = {}) {
209
210
  function matchesRoute(pathname, patterns) {
210
211
  return patterns.some((pattern) => pattern.test(pathname));
211
212
  }
213
+ function escapeRegExp(value) {
214
+ return value.replace(/[.*+?^${}()|[\]\\/]/g, "\\$&");
215
+ }
212
216
  var routePatterns = {
213
217
  /** Match all /auth/* routes */
214
218
  auth: /^\/auth\//,
@@ -225,15 +229,16 @@ var routePatterns = {
225
229
  /** Match health check endpoints */
226
230
  health: /^\/(api\/)?(health|healthz|ready|live)\/?$/,
227
231
  /**
228
- * Create a pattern for a specific path prefix.
232
+ * Create a pattern for a specific path prefix. Matches whole path segments:
233
+ * '/admin' matches '/admin' and '/admin/users' but not '/administrator'.
229
234
  * @param prefix - Path prefix (e.g., '/dashboard')
230
235
  */
231
- prefix: (prefix) => new RegExp(`^${prefix.replace(/\//g, "\\/")}`),
236
+ prefix: (prefix) => new RegExp(`^${escapeRegExp(prefix)}${prefix.endsWith("/") ? "" : "(?:/|$)"}`),
232
237
  /**
233
238
  * Create a pattern for exact path match.
234
239
  * @param path - Exact path (e.g., '/about')
235
240
  */
236
- exact: (path) => new RegExp(`^${path.replace(/\//g, "\\/")}$`)
241
+ exact: (path) => new RegExp(`^${escapeRegExp(path)}$`)
237
242
  };
238
243
 
239
244
  export { canAccess, checkAuth, createAuthClient, createAuthGuard, createAuthHook, createNavFilter, filterByAccess, filterNavSections, matchesRoute, protectedLoad, requireAuth, requirePermission, requireRole, routePatterns };
@@ -532,7 +532,9 @@ declare function extractClaims<T extends string>(token: string, claims: T[]): Pi
532
532
  * `<department>_staff` roles are grant-on-top docs roles held alongside another
533
533
  * role, one per department the API lists in `DEPARTMENT_SCOPES`;
534
534
  * `hotsheet_editor` is a grant-on-top role for the Hotsheet hub's write
535
- * surface; `employee` is the read-only base staff
535
+ * surface; `office_admin` is a grant-on-top role for the office
536
+ * administrative assistant (home closing & financing fields, permits, walks,
537
+ * lenders); `employee` is the read-only base staff
536
538
  * floor (default for Authentik SSO); `vendor`/`customer`/`subcontractor` are
537
539
  * clones of `user`, row-scoped to their own homes.
538
540
  *
@@ -540,7 +542,7 @@ declare function extractClaims<T extends string>(token: string, claims: T[]): Pi
540
542
  * field app's clone of `agent`, the second is that department's docs role.
541
543
  * Someone on the stormwater team who also reads the docs holds both.
542
544
  */
543
- declare const ROLE_NAMES: readonly ["admin", "manager", "agent", "builder", "customer_service", "demo", "stormwater", "accounting_staff", "architecture_staff", "construction_staff", "crl_staff", "design_staff", "hr_staff", "it_staff", "landdev_staff", "marketing_staff", "purchasing_staff", "sales_staff", "stormwater_staff", "warranty_staff", "hotsheet_editor", "employee", "user", "vendor", "customer", "subcontractor", "guest"];
545
+ declare const ROLE_NAMES: readonly ["admin", "manager", "agent", "builder", "customer_service", "demo", "stormwater", "accounting_staff", "architecture_staff", "construction_staff", "crl_staff", "design_staff", "hr_staff", "it_staff", "landdev_staff", "marketing_staff", "purchasing_staff", "sales_staff", "stormwater_staff", "warranty_staff", "hotsheet_editor", "office_admin", "employee", "user", "vendor", "customer", "subcontractor", "guest"];
544
546
  /**
545
547
  * A known role name.
546
548
  *
@@ -1,3 +1,3 @@
1
- export { AuthService, RoleDeniedError, authService, formatUserRoles, getAvailableMethods, getAvatarFallback, getDisplayName, getGreeting, getMfaToken, getUserEmail, getUserInitials, isLoginSuccessResponse, isMfaChallengeResponse, isRoleDeniedError } from '../chunk-S5LHUKA5.js';
2
- export { api, apiRequest, authApi, clearStoredAuth, extractData, getAccessToken, getRefreshToken, getSessionToken, initCrossTabSync, refreshSession, updateStoredTokens } from '../chunk-LFNG4XAP.js';
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-PYCXNOMA.js';
1
+ export { AuthService, RoleDeniedError, authService, formatUserRoles, getAvailableMethods, getAvatarFallback, getDisplayName, getGreeting, getMfaToken, getUserEmail, getUserInitials, isLoginSuccessResponse, isMfaChallengeResponse, isRoleDeniedError } from '../chunk-DFCBWKCU.js';
2
+ export { api, apiRequest, authApi, clearStoredAuth, extractData, getAccessToken, getRefreshToken, getSessionToken, initCrossTabSync, refreshSession, updateStoredTokens } from '../chunk-ETKDIPD2.js';
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-2CYGQUUY.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-WHNMH73M.js';
2
- export { AuthService, RoleDeniedError, authService, formatUserRoles, getAvailableMethods, getAvatarFallback, getDisplayName, getGreeting, getMfaToken, getUserEmail, getUserInitials, isLoginSuccessResponse, isMfaChallengeResponse, isRoleDeniedError } from './chunk-S5LHUKA5.js';
3
- export { authActions, authStore, currentUser, isAuthenticated } from './chunk-B6MOGO74.js';
4
- export { api, apiRequest, authApi, clearStoredAuth, extractData, getAccessToken, getRefreshToken, getSessionToken, initCrossTabSync, refreshSession, updateStoredTokens } from './chunk-LFNG4XAP.js';
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-PYCXNOMA.js';
1
+ export { canAccess, checkAuth, createAuthClient, createAuthGuard, createAuthHook, createNavFilter, filterByAccess, filterNavSections, matchesRoute, protectedLoad, requireAuth, requirePermission, requireRole, routePatterns } from './chunk-NLG6NSE4.js';
2
+ export { AuthService, RoleDeniedError, authService, formatUserRoles, getAvailableMethods, getAvatarFallback, getDisplayName, getGreeting, getMfaToken, getUserEmail, getUserInitials, isLoginSuccessResponse, isMfaChallengeResponse, isRoleDeniedError } from './chunk-DFCBWKCU.js';
3
+ export { authActions, authStore, currentUser, isAuthenticated } from './chunk-KSOYQYUZ.js';
4
+ export { api, apiRequest, authApi, clearStoredAuth, extractData, getAccessToken, getRefreshToken, getSessionToken, initCrossTabSync, refreshSession, updateStoredTokens } from './chunk-ETKDIPD2.js';
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-2CYGQUUY.js';
@@ -584,7 +584,9 @@ type Handle = (input: {
584
584
  */
585
585
  interface AuthHookOptions {
586
586
  /**
587
- * Path to redirect unauthenticated users.
587
+ * Path to redirect unauthenticated users. This exact path is always public
588
+ * (to avoid a redirect loop); paths below it are not, so list e.g. an SSO
589
+ * callback under it in publicRoutes if it must be reachable signed out.
588
590
  * @default '/login'
589
591
  */
590
592
  loginPath?: string;
@@ -709,7 +711,8 @@ declare const routePatterns: {
709
711
  /** Match health check endpoints */
710
712
  health: RegExp;
711
713
  /**
712
- * Create a pattern for a specific path prefix.
714
+ * Create a pattern for a specific path prefix. Matches whole path segments:
715
+ * '/admin' matches '/admin' and '/admin/users' but not '/administrator'.
713
716
  * @param prefix - Path prefix (e.g., '/dashboard')
714
717
  */
715
718
  prefix: (prefix: string) => RegExp;
@@ -1,5 +1,5 @@
1
- export { canAccess, checkAuth, createAuthClient, createAuthGuard, createAuthHook, createNavFilter, filterByAccess, filterNavSections, matchesRoute, protectedLoad, requireAuth, requirePermission, requireRole, routePatterns } from '../chunk-WHNMH73M.js';
2
- export { RoleDeniedError, formatUserRoles, getAvatarFallback, getDisplayName, getGreeting, getUserEmail, getUserInitials, isRoleDeniedError } from '../chunk-S5LHUKA5.js';
3
- export { authActions, authStore, currentUser, isAuthenticated } from '../chunk-B6MOGO74.js';
4
- import '../chunk-LFNG4XAP.js';
5
- export { initAuth, isInitialized } from '../chunk-PYCXNOMA.js';
1
+ export { canAccess, checkAuth, createAuthClient, createAuthGuard, createAuthHook, createNavFilter, filterByAccess, filterNavSections, matchesRoute, protectedLoad, requireAuth, requirePermission, requireRole, routePatterns } from '../chunk-NLG6NSE4.js';
2
+ export { RoleDeniedError, formatUserRoles, getAvatarFallback, getDisplayName, getGreeting, getUserEmail, getUserInitials, isRoleDeniedError } from '../chunk-DFCBWKCU.js';
3
+ export { authActions, authStore, currentUser, isAuthenticated } from '../chunk-KSOYQYUZ.js';
4
+ import '../chunk-ETKDIPD2.js';
5
+ export { initAuth, isInitialized } from '../chunk-2CYGQUUY.js';
@@ -1,4 +1,4 @@
1
- import { hasRole, hasAnyRole, hasAllRoles, initAuth, resetConfig, getUserRoles, isTokenExpired, decodeJWT } from '../chunk-PYCXNOMA.js';
1
+ import { hasRole, hasAnyRole, hasAllRoles, initAuth, resetConfig, getUserRoles, isTokenExpired, decodeJWT } from '../chunk-2CYGQUUY.js';
2
2
 
3
3
  // src/testing/fixtures/users.ts
4
4
  var mockUser = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classic-homes/auth",
3
- "version": "1.22.1",
3
+ "version": "1.23.0",
4
4
  "description": "Authentication services and Svelte bindings for Classic Theme apps",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,3 +0,0 @@
1
- export { authActions, authStore, currentUser, isAuthenticated } from './chunk-B6MOGO74.js';
2
- import './chunk-LFNG4XAP.js';
3
- import './chunk-PYCXNOMA.js';