@classic-homes/auth 0.1.55 → 0.1.56
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/README.md +6 -0
- package/dist/auth.svelte-WPCYPHEE.js +3 -0
- package/dist/{chunk-GRQL5FSH.js → chunk-2QYFVJEM.js} +61 -20
- package/dist/{chunk-EM7PUNZB.js → chunk-6NTZVDLW.js} +31 -2
- package/dist/{chunk-BK34CVH5.js → chunk-CPFM7JEI.js} +2 -2
- package/dist/{chunk-TUHQ4FHC.js → chunk-MPPV5S7S.js} +3 -3
- package/dist/{chunk-RKSETJ4V.js → chunk-UG4GSPGL.js} +3 -3
- package/dist/core/index.d.ts +7 -6
- package/dist/core/index.js +3 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.js +5 -5
- package/dist/svelte/index.d.ts +4 -4
- package/dist/svelte/index.js +5 -5
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +1 -1
- package/dist/{types-BRxyphcX.d.ts → types-Di6SR1q5.d.ts} +28 -1
- package/dist/{user-utils-BSbNN3Hb.d.ts → user-utils-C-JbXqbj.d.ts} +1 -1
- package/package.json +1 -1
- package/dist/auth.svelte-BBLX2MKB.js +0 -3
package/README.md
CHANGED
|
@@ -37,6 +37,12 @@ initAuth({
|
|
|
37
37
|
setItem: (key, value) => localStorage.setItem(key, value),
|
|
38
38
|
removeItem: (key) => localStorage.removeItem(key),
|
|
39
39
|
},
|
|
40
|
+
// ⚠️ SECURITY: localStorage (also the default when `storage` is omitted)
|
|
41
|
+
// persists the long-lived refresh token where any XSS can read it.
|
|
42
|
+
// Safer options exported from '@classic-homes/auth/core':
|
|
43
|
+
// storage: createSessionStorage() // per-tab, cleared on close
|
|
44
|
+
// storage: createMemoryStorage() // never persisted, lost on reload
|
|
45
|
+
// or keep tokens out of JS entirely with an httpOnly-cookie flow.
|
|
40
46
|
// SSO configuration (optional)
|
|
41
47
|
sso: {
|
|
42
48
|
enabled: true,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getConfig, getStorage, getFetch, isValidRedirectUrl } from './chunk-
|
|
1
|
+
import { getConfig, getStorage, getFetch, isValidRedirectUrl } from './chunk-6NTZVDLW.js';
|
|
2
2
|
|
|
3
3
|
// src/core/client.ts
|
|
4
4
|
var isRefreshing = false;
|
|
@@ -70,9 +70,8 @@ function updateStoredTokens(accessToken, refreshToken) {
|
|
|
70
70
|
}
|
|
71
71
|
parsed.accessToken = accessToken;
|
|
72
72
|
parsed.refreshToken = refreshToken;
|
|
73
|
-
parsed._version = (parsed._version || 0) + 1;
|
|
74
73
|
storage.setItem(storageKey, JSON.stringify(parsed));
|
|
75
|
-
import('./auth.svelte-
|
|
74
|
+
import('./auth.svelte-WPCYPHEE.js').then(({ authStore }) => {
|
|
76
75
|
authStore.updateTokens(accessToken, refreshToken);
|
|
77
76
|
}).catch(() => {
|
|
78
77
|
});
|
|
@@ -91,13 +90,17 @@ async function refreshAccessToken() {
|
|
|
91
90
|
if (!refreshToken) {
|
|
92
91
|
return false;
|
|
93
92
|
}
|
|
93
|
+
const timeoutMs = config.requestTimeout ?? 3e4;
|
|
94
|
+
const controller = new AbortController();
|
|
95
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
94
96
|
try {
|
|
95
97
|
const response = await fetchFn(`${config.baseUrl}/auth/refresh`, {
|
|
96
98
|
method: "POST",
|
|
97
99
|
headers: {
|
|
98
100
|
"Content-Type": "application/json"
|
|
99
101
|
},
|
|
100
|
-
body: JSON.stringify({ refreshToken })
|
|
102
|
+
body: JSON.stringify({ refreshToken }),
|
|
103
|
+
signal: controller.signal
|
|
101
104
|
});
|
|
102
105
|
if (response.ok) {
|
|
103
106
|
let apiResponse;
|
|
@@ -126,6 +129,8 @@ async function refreshAccessToken() {
|
|
|
126
129
|
}
|
|
127
130
|
} catch (error) {
|
|
128
131
|
config.onAuthError?.(error instanceof Error ? error : new Error("Token refresh failed"));
|
|
132
|
+
} finally {
|
|
133
|
+
clearTimeout(timeoutId);
|
|
129
134
|
}
|
|
130
135
|
return false;
|
|
131
136
|
}
|
|
@@ -141,7 +146,10 @@ function extractData(response) {
|
|
|
141
146
|
}
|
|
142
147
|
return response;
|
|
143
148
|
}
|
|
144
|
-
|
|
149
|
+
function apiRequest(endpoint, options = {}) {
|
|
150
|
+
return apiRequestInternal(endpoint, options, false);
|
|
151
|
+
}
|
|
152
|
+
async function apiRequestInternal(endpoint, options, isRetry) {
|
|
145
153
|
const { authenticated = false, customFetch, body, timeout, signal, ...fetchOptions } = options;
|
|
146
154
|
const config = getConfig();
|
|
147
155
|
const fetchFn = customFetch ?? getFetch();
|
|
@@ -179,12 +187,21 @@ async function apiRequest(endpoint, options = {}) {
|
|
|
179
187
|
});
|
|
180
188
|
clearTimeout(timeoutId);
|
|
181
189
|
if (response.status === 401 && authenticated && typeof window !== "undefined") {
|
|
190
|
+
if (isRetry) {
|
|
191
|
+
clearStoredAuth();
|
|
192
|
+
config.onLogout?.();
|
|
193
|
+
throw new Error("Authentication failed. Please sign in again.");
|
|
194
|
+
}
|
|
182
195
|
if (!isRefreshing) {
|
|
183
196
|
isRefreshing = true;
|
|
184
|
-
|
|
185
|
-
|
|
197
|
+
let refreshed = false;
|
|
198
|
+
try {
|
|
199
|
+
refreshed = await refreshAccessToken();
|
|
200
|
+
} finally {
|
|
201
|
+
isRefreshing = false;
|
|
202
|
+
}
|
|
186
203
|
if (refreshed) {
|
|
187
|
-
return
|
|
204
|
+
return apiRequestInternal(endpoint, options, true);
|
|
188
205
|
} else {
|
|
189
206
|
clearStoredAuth();
|
|
190
207
|
config.onLogout?.();
|
|
@@ -194,21 +211,29 @@ async function apiRequest(endpoint, options = {}) {
|
|
|
194
211
|
const REFRESH_TIMEOUT_MS = 3e4;
|
|
195
212
|
return new Promise((resolve, reject) => {
|
|
196
213
|
let settled = false;
|
|
197
|
-
|
|
198
|
-
const timeoutId2 = setTimeout(() => {
|
|
214
|
+
const refreshTimeoutId = setTimeout(() => {
|
|
199
215
|
if (!settled) {
|
|
200
216
|
settled = true;
|
|
201
217
|
unsubscribe?.();
|
|
202
218
|
reject(new Error("Token refresh timed out. Please sign in again."));
|
|
203
219
|
}
|
|
204
220
|
}, REFRESH_TIMEOUT_MS);
|
|
205
|
-
unsubscribe =
|
|
221
|
+
let unsubscribe = null;
|
|
222
|
+
try {
|
|
223
|
+
unsubscribe = subscribeTokenRefresh(() => {
|
|
224
|
+
if (!settled) {
|
|
225
|
+
settled = true;
|
|
226
|
+
clearTimeout(refreshTimeoutId);
|
|
227
|
+
apiRequestInternal(endpoint, options, true).then(resolve).catch(reject);
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
} catch (subscribeError) {
|
|
231
|
+
clearTimeout(refreshTimeoutId);
|
|
206
232
|
if (!settled) {
|
|
207
233
|
settled = true;
|
|
208
|
-
|
|
209
|
-
apiRequest(endpoint, options).then(resolve).catch(reject);
|
|
234
|
+
reject(subscribeError);
|
|
210
235
|
}
|
|
211
|
-
}
|
|
236
|
+
}
|
|
212
237
|
});
|
|
213
238
|
}
|
|
214
239
|
}
|
|
@@ -294,6 +319,23 @@ var api = {
|
|
|
294
319
|
};
|
|
295
320
|
|
|
296
321
|
// src/core/api.ts
|
|
322
|
+
async function fetchWithTimeout(url, init) {
|
|
323
|
+
const config = getConfig();
|
|
324
|
+
const fetchFn = config.fetch ?? fetch;
|
|
325
|
+
const timeoutMs = config.requestTimeout ?? 3e4;
|
|
326
|
+
const controller = new AbortController();
|
|
327
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
328
|
+
try {
|
|
329
|
+
return await fetchFn(url, { ...init, signal: controller.signal });
|
|
330
|
+
} catch (error) {
|
|
331
|
+
if (error instanceof DOMException && error.name === "AbortError") {
|
|
332
|
+
throw new Error(`Request timed out after ${timeoutMs}ms`);
|
|
333
|
+
}
|
|
334
|
+
throw error;
|
|
335
|
+
} finally {
|
|
336
|
+
clearTimeout(timeoutId);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
297
339
|
var authApi = {
|
|
298
340
|
// ============================================================================
|
|
299
341
|
// Authentication
|
|
@@ -318,8 +360,9 @@ var authApi = {
|
|
|
318
360
|
return extractData(response);
|
|
319
361
|
} catch (error) {
|
|
320
362
|
const config = getConfig();
|
|
321
|
-
|
|
322
|
-
|
|
363
|
+
const err = error instanceof Error ? error : new Error("Logout API call failed");
|
|
364
|
+
config.onAuthError?.(err);
|
|
365
|
+
return { success: true, serverError: err.message };
|
|
323
366
|
}
|
|
324
367
|
},
|
|
325
368
|
/**
|
|
@@ -515,13 +558,12 @@ var authApi = {
|
|
|
515
558
|
*/
|
|
516
559
|
async verifyMFAChallenge(data) {
|
|
517
560
|
const config = getConfig();
|
|
518
|
-
const fetchFn = config.fetch ?? fetch;
|
|
519
561
|
const requestBody = {
|
|
520
562
|
code: data.code,
|
|
521
563
|
type: data.method === "backup" ? "backup" : "totp",
|
|
522
564
|
trustDevice: data.trustDevice
|
|
523
565
|
};
|
|
524
|
-
const response = await
|
|
566
|
+
const response = await fetchWithTimeout(`${config.baseUrl}/auth/mfa/challenge`, {
|
|
525
567
|
method: "POST",
|
|
526
568
|
headers: {
|
|
527
569
|
"Content-Type": "application/json",
|
|
@@ -650,8 +692,7 @@ var authApi = {
|
|
|
650
692
|
throw new Error("Not authenticated");
|
|
651
693
|
}
|
|
652
694
|
const config = getConfig();
|
|
653
|
-
const
|
|
654
|
-
const response = await fetchFn(`${config.baseUrl}/auth/sso/link`, {
|
|
695
|
+
const response = await fetchWithTimeout(`${config.baseUrl}/auth/sso/link`, {
|
|
655
696
|
method: "POST",
|
|
656
697
|
headers: {
|
|
657
698
|
"Content-Type": "application/json",
|
|
@@ -36,6 +36,34 @@ function getDefaultStorage() {
|
|
|
36
36
|
}
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
|
+
function createSessionStorage() {
|
|
40
|
+
if (typeof window !== "undefined" && window.sessionStorage) {
|
|
41
|
+
return {
|
|
42
|
+
getItem: (key) => sessionStorage.getItem(key),
|
|
43
|
+
setItem: (key, value) => sessionStorage.setItem(key, value),
|
|
44
|
+
removeItem: (key) => sessionStorage.removeItem(key)
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
getItem: () => null,
|
|
49
|
+
setItem: () => {
|
|
50
|
+
},
|
|
51
|
+
removeItem: () => {
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function createMemoryStorage() {
|
|
56
|
+
const store = /* @__PURE__ */ new Map();
|
|
57
|
+
return {
|
|
58
|
+
getItem: (key) => store.get(key) ?? null,
|
|
59
|
+
setItem: (key, value) => {
|
|
60
|
+
store.set(key, value);
|
|
61
|
+
},
|
|
62
|
+
removeItem: (key) => {
|
|
63
|
+
store.delete(key);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
39
67
|
function getStorage() {
|
|
40
68
|
const cfg = getConfig();
|
|
41
69
|
return cfg.storage ?? getDefaultStorage();
|
|
@@ -91,7 +119,8 @@ function isTokenExpired(token) {
|
|
|
91
119
|
if (!payload || !payload.exp) {
|
|
92
120
|
return true;
|
|
93
121
|
}
|
|
94
|
-
|
|
122
|
+
const CLOCK_SKEW_MS = 3e4;
|
|
123
|
+
return payload.exp * 1e3 < Date.now() - CLOCK_SKEW_MS;
|
|
95
124
|
}
|
|
96
125
|
function getTokenRemainingTime(token) {
|
|
97
126
|
const payload = decodeJWT(token);
|
|
@@ -122,4 +151,4 @@ function extractClaims(token, claims) {
|
|
|
122
151
|
return result;
|
|
123
152
|
}
|
|
124
153
|
|
|
125
|
-
export { decodeJWT, extractClaims, getConfig, getDefaultStorage, getFetch, getStorage, getTokenExpiration, getTokenRemainingTime, initAuth, isInitialized, isTokenExpired, isValidRedirectUrl, resetConfig };
|
|
154
|
+
export { createMemoryStorage, createSessionStorage, decodeJWT, extractClaims, getConfig, getDefaultStorage, getFetch, getStorage, getTokenExpiration, getTokenRemainingTime, initAuth, isInitialized, isTokenExpired, isValidRedirectUrl, resetConfig };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { authApi } from './chunk-
|
|
2
|
-
import { decodeJWT, isInitialized, getConfig, getStorage, getDefaultStorage } from './chunk-
|
|
1
|
+
import { authApi } from './chunk-2QYFVJEM.js';
|
|
2
|
+
import { decodeJWT, isInitialized, getConfig, getStorage, getDefaultStorage } from './chunk-6NTZVDLW.js';
|
|
3
3
|
|
|
4
4
|
// src/svelte/stores/auth.svelte.ts
|
|
5
5
|
function getStorageKey() {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { authApi } from './chunk-
|
|
1
|
+
import { authApi } from './chunk-2QYFVJEM.js';
|
|
2
2
|
|
|
3
3
|
// src/core/guards.ts
|
|
4
4
|
function isMfaChallengeResponse(response) {
|
|
@@ -60,7 +60,7 @@ var AuthService = class {
|
|
|
60
60
|
}
|
|
61
61
|
if (options?.autoSetAuth !== false && !isMfaChallengeResponse(response)) {
|
|
62
62
|
try {
|
|
63
|
-
const { authStore } = await import('./auth.svelte-
|
|
63
|
+
const { authStore } = await import('./auth.svelte-WPCYPHEE.js');
|
|
64
64
|
authStore.setAuth(
|
|
65
65
|
response.accessToken,
|
|
66
66
|
response.refreshToken,
|
|
@@ -246,7 +246,7 @@ var AuthService = class {
|
|
|
246
246
|
}
|
|
247
247
|
if (options?.autoSetAuth !== false) {
|
|
248
248
|
try {
|
|
249
|
-
const { authStore } = await import('./auth.svelte-
|
|
249
|
+
const { authStore } = await import('./auth.svelte-WPCYPHEE.js');
|
|
250
250
|
authStore.setAuth(
|
|
251
251
|
response.accessToken,
|
|
252
252
|
response.refreshToken,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { authService } from './chunk-
|
|
2
|
-
import { authStore, currentUser, isAuthenticated, authActions } from './chunk-
|
|
3
|
-
import { isInitialized, initAuth } from './chunk-
|
|
1
|
+
import { authService } from './chunk-MPPV5S7S.js';
|
|
2
|
+
import { authStore, currentUser, isAuthenticated, authActions } from './chunk-CPFM7JEI.js';
|
|
3
|
+
import { isInitialized, initAuth } from './chunk-6NTZVDLW.js';
|
|
4
4
|
|
|
5
5
|
// src/svelte/guards/auth-guard.ts
|
|
6
6
|
function checkAuth(options = {}) {
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { e as LoginCredentials, f as LoginResponse, g as LogoutResponse, R as RegisterData, k as RegisterResponse, U as User, j as ProfileUpdateData, C as ChangePasswordData, n as Session, A as ApiKey, c as CreateApiKeyRequest, d as CreateApiKeyResponse, i as MFAStatus, h as MFASetupResponse, M as MFAChallengeData, D as Device, p as UserPreferences, L as LinkedAccount, m as SecurityEvent, P as Pagination } from '../types-
|
|
2
|
-
export { a as AuthConfig, b as AuthState, l as ResetPasswordData, S as SSOConfig, o as StorageAdapter, q as
|
|
3
|
-
export { A as AuthService, L as LoginOptions, M as MFAVerifyOptions, R as RoleDeniedError, a as authService, f as formatUserRoles, g as getAvatarFallback, b as getDisplayName, c as getGreeting, d as getUserEmail, e as getUserInitials, i as isRoleDeniedError } from '../user-utils-
|
|
1
|
+
import { e as LoginCredentials, f as LoginResponse, g as LogoutResponse, R as RegisterData, k as RegisterResponse, U as User, j as ProfileUpdateData, C as ChangePasswordData, n as Session, A as ApiKey, c as CreateApiKeyRequest, d as CreateApiKeyResponse, i as MFAStatus, h as MFASetupResponse, M as MFAChallengeData, D as Device, p as UserPreferences, L as LinkedAccount, m as SecurityEvent, P as Pagination } from '../types-Di6SR1q5.js';
|
|
2
|
+
export { a as AuthConfig, b as AuthState, l as ResetPasswordData, S as SSOConfig, o as StorageAdapter, q as createMemoryStorage, r as createSessionStorage, s as getConfig, t as getDefaultStorage, u as getFetch, v as getStorage, w as initAuth, x as isInitialized, y as resetConfig } from '../types-Di6SR1q5.js';
|
|
3
|
+
export { A as AuthService, L as LoginOptions, M as MFAVerifyOptions, R as RoleDeniedError, a as authService, f as formatUserRoles, g as getAvatarFallback, b as getDisplayName, c as getGreeting, d as getUserEmail, e as getUserInitials, i as isRoleDeniedError } from '../user-utils-C-JbXqbj.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* HTTP Client
|
|
@@ -47,9 +47,10 @@ declare function getSessionToken(): string | null;
|
|
|
47
47
|
* Update stored tokens.
|
|
48
48
|
* Also updates the Svelte auth store if available.
|
|
49
49
|
*
|
|
50
|
-
* Note: The read-modify-write on localStorage is not atomic across tabs
|
|
51
|
-
*
|
|
52
|
-
*
|
|
50
|
+
* Note: The read-modify-write on localStorage is not atomic across tabs —
|
|
51
|
+
* concurrent refreshes in two tabs are last-write-wins. The `storage` event
|
|
52
|
+
* listener (set up via `initCrossTabSync`) propagates whichever write landed
|
|
53
|
+
* last, so tabs converge on the same tokens.
|
|
53
54
|
*/
|
|
54
55
|
declare function updateStoredTokens(accessToken: string, refreshToken: string): void;
|
|
55
56
|
/**
|
package/dist/core/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { AuthService, RoleDeniedError, authService, formatUserRoles, getAvailableMethods, getAvatarFallback, getDisplayName, getGreeting, getMfaToken, getUserEmail, getUserInitials, isLoginSuccessResponse, isMfaChallengeResponse, isRoleDeniedError } from '../chunk-
|
|
2
|
-
export { api, apiRequest, authApi, clearStoredAuth, extractData, getAccessToken, getRefreshToken, getSessionToken, updateStoredTokens } from '../chunk-
|
|
3
|
-
export { decodeJWT, extractClaims, getConfig, getDefaultStorage, getFetch, getStorage, getTokenExpiration, getTokenRemainingTime, initAuth, isInitialized, isTokenExpired, resetConfig } from '../chunk-
|
|
1
|
+
export { AuthService, RoleDeniedError, authService, formatUserRoles, getAvailableMethods, getAvatarFallback, getDisplayName, getGreeting, getMfaToken, getUserEmail, getUserInitials, isLoginSuccessResponse, isMfaChallengeResponse, isRoleDeniedError } from '../chunk-MPPV5S7S.js';
|
|
2
|
+
export { api, apiRequest, authApi, clearStoredAuth, extractData, getAccessToken, getRefreshToken, getSessionToken, updateStoredTokens } from '../chunk-2QYFVJEM.js';
|
|
3
|
+
export { createMemoryStorage, createSessionStorage, decodeJWT, extractClaims, getConfig, getDefaultStorage, getFetch, getStorage, getTokenExpiration, getTokenRemainingTime, initAuth, isInitialized, isTokenExpired, resetConfig } from '../chunk-6NTZVDLW.js';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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 MFASetupResponse, i as MFAStatus, P as Pagination, j as ProfileUpdateData, R as RegisterData, k as RegisterResponse, l as ResetPasswordData, S as SSOConfig, m as SecurityEvent, n as Session, o as StorageAdapter, U as User, p as UserPreferences, q as
|
|
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 MFASetupResponse, i as MFAStatus, P as Pagination, j as ProfileUpdateData, R as RegisterData, k as RegisterResponse, l as ResetPasswordData, S as SSOConfig, m as SecurityEvent, n as Session, o as StorageAdapter, U as User, p as UserPreferences, q as createMemoryStorage, r as createSessionStorage, s as getConfig, t as getDefaultStorage, u as getFetch, v as getStorage, w as initAuth, x as isInitialized, y as resetConfig } from './types-Di6SR1q5.js';
|
|
2
2
|
export { ApiRequestOptions, ApiResponse, JWTPayload, api, apiRequest, authApi, clearStoredAuth, decodeJWT, extractClaims, extractData, getAccessToken, getAvailableMethods, getMfaToken, getRefreshToken, getSessionToken, getTokenExpiration, getTokenRemainingTime, isLoginSuccessResponse, isMfaChallengeResponse, isTokenExpired, updateStoredTokens } from './core/index.js';
|
|
3
|
-
export { A as AuthService, L as LoginOptions, M as MFAVerifyOptions, R as RoleDeniedError, a as authService, f as formatUserRoles, g as getAvatarFallback, b as getDisplayName, c as getGreeting, d as getUserEmail, e as getUserInitials, i as isRoleDeniedError } from './user-utils-
|
|
3
|
+
export { A as AuthService, L as LoginOptions, M as MFAVerifyOptions, R as RoleDeniedError, a as authService, f as formatUserRoles, g as getAvatarFallback, b as getDisplayName, c as getGreeting, d as getUserEmail, e as getUserInitials, i as isRoleDeniedError } from './user-utils-C-JbXqbj.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-
|
|
2
|
-
export { AuthService, RoleDeniedError, authService, formatUserRoles, getAvailableMethods, getAvatarFallback, getDisplayName, getGreeting, getMfaToken, getUserEmail, getUserInitials, isLoginSuccessResponse, isMfaChallengeResponse, isRoleDeniedError } from './chunk-
|
|
3
|
-
export { authActions, authStore, currentUser, isAuthenticated } from './chunk-
|
|
4
|
-
export { api, apiRequest, authApi, clearStoredAuth, extractData, getAccessToken, getRefreshToken, getSessionToken, updateStoredTokens } from './chunk-
|
|
5
|
-
export { decodeJWT, extractClaims, getConfig, getDefaultStorage, getFetch, getStorage, getTokenExpiration, getTokenRemainingTime, initAuth, isInitialized, isTokenExpired, resetConfig } from './chunk-
|
|
1
|
+
export { canAccess, checkAuth, createAuthClient, createAuthGuard, createAuthHook, createNavFilter, filterByAccess, filterNavSections, matchesRoute, protectedLoad, requireAuth, requirePermission, requireRole, routePatterns } from './chunk-UG4GSPGL.js';
|
|
2
|
+
export { AuthService, RoleDeniedError, authService, formatUserRoles, getAvailableMethods, getAvatarFallback, getDisplayName, getGreeting, getMfaToken, getUserEmail, getUserInitials, isLoginSuccessResponse, isMfaChallengeResponse, isRoleDeniedError } from './chunk-MPPV5S7S.js';
|
|
3
|
+
export { authActions, authStore, currentUser, isAuthenticated } from './chunk-CPFM7JEI.js';
|
|
4
|
+
export { api, apiRequest, authApi, clearStoredAuth, extractData, getAccessToken, getRefreshToken, getSessionToken, updateStoredTokens } from './chunk-2QYFVJEM.js';
|
|
5
|
+
export { createMemoryStorage, createSessionStorage, decodeJWT, extractClaims, getConfig, getDefaultStorage, getFetch, getStorage, getTokenExpiration, getTokenRemainingTime, initAuth, isInitialized, isTokenExpired, resetConfig } from './chunk-6NTZVDLW.js';
|
package/dist/svelte/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { b as AuthState, U as User, a as AuthConfig } from '../types-
|
|
2
|
-
export {
|
|
3
|
-
import { a as authService } from '../user-utils-
|
|
4
|
-
export { R as RoleDeniedError, f as formatUserRoles, g as getAvatarFallback, b as getDisplayName, c as getGreeting, d as getUserEmail, e as getUserInitials, i as isRoleDeniedError } from '../user-utils-
|
|
1
|
+
import { b as AuthState, U as User, a as AuthConfig } from '../types-Di6SR1q5.js';
|
|
2
|
+
export { w as initAuth, x as isInitialized } from '../types-Di6SR1q5.js';
|
|
3
|
+
import { a as authService } from '../user-utils-C-JbXqbj.js';
|
|
4
|
+
export { R as RoleDeniedError, f as formatUserRoles, g as getAvatarFallback, b as getDisplayName, c as getGreeting, d as getUserEmail, e as getUserInitials, i as isRoleDeniedError } from '../user-utils-C-JbXqbj.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Auth Store
|
package/dist/svelte/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-
|
|
2
|
-
export { RoleDeniedError, formatUserRoles, getAvatarFallback, getDisplayName, getGreeting, getUserEmail, getUserInitials, isRoleDeniedError } from '../chunk-
|
|
3
|
-
export { authActions, authStore, currentUser, isAuthenticated } from '../chunk-
|
|
4
|
-
import '../chunk-
|
|
5
|
-
export { initAuth, isInitialized } from '../chunk-
|
|
1
|
+
export { canAccess, checkAuth, createAuthClient, createAuthGuard, createAuthHook, createNavFilter, filterByAccess, filterNavSections, matchesRoute, protectedLoad, requireAuth, requirePermission, requireRole, routePatterns } from '../chunk-UG4GSPGL.js';
|
|
2
|
+
export { RoleDeniedError, formatUserRoles, getAvatarFallback, getDisplayName, getGreeting, getUserEmail, getUserInitials, isRoleDeniedError } from '../chunk-MPPV5S7S.js';
|
|
3
|
+
export { authActions, authStore, currentUser, isAuthenticated } from '../chunk-CPFM7JEI.js';
|
|
4
|
+
import '../chunk-2QYFVJEM.js';
|
|
5
|
+
export { initAuth, isInitialized } from '../chunk-6NTZVDLW.js';
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { U as User, D as Device, f as LoginResponse, m as SecurityEvent, n as Session, A as ApiKey, L as LinkedAccount, g as LogoutResponse, h as MFASetupResponse, i as MFAStatus, k as RegisterResponse, p as UserPreferences, o as StorageAdapter, b as AuthState, a as AuthConfig } from '../types-
|
|
1
|
+
import { U as User, D as Device, f as LoginResponse, m as SecurityEvent, n as Session, A as ApiKey, L as LinkedAccount, g as LogoutResponse, h as MFASetupResponse, i as MFAStatus, k as RegisterResponse, p as UserPreferences, o as StorageAdapter, b as AuthState, a as AuthConfig } from '../types-Di6SR1q5.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* User Fixtures
|
package/dist/testing/index.js
CHANGED
|
@@ -105,8 +105,29 @@ declare function resetConfig(): void;
|
|
|
105
105
|
/**
|
|
106
106
|
* Get the default storage adapter.
|
|
107
107
|
* Returns localStorage in browser, or a no-op adapter in SSR.
|
|
108
|
+
*
|
|
109
|
+
* SECURITY NOTE: localStorage persists tokens (including the long-lived
|
|
110
|
+
* refresh token) where any XSS on the page can read them. It is the default
|
|
111
|
+
* for cross-tab session continuity, but consider the safer alternatives:
|
|
112
|
+
* `createSessionStorage()` (per-tab, cleared on close),
|
|
113
|
+
* `createMemoryStorage()` (never persisted, lost on reload), or an
|
|
114
|
+
* httpOnly-cookie flow on your backend so tokens never reach JS at all.
|
|
115
|
+
* Pass the adapter via `initAuth({ storage: ... })`.
|
|
108
116
|
*/
|
|
109
117
|
declare function getDefaultStorage(): StorageAdapter;
|
|
118
|
+
/**
|
|
119
|
+
* Storage adapter backed by sessionStorage: tokens live per-tab and are
|
|
120
|
+
* cleared when the tab closes. Safer than localStorage against persistent
|
|
121
|
+
* token theft, at the cost of cross-tab session continuity.
|
|
122
|
+
* Falls back to no-op in SSR.
|
|
123
|
+
*/
|
|
124
|
+
declare function createSessionStorage(): StorageAdapter;
|
|
125
|
+
/**
|
|
126
|
+
* In-memory storage adapter: tokens are never persisted and are lost on
|
|
127
|
+
* page reload (the user re-authenticates or a silent SSO flow restores the
|
|
128
|
+
* session). The safest JS-side option against token exfiltration.
|
|
129
|
+
*/
|
|
130
|
+
declare function createMemoryStorage(): StorageAdapter;
|
|
110
131
|
/**
|
|
111
132
|
* Get the storage adapter from config or use default.
|
|
112
133
|
*/
|
|
@@ -174,6 +195,12 @@ interface LogoutResponse {
|
|
|
174
195
|
message?: string;
|
|
175
196
|
ssoLogout?: boolean;
|
|
176
197
|
logoutUrl?: string;
|
|
198
|
+
/**
|
|
199
|
+
* Set when the server-side logout call failed. `success` stays true so
|
|
200
|
+
* callers clear local state, but the server session may still be alive —
|
|
201
|
+
* check this to warn the user or retry revocation.
|
|
202
|
+
*/
|
|
203
|
+
serverError?: string;
|
|
177
204
|
}
|
|
178
205
|
interface RegisterResponse {
|
|
179
206
|
message: string;
|
|
@@ -320,4 +347,4 @@ interface ResetPasswordData {
|
|
|
320
347
|
newPassword: string;
|
|
321
348
|
}
|
|
322
349
|
|
|
323
|
-
export { type ApiKey as A, type ChangePasswordData as C, type Device as D, type LinkedAccount as L, type MFAChallengeData as M, type Pagination as P, type RegisterData as R, type SSOConfig as S, type User as U, type AuthConfig as a, type AuthState as b, type CreateApiKeyRequest as c, type CreateApiKeyResponse as d, type LoginCredentials as e, type LoginResponse as f, type LogoutResponse as g, type MFASetupResponse as h, type MFAStatus as i, type ProfileUpdateData as j, type RegisterResponse as k, type ResetPasswordData as l, type SecurityEvent as m, type Session as n, type StorageAdapter as o, type UserPreferences as p,
|
|
350
|
+
export { type ApiKey as A, type ChangePasswordData as C, type Device as D, type LinkedAccount as L, type MFAChallengeData as M, type Pagination as P, type RegisterData as R, type SSOConfig as S, type User as U, type AuthConfig as a, type AuthState as b, type CreateApiKeyRequest as c, type CreateApiKeyResponse as d, type LoginCredentials as e, type LoginResponse as f, type LogoutResponse as g, type MFASetupResponse as h, type MFAStatus as i, type ProfileUpdateData as j, type RegisterResponse as k, type ResetPasswordData as l, type SecurityEvent as m, type Session as n, type StorageAdapter as o, type UserPreferences as p, createMemoryStorage as q, createSessionStorage as r, getConfig as s, getDefaultStorage as t, getFetch as u, getStorage as v, initAuth as w, isInitialized as x, resetConfig as y };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { e as LoginCredentials, f as LoginResponse, g as LogoutResponse, R as RegisterData, k as RegisterResponse, U as User, j as ProfileUpdateData, n as Session, A as ApiKey, c as CreateApiKeyRequest, d as CreateApiKeyResponse, i as MFAStatus, h as MFASetupResponse, M as MFAChallengeData, D as Device, p as UserPreferences, L as LinkedAccount, m as SecurityEvent, P as Pagination } from './types-
|
|
1
|
+
import { e as LoginCredentials, f as LoginResponse, g as LogoutResponse, R as RegisterData, k as RegisterResponse, U as User, j as ProfileUpdateData, n as Session, A as ApiKey, c as CreateApiKeyRequest, d as CreateApiKeyResponse, i as MFAStatus, h as MFASetupResponse, M as MFAChallengeData, D as Device, p as UserPreferences, L as LinkedAccount, m as SecurityEvent, P as Pagination } from './types-Di6SR1q5.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Auth Service
|
package/package.json
CHANGED