@djangocfg/api 2.1.581 → 2.1.583
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 +18 -0
- package/dist/auth.cjs +272 -80
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.mjs +272 -80
- package/dist/auth.mjs.map +1 -1
- package/dist/clients.cjs +243 -54
- package/dist/clients.cjs.map +1 -1
- package/dist/clients.mjs +243 -54
- package/dist/clients.mjs.map +1 -1
- package/dist/hooks.cjs +243 -54
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.mjs +243 -54
- package/dist/hooks.mjs.map +1 -1
- package/dist/index.cjs +248 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +85 -1
- package/dist/index.d.ts +85 -1
- package/dist/index.mjs +248 -54
- package/dist/index.mjs.map +1 -1
- package/dist/storage.cjs +269 -0
- package/dist/storage.cjs.map +1 -0
- package/dist/storage.d.cts +85 -0
- package/dist/storage.d.ts +85 -0
- package/dist/storage.mjs +248 -0
- package/dist/storage.mjs.map +1 -0
- package/package.json +8 -2
- package/src/__tests__/noStorageLiterals.test.ts +27 -0
- package/src/__tests__/storage.test.ts +134 -0
- package/src/__tests__/storageSsr.test.ts +14 -0
- package/src/_api/generated/helpers/auth.ts +27 -64
- package/src/_api/generated/helpers/index.ts +12 -0
- package/src/_api/generated/helpers/keys.ts +328 -0
- package/src/auth/__tests__/authRedirect.test.ts +1 -1
- package/src/auth/__tests__/profileCache.test.ts +1 -1
- package/src/auth/context/AuthContext.tsx +2 -1
- package/src/auth/hooks/useAuthRedirect.ts +3 -2
- package/src/auth/hooks/useGithubAuth.ts +13 -8
- package/src/auth/hooks/useLocalStorage.ts +7 -7
- package/src/auth/hooks/useProfileCache.ts +2 -1
- package/src/auth/hooks/useSessionStorage.ts +7 -7
- package/src/storage.ts +21 -0
package/README.md
CHANGED
|
@@ -102,6 +102,24 @@ valid, so the auth form cannot fix it, and redirecting would loop on the saved
|
|
|
102
102
|
URL. Render a distinct "not authorised" state instead. `resolveGuardIsLoading`
|
|
103
103
|
returns `false` once forbidden, so the preloader never spins on it.
|
|
104
104
|
|
|
105
|
+
## Storage keys
|
|
106
|
+
|
|
107
|
+
Every browser-storage key is `cfg.<area>.<name>` (framework) or
|
|
108
|
+
`<owner>.<area>.<name>` (app). Use the registry, never a literal or raw `localStorage`:
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
import { CFG_KEYS, cfgStorage, createStorage } from '@djangocfg/api/storage';
|
|
112
|
+
|
|
113
|
+
cfgStorage.read(CFG_KEYS.email.key);
|
|
114
|
+
cfgStorage.clearAll(); // sign-out: removes personal keys
|
|
115
|
+
|
|
116
|
+
const storage = createStorage('kino');
|
|
117
|
+
storage.writeJSON(storage.key('player', 'volume'), 0.4);
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Old key names are not migrated. Full rules, the key list and cross-tab behavior:
|
|
121
|
+
[`@docs/STORAGE_KEYS.md`](./@docs/STORAGE_KEYS.md).
|
|
122
|
+
|
|
105
123
|
## Token storage & DPoP
|
|
106
124
|
|
|
107
125
|
The token lives in the shared `auth` store (localStorage by default, switchable
|
package/dist/auth.cjs
CHANGED
|
@@ -297,77 +297,264 @@ var APIError = class extends Error {
|
|
|
297
297
|
}
|
|
298
298
|
};
|
|
299
299
|
|
|
300
|
-
// src/_api/generated/helpers/
|
|
301
|
-
var
|
|
302
|
-
var
|
|
303
|
-
var
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
300
|
+
// src/_api/generated/helpers/keys.ts
|
|
301
|
+
var k = /* @__PURE__ */ __name((key, store, personal) => ({ key, store, personal }), "k");
|
|
302
|
+
var f = /* @__PURE__ */ __name((prefix, store, personal) => ({ prefix, store, personal }), "f");
|
|
303
|
+
var CFG_KEYS = {
|
|
304
|
+
accessToken: k("cfg.auth.access_token", "local", true),
|
|
305
|
+
refreshToken: k("cfg.auth.refresh_token", "local", true),
|
|
306
|
+
apiKey: k("cfg.auth.api_key", "local", true),
|
|
307
|
+
email: k("cfg.auth.email", "local", false),
|
|
308
|
+
emailTs: k("cfg.auth.email_ts", "local", false),
|
|
309
|
+
redirectUrl: k("cfg.auth.redirect_url", "session", true),
|
|
310
|
+
redirectUrlTs: k("cfg.auth.redirect_url_ts", "session", true),
|
|
311
|
+
oauthState: k("cfg.auth.oauth_state", "session", true),
|
|
312
|
+
oauthProvider: k("cfg.auth.oauth_provider", "session", true),
|
|
313
|
+
oauthRememberMe: k("cfg.auth.oauth_remember_me", "session", true),
|
|
314
|
+
profileCache: k("cfg.profile.cache", "local", true),
|
|
315
|
+
monitorSessionId: k("cfg.monitor.session_id", "local", false),
|
|
316
|
+
monitorSessionCookie: k("cfg.monitor.session_id", "cookie", false),
|
|
317
|
+
monitorDebug: k("cfg.monitor.debug", "local", false),
|
|
318
|
+
uiTabId: k("cfg.ui.tab_id", "session", false),
|
|
319
|
+
uiRouterSerial: k("cfg.ui.router_serial", "session", false),
|
|
320
|
+
uiState: k("cfg.ui.state", "local", false),
|
|
321
|
+
chatSpeechLanguage: k("cfg.chat.speech_language", "local", false),
|
|
322
|
+
chatRecentTools: k("cfg.chat.recent_tools", "local", false),
|
|
323
|
+
formsSpeechDebug: k("cfg.forms.speech_debug", "local", false),
|
|
324
|
+
formsSpeechPrefs: k("cfg.forms.speech_prefs", "local", false),
|
|
325
|
+
agentPlaygroundApiKeyId: k("cfg.agent.playground_api_key_id", "session", true),
|
|
326
|
+
agentPlaygroundBearer: k("cfg.agent.playground_bearer", "session", true),
|
|
327
|
+
agentEndpointDoc: k("cfg.agent.endpoint_doc", "session", false)
|
|
328
|
+
};
|
|
329
|
+
var CFG_FAMILIES = {
|
|
330
|
+
chatDraft: f("cfg.chat.draft.", "session", true),
|
|
331
|
+
dataTree: f("cfg.data.tree.", "local", false),
|
|
332
|
+
agentEndpointDraft: f("cfg.agent.endpoint_draft.", "local", false)
|
|
333
|
+
};
|
|
334
|
+
var OWNER_RE = /^[a-z][a-z0-9_]*$/;
|
|
335
|
+
function normalizeSegment(raw) {
|
|
336
|
+
return raw.trim().toLowerCase().replace(/[^a-z0-9_]+/g, "_").replace(/^_+|_+$/g, "");
|
|
337
|
+
}
|
|
338
|
+
__name(normalizeSegment, "normalizeSegment");
|
|
339
|
+
var hasWindow = /* @__PURE__ */ __name(() => typeof window !== "undefined", "hasWindow");
|
|
340
|
+
function nativeStorage(store) {
|
|
341
|
+
if (!hasWindow()) return null;
|
|
342
|
+
try {
|
|
343
|
+
return store === "session" ? window.sessionStorage : window.localStorage;
|
|
344
|
+
} catch {
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
__name(nativeStorage, "nativeStorage");
|
|
349
|
+
function cookieNames() {
|
|
350
|
+
if (!hasWindow()) return [];
|
|
351
|
+
try {
|
|
352
|
+
return document.cookie.split("; ").map((part) => decodeURIComponent(part.split("=")[0] ?? "")).filter(Boolean);
|
|
353
|
+
} catch {
|
|
354
|
+
return [];
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
__name(cookieNames, "cookieNames");
|
|
358
|
+
function createStorage(owner, options = {}) {
|
|
359
|
+
if (!OWNER_RE.test(owner)) {
|
|
360
|
+
throw new TypeError(`createStorage: owner "${owner}" must match ${OWNER_RE}`);
|
|
361
|
+
}
|
|
362
|
+
const prefix = `${owner}.`;
|
|
363
|
+
const pattern = owner === "cfg" ? /^cfg(\.[a-z0-9_]+)+$/ : new RegExp(`^(cfg|${owner})(\\.[a-z0-9_]+)+$`);
|
|
364
|
+
const cookieMaxAge = options.cookieMaxAgeSeconds ?? 60 * 60 * 24 * 30;
|
|
365
|
+
const specs = Object.values(options.keys ?? {});
|
|
366
|
+
const families = Object.values(options.families ?? {});
|
|
367
|
+
const specByKey = /* @__PURE__ */ new Map();
|
|
368
|
+
for (const spec of specs) specByKey.set(spec.key, [...specByKey.get(spec.key) ?? [], spec]);
|
|
369
|
+
const memory = {
|
|
370
|
+
local: /* @__PURE__ */ new Map(),
|
|
371
|
+
session: /* @__PURE__ */ new Map(),
|
|
372
|
+
cookie: /* @__PURE__ */ new Map()
|
|
373
|
+
};
|
|
374
|
+
const isValid = /* @__PURE__ */ __name((key) => pattern.test(key), "isValid");
|
|
375
|
+
const assertValid = /* @__PURE__ */ __name((key) => {
|
|
376
|
+
if (!isValid(key)) throw new TypeError(`storage key "${key}" must match ${pattern}`);
|
|
377
|
+
}, "assertValid");
|
|
378
|
+
const assertOwned = /* @__PURE__ */ __name((key) => {
|
|
379
|
+
assertValid(key);
|
|
380
|
+
if (!key.startsWith(prefix)) throw new TypeError(`storage key "${key}" is not owned by "${owner}"`);
|
|
381
|
+
}, "assertOwned");
|
|
382
|
+
function rawGet(store, key) {
|
|
383
|
+
if (!hasWindow()) return null;
|
|
384
|
+
if (store === "cookie") {
|
|
385
|
+
try {
|
|
386
|
+
const escaped = encodeURIComponent(key).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
387
|
+
const match = document.cookie.match(new RegExp(`(?:^|;\\s*)${escaped}=([^;]*)`));
|
|
388
|
+
if (match?.[1] !== void 0) return decodeURIComponent(match[1]);
|
|
389
|
+
} catch {
|
|
390
|
+
}
|
|
391
|
+
return memory.cookie.get(key) ?? null;
|
|
312
392
|
}
|
|
313
|
-
},
|
|
314
|
-
set(key, value) {
|
|
315
|
-
if (!isBrowser) return;
|
|
316
393
|
try {
|
|
317
|
-
|
|
318
|
-
|
|
394
|
+
const value = nativeStorage(store)?.getItem(key) ?? null;
|
|
395
|
+
if (value !== null) return value;
|
|
319
396
|
} catch {
|
|
320
397
|
}
|
|
398
|
+
return memory[store].get(key) ?? null;
|
|
321
399
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
if (!isBrowser) return null;
|
|
400
|
+
__name(rawGet, "rawGet");
|
|
401
|
+
function rawSet(store, key, value) {
|
|
402
|
+
if (!hasWindow()) return false;
|
|
326
403
|
try {
|
|
327
|
-
|
|
404
|
+
if (store === "cookie") {
|
|
405
|
+
const secure = window.location.protocol === "https:" ? "; Secure" : "";
|
|
406
|
+
document.cookie = `${encodeURIComponent(key)}=${encodeURIComponent(value)}; Path=/; Max-Age=${cookieMaxAge}; SameSite=Lax${secure}`;
|
|
407
|
+
if (rawGet("cookie", key) === value && !memory.cookie.has(key)) return true;
|
|
408
|
+
memory.cookie.set(key, value);
|
|
409
|
+
return false;
|
|
410
|
+
}
|
|
411
|
+
const native = nativeStorage(store);
|
|
412
|
+
if (!native) throw new Error("storage unavailable");
|
|
413
|
+
native.setItem(key, value);
|
|
414
|
+
memory[store].delete(key);
|
|
415
|
+
return true;
|
|
328
416
|
} catch {
|
|
329
|
-
|
|
417
|
+
memory[store].set(key, value);
|
|
418
|
+
return false;
|
|
330
419
|
}
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
|
|
420
|
+
}
|
|
421
|
+
__name(rawSet, "rawSet");
|
|
422
|
+
function rawRemove(store, key) {
|
|
423
|
+
memory[store].delete(key);
|
|
424
|
+
if (!hasWindow()) return;
|
|
334
425
|
try {
|
|
335
|
-
if (
|
|
336
|
-
|
|
426
|
+
if (store === "cookie") {
|
|
427
|
+
const secure = window.location.protocol === "https:" ? "; Secure" : "";
|
|
428
|
+
document.cookie = `${encodeURIComponent(key)}=; Path=/; Max-Age=0; SameSite=Lax${secure}`;
|
|
429
|
+
} else {
|
|
430
|
+
nativeStorage(store)?.removeItem(key);
|
|
431
|
+
}
|
|
337
432
|
} catch {
|
|
338
433
|
}
|
|
339
434
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
435
|
+
__name(rawRemove, "rawRemove");
|
|
436
|
+
function resolveStore(key, store) {
|
|
437
|
+
return store ?? specByKey.get(key)?.[0]?.store ?? "local";
|
|
438
|
+
}
|
|
439
|
+
__name(resolveStore, "resolveStore");
|
|
440
|
+
function listKeys(store, startsWith) {
|
|
441
|
+
const out = [];
|
|
345
442
|
try {
|
|
346
|
-
const
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
443
|
+
const native = nativeStorage(store);
|
|
444
|
+
if (native) {
|
|
445
|
+
for (let i = 0; i < native.length; i += 1) {
|
|
446
|
+
const name = native.key(i);
|
|
447
|
+
if (name?.startsWith(startsWith)) out.push(name);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
350
450
|
} catch {
|
|
351
|
-
return null;
|
|
352
451
|
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
452
|
+
for (const name of memory[store].keys()) if (name.startsWith(startsWith) && !out.includes(name)) out.push(name);
|
|
453
|
+
return out;
|
|
454
|
+
}
|
|
455
|
+
__name(listKeys, "listKeys");
|
|
456
|
+
const familyKey = /* @__PURE__ */ __name((family, id) => {
|
|
457
|
+
const part = normalizeSegment(id);
|
|
458
|
+
if (!part) throw new TypeError("storage family id is empty after normalisation");
|
|
459
|
+
return family.prefix + part;
|
|
460
|
+
}, "familyKey");
|
|
461
|
+
const api = {
|
|
462
|
+
owner,
|
|
463
|
+
key(...parts) {
|
|
464
|
+
const segments = parts.map(normalizeSegment);
|
|
465
|
+
if (segments.length === 0 || segments.some((segment) => !segment)) {
|
|
466
|
+
throw new TypeError(`storage key parts must be non-empty: ${JSON.stringify(parts)}`);
|
|
364
467
|
}
|
|
365
|
-
|
|
468
|
+
return `${prefix}${segments.join(".")}`;
|
|
469
|
+
},
|
|
470
|
+
familyKey,
|
|
471
|
+
isValid,
|
|
472
|
+
read(key, store) {
|
|
473
|
+
assertValid(key);
|
|
474
|
+
const target = resolveStore(key, store);
|
|
475
|
+
return rawGet(target, key);
|
|
476
|
+
},
|
|
477
|
+
write(key, value, store) {
|
|
478
|
+
assertOwned(key);
|
|
479
|
+
const target = resolveStore(key, store);
|
|
480
|
+
return rawSet(target, key, value);
|
|
481
|
+
},
|
|
482
|
+
remove(key, store) {
|
|
483
|
+
assertOwned(key);
|
|
484
|
+
const target = resolveStore(key, store);
|
|
485
|
+
rawRemove(target, key);
|
|
486
|
+
},
|
|
487
|
+
readJSON(key, store) {
|
|
488
|
+
const raw = api.read(key, store);
|
|
489
|
+
if (raw === null) return null;
|
|
490
|
+
try {
|
|
491
|
+
return JSON.parse(raw);
|
|
492
|
+
} catch {
|
|
493
|
+
return null;
|
|
494
|
+
}
|
|
495
|
+
},
|
|
496
|
+
writeJSON(key, value, store) {
|
|
497
|
+
return api.write(key, JSON.stringify(value), store);
|
|
498
|
+
},
|
|
499
|
+
keys(store = "local") {
|
|
500
|
+
return listKeys(store, prefix);
|
|
501
|
+
},
|
|
502
|
+
clearAll({ all = false } = {}) {
|
|
503
|
+
for (const spec of specs) {
|
|
504
|
+
if (!all && !spec.personal) continue;
|
|
505
|
+
rawRemove(spec.store, spec.key);
|
|
506
|
+
}
|
|
507
|
+
for (const family of families) {
|
|
508
|
+
if (!all && !family.personal) continue;
|
|
509
|
+
for (const name of listKeys(family.store, family.prefix)) rawRemove(family.store, name);
|
|
510
|
+
}
|
|
511
|
+
if (all) {
|
|
512
|
+
for (const store of ["local", "session"]) {
|
|
513
|
+
for (const name of listKeys(store, prefix)) rawRemove(store, name);
|
|
514
|
+
}
|
|
515
|
+
for (const name of cookieNames()) if (name.startsWith(prefix)) rawRemove("cookie", name);
|
|
516
|
+
}
|
|
517
|
+
},
|
|
518
|
+
onChange(key, listener, store = "local") {
|
|
519
|
+
assertValid(key);
|
|
520
|
+
if (!hasWindow()) return () => {
|
|
521
|
+
};
|
|
522
|
+
const handler = /* @__PURE__ */ __name((event) => {
|
|
523
|
+
if (event.storageArea !== nativeStorage(store)) return;
|
|
524
|
+
if (event.key === null || event.key === key) listener(event.key === null ? null : event.newValue);
|
|
525
|
+
}, "handler");
|
|
526
|
+
window.addEventListener("storage", handler);
|
|
527
|
+
return () => window.removeEventListener("storage", handler);
|
|
366
528
|
}
|
|
367
|
-
}
|
|
529
|
+
};
|
|
530
|
+
return api;
|
|
531
|
+
}
|
|
532
|
+
__name(createStorage, "createStorage");
|
|
533
|
+
var cfgStorage = createStorage("cfg", {
|
|
534
|
+
keys: CFG_KEYS,
|
|
535
|
+
families: CFG_FAMILIES
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
// src/_api/generated/helpers/auth.ts
|
|
539
|
+
var ACCESS_KEY = "cfg.auth.access_token";
|
|
540
|
+
var REFRESH_KEY = "cfg.auth.refresh_token";
|
|
541
|
+
var API_KEY_KEY = "cfg.auth.api_key";
|
|
542
|
+
var storage = true ? cfgStorage : createStorage2("cfg");
|
|
543
|
+
var isBrowser = typeof window !== "undefined";
|
|
544
|
+
var STORE_OF = {
|
|
545
|
+
localStorage: "local",
|
|
546
|
+
sessionStorage: "session",
|
|
547
|
+
cookie: "cookie"
|
|
368
548
|
};
|
|
369
549
|
function backendFor(mode) {
|
|
370
|
-
|
|
550
|
+
const store = STORE_OF[mode];
|
|
551
|
+
return {
|
|
552
|
+
get: /* @__PURE__ */ __name((key) => storage.read(key, store), "get"),
|
|
553
|
+
set(key, value) {
|
|
554
|
+
if (value === null) storage.remove(key, store);
|
|
555
|
+
else storage.write(key, value, store);
|
|
556
|
+
}
|
|
557
|
+
};
|
|
371
558
|
}
|
|
372
559
|
__name(backendFor, "backendFor");
|
|
373
560
|
var _storageMode = "localStorage";
|
|
@@ -556,10 +743,12 @@ var auth = {
|
|
|
556
743
|
notifySessionChanged();
|
|
557
744
|
},
|
|
558
745
|
clearTokens() {
|
|
559
|
-
for (const
|
|
746
|
+
for (const mode of ["localStorage", "sessionStorage", "cookie"]) {
|
|
747
|
+
const backend = backendFor(mode);
|
|
560
748
|
backend.set(ACCESS_KEY, null);
|
|
561
749
|
backend.set(REFRESH_KEY, null);
|
|
562
750
|
}
|
|
751
|
+
storage.clearAll();
|
|
563
752
|
notifySessionChanged();
|
|
564
753
|
},
|
|
565
754
|
/** Session-aware: token PRESENT and not past its `exp` (or a live refresh
|
|
@@ -751,7 +940,7 @@ function dpopEnabled() {
|
|
|
751
940
|
}
|
|
752
941
|
}
|
|
753
942
|
__name(dpopEnabled, "dpopEnabled");
|
|
754
|
-
var _DPOP_DB = "cfg
|
|
943
|
+
var _DPOP_DB = "cfg.auth.dpop";
|
|
755
944
|
var _DPOP_STORE = "keys";
|
|
756
945
|
var _DPOP_KEY_ID = "dpop-ec-p256";
|
|
757
946
|
function _idbOpen() {
|
|
@@ -3086,6 +3275,9 @@ var logAuthFailure = /* @__PURE__ */ __name((log, message, error) => {
|
|
|
3086
3275
|
}, "logAuthFailure");
|
|
3087
3276
|
|
|
3088
3277
|
// src/auth/hooks/useGithubAuth.ts
|
|
3278
|
+
var OAUTH_STATE_KEY = CFG_KEYS.oauthState.key;
|
|
3279
|
+
var OAUTH_PROVIDER_KEY = CFG_KEYS.oauthProvider.key;
|
|
3280
|
+
var OAUTH_REMEMBER_KEY = CFG_KEYS.oauthRememberMe.key;
|
|
3089
3281
|
var useGithubAuth = /* @__PURE__ */ __name((options = {}) => {
|
|
3090
3282
|
const { sourceUrl, rememberMe = false, onSuccess, onError, onRequires2FA, redirectUrl, skipRedirect = false } = options;
|
|
3091
3283
|
const router = useCfgRouter();
|
|
@@ -3113,9 +3305,9 @@ var useGithubAuth = /* @__PURE__ */ __name((options = {}) => {
|
|
|
3113
3305
|
}
|
|
3114
3306
|
authLogger.info("Redirecting to GitHub...", response.authorization_url);
|
|
3115
3307
|
if (typeof window !== "undefined") {
|
|
3116
|
-
sessionStorage.setItem(
|
|
3117
|
-
sessionStorage.setItem(
|
|
3118
|
-
sessionStorage.setItem(
|
|
3308
|
+
sessionStorage.setItem(OAUTH_STATE_KEY, response.state);
|
|
3309
|
+
sessionStorage.setItem(OAUTH_PROVIDER_KEY, "github");
|
|
3310
|
+
sessionStorage.setItem(OAUTH_REMEMBER_KEY, String(rememberMe));
|
|
3119
3311
|
}
|
|
3120
3312
|
window.location.href = response.authorization_url;
|
|
3121
3313
|
} catch (err) {
|
|
@@ -3138,14 +3330,14 @@ var useGithubAuth = /* @__PURE__ */ __name((options = {}) => {
|
|
|
3138
3330
|
authLogger.info("Processing GitHub OAuth callback...");
|
|
3139
3331
|
let rememberMeForSession = false;
|
|
3140
3332
|
if (typeof window !== "undefined") {
|
|
3141
|
-
const storedState = sessionStorage.getItem(
|
|
3333
|
+
const storedState = sessionStorage.getItem(OAUTH_STATE_KEY);
|
|
3142
3334
|
if (storedState && storedState !== state) {
|
|
3143
3335
|
throw new Error("Invalid OAuth state - possible CSRF attack");
|
|
3144
3336
|
}
|
|
3145
|
-
rememberMeForSession = sessionStorage.getItem(
|
|
3146
|
-
sessionStorage.removeItem(
|
|
3147
|
-
sessionStorage.removeItem(
|
|
3148
|
-
sessionStorage.removeItem(
|
|
3337
|
+
rememberMeForSession = sessionStorage.getItem(OAUTH_REMEMBER_KEY) === "true";
|
|
3338
|
+
sessionStorage.removeItem(OAUTH_STATE_KEY);
|
|
3339
|
+
sessionStorage.removeItem(OAUTH_PROVIDER_KEY);
|
|
3340
|
+
sessionStorage.removeItem(OAUTH_REMEMBER_KEY);
|
|
3149
3341
|
}
|
|
3150
3342
|
const result = await CfgAccountsOauth.cfgAccountsOauthGithubCallbackCreate({
|
|
3151
3343
|
body: { code, state, remember_me: rememberMeForSession },
|
|
@@ -3257,7 +3449,7 @@ function useSessionStorage(key, initialValue) {
|
|
|
3257
3449
|
const key2 = keys[i];
|
|
3258
3450
|
if (key2) {
|
|
3259
3451
|
sessionStorage.removeItem(key2);
|
|
3260
|
-
sessionStorage.removeItem(`${key2}
|
|
3452
|
+
sessionStorage.removeItem(`${key2}_ts`);
|
|
3261
3453
|
}
|
|
3262
3454
|
} catch {
|
|
3263
3455
|
}
|
|
@@ -3287,7 +3479,7 @@ function useSessionStorage(key, initialValue) {
|
|
|
3287
3479
|
authLogger.warn(`Data size too large for key "${key}", removing key`);
|
|
3288
3480
|
try {
|
|
3289
3481
|
window.sessionStorage.removeItem(key);
|
|
3290
|
-
window.sessionStorage.removeItem(`${key}
|
|
3482
|
+
window.sessionStorage.removeItem(`${key}_ts`);
|
|
3291
3483
|
} catch {
|
|
3292
3484
|
}
|
|
3293
3485
|
setStoredValue(valueToStore);
|
|
@@ -3297,20 +3489,20 @@ function useSessionStorage(key, initialValue) {
|
|
|
3297
3489
|
if (typeof window !== "undefined") {
|
|
3298
3490
|
try {
|
|
3299
3491
|
window.sessionStorage.setItem(key, JSON.stringify(valueToStore));
|
|
3300
|
-
window.sessionStorage.setItem(`${key}
|
|
3492
|
+
window.sessionStorage.setItem(`${key}_ts`, Date.now().toString());
|
|
3301
3493
|
} catch (storageError) {
|
|
3302
3494
|
if (isQuotaExceededError(storageError)) {
|
|
3303
3495
|
authLogger.warn("sessionStorage quota exceeded, clearing old data...");
|
|
3304
3496
|
clearOldData();
|
|
3305
3497
|
try {
|
|
3306
3498
|
window.sessionStorage.setItem(key, JSON.stringify(valueToStore));
|
|
3307
|
-
window.sessionStorage.setItem(`${key}
|
|
3499
|
+
window.sessionStorage.setItem(`${key}_ts`, Date.now().toString());
|
|
3308
3500
|
} catch (retryError) {
|
|
3309
3501
|
authLogger.error(`Failed to set sessionStorage key "${key}" after clearing old data:`, retryError);
|
|
3310
3502
|
try {
|
|
3311
3503
|
forceClearAll();
|
|
3312
3504
|
window.sessionStorage.setItem(key, JSON.stringify(valueToStore));
|
|
3313
|
-
window.sessionStorage.setItem(`${key}
|
|
3505
|
+
window.sessionStorage.setItem(`${key}_ts`, Date.now().toString());
|
|
3314
3506
|
} catch (finalError) {
|
|
3315
3507
|
authLogger.error(`Failed to set sessionStorage key "${key}" after force clearing:`, finalError);
|
|
3316
3508
|
setStoredValue(valueToStore);
|
|
@@ -3333,14 +3525,14 @@ function useSessionStorage(key, initialValue) {
|
|
|
3333
3525
|
if (typeof window !== "undefined") {
|
|
3334
3526
|
try {
|
|
3335
3527
|
window.sessionStorage.removeItem(key);
|
|
3336
|
-
window.sessionStorage.removeItem(`${key}
|
|
3528
|
+
window.sessionStorage.removeItem(`${key}_ts`);
|
|
3337
3529
|
} catch (removeError) {
|
|
3338
3530
|
if (isQuotaExceededError(removeError)) {
|
|
3339
3531
|
authLogger.warn("sessionStorage quota exceeded during removal, clearing old data...");
|
|
3340
3532
|
clearOldData();
|
|
3341
3533
|
try {
|
|
3342
3534
|
window.sessionStorage.removeItem(key);
|
|
3343
|
-
window.sessionStorage.removeItem(`${key}
|
|
3535
|
+
window.sessionStorage.removeItem(`${key}_ts`);
|
|
3344
3536
|
} catch (retryError) {
|
|
3345
3537
|
authLogger.error(`Failed to remove sessionStorage key "${key}" after clearing:`, retryError);
|
|
3346
3538
|
forceClearAll();
|
|
@@ -3359,7 +3551,7 @@ function useSessionStorage(key, initialValue) {
|
|
|
3359
3551
|
__name(useSessionStorage, "useSessionStorage");
|
|
3360
3552
|
|
|
3361
3553
|
// src/auth/hooks/useAuthRedirect.ts
|
|
3362
|
-
var AUTH_REDIRECT_KEY =
|
|
3554
|
+
var AUTH_REDIRECT_KEY = CFG_KEYS.redirectUrl.key;
|
|
3363
3555
|
var getRedirectFromStorage = /* @__PURE__ */ __name(() => {
|
|
3364
3556
|
if (typeof window === "undefined") return "";
|
|
3365
3557
|
try {
|
|
@@ -3373,7 +3565,7 @@ var clearRedirectFromStorage = /* @__PURE__ */ __name(() => {
|
|
|
3373
3565
|
if (typeof window === "undefined") return;
|
|
3374
3566
|
try {
|
|
3375
3567
|
window.sessionStorage.removeItem(AUTH_REDIRECT_KEY);
|
|
3376
|
-
window.sessionStorage.removeItem(`${AUTH_REDIRECT_KEY}
|
|
3568
|
+
window.sessionStorage.removeItem(`${AUTH_REDIRECT_KEY}_ts`);
|
|
3377
3569
|
} catch {
|
|
3378
3570
|
}
|
|
3379
3571
|
}, "clearRedirectFromStorage");
|
|
@@ -3789,7 +3981,7 @@ function useLocalStorage(key, initialValue) {
|
|
|
3789
3981
|
const key2 = keys[i];
|
|
3790
3982
|
if (key2) {
|
|
3791
3983
|
localStorage.removeItem(key2);
|
|
3792
|
-
localStorage.removeItem(`${key2}
|
|
3984
|
+
localStorage.removeItem(`${key2}_ts`);
|
|
3793
3985
|
}
|
|
3794
3986
|
} catch {
|
|
3795
3987
|
}
|
|
@@ -3819,7 +4011,7 @@ function useLocalStorage(key, initialValue) {
|
|
|
3819
4011
|
authLogger.warn(`Data size too large for key "${key}", removing key`);
|
|
3820
4012
|
try {
|
|
3821
4013
|
window.localStorage.removeItem(key);
|
|
3822
|
-
window.localStorage.removeItem(`${key}
|
|
4014
|
+
window.localStorage.removeItem(`${key}_ts`);
|
|
3823
4015
|
} catch {
|
|
3824
4016
|
}
|
|
3825
4017
|
setStoredValue(valueToStore);
|
|
@@ -3833,7 +4025,7 @@ function useLocalStorage(key, initialValue) {
|
|
|
3833
4025
|
} else {
|
|
3834
4026
|
window.localStorage.setItem(key, JSON.stringify(valueToStore));
|
|
3835
4027
|
}
|
|
3836
|
-
window.localStorage.setItem(`${key}
|
|
4028
|
+
window.localStorage.setItem(`${key}_ts`, Date.now().toString());
|
|
3837
4029
|
} catch (storageError) {
|
|
3838
4030
|
if (isQuotaExceededError(storageError)) {
|
|
3839
4031
|
authLogger.warn("localStorage quota exceeded, clearing old data...");
|
|
@@ -3844,7 +4036,7 @@ function useLocalStorage(key, initialValue) {
|
|
|
3844
4036
|
} else {
|
|
3845
4037
|
window.localStorage.setItem(key, JSON.stringify(valueToStore));
|
|
3846
4038
|
}
|
|
3847
|
-
window.localStorage.setItem(`${key}
|
|
4039
|
+
window.localStorage.setItem(`${key}_ts`, Date.now().toString());
|
|
3848
4040
|
} catch (retryError) {
|
|
3849
4041
|
authLogger.error(`Failed to set localStorage key "${key}" after clearing old data:`, retryError);
|
|
3850
4042
|
try {
|
|
@@ -3854,7 +4046,7 @@ function useLocalStorage(key, initialValue) {
|
|
|
3854
4046
|
} else {
|
|
3855
4047
|
window.localStorage.setItem(key, JSON.stringify(valueToStore));
|
|
3856
4048
|
}
|
|
3857
|
-
window.localStorage.setItem(`${key}
|
|
4049
|
+
window.localStorage.setItem(`${key}_ts`, Date.now().toString());
|
|
3858
4050
|
} catch (finalError) {
|
|
3859
4051
|
authLogger.error(`Failed to set localStorage key "${key}" after force clearing:`, finalError);
|
|
3860
4052
|
setStoredValue(valueToStore);
|
|
@@ -3877,14 +4069,14 @@ function useLocalStorage(key, initialValue) {
|
|
|
3877
4069
|
if (typeof window !== "undefined") {
|
|
3878
4070
|
try {
|
|
3879
4071
|
window.localStorage.removeItem(key);
|
|
3880
|
-
window.localStorage.removeItem(`${key}
|
|
4072
|
+
window.localStorage.removeItem(`${key}_ts`);
|
|
3881
4073
|
} catch (removeError) {
|
|
3882
4074
|
if (isQuotaExceededError(removeError)) {
|
|
3883
4075
|
authLogger.warn("localStorage quota exceeded during removal, clearing old data...");
|
|
3884
4076
|
clearOldData();
|
|
3885
4077
|
try {
|
|
3886
4078
|
window.localStorage.removeItem(key);
|
|
3887
|
-
window.localStorage.removeItem(`${key}
|
|
4079
|
+
window.localStorage.removeItem(`${key}_ts`);
|
|
3888
4080
|
} catch (retryError) {
|
|
3889
4081
|
authLogger.error(`Failed to remove localStorage key "${key}" after clearing:`, retryError);
|
|
3890
4082
|
forceClearAll();
|
|
@@ -3952,7 +4144,7 @@ function useBase64() {
|
|
|
3952
4144
|
__name(useBase64, "useBase64");
|
|
3953
4145
|
|
|
3954
4146
|
// src/auth/hooks/useProfileCache.ts
|
|
3955
|
-
var CACHE_KEY =
|
|
4147
|
+
var CACHE_KEY = CFG_KEYS.profileCache.key;
|
|
3956
4148
|
var CACHE_VERSION = 1;
|
|
3957
4149
|
var DEFAULT_TTL = 144e5;
|
|
3958
4150
|
function getCachedProfile() {
|
|
@@ -4597,7 +4789,7 @@ var resolveAuthRoutes = /* @__PURE__ */ __name((routes) => ({
|
|
|
4597
4789
|
defaultCallback: routes?.defaultCallback || defaultRoutes.defaultCallback,
|
|
4598
4790
|
defaultAuthCallback: routes?.defaultAuthCallback || routes?.auth || defaultRoutes.defaultAuthCallback
|
|
4599
4791
|
}), "resolveAuthRoutes");
|
|
4600
|
-
var EMAIL_STORAGE_KEY =
|
|
4792
|
+
var EMAIL_STORAGE_KEY = CFG_KEYS.email.key;
|
|
4601
4793
|
var AuthContext = (0, import_react17.createContext)(void 0);
|
|
4602
4794
|
var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
4603
4795
|
const accounts = useAccountsContext();
|