@djangocfg/api 2.1.619 → 2.1.622
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth.cjs +441 -106
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +80 -2
- package/dist/auth.d.ts +80 -2
- package/dist/auth.mjs +396 -63
- package/dist/auth.mjs.map +1 -1
- package/dist/clients.cjs +43 -6
- package/dist/clients.cjs.map +1 -1
- package/dist/clients.mjs +43 -6
- package/dist/clients.mjs.map +1 -1
- package/dist/hooks.cjs +43 -6
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.mjs +43 -6
- package/dist/hooks.mjs.map +1 -1
- package/dist/index.cjs +264 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +264 -40
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/_api/generated/helpers/auth.ts +33 -6
- package/src/auth/__tests__/authState.test.ts +46 -0
- package/src/auth/__tests__/formatAuthError.test.ts +7 -0
- package/src/auth/__tests__/sharedContext.test.ts +16 -0
- package/src/auth/__tests__/trace.test.ts +38 -0
- package/src/auth/context/AccountsContext.tsx +6 -2
- package/src/auth/context/AuthContext.tsx +63 -10
- package/src/auth/context/sharedContext.ts +16 -0
- package/src/auth/context/types.ts +2 -0
- package/src/auth/hooks/useCfgRouter.ts +31 -0
- package/src/auth/hooks/useOAuthLogin.ts +3 -0
- package/src/auth/hooks/useTwoFactorVerify.ts +2 -0
- package/src/auth/index.ts +3 -0
- package/src/auth/trace.ts +253 -0
- package/src/auth/utils/authState.ts +39 -0
- package/src/auth/utils/errors.ts +5 -2
- package/src/auth/utils/index.ts +1 -0
- package/src/index.ts +3 -0
package/dist/auth.cjs
CHANGED
|
@@ -216,17 +216,21 @@ __export(auth_exports, {
|
|
|
216
216
|
AuthProvider: () => AuthProvider,
|
|
217
217
|
OAUTH_PROVIDER_IDS: () => OAUTH_PROVIDER_IDS,
|
|
218
218
|
authLogger: () => authLogger,
|
|
219
|
+
authTrace: () => authTrace,
|
|
219
220
|
beginTwoFactorChallenge: () => beginTwoFactorChallenge,
|
|
221
|
+
clearAuthTrace: () => clearAuthTrace,
|
|
220
222
|
clearOAuthAttempt: () => clearOAuthAttempt,
|
|
221
223
|
clearProfileCache: () => clearProfileCache,
|
|
222
224
|
consumeSavedRedirect: () => consumeSavedRedirect,
|
|
223
225
|
decodeBase64: () => decodeBase64,
|
|
226
|
+
dumpAuthTrace: () => dumpAuthTrace,
|
|
224
227
|
encodeBase64: () => encodeBase64,
|
|
225
228
|
endTwoFactorChallenge: () => endTwoFactorChallenge,
|
|
226
229
|
formatAuthError: () => formatAuthError,
|
|
227
230
|
getCacheMetadata: () => getCacheMetadata,
|
|
228
231
|
getCachedProfile: () => getCachedProfile,
|
|
229
232
|
hasValidCache: () => hasValidCache,
|
|
233
|
+
installAuthTrace: () => installAuthTrace,
|
|
230
234
|
isAllowedAuthPath: () => isAllowedAuthPath,
|
|
231
235
|
isForbidden: () => isForbidden,
|
|
232
236
|
isOAuthProviderId: () => isOAuthProviderId,
|
|
@@ -234,8 +238,11 @@ __export(auth_exports, {
|
|
|
234
238
|
logger: () => logger,
|
|
235
239
|
normalizePath: () => normalizePath,
|
|
236
240
|
peekSavedRedirect: () => peekSavedRedirect,
|
|
241
|
+
readAuthTrace: () => readAuthTrace,
|
|
237
242
|
readOAuthFailure: () => readOAuthFailure,
|
|
243
|
+
resetAuthTraceForTests: () => resetAuthTraceForTests,
|
|
238
244
|
resolveAuthError: () => resolveAuthError,
|
|
245
|
+
resolveAuthStatus: () => resolveAuthStatus,
|
|
239
246
|
resolveGuardIsAuthenticated: () => resolveGuardIsAuthenticated,
|
|
240
247
|
resolveGuardIsLoading: () => resolveGuardIsLoading,
|
|
241
248
|
setAnalyticsSink: () => setAnalyticsSink,
|
|
@@ -281,9 +288,201 @@ var AUTH_CONSTANTS = {
|
|
|
281
288
|
RESEND_COOLDOWN_SECONDS: 30
|
|
282
289
|
};
|
|
283
290
|
|
|
291
|
+
// src/auth/trace.ts
|
|
292
|
+
var KEY = "cfg.auth.trace";
|
|
293
|
+
var MAX = 200;
|
|
294
|
+
var MAX_STRING = 120;
|
|
295
|
+
var SENSITIVE = /token|otp|code|email|password|secret|cookie|authorization|key|identifier/i;
|
|
296
|
+
var TAB = (() => {
|
|
297
|
+
const g = globalThis;
|
|
298
|
+
return g.__cfgAuthTab ??= Math.random().toString(36).slice(2, 6);
|
|
299
|
+
})();
|
|
300
|
+
var hasWindow = typeof window !== "undefined";
|
|
301
|
+
var memory = [];
|
|
302
|
+
var loaded = false;
|
|
303
|
+
function backend() {
|
|
304
|
+
if (!hasWindow) return null;
|
|
305
|
+
for (const name of ["localStorage", "sessionStorage"]) {
|
|
306
|
+
try {
|
|
307
|
+
const s = window[name];
|
|
308
|
+
s.setItem("__cfg_probe", "1");
|
|
309
|
+
s.removeItem("__cfg_probe");
|
|
310
|
+
return s;
|
|
311
|
+
} catch {
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return null;
|
|
315
|
+
}
|
|
316
|
+
__name(backend, "backend");
|
|
317
|
+
function load() {
|
|
318
|
+
if (loaded) return memory;
|
|
319
|
+
loaded = true;
|
|
320
|
+
try {
|
|
321
|
+
const raw = backend()?.getItem(KEY);
|
|
322
|
+
const parsed = raw ? JSON.parse(raw) : [];
|
|
323
|
+
if (Array.isArray(parsed)) memory = parsed.filter((e) => typeof e === "object" && e !== null);
|
|
324
|
+
} catch {
|
|
325
|
+
memory = [];
|
|
326
|
+
}
|
|
327
|
+
return memory;
|
|
328
|
+
}
|
|
329
|
+
__name(load, "load");
|
|
330
|
+
function persist() {
|
|
331
|
+
try {
|
|
332
|
+
backend()?.setItem(KEY, JSON.stringify(memory));
|
|
333
|
+
} catch {
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
__name(persist, "persist");
|
|
337
|
+
function clean(fields) {
|
|
338
|
+
if (!fields) return void 0;
|
|
339
|
+
const out = {};
|
|
340
|
+
for (const [k2, v] of Object.entries(fields)) {
|
|
341
|
+
if (SENSITIVE.test(k2)) continue;
|
|
342
|
+
if (typeof v === "string") out[k2] = v.length > MAX_STRING ? `${v.slice(0, MAX_STRING)}\u2026` : v;
|
|
343
|
+
else if (typeof v === "number" || typeof v === "boolean" || v === null) out[k2] = v;
|
|
344
|
+
}
|
|
345
|
+
return Object.keys(out).length ? out : void 0;
|
|
346
|
+
}
|
|
347
|
+
__name(clean, "clean");
|
|
348
|
+
function refresh() {
|
|
349
|
+
try {
|
|
350
|
+
const raw = backend()?.getItem(KEY);
|
|
351
|
+
const parsed = raw ? JSON.parse(raw) : null;
|
|
352
|
+
if (Array.isArray(parsed)) memory = parsed.filter((e) => typeof e === "object" && e !== null);
|
|
353
|
+
} catch {
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
__name(refresh, "refresh");
|
|
357
|
+
function record(at, ev, fields) {
|
|
358
|
+
load();
|
|
359
|
+
refresh();
|
|
360
|
+
const entries = memory;
|
|
361
|
+
const p = hasWindow && typeof performance !== "undefined" ? Math.round(performance.now()) : 0;
|
|
362
|
+
const f2 = clean(fields);
|
|
363
|
+
const last = entries[entries.length - 1];
|
|
364
|
+
if (last && last.tab === TAB && last.ev === ev && JSON.stringify(last.f) === JSON.stringify(f2)) {
|
|
365
|
+
last.n = (last.n ?? 1) + 1;
|
|
366
|
+
last.t = at;
|
|
367
|
+
last.p = p;
|
|
368
|
+
persist();
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
entries.push({ t: at, p, tab: TAB, ev, f: f2 });
|
|
372
|
+
if (entries.length > MAX) entries.splice(0, entries.length - MAX);
|
|
373
|
+
persist();
|
|
374
|
+
}
|
|
375
|
+
__name(record, "record");
|
|
376
|
+
function authTrace(ev, fields) {
|
|
377
|
+
if (!hasWindow) return;
|
|
378
|
+
try {
|
|
379
|
+
record(Date.now(), ev, fields);
|
|
380
|
+
} catch {
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
__name(authTrace, "authTrace");
|
|
384
|
+
function resetAuthTraceForTests() {
|
|
385
|
+
memory = [];
|
|
386
|
+
loaded = true;
|
|
387
|
+
}
|
|
388
|
+
__name(resetAuthTraceForTests, "resetAuthTraceForTests");
|
|
389
|
+
function readAuthTrace() {
|
|
390
|
+
return load().slice();
|
|
391
|
+
}
|
|
392
|
+
__name(readAuthTrace, "readAuthTrace");
|
|
393
|
+
function clearAuthTrace() {
|
|
394
|
+
memory = [];
|
|
395
|
+
loaded = true;
|
|
396
|
+
try {
|
|
397
|
+
backend()?.removeItem(KEY);
|
|
398
|
+
} catch {
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
__name(clearAuthTrace, "clearAuthTrace");
|
|
402
|
+
function context() {
|
|
403
|
+
if (!hasWindow) return [];
|
|
404
|
+
const copies = globalThis.__cfgAuthCopies ?? 1;
|
|
405
|
+
const lines = [`url: ${window.location.href.split("?")[0]}`, `copies: ${String(copies)}`, `online: ${navigator.onLine}`, `ua: ${navigator.userAgent}`];
|
|
406
|
+
try {
|
|
407
|
+
const auth2 = globalThis.__cfgAuthNow;
|
|
408
|
+
const now = auth2?.();
|
|
409
|
+
if (now) lines.push(`now: ${Object.entries(now).map(([k2, v]) => `${k2}=${String(v)}`).join(" ")}`);
|
|
410
|
+
} catch {
|
|
411
|
+
}
|
|
412
|
+
return lines;
|
|
413
|
+
}
|
|
414
|
+
__name(context, "context");
|
|
415
|
+
function dumpAuthTrace() {
|
|
416
|
+
const entries = load();
|
|
417
|
+
const first = entries[0]?.t ?? Date.now();
|
|
418
|
+
const rows = entries.map((e) => {
|
|
419
|
+
const fields = e.f ? ` ${Object.entries(e.f).map(([k2, v]) => `${k2}=${String(v)}`).join(" ")}` : "";
|
|
420
|
+
const at = new Date(e.t).toISOString().slice(11, 23);
|
|
421
|
+
return `${at} +${String(e.t - first).padStart(6)}ms [${e.tab} p${e.p}] ${e.ev}${fields}${e.n && e.n > 1 ? ` x${e.n}` : ""}`;
|
|
422
|
+
});
|
|
423
|
+
return [`# cfg auth trace, ${entries.length} events`, ...context(), "", ...rows].join("\n");
|
|
424
|
+
}
|
|
425
|
+
__name(dumpAuthTrace, "dumpAuthTrace");
|
|
426
|
+
function installAuthTrace() {
|
|
427
|
+
if (!hasWindow) return;
|
|
428
|
+
const g = globalThis;
|
|
429
|
+
g.__cfgAuthTrace = authTrace;
|
|
430
|
+
g.__cfgAuth = {
|
|
431
|
+
trace: readAuthTrace,
|
|
432
|
+
dump: /* @__PURE__ */ __name(() => {
|
|
433
|
+
const text = dumpAuthTrace();
|
|
434
|
+
console.log(text);
|
|
435
|
+
return text;
|
|
436
|
+
}, "dump"),
|
|
437
|
+
clear: clearAuthTrace,
|
|
438
|
+
/** Put the dump on the clipboard (works when the console output is blocked or too long to select). */
|
|
439
|
+
copy: /* @__PURE__ */ __name(() => {
|
|
440
|
+
const text = dumpAuthTrace();
|
|
441
|
+
void navigator.clipboard?.writeText(text);
|
|
442
|
+
return `${text.split("\n").length} lines copied`;
|
|
443
|
+
}, "copy"),
|
|
444
|
+
/** Download the raw trace as a JSON file. */
|
|
445
|
+
download: /* @__PURE__ */ __name(() => {
|
|
446
|
+
const blob = new Blob([JSON.stringify(readAuthTrace(), null, 1)], { type: "application/json" });
|
|
447
|
+
const a = document.createElement("a");
|
|
448
|
+
a.href = URL.createObjectURL(blob);
|
|
449
|
+
a.download = `auth-trace-${Date.now()}.json`;
|
|
450
|
+
a.click();
|
|
451
|
+
}, "download")
|
|
452
|
+
};
|
|
453
|
+
const queued = g.__cfgAuthTraceQ;
|
|
454
|
+
if (Array.isArray(queued)) {
|
|
455
|
+
g.__cfgAuthTraceQ = [];
|
|
456
|
+
for (const item of queued) {
|
|
457
|
+
if (Array.isArray(item) && typeof item[1] === "string") {
|
|
458
|
+
try {
|
|
459
|
+
record(Number(item[0]) || Date.now(), item[1], item[2]);
|
|
460
|
+
} catch {
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
__name(installAuthTrace, "installAuthTrace");
|
|
467
|
+
function registerCopy() {
|
|
468
|
+
if (!hasWindow) return;
|
|
469
|
+
const g = globalThis;
|
|
470
|
+
const n = (g.__cfgAuthCopies ?? 0) + 1;
|
|
471
|
+
g.__cfgAuthCopies = n;
|
|
472
|
+
if (n > 1) {
|
|
473
|
+
authTrace("dup.copy", { copies: n });
|
|
474
|
+
if (n === 2) {
|
|
475
|
+
console.warn("[@djangocfg/api] more than one copy of the auth package is loaded; see __cfgAuth.dump() (dup.copy). Align the peer set so pnpm installs one instance.");
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
__name(registerCopy, "registerCopy");
|
|
480
|
+
registerCopy();
|
|
481
|
+
installAuthTrace();
|
|
482
|
+
|
|
284
483
|
// src/auth/context/AuthContext.tsx
|
|
285
484
|
var import_navigation4 = require("next/navigation");
|
|
286
|
-
var
|
|
485
|
+
var import_react21 = require("react");
|
|
287
486
|
|
|
288
487
|
// src/_api/generated/helpers/errors.ts
|
|
289
488
|
var APIError = class extends Error {
|
|
@@ -388,10 +587,10 @@ function normalizeSegment(raw) {
|
|
|
388
587
|
return raw.trim().toLowerCase().replace(/[^a-z0-9_]+/g, "_").replace(/^_+|_+$/g, "");
|
|
389
588
|
}
|
|
390
589
|
__name(normalizeSegment, "normalizeSegment");
|
|
391
|
-
var
|
|
590
|
+
var hasWindow2 = /* @__PURE__ */ __name(() => typeof window !== "undefined", "hasWindow");
|
|
392
591
|
var domainByHost = /* @__PURE__ */ new Map();
|
|
393
592
|
function detectCookieDomain() {
|
|
394
|
-
if (!
|
|
593
|
+
if (!hasWindow2() || typeof document === "undefined") return null;
|
|
395
594
|
const host = window.location.hostname.toLowerCase();
|
|
396
595
|
if (!host || !host.includes(".") || host.includes(":") || /^[0-9.]+$/.test(host)) return null;
|
|
397
596
|
const cached = domainByHost.get(host);
|
|
@@ -415,7 +614,7 @@ function detectCookieDomain() {
|
|
|
415
614
|
}
|
|
416
615
|
__name(detectCookieDomain, "detectCookieDomain");
|
|
417
616
|
function nativeStorage(store) {
|
|
418
|
-
if (!
|
|
617
|
+
if (!hasWindow2()) return null;
|
|
419
618
|
try {
|
|
420
619
|
return store === "session" ? window.sessionStorage : window.localStorage;
|
|
421
620
|
} catch {
|
|
@@ -424,7 +623,7 @@ function nativeStorage(store) {
|
|
|
424
623
|
}
|
|
425
624
|
__name(nativeStorage, "nativeStorage");
|
|
426
625
|
function cookieNames() {
|
|
427
|
-
if (!
|
|
626
|
+
if (!hasWindow2()) return [];
|
|
428
627
|
try {
|
|
429
628
|
return document.cookie.split("; ").map((part) => decodeURIComponent(part.split("=")[0] ?? "")).filter(Boolean);
|
|
430
629
|
} catch {
|
|
@@ -449,7 +648,7 @@ function createStorage(owner, options = {}) {
|
|
|
449
648
|
const families = Object.values(options.families ?? {});
|
|
450
649
|
const specByKey = /* @__PURE__ */ new Map();
|
|
451
650
|
for (const spec of specs) specByKey.set(spec.key, [...specByKey.get(spec.key) ?? [], spec]);
|
|
452
|
-
const
|
|
651
|
+
const memory2 = {
|
|
453
652
|
local: /* @__PURE__ */ new Map(),
|
|
454
653
|
session: /* @__PURE__ */ new Map(),
|
|
455
654
|
cookie: /* @__PURE__ */ new Map()
|
|
@@ -463,7 +662,7 @@ function createStorage(owner, options = {}) {
|
|
|
463
662
|
if (!key.startsWith(prefix)) throw new TypeError(`storage key "${key}" is not owned by "${owner}"`);
|
|
464
663
|
}, "assertOwned");
|
|
465
664
|
function rawGet(store, key) {
|
|
466
|
-
if (!
|
|
665
|
+
if (!hasWindow2()) return null;
|
|
467
666
|
if (store === "cookie") {
|
|
468
667
|
try {
|
|
469
668
|
const escaped = encodeURIComponent(key).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -471,18 +670,18 @@ function createStorage(owner, options = {}) {
|
|
|
471
670
|
if (match?.[1] !== void 0) return decodeURIComponent(match[1]);
|
|
472
671
|
} catch {
|
|
473
672
|
}
|
|
474
|
-
return
|
|
673
|
+
return memory2.cookie.get(key) ?? null;
|
|
475
674
|
}
|
|
476
675
|
try {
|
|
477
676
|
const value = nativeStorage(store)?.getItem(key) ?? null;
|
|
478
677
|
if (value !== null) return value;
|
|
479
678
|
} catch {
|
|
480
679
|
}
|
|
481
|
-
return
|
|
680
|
+
return memory2[store].get(key) ?? null;
|
|
482
681
|
}
|
|
483
682
|
__name(rawGet, "rawGet");
|
|
484
683
|
function rawSet(store, key, value, maxAgeSeconds) {
|
|
485
|
-
if (!
|
|
684
|
+
if (!hasWindow2()) return false;
|
|
486
685
|
try {
|
|
487
686
|
if (store === "cookie") {
|
|
488
687
|
const secure = window.location.protocol === "https:" ? "; Secure" : "";
|
|
@@ -490,24 +689,24 @@ function createStorage(owner, options = {}) {
|
|
|
490
689
|
const domainPart = domain ? `; Domain=${domain}` : "";
|
|
491
690
|
document.cookie = `${encodeURIComponent(key)}=${encodeURIComponent(value)}; Path=/; Max-Age=${Math.max(1, Math.floor(maxAgeSeconds ?? cookieMaxAge))}; SameSite=Lax${domainPart}${secure}`;
|
|
492
691
|
if (domain) expireCookie(key, null);
|
|
493
|
-
if (rawGet("cookie", key) === value && !
|
|
494
|
-
|
|
692
|
+
if (rawGet("cookie", key) === value && !memory2.cookie.has(key)) return true;
|
|
693
|
+
memory2.cookie.set(key, value);
|
|
495
694
|
return false;
|
|
496
695
|
}
|
|
497
696
|
const native = nativeStorage(store);
|
|
498
697
|
if (!native) throw new Error("storage unavailable");
|
|
499
698
|
native.setItem(key, value);
|
|
500
|
-
|
|
699
|
+
memory2[store].delete(key);
|
|
501
700
|
return true;
|
|
502
701
|
} catch {
|
|
503
|
-
|
|
702
|
+
memory2[store].set(key, value);
|
|
504
703
|
return false;
|
|
505
704
|
}
|
|
506
705
|
}
|
|
507
706
|
__name(rawSet, "rawSet");
|
|
508
707
|
function rawRemove(store, key) {
|
|
509
|
-
|
|
510
|
-
if (!
|
|
708
|
+
memory2[store].delete(key);
|
|
709
|
+
if (!hasWindow2()) return;
|
|
511
710
|
try {
|
|
512
711
|
if (store === "cookie") {
|
|
513
712
|
expireCookie(key, null);
|
|
@@ -536,7 +735,7 @@ function createStorage(owner, options = {}) {
|
|
|
536
735
|
}
|
|
537
736
|
} catch {
|
|
538
737
|
}
|
|
539
|
-
for (const name of
|
|
738
|
+
for (const name of memory2[store].keys()) if (name.startsWith(startsWith) && !out.includes(name)) out.push(name);
|
|
540
739
|
return out;
|
|
541
740
|
}
|
|
542
741
|
__name(listKeys, "listKeys");
|
|
@@ -608,7 +807,7 @@ function createStorage(owner, options = {}) {
|
|
|
608
807
|
cookieDomain: resolveCookieDomain,
|
|
609
808
|
onChange(key, listener, store = "local") {
|
|
610
809
|
assertValid(key);
|
|
611
|
-
if (!
|
|
810
|
+
if (!hasWindow2()) return () => {
|
|
612
811
|
};
|
|
613
812
|
const handler = /* @__PURE__ */ __name((event) => {
|
|
614
813
|
if (event.storageArea !== nativeStorage(store)) return;
|
|
@@ -632,6 +831,29 @@ var REFRESH_KEY = "cfg.auth.refresh_token";
|
|
|
632
831
|
var API_KEY_KEY = "cfg.auth.api_key";
|
|
633
832
|
var storage = true ? cfgStorage : createStorage2("cfg");
|
|
634
833
|
var isBrowser = typeof window !== "undefined";
|
|
834
|
+
function trace(ev, fields) {
|
|
835
|
+
try {
|
|
836
|
+
const g = globalThis;
|
|
837
|
+
const sink2 = g.__cfgAuthTrace;
|
|
838
|
+
if (sink2) {
|
|
839
|
+
sink2(ev, fields);
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
842
|
+
const queue = g.__cfgAuthTraceQ ?? [];
|
|
843
|
+
g.__cfgAuthTraceQ = queue;
|
|
844
|
+
if (queue.length < 100) queue.push([Date.now(), ev, fields]);
|
|
845
|
+
} catch {
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
__name(trace, "trace");
|
|
849
|
+
function pathOf(url) {
|
|
850
|
+
try {
|
|
851
|
+
return new URL(url, "http://x").pathname;
|
|
852
|
+
} catch {
|
|
853
|
+
return "";
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
__name(pathOf, "pathOf");
|
|
635
857
|
function secondsUntilExp(token) {
|
|
636
858
|
const exp = jwtExpMs(token);
|
|
637
859
|
return exp === null ? void 0 : Math.max(1, Math.floor((exp - Date.now()) / 1e3));
|
|
@@ -662,10 +884,10 @@ function adoptLegacySession() {
|
|
|
662
884
|
if (_storage.get(ACCESS_KEY) !== null || _storage.get(REFRESH_KEY) !== null) return;
|
|
663
885
|
const legacy = backendFor("localStorage");
|
|
664
886
|
const access = legacy.get(ACCESS_KEY);
|
|
665
|
-
const
|
|
666
|
-
if (access === null &&
|
|
887
|
+
const refresh2 = legacy.get(REFRESH_KEY);
|
|
888
|
+
if (access === null && refresh2 === null) return;
|
|
667
889
|
if (access !== null) _storage.set(ACCESS_KEY, access);
|
|
668
|
-
if (
|
|
890
|
+
if (refresh2 !== null) _storage.set(REFRESH_KEY, refresh2);
|
|
669
891
|
legacy.set(ACCESS_KEY, null);
|
|
670
892
|
legacy.set(REFRESH_KEY, null);
|
|
671
893
|
} catch {
|
|
@@ -750,12 +972,12 @@ function jwtExpMs(token) {
|
|
|
750
972
|
__name(jwtExpMs, "jwtExpMs");
|
|
751
973
|
function computeSnapshot() {
|
|
752
974
|
const access = _storage.get(ACCESS_KEY);
|
|
753
|
-
const
|
|
975
|
+
const refresh2 = _storage.get(REFRESH_KEY);
|
|
754
976
|
const now = Date.now();
|
|
755
977
|
const accessExp = access ? jwtExpMs(access) : null;
|
|
756
978
|
const accessAlive = access !== null && (accessExp === null || accessExp > now);
|
|
757
|
-
const refreshExp =
|
|
758
|
-
const refreshAlive =
|
|
979
|
+
const refreshExp = refresh2 ? jwtExpMs(refresh2) : null;
|
|
980
|
+
const refreshAlive = refresh2 !== null && (refreshExp === null || refreshExp > now);
|
|
759
981
|
return {
|
|
760
982
|
status: accessAlive || refreshAlive ? "authenticated" : "anonymous",
|
|
761
983
|
accessExpiresAt: accessExp
|
|
@@ -778,9 +1000,9 @@ function scheduleExpiryFlip() {
|
|
|
778
1000
|
const now = Date.now();
|
|
779
1001
|
const exps = [];
|
|
780
1002
|
const access = _storage.get(ACCESS_KEY);
|
|
781
|
-
const
|
|
1003
|
+
const refresh2 = _storage.get(REFRESH_KEY);
|
|
782
1004
|
const accessExp = access ? jwtExpMs(access) : null;
|
|
783
|
-
const refreshExp =
|
|
1005
|
+
const refreshExp = refresh2 ? jwtExpMs(refresh2) : null;
|
|
784
1006
|
if (accessExp !== null && accessExp > now) exps.push(accessExp);
|
|
785
1007
|
if (refreshExp !== null && refreshExp > now) exps.push(refreshExp);
|
|
786
1008
|
if (!exps.length) return;
|
|
@@ -791,7 +1013,10 @@ __name(scheduleExpiryFlip, "scheduleExpiryFlip");
|
|
|
791
1013
|
function notifySessionChanged() {
|
|
792
1014
|
const next = computeSnapshot();
|
|
793
1015
|
const changed = next.status !== _snapshot.status || next.accessExpiresAt !== _snapshot.accessExpiresAt;
|
|
794
|
-
if (changed)
|
|
1016
|
+
if (changed) {
|
|
1017
|
+
_snapshot = next;
|
|
1018
|
+
trace("store.snapshot", { status: next.status });
|
|
1019
|
+
}
|
|
795
1020
|
scheduleExpiryFlip();
|
|
796
1021
|
if (!changed) return;
|
|
797
1022
|
for (const listener of Array.from(_sessionListeners)) {
|
|
@@ -874,6 +1099,7 @@ var auth = {
|
|
|
874
1099
|
return _storage.get(ACCESS_KEY);
|
|
875
1100
|
},
|
|
876
1101
|
setToken(token) {
|
|
1102
|
+
trace("store.setToken", { present: token !== null });
|
|
877
1103
|
_storage.set(ACCESS_KEY, token);
|
|
878
1104
|
notifySessionChanged();
|
|
879
1105
|
},
|
|
@@ -881,14 +1107,16 @@ var auth = {
|
|
|
881
1107
|
return _storage.get(REFRESH_KEY);
|
|
882
1108
|
},
|
|
883
1109
|
setRefreshToken(token) {
|
|
1110
|
+
trace("store.setRefreshToken", { present: token !== null });
|
|
884
1111
|
_storage.set(REFRESH_KEY, token);
|
|
885
1112
|
notifySessionChanged();
|
|
886
1113
|
},
|
|
887
1114
|
clearTokens() {
|
|
1115
|
+
trace("store.clearTokens");
|
|
888
1116
|
for (const mode of ["localStorage", "sessionStorage", "cookie"]) {
|
|
889
|
-
const
|
|
890
|
-
|
|
891
|
-
|
|
1117
|
+
const backend2 = backendFor(mode);
|
|
1118
|
+
backend2.set(ACCESS_KEY, null);
|
|
1119
|
+
backend2.set(REFRESH_KEY, null);
|
|
892
1120
|
}
|
|
893
1121
|
storage.clearAll();
|
|
894
1122
|
notifySessionChanged();
|
|
@@ -907,6 +1135,7 @@ var auth = {
|
|
|
907
1135
|
* rotation); `refresh: null` explicitly drops it.
|
|
908
1136
|
*/
|
|
909
1137
|
setSession(tokens) {
|
|
1138
|
+
trace("store.setSession", { refresh: tokens.refresh === void 0 ? "kept" : tokens.refresh === null ? "dropped" : "set" });
|
|
910
1139
|
_storage.set(ACCESS_KEY, tokens.access);
|
|
911
1140
|
if (tokens.refresh !== void 0) _storage.set(REFRESH_KEY, tokens.refresh);
|
|
912
1141
|
notifySessionChanged();
|
|
@@ -1042,10 +1271,14 @@ async function tryRefresh() {
|
|
|
1042
1271
|
if (_refreshInflight) return _refreshInflight;
|
|
1043
1272
|
if (!_refreshHandler) return null;
|
|
1044
1273
|
const runRefresh = /* @__PURE__ */ __name(async () => {
|
|
1045
|
-
const
|
|
1046
|
-
if (!
|
|
1047
|
-
const result = await _refreshHandler(
|
|
1048
|
-
if (!result?.access)
|
|
1274
|
+
const refresh2 = auth.getRefreshToken();
|
|
1275
|
+
if (!refresh2) return null;
|
|
1276
|
+
const result = await _refreshHandler(refresh2);
|
|
1277
|
+
if (!result?.access) {
|
|
1278
|
+
trace("refresh", { ok: false, why: "no-access" });
|
|
1279
|
+
return null;
|
|
1280
|
+
}
|
|
1281
|
+
trace("refresh", { ok: true, rotated: Boolean(result.refresh) });
|
|
1049
1282
|
auth.setToken(result.access);
|
|
1050
1283
|
if (result.refresh) auth.setRefreshToken(result.refresh);
|
|
1051
1284
|
return result.access;
|
|
@@ -1058,6 +1291,7 @@ async function tryRefresh() {
|
|
|
1058
1291
|
}
|
|
1059
1292
|
return await runRefresh();
|
|
1060
1293
|
} catch {
|
|
1294
|
+
trace("refresh", { ok: false, why: "threw" });
|
|
1061
1295
|
return null;
|
|
1062
1296
|
} finally {
|
|
1063
1297
|
_refreshInflight = null;
|
|
@@ -1066,7 +1300,8 @@ async function tryRefresh() {
|
|
|
1066
1300
|
return _refreshInflight;
|
|
1067
1301
|
}
|
|
1068
1302
|
__name(tryRefresh, "tryRefresh");
|
|
1069
|
-
function expireSession(response) {
|
|
1303
|
+
function expireSession(response, why) {
|
|
1304
|
+
trace("store.expire", { why, status: response.status, path: pathOf(response.url), handlers: _sessionExpiredHandlers.size });
|
|
1070
1305
|
auth.clearTokens();
|
|
1071
1306
|
for (const cb of Array.from(_sessionExpiredHandlers)) {
|
|
1072
1307
|
try {
|
|
@@ -1209,15 +1444,16 @@ function installAuthOnClient(client2) {
|
|
|
1209
1444
|
client2.interceptors.response.use(async (response, request) => {
|
|
1210
1445
|
if (response.status !== 401) return response;
|
|
1211
1446
|
if (/\/accounts\/(otp|oauth|login|register|token)\b/.test(request.url)) {
|
|
1447
|
+
trace("401.passthrough", { path: pathOf(request.url) });
|
|
1212
1448
|
return response;
|
|
1213
1449
|
}
|
|
1214
1450
|
if (request.headers.get(RETRY_MARKER)) {
|
|
1215
|
-
expireSession(response);
|
|
1451
|
+
expireSession(response, "retry-marker");
|
|
1216
1452
|
return response;
|
|
1217
1453
|
}
|
|
1218
1454
|
const newToken = await tryRefresh();
|
|
1219
1455
|
if (!newToken) {
|
|
1220
|
-
expireSession(response);
|
|
1456
|
+
expireSession(response, "refresh-failed");
|
|
1221
1457
|
return response;
|
|
1222
1458
|
}
|
|
1223
1459
|
const retry = request.clone();
|
|
@@ -1229,7 +1465,7 @@ function installAuthOnClient(client2) {
|
|
|
1229
1465
|
}
|
|
1230
1466
|
try {
|
|
1231
1467
|
const retried = await fetch(retry);
|
|
1232
|
-
if (retried.status === 401) expireSession(retried);
|
|
1468
|
+
if (retried.status === 401) expireSession(retried, "retry-401");
|
|
1233
1469
|
return retried;
|
|
1234
1470
|
} catch {
|
|
1235
1471
|
return response;
|
|
@@ -1238,7 +1474,7 @@ function installAuthOnClient(client2) {
|
|
|
1238
1474
|
}
|
|
1239
1475
|
__name(installAuthOnClient, "installAuthOnClient");
|
|
1240
1476
|
var REFRESH_ENDPOINT = "/cfg/accounts/token/refresh/";
|
|
1241
|
-
auth.setRefreshHandler(async (
|
|
1477
|
+
auth.setRefreshHandler(async (refresh2) => {
|
|
1242
1478
|
try {
|
|
1243
1479
|
const url = `${auth.getBaseUrl()}${REFRESH_ENDPOINT}`;
|
|
1244
1480
|
const headers = { "Content-Type": "application/json" };
|
|
@@ -1250,11 +1486,11 @@ auth.setRefreshHandler(async (refresh) => {
|
|
|
1250
1486
|
method: "POST",
|
|
1251
1487
|
headers,
|
|
1252
1488
|
credentials: auth.getWithCredentials() ? "include" : "same-origin",
|
|
1253
|
-
body: JSON.stringify({ refresh })
|
|
1489
|
+
body: JSON.stringify({ refresh: refresh2 })
|
|
1254
1490
|
});
|
|
1255
1491
|
if (!res.ok) return null;
|
|
1256
1492
|
const data = await res.json();
|
|
1257
|
-
return data?.access ? { access: data.access, refresh: data.refresh ??
|
|
1493
|
+
return data?.access ? { access: data.access, refresh: data.refresh ?? refresh2 } : null;
|
|
1258
1494
|
} catch {
|
|
1259
1495
|
return null;
|
|
1260
1496
|
}
|
|
@@ -1453,6 +1689,16 @@ __name(useTimezone, "useTimezone");
|
|
|
1453
1689
|
// src/auth/hooks/useCfgRouter.ts
|
|
1454
1690
|
var import_navigation = require("next/navigation");
|
|
1455
1691
|
var import_react3 = require("react");
|
|
1692
|
+
var hardNavigating = false;
|
|
1693
|
+
if (typeof window !== "undefined") {
|
|
1694
|
+
window.addEventListener("pageshow", (e) => {
|
|
1695
|
+
if (e.persisted) hardNavigating = false;
|
|
1696
|
+
});
|
|
1697
|
+
}
|
|
1698
|
+
function fromPath() {
|
|
1699
|
+
return typeof window === "undefined" ? "" : window.location.pathname;
|
|
1700
|
+
}
|
|
1701
|
+
__name(fromPath, "fromPath");
|
|
1456
1702
|
function getBasePath() {
|
|
1457
1703
|
if (typeof process === "undefined") {
|
|
1458
1704
|
return "";
|
|
@@ -1473,6 +1719,7 @@ function useCfgRouter() {
|
|
|
1473
1719
|
const router = (0, import_navigation.useRouter)();
|
|
1474
1720
|
const basePath = (0, import_react3.useMemo)(() => getBasePath(), []);
|
|
1475
1721
|
const push = (0, import_react3.useCallback)((href, options) => {
|
|
1722
|
+
authTrace("nav.push", { from: fromPath(), to: href });
|
|
1476
1723
|
if (basePath) {
|
|
1477
1724
|
window.location.href = withBasePath(href, basePath);
|
|
1478
1725
|
} else {
|
|
@@ -1480,6 +1727,7 @@ function useCfgRouter() {
|
|
|
1480
1727
|
}
|
|
1481
1728
|
}, [router, basePath]);
|
|
1482
1729
|
const replace = (0, import_react3.useCallback)((href, options) => {
|
|
1730
|
+
authTrace("nav.replace", { from: fromPath(), to: href });
|
|
1483
1731
|
if (basePath) {
|
|
1484
1732
|
window.location.replace(withBasePath(href, basePath));
|
|
1485
1733
|
} else {
|
|
@@ -1487,9 +1735,21 @@ function useCfgRouter() {
|
|
|
1487
1735
|
}
|
|
1488
1736
|
}, [router, basePath]);
|
|
1489
1737
|
const hardPush = (0, import_react3.useCallback)((href) => {
|
|
1738
|
+
if (hardNavigating) {
|
|
1739
|
+
authTrace("nav.hardPush.ignored", { from: fromPath(), to: href });
|
|
1740
|
+
return;
|
|
1741
|
+
}
|
|
1742
|
+
hardNavigating = true;
|
|
1743
|
+
authTrace("nav.hardPush", { from: fromPath(), to: href });
|
|
1490
1744
|
window.location.href = withBasePath(href, basePath);
|
|
1491
1745
|
}, [basePath]);
|
|
1492
1746
|
const hardReplace = (0, import_react3.useCallback)((href) => {
|
|
1747
|
+
if (hardNavigating) {
|
|
1748
|
+
authTrace("nav.hardReplace.ignored", { from: fromPath(), to: href });
|
|
1749
|
+
return;
|
|
1750
|
+
}
|
|
1751
|
+
hardNavigating = true;
|
|
1752
|
+
authTrace("nav.hardReplace", { from: fromPath(), to: href });
|
|
1493
1753
|
window.location.replace(withBasePath(href, basePath));
|
|
1494
1754
|
}, [basePath]);
|
|
1495
1755
|
const prefetch = (0, import_react3.useCallback)((href) => {
|
|
@@ -1501,7 +1761,7 @@ function useCfgRouter() {
|
|
|
1501
1761
|
const forward = (0, import_react3.useCallback)(() => {
|
|
1502
1762
|
router.forward();
|
|
1503
1763
|
}, [router]);
|
|
1504
|
-
const
|
|
1764
|
+
const refresh2 = (0, import_react3.useCallback)(() => {
|
|
1505
1765
|
router.refresh();
|
|
1506
1766
|
}, [router]);
|
|
1507
1767
|
return {
|
|
@@ -1512,7 +1772,7 @@ function useCfgRouter() {
|
|
|
1512
1772
|
prefetch,
|
|
1513
1773
|
back,
|
|
1514
1774
|
forward,
|
|
1515
|
-
refresh
|
|
1775
|
+
refresh: refresh2
|
|
1516
1776
|
};
|
|
1517
1777
|
}
|
|
1518
1778
|
__name(useCfgRouter, "useCfgRouter");
|
|
@@ -3455,7 +3715,7 @@ var OAuthErrorCodeEnum = /* @__PURE__ */ ((OAuthErrorCodeEnum2) => {
|
|
|
3455
3715
|
|
|
3456
3716
|
// src/auth/utils/errors.ts
|
|
3457
3717
|
var prop = /* @__PURE__ */ __name((value, key) => typeof value === "object" && value !== null ? value[key] : void 0, "prop");
|
|
3458
|
-
var TRANSPORT_FALLBACK = /^HTTP \d{3}:\s*/;
|
|
3718
|
+
var TRANSPORT_FALLBACK = /^HTTP \d{1,3}:\s*/;
|
|
3459
3719
|
var AUTH_ERROR_KEYS = {
|
|
3460
3720
|
invalidCredentials: "ui.errors.unauthorized",
|
|
3461
3721
|
rateLimited: "api.errors.rateLimited",
|
|
@@ -3472,6 +3732,7 @@ var FALLBACK_COPY = {
|
|
|
3472
3732
|
};
|
|
3473
3733
|
var keyForStatus = /* @__PURE__ */ __name((status) => {
|
|
3474
3734
|
if (status === void 0) return AUTH_ERROR_KEYS.generic;
|
|
3735
|
+
if (status === 0) return AUTH_ERROR_KEYS.networkError;
|
|
3475
3736
|
if (status === 401 || status === 403) return AUTH_ERROR_KEYS.invalidCredentials;
|
|
3476
3737
|
if (status === 404) return AUTH_ERROR_KEYS.serverUnavailable;
|
|
3477
3738
|
if (status === 429) return AUTH_ERROR_KEYS.rateLimited;
|
|
@@ -3516,9 +3777,9 @@ var logAuthFailure = /* @__PURE__ */ __name((log, message, error) => {
|
|
|
3516
3777
|
|
|
3517
3778
|
// src/auth/utils/oauthErrors.ts
|
|
3518
3779
|
var SERVER_CODES = new Set(Object.values(OAuthErrorCodeEnum));
|
|
3519
|
-
var
|
|
3780
|
+
var record2 = /* @__PURE__ */ __name((value) => typeof value === "object" && value !== null ? value : null, "record");
|
|
3520
3781
|
var readOAuthFailure = /* @__PURE__ */ __name((err, fallback) => {
|
|
3521
|
-
const body =
|
|
3782
|
+
const body = record2(record2(err)?.response);
|
|
3522
3783
|
const code = body?.error;
|
|
3523
3784
|
if (typeof code === "string" && SERVER_CODES.has(code)) {
|
|
3524
3785
|
const description = body?.error_description;
|
|
@@ -3797,6 +4058,7 @@ var useOAuthLogin = /* @__PURE__ */ __name((options = {}) => {
|
|
|
3797
4058
|
setLoadingProvider(provider);
|
|
3798
4059
|
setError(null);
|
|
3799
4060
|
setErrorCode(null);
|
|
4061
|
+
authTrace("oauth.start");
|
|
3800
4062
|
auth.clearSession();
|
|
3801
4063
|
try {
|
|
3802
4064
|
Analytics.event("auth_oauth_start" /* AUTH_OAUTH_START */, {
|
|
@@ -3844,6 +4106,7 @@ var useOAuthLogin = /* @__PURE__ */ __name((options = {}) => {
|
|
|
3844
4106
|
if (!response.access || !response.refresh) {
|
|
3845
4107
|
throw new Error("Invalid response from OAuth callback");
|
|
3846
4108
|
}
|
|
4109
|
+
authTrace("oauth.session");
|
|
3847
4110
|
auth.setSession({ access: response.access, refresh: response.refresh });
|
|
3848
4111
|
Analytics.event("auth_login_success" /* AUTH_LOGIN_SUCCESS */, {
|
|
3849
4112
|
category: "auth" /* AUTH */,
|
|
@@ -4024,6 +4287,7 @@ var useTwoFactorVerify = /* @__PURE__ */ __name((options = {}) => {
|
|
|
4024
4287
|
setError(null);
|
|
4025
4288
|
}, []);
|
|
4026
4289
|
const handleSuccess = (0, import_react14.useCallback)((response) => {
|
|
4290
|
+
authTrace("2fa.session");
|
|
4027
4291
|
auth.setSession({ access: response.access_token, refresh: response.refresh_token });
|
|
4028
4292
|
if (response.warning) {
|
|
4029
4293
|
setWarning(response.warning);
|
|
@@ -4675,8 +4939,19 @@ function purgeLegacyTokenStorage() {
|
|
|
4675
4939
|
}
|
|
4676
4940
|
__name(purgeLegacyTokenStorage, "purgeLegacyTokenStorage");
|
|
4677
4941
|
|
|
4942
|
+
// src/auth/utils/authState.ts
|
|
4943
|
+
function resolveAuthStatus(s) {
|
|
4944
|
+
if (!s.clientReady) return "resolving";
|
|
4945
|
+
if (s.snapshotAuthenticated) {
|
|
4946
|
+
return s.profileSettled || s.timedOut ? "authenticated" : "resolving";
|
|
4947
|
+
}
|
|
4948
|
+
if (s.storeAuthenticated && !s.timedOut) return "resolving";
|
|
4949
|
+
return "anonymous";
|
|
4950
|
+
}
|
|
4951
|
+
__name(resolveAuthStatus, "resolveAuthStatus");
|
|
4952
|
+
|
|
4678
4953
|
// src/auth/context/AccountsContext.tsx
|
|
4679
|
-
var
|
|
4954
|
+
var import_react20 = require("react");
|
|
4680
4955
|
|
|
4681
4956
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsApiKeyRegenerateCreate.ts
|
|
4682
4957
|
var import_mutation = __toESM(require("swr/mutation"), 1);
|
|
@@ -5023,6 +5298,15 @@ __name(useCfgAccountsTokenCreate, "useCfgAccountsTokenCreate");
|
|
|
5023
5298
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsTokenRefreshCreate.ts
|
|
5024
5299
|
var import_mutation19 = __toESM(require("swr/mutation"), 1);
|
|
5025
5300
|
|
|
5301
|
+
// src/auth/context/sharedContext.ts
|
|
5302
|
+
var import_react19 = require("react");
|
|
5303
|
+
function sharedContext(key, initial) {
|
|
5304
|
+
const g = globalThis;
|
|
5305
|
+
const registry = g.__cfgAuthContexts ??= {};
|
|
5306
|
+
return registry[key] ??= (0, import_react19.createContext)(initial);
|
|
5307
|
+
}
|
|
5308
|
+
__name(sharedContext, "sharedContext");
|
|
5309
|
+
|
|
5026
5310
|
// src/auth/context/AccountsContext.tsx
|
|
5027
5311
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
5028
5312
|
function hasApiOrigin() {
|
|
@@ -5036,9 +5320,9 @@ function hasApiOrigin() {
|
|
|
5036
5320
|
}
|
|
5037
5321
|
}
|
|
5038
5322
|
__name(hasApiOrigin, "hasApiOrigin");
|
|
5039
|
-
var AccountsContext = (
|
|
5323
|
+
var AccountsContext = sharedContext("accounts", void 0);
|
|
5040
5324
|
function AccountsProvider({ children }) {
|
|
5041
|
-
const [profile, setProfile] = (0,
|
|
5325
|
+
const [profile, setProfile] = (0, import_react20.useState)(() => {
|
|
5042
5326
|
if (!auth.isAuthenticated()) {
|
|
5043
5327
|
clearProfileCache();
|
|
5044
5328
|
return void 0;
|
|
@@ -5046,15 +5330,15 @@ function AccountsProvider({ children }) {
|
|
|
5046
5330
|
const cached = getCachedProfile();
|
|
5047
5331
|
return cached || void 0;
|
|
5048
5332
|
});
|
|
5049
|
-
const [isLoadingProfile, setIsLoadingProfile] = (0,
|
|
5050
|
-
const [profileError, setProfileError] = (0,
|
|
5051
|
-
const profileRef = (0,
|
|
5052
|
-
const isLoadingRef = (0,
|
|
5053
|
-
const fetchSeqRef = (0,
|
|
5054
|
-
(0,
|
|
5333
|
+
const [isLoadingProfile, setIsLoadingProfile] = (0, import_react20.useState)(false);
|
|
5334
|
+
const [profileError, setProfileError] = (0, import_react20.useState)(null);
|
|
5335
|
+
const profileRef = (0, import_react20.useRef)(profile);
|
|
5336
|
+
const isLoadingRef = (0, import_react20.useRef)(false);
|
|
5337
|
+
const fetchSeqRef = (0, import_react20.useRef)(0);
|
|
5338
|
+
(0, import_react20.useEffect)(() => {
|
|
5055
5339
|
profileRef.current = profile;
|
|
5056
5340
|
}, [profile]);
|
|
5057
|
-
(0,
|
|
5341
|
+
(0, import_react20.useEffect)(() => {
|
|
5058
5342
|
isLoadingRef.current = isLoadingProfile;
|
|
5059
5343
|
}, [isLoadingProfile]);
|
|
5060
5344
|
const { trigger: triggerProfileUpdate } = useCfgAccountsProfileUpdateUpdate();
|
|
@@ -5063,7 +5347,7 @@ function AccountsProvider({ children }) {
|
|
|
5063
5347
|
const { trigger: triggerOtpRequest } = useCfgAccountsOtpRequestCreate();
|
|
5064
5348
|
const { trigger: triggerOtpVerify } = useCfgAccountsOtpVerifyCreate();
|
|
5065
5349
|
const { trigger: triggerPasswordLogin } = useCfgAccountsTokenCreate();
|
|
5066
|
-
const refreshProfile = (0,
|
|
5350
|
+
const refreshProfile = (0, import_react20.useCallback)(async (options) => {
|
|
5067
5351
|
const { callerId, force } = options || {};
|
|
5068
5352
|
if (!hasApiOrigin()) {
|
|
5069
5353
|
authLogger.debug(`No API origin configured, skipping profile fetch (caller: ${callerId})`);
|
|
@@ -5097,31 +5381,32 @@ function AccountsProvider({ children }) {
|
|
|
5097
5381
|
}
|
|
5098
5382
|
}
|
|
5099
5383
|
}, []);
|
|
5100
|
-
const updateProfile = (0,
|
|
5384
|
+
const updateProfile = (0, import_react20.useCallback)(async (data) => {
|
|
5101
5385
|
await triggerProfileUpdate({ body: data });
|
|
5102
5386
|
const user = await refreshProfile({ callerId: "updateProfile", force: true });
|
|
5103
5387
|
return user;
|
|
5104
5388
|
}, [triggerProfileUpdate, refreshProfile]);
|
|
5105
|
-
const partialUpdateProfile = (0,
|
|
5389
|
+
const partialUpdateProfile = (0, import_react20.useCallback)(async (data) => {
|
|
5106
5390
|
await triggerProfilePartialUpdate({ body: data });
|
|
5107
5391
|
const user = await refreshProfile({ callerId: "partialUpdateProfile", force: true });
|
|
5108
5392
|
return user;
|
|
5109
5393
|
}, [triggerProfilePartialUpdate, refreshProfile]);
|
|
5110
|
-
const uploadAvatar = (0,
|
|
5394
|
+
const uploadAvatar = (0, import_react20.useCallback)(async (avatar) => {
|
|
5111
5395
|
await triggerAvatar({ body: { avatar } });
|
|
5112
5396
|
const user = await refreshProfile({ callerId: "uploadAvatar", force: true });
|
|
5113
5397
|
return user;
|
|
5114
5398
|
}, [triggerAvatar, refreshProfile]);
|
|
5115
|
-
const requestOTP = (0,
|
|
5399
|
+
const requestOTP = (0, import_react20.useCallback)(async (data) => {
|
|
5116
5400
|
const result = await triggerOtpRequest({ body: data });
|
|
5117
5401
|
return result;
|
|
5118
5402
|
}, [triggerOtpRequest]);
|
|
5119
|
-
const settleLoginEnvelope = (0,
|
|
5403
|
+
const settleLoginEnvelope = (0, import_react20.useCallback)(async (result, callerId) => {
|
|
5120
5404
|
if (result.requires_2fa && result.session_id) {
|
|
5121
5405
|
authLogger.info("2FA required, session:", result.session_id);
|
|
5122
5406
|
return;
|
|
5123
5407
|
}
|
|
5124
5408
|
if (result.access && result.refresh) {
|
|
5409
|
+
authTrace("accounts.otp.session");
|
|
5125
5410
|
auth.setSession({ access: result.access, refresh: result.refresh });
|
|
5126
5411
|
try {
|
|
5127
5412
|
await refreshProfile({ callerId, force: true });
|
|
@@ -5130,29 +5415,30 @@ function AccountsProvider({ children }) {
|
|
|
5130
5415
|
}
|
|
5131
5416
|
}
|
|
5132
5417
|
}, [refreshProfile]);
|
|
5133
|
-
const verifyOTP = (0,
|
|
5418
|
+
const verifyOTP = (0, import_react20.useCallback)(async (data) => {
|
|
5134
5419
|
const result = await triggerOtpVerify({ body: data });
|
|
5135
5420
|
await settleLoginEnvelope(result, "verifyOTP");
|
|
5136
5421
|
return result;
|
|
5137
5422
|
}, [triggerOtpVerify, settleLoginEnvelope]);
|
|
5138
|
-
const loginWithPassword = (0,
|
|
5423
|
+
const loginWithPassword = (0, import_react20.useCallback)(async (data) => {
|
|
5139
5424
|
const result = await triggerPasswordLogin({ body: data });
|
|
5140
5425
|
await settleLoginEnvelope(result, "loginWithPassword");
|
|
5141
5426
|
return result;
|
|
5142
5427
|
}, [triggerPasswordLogin, settleLoginEnvelope]);
|
|
5143
|
-
const logout = (0,
|
|
5144
|
-
const
|
|
5145
|
-
if (
|
|
5146
|
-
CfgAccountsAuth.cfgAccountsTokenBlacklistCreate({ body: { refresh } }).catch(() => {
|
|
5428
|
+
const logout = (0, import_react20.useCallback)(() => {
|
|
5429
|
+
const refresh2 = auth.getRefreshToken();
|
|
5430
|
+
if (refresh2) {
|
|
5431
|
+
CfgAccountsAuth.cfgAccountsTokenBlacklistCreate({ body: { refresh: refresh2 } }).catch(() => {
|
|
5147
5432
|
authLogger.warn("Refresh-token blacklist failed (logged out locally anyway)");
|
|
5148
5433
|
});
|
|
5149
5434
|
}
|
|
5435
|
+
authTrace("accounts.logout");
|
|
5150
5436
|
auth.clearSession();
|
|
5151
5437
|
setProfile(void 0);
|
|
5152
5438
|
setProfileError(null);
|
|
5153
5439
|
clearProfileCache();
|
|
5154
5440
|
}, []);
|
|
5155
|
-
const value = (0,
|
|
5441
|
+
const value = (0, import_react20.useMemo)(() => ({
|
|
5156
5442
|
profile,
|
|
5157
5443
|
isLoadingProfile,
|
|
5158
5444
|
profileError,
|
|
@@ -5181,11 +5467,11 @@ function AccountsProvider({ children }) {
|
|
|
5181
5467
|
}
|
|
5182
5468
|
__name(AccountsProvider, "AccountsProvider");
|
|
5183
5469
|
function useAccountsContext() {
|
|
5184
|
-
const
|
|
5185
|
-
if (!
|
|
5470
|
+
const context2 = (0, import_react20.useContext)(AccountsContext);
|
|
5471
|
+
if (!context2) {
|
|
5186
5472
|
throw new Error("useAccountsContext must be used within AccountsProvider");
|
|
5187
5473
|
}
|
|
5188
|
-
return
|
|
5474
|
+
return context2;
|
|
5189
5475
|
}
|
|
5190
5476
|
__name(useAccountsContext, "useAccountsContext");
|
|
5191
5477
|
|
|
@@ -5202,7 +5488,7 @@ var resolveAuthRoutes = /* @__PURE__ */ __name((routes) => ({
|
|
|
5202
5488
|
defaultAuthCallback: routes?.defaultAuthCallback || routes?.auth || defaultRoutes.defaultAuthCallback
|
|
5203
5489
|
}), "resolveAuthRoutes");
|
|
5204
5490
|
var EMAIL_STORAGE_KEY = CFG_KEYS.email.key;
|
|
5205
|
-
var AuthContext = (
|
|
5491
|
+
var AuthContext = sharedContext("auth", void 0);
|
|
5206
5492
|
var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
5207
5493
|
const accounts = useAccountsContext();
|
|
5208
5494
|
const session = useSession();
|
|
@@ -5214,41 +5500,42 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
5214
5500
|
EMAIL_STORAGE_KEY,
|
|
5215
5501
|
null
|
|
5216
5502
|
);
|
|
5217
|
-
const routes = (0,
|
|
5218
|
-
const routesRef = (0,
|
|
5219
|
-
(0,
|
|
5503
|
+
const routes = (0, import_react21.useMemo)(() => resolveAuthRoutes(config?.routes), [config?.routes]);
|
|
5504
|
+
const routesRef = (0, import_react21.useRef)(routes);
|
|
5505
|
+
(0, import_react21.useEffect)(() => {
|
|
5220
5506
|
routesRef.current = routes;
|
|
5221
5507
|
}, [routes]);
|
|
5222
5508
|
const redirectManager = useAuthRedirectManager({
|
|
5223
5509
|
fallbackUrl: routes.defaultCallback,
|
|
5224
5510
|
clearOnUse: true
|
|
5225
5511
|
});
|
|
5226
|
-
const configRef = (0,
|
|
5227
|
-
(0,
|
|
5512
|
+
const configRef = (0, import_react21.useRef)(config);
|
|
5513
|
+
(0, import_react21.useEffect)(() => {
|
|
5228
5514
|
configRef.current = config;
|
|
5229
5515
|
}, [config]);
|
|
5230
|
-
const accountsRef = (0,
|
|
5231
|
-
(0,
|
|
5516
|
+
const accountsRef = (0, import_react21.useRef)(accounts);
|
|
5517
|
+
(0, import_react21.useEffect)(() => {
|
|
5232
5518
|
accountsRef.current = accounts;
|
|
5233
5519
|
}, [accounts]);
|
|
5234
|
-
const pendingManualNavRef = (0,
|
|
5235
|
-
const [profileSettled, setProfileSettled] = (0,
|
|
5520
|
+
const pendingManualNavRef = (0, import_react21.useRef)(false);
|
|
5521
|
+
const [profileSettled, setProfileSettled] = (0, import_react21.useState)(false);
|
|
5236
5522
|
const hasProfile = Boolean(accounts.profile);
|
|
5237
|
-
const profileAttemptedRef = (0,
|
|
5238
|
-
(0,
|
|
5523
|
+
const profileAttemptedRef = (0, import_react21.useRef)(false);
|
|
5524
|
+
(0, import_react21.useEffect)(() => {
|
|
5239
5525
|
if (!isAuthenticated) {
|
|
5240
5526
|
profileAttemptedRef.current = false;
|
|
5241
5527
|
const hasTokens = Boolean(auth.getToken() || auth.getRefreshToken());
|
|
5242
5528
|
if (hasTokens && !auth.isAuthenticated()) {
|
|
5243
5529
|
authLogger.warn("Dead session in storage \u2014 clearing");
|
|
5530
|
+
authTrace("bootstrap.purge", { why: "dead-tokens" });
|
|
5244
5531
|
auth.clearSession();
|
|
5245
5532
|
clearProfileCache();
|
|
5246
5533
|
} else if (!hasTokens && !auth.isAuthenticated()) {
|
|
5534
|
+
authTrace("bootstrap.purge", { why: "no-session" });
|
|
5247
5535
|
clearProfileCache();
|
|
5248
5536
|
purgeLegacyTokenStorage();
|
|
5249
5537
|
if (accountsRef.current.profile) accountsRef.current.logout();
|
|
5250
5538
|
}
|
|
5251
|
-
if (auth.isAuthenticated()) return;
|
|
5252
5539
|
setProfileSettled(true);
|
|
5253
5540
|
return;
|
|
5254
5541
|
}
|
|
@@ -5257,9 +5544,13 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
5257
5544
|
return;
|
|
5258
5545
|
}
|
|
5259
5546
|
profileAttemptedRef.current = true;
|
|
5547
|
+
authTrace("bootstrap.profile.start");
|
|
5260
5548
|
let cancelled = false;
|
|
5261
5549
|
accountsRef.current.refreshProfile({ callerId: "AuthProvider:bootstrap" }).catch((error) => {
|
|
5262
5550
|
authLogger.warn("Profile load failed (session kept):", error);
|
|
5551
|
+
authTrace("bootstrap.profile.failed", {
|
|
5552
|
+
status: error instanceof APIError ? error.statusCode : 0
|
|
5553
|
+
});
|
|
5263
5554
|
}).finally(() => {
|
|
5264
5555
|
if (!cancelled) setProfileSettled(true);
|
|
5265
5556
|
});
|
|
@@ -5268,11 +5559,47 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
5268
5559
|
};
|
|
5269
5560
|
}, [isAuthenticated, hasProfile]);
|
|
5270
5561
|
const isLoading = !profileSettled;
|
|
5271
|
-
const
|
|
5272
|
-
(0,
|
|
5562
|
+
const [clientReady, setClientReady] = (0, import_react21.useState)(false);
|
|
5563
|
+
const [timedOut, setTimedOut] = (0, import_react21.useState)(false);
|
|
5564
|
+
(0, import_react21.useEffect)(() => {
|
|
5565
|
+
setClientReady(true);
|
|
5566
|
+
const timer = setTimeout(() => setTimedOut(true), 8e3);
|
|
5567
|
+
return () => clearTimeout(timer);
|
|
5568
|
+
}, []);
|
|
5569
|
+
const status = resolveAuthStatus({
|
|
5570
|
+
clientReady,
|
|
5571
|
+
snapshotAuthenticated: isAuthenticated,
|
|
5572
|
+
storeAuthenticated: isBrowser2 ? auth.isAuthenticated() : false,
|
|
5573
|
+
profileSettled,
|
|
5574
|
+
timedOut
|
|
5575
|
+
});
|
|
5576
|
+
const lastStatusRef = (0, import_react21.useRef)("");
|
|
5577
|
+
(0, import_react21.useEffect)(() => {
|
|
5578
|
+
if (lastStatusRef.current === status) return;
|
|
5579
|
+
lastStatusRef.current = status;
|
|
5580
|
+
authTrace("status", {
|
|
5581
|
+
status,
|
|
5582
|
+
snapshot: isAuthenticated,
|
|
5583
|
+
store: auth.isAuthenticated(),
|
|
5584
|
+
profileSettled,
|
|
5585
|
+
timedOut,
|
|
5586
|
+
path: pathname ?? ""
|
|
5587
|
+
});
|
|
5588
|
+
}, [status, isAuthenticated, profileSettled, timedOut, pathname]);
|
|
5589
|
+
(0, import_react21.useEffect)(() => {
|
|
5590
|
+
globalThis.__cfgAuthNow = () => ({
|
|
5591
|
+
status,
|
|
5592
|
+
snapshot: isAuthenticated,
|
|
5593
|
+
store: auth.isAuthenticated(),
|
|
5594
|
+
hasToken: Boolean(auth.getToken()),
|
|
5595
|
+
hasRefresh: Boolean(auth.getRefreshToken()),
|
|
5596
|
+
profileSettled,
|
|
5597
|
+
timedOut
|
|
5598
|
+
});
|
|
5599
|
+
}, [status, isAuthenticated, profileSettled, timedOut]);
|
|
5600
|
+
(0, import_react21.useEffect)(() => {
|
|
5273
5601
|
const unsubscribe = auth.onSessionExpired(() => {
|
|
5274
|
-
|
|
5275
|
-
expiredHandledRef.current = true;
|
|
5602
|
+
authTrace("expired.handler", { path: pathname ?? "" });
|
|
5276
5603
|
authLogger.warn("Session expired (terminal 401) \u2014 redirecting to login");
|
|
5277
5604
|
clearProfileCache();
|
|
5278
5605
|
Analytics.event("auth_session_expired" /* AUTH_SESSION_EXPIRED */, {
|
|
@@ -5281,16 +5608,17 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
5281
5608
|
router.hardReplace(routesRef.current.defaultAuthCallback);
|
|
5282
5609
|
});
|
|
5283
5610
|
return unsubscribe;
|
|
5284
|
-
}, [router]);
|
|
5285
|
-
(0,
|
|
5611
|
+
}, [router, pathname]);
|
|
5612
|
+
(0, import_react21.useEffect)(() => {
|
|
5286
5613
|
if (!isAuthenticated || pendingManualNavRef.current) return;
|
|
5287
5614
|
if (pathname === routes.auth && !queryParams.get("flow")) {
|
|
5288
5615
|
const saved = redirectManager.hasRedirect() ? redirectManager.getRedirect() : null;
|
|
5289
5616
|
if (saved) redirectManager.clearRedirect();
|
|
5617
|
+
authTrace("leave-auth", { to: saved || routes.defaultCallback, saved: Boolean(saved) });
|
|
5290
5618
|
router.push(saved || routes.defaultCallback);
|
|
5291
5619
|
}
|
|
5292
5620
|
}, [isAuthenticated, pathname, queryParams, routes, router, redirectManager]);
|
|
5293
|
-
const loadCurrentProfile = (0,
|
|
5621
|
+
const loadCurrentProfile = (0, import_react21.useCallback)(async (callerId) => {
|
|
5294
5622
|
if (!auth.isAuthenticated()) {
|
|
5295
5623
|
throw new Error("No valid authentication token");
|
|
5296
5624
|
}
|
|
@@ -5298,7 +5626,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
5298
5626
|
callerId: callerId || "AuthContext.loadCurrentProfile"
|
|
5299
5627
|
});
|
|
5300
5628
|
}, []);
|
|
5301
|
-
const checkAuthAndRedirect = (0,
|
|
5629
|
+
const checkAuthAndRedirect = (0, import_react21.useCallback)(async () => {
|
|
5302
5630
|
if (auth.isAuthenticated()) {
|
|
5303
5631
|
try {
|
|
5304
5632
|
await loadCurrentProfile("checkAuthAndRedirect");
|
|
@@ -5310,8 +5638,9 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
5310
5638
|
router.push(routesRef.current.defaultAuthCallback);
|
|
5311
5639
|
}
|
|
5312
5640
|
}, [loadCurrentProfile, router]);
|
|
5313
|
-
const requestOTP = (0,
|
|
5641
|
+
const requestOTP = (0, import_react21.useCallback)(
|
|
5314
5642
|
async (identifier, sourceUrl, consent) => {
|
|
5643
|
+
authTrace("otp.request");
|
|
5315
5644
|
auth.clearSession();
|
|
5316
5645
|
try {
|
|
5317
5646
|
const body = {
|
|
@@ -5352,10 +5681,11 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
5352
5681
|
},
|
|
5353
5682
|
[]
|
|
5354
5683
|
);
|
|
5355
|
-
const verifyOTP = (0,
|
|
5684
|
+
const verifyOTP = (0, import_react21.useCallback)(
|
|
5356
5685
|
async (identifier, otpCode, sourceUrl, redirectUrl, skipRedirect) => {
|
|
5357
5686
|
try {
|
|
5358
5687
|
pendingManualNavRef.current = Boolean(skipRedirect);
|
|
5688
|
+
authTrace("otp.verify", { skipRedirect: Boolean(skipRedirect) });
|
|
5359
5689
|
const result = await accountsRef.current.verifyOTP({
|
|
5360
5690
|
identifier,
|
|
5361
5691
|
otp: otpCode,
|
|
@@ -5412,11 +5742,12 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
5412
5742
|
},
|
|
5413
5743
|
[setStoredEmail, redirectManager, router]
|
|
5414
5744
|
);
|
|
5415
|
-
const login = (0,
|
|
5745
|
+
const login = (0, import_react21.useCallback)(
|
|
5416
5746
|
async (email, password, options) => {
|
|
5417
5747
|
const { redirectUrl, skipRedirect } = options || {};
|
|
5418
5748
|
try {
|
|
5419
5749
|
pendingManualNavRef.current = Boolean(skipRedirect);
|
|
5750
|
+
authTrace("password.login", { skipRedirect: Boolean(skipRedirect) });
|
|
5420
5751
|
const result = await accountsRef.current.loginWithPassword({
|
|
5421
5752
|
email,
|
|
5422
5753
|
password
|
|
@@ -5477,7 +5808,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
5477
5808
|
},
|
|
5478
5809
|
[setStoredEmail, redirectManager, router]
|
|
5479
5810
|
);
|
|
5480
|
-
const refreshToken = (0,
|
|
5811
|
+
const refreshToken = (0, import_react21.useCallback)(async () => {
|
|
5481
5812
|
const access = await auth.refreshNow();
|
|
5482
5813
|
if (access) {
|
|
5483
5814
|
Analytics.event("auth_token_refresh" /* AUTH_TOKEN_REFRESH */, {
|
|
@@ -5490,7 +5821,8 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
5490
5821
|
});
|
|
5491
5822
|
return { success: false, message: "Error refreshing token" };
|
|
5492
5823
|
}, []);
|
|
5493
|
-
const logout = (0,
|
|
5824
|
+
const logout = (0, import_react21.useCallback)(() => {
|
|
5825
|
+
authTrace("logout");
|
|
5494
5826
|
Analytics.event("auth_logout" /* AUTH_LOGOUT */, {
|
|
5495
5827
|
category: "auth" /* AUTH */
|
|
5496
5828
|
});
|
|
@@ -5499,24 +5831,25 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
5499
5831
|
}, [router]);
|
|
5500
5832
|
const user = accounts.profile ?? null;
|
|
5501
5833
|
const isAdminUser = Boolean(user?.is_staff || user?.is_superuser);
|
|
5502
|
-
(0,
|
|
5834
|
+
(0, import_react21.useEffect)(() => {
|
|
5503
5835
|
applyRoleLogPolicy({ isAdmin: isAdminUser });
|
|
5504
5836
|
}, [isAdminUser]);
|
|
5505
|
-
const updateProfile = (0,
|
|
5837
|
+
const updateProfile = (0, import_react21.useCallback)(
|
|
5506
5838
|
async (data) => {
|
|
5507
5839
|
const result = await accountsRef.current.partialUpdateProfile(data);
|
|
5508
5840
|
return result;
|
|
5509
5841
|
},
|
|
5510
5842
|
[]
|
|
5511
5843
|
);
|
|
5512
|
-
const uploadAvatar = (0,
|
|
5844
|
+
const uploadAvatar = (0, import_react21.useCallback)(async (avatar) => {
|
|
5513
5845
|
const result = await accountsRef.current.uploadAvatar(avatar);
|
|
5514
5846
|
return result;
|
|
5515
5847
|
}, []);
|
|
5516
|
-
const value = (0,
|
|
5848
|
+
const value = (0, import_react21.useMemo)(
|
|
5517
5849
|
() => ({
|
|
5518
5850
|
user,
|
|
5519
5851
|
isLoading,
|
|
5852
|
+
status,
|
|
5520
5853
|
// Reactive: flips via the store snapshot (token writes, refreshes,
|
|
5521
5854
|
// expiry timer, cross-tab/cross-store sync) — no ticks, no polling.
|
|
5522
5855
|
isAuthenticated,
|
|
@@ -5544,6 +5877,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
5544
5877
|
[
|
|
5545
5878
|
user,
|
|
5546
5879
|
isLoading,
|
|
5880
|
+
status,
|
|
5547
5881
|
isAuthenticated,
|
|
5548
5882
|
isAdminUser,
|
|
5549
5883
|
routes,
|
|
@@ -5569,10 +5903,11 @@ function AuthProviderRaw({ children, config, enabled = true }) {
|
|
|
5569
5903
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AccountsProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AuthProviderInternal, { config, children }) });
|
|
5570
5904
|
}
|
|
5571
5905
|
__name(AuthProviderRaw, "AuthProviderRaw");
|
|
5572
|
-
var AuthProvider = (0,
|
|
5906
|
+
var AuthProvider = (0, import_react21.memo)(AuthProviderRaw);
|
|
5573
5907
|
var defaultAuthState = {
|
|
5574
5908
|
user: null,
|
|
5575
5909
|
isLoading: false,
|
|
5910
|
+
status: "anonymous",
|
|
5576
5911
|
isAuthenticated: false,
|
|
5577
5912
|
isAdminUser: false,
|
|
5578
5913
|
routes: resolveAuthRoutes(),
|
|
@@ -5625,14 +5960,14 @@ var defaultAuthState = {
|
|
|
5625
5960
|
}, "uploadAvatar")
|
|
5626
5961
|
};
|
|
5627
5962
|
var useAuth = /* @__PURE__ */ __name(() => {
|
|
5628
|
-
const
|
|
5629
|
-
if (
|
|
5963
|
+
const context2 = (0, import_react21.useContext)(AuthContext);
|
|
5964
|
+
if (context2 === void 0) {
|
|
5630
5965
|
if (isBrowser2 && isDev) {
|
|
5631
5966
|
authLogger.debug("useAuth called outside AuthProvider, returning default state");
|
|
5632
5967
|
}
|
|
5633
5968
|
return defaultAuthState;
|
|
5634
5969
|
}
|
|
5635
|
-
return
|
|
5970
|
+
return context2;
|
|
5636
5971
|
}, "useAuth");
|
|
5637
5972
|
var AuthContext_default = AuthContext;
|
|
5638
5973
|
|