@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/clients.mjs
CHANGED
|
@@ -349,6 +349,29 @@ var REFRESH_KEY = "cfg.auth.refresh_token";
|
|
|
349
349
|
var API_KEY_KEY = "cfg.auth.api_key";
|
|
350
350
|
var storage = true ? cfgStorage : createStorage2("cfg");
|
|
351
351
|
var isBrowser = typeof window !== "undefined";
|
|
352
|
+
function trace(ev, fields) {
|
|
353
|
+
try {
|
|
354
|
+
const g = globalThis;
|
|
355
|
+
const sink = g.__cfgAuthTrace;
|
|
356
|
+
if (sink) {
|
|
357
|
+
sink(ev, fields);
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
const queue = g.__cfgAuthTraceQ ?? [];
|
|
361
|
+
g.__cfgAuthTraceQ = queue;
|
|
362
|
+
if (queue.length < 100) queue.push([Date.now(), ev, fields]);
|
|
363
|
+
} catch {
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
__name(trace, "trace");
|
|
367
|
+
function pathOf(url) {
|
|
368
|
+
try {
|
|
369
|
+
return new URL(url, "http://x").pathname;
|
|
370
|
+
} catch {
|
|
371
|
+
return "";
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
__name(pathOf, "pathOf");
|
|
352
375
|
function secondsUntilExp(token) {
|
|
353
376
|
const exp = jwtExpMs(token);
|
|
354
377
|
return exp === null ? void 0 : Math.max(1, Math.floor((exp - Date.now()) / 1e3));
|
|
@@ -508,7 +531,10 @@ __name(scheduleExpiryFlip, "scheduleExpiryFlip");
|
|
|
508
531
|
function notifySessionChanged() {
|
|
509
532
|
const next = computeSnapshot();
|
|
510
533
|
const changed = next.status !== _snapshot.status || next.accessExpiresAt !== _snapshot.accessExpiresAt;
|
|
511
|
-
if (changed)
|
|
534
|
+
if (changed) {
|
|
535
|
+
_snapshot = next;
|
|
536
|
+
trace("store.snapshot", { status: next.status });
|
|
537
|
+
}
|
|
512
538
|
scheduleExpiryFlip();
|
|
513
539
|
if (!changed) return;
|
|
514
540
|
for (const listener of Array.from(_sessionListeners)) {
|
|
@@ -591,6 +617,7 @@ var auth = {
|
|
|
591
617
|
return _storage.get(ACCESS_KEY);
|
|
592
618
|
},
|
|
593
619
|
setToken(token) {
|
|
620
|
+
trace("store.setToken", { present: token !== null });
|
|
594
621
|
_storage.set(ACCESS_KEY, token);
|
|
595
622
|
notifySessionChanged();
|
|
596
623
|
},
|
|
@@ -598,10 +625,12 @@ var auth = {
|
|
|
598
625
|
return _storage.get(REFRESH_KEY);
|
|
599
626
|
},
|
|
600
627
|
setRefreshToken(token) {
|
|
628
|
+
trace("store.setRefreshToken", { present: token !== null });
|
|
601
629
|
_storage.set(REFRESH_KEY, token);
|
|
602
630
|
notifySessionChanged();
|
|
603
631
|
},
|
|
604
632
|
clearTokens() {
|
|
633
|
+
trace("store.clearTokens");
|
|
605
634
|
for (const mode of ["localStorage", "sessionStorage", "cookie"]) {
|
|
606
635
|
const backend = backendFor(mode);
|
|
607
636
|
backend.set(ACCESS_KEY, null);
|
|
@@ -624,6 +653,7 @@ var auth = {
|
|
|
624
653
|
* rotation); `refresh: null` explicitly drops it.
|
|
625
654
|
*/
|
|
626
655
|
setSession(tokens) {
|
|
656
|
+
trace("store.setSession", { refresh: tokens.refresh === void 0 ? "kept" : tokens.refresh === null ? "dropped" : "set" });
|
|
627
657
|
_storage.set(ACCESS_KEY, tokens.access);
|
|
628
658
|
if (tokens.refresh !== void 0) _storage.set(REFRESH_KEY, tokens.refresh);
|
|
629
659
|
notifySessionChanged();
|
|
@@ -762,7 +792,11 @@ async function tryRefresh() {
|
|
|
762
792
|
const refresh = auth.getRefreshToken();
|
|
763
793
|
if (!refresh) return null;
|
|
764
794
|
const result = await _refreshHandler(refresh);
|
|
765
|
-
if (!result?.access)
|
|
795
|
+
if (!result?.access) {
|
|
796
|
+
trace("refresh", { ok: false, why: "no-access" });
|
|
797
|
+
return null;
|
|
798
|
+
}
|
|
799
|
+
trace("refresh", { ok: true, rotated: Boolean(result.refresh) });
|
|
766
800
|
auth.setToken(result.access);
|
|
767
801
|
if (result.refresh) auth.setRefreshToken(result.refresh);
|
|
768
802
|
return result.access;
|
|
@@ -775,6 +809,7 @@ async function tryRefresh() {
|
|
|
775
809
|
}
|
|
776
810
|
return await runRefresh();
|
|
777
811
|
} catch {
|
|
812
|
+
trace("refresh", { ok: false, why: "threw" });
|
|
778
813
|
return null;
|
|
779
814
|
} finally {
|
|
780
815
|
_refreshInflight = null;
|
|
@@ -783,7 +818,8 @@ async function tryRefresh() {
|
|
|
783
818
|
return _refreshInflight;
|
|
784
819
|
}
|
|
785
820
|
__name(tryRefresh, "tryRefresh");
|
|
786
|
-
function expireSession(response) {
|
|
821
|
+
function expireSession(response, why) {
|
|
822
|
+
trace("store.expire", { why, status: response.status, path: pathOf(response.url), handlers: _sessionExpiredHandlers.size });
|
|
787
823
|
auth.clearTokens();
|
|
788
824
|
for (const cb of Array.from(_sessionExpiredHandlers)) {
|
|
789
825
|
try {
|
|
@@ -926,15 +962,16 @@ function installAuthOnClient(client2) {
|
|
|
926
962
|
client2.interceptors.response.use(async (response, request) => {
|
|
927
963
|
if (response.status !== 401) return response;
|
|
928
964
|
if (/\/accounts\/(otp|oauth|login|register|token)\b/.test(request.url)) {
|
|
965
|
+
trace("401.passthrough", { path: pathOf(request.url) });
|
|
929
966
|
return response;
|
|
930
967
|
}
|
|
931
968
|
if (request.headers.get(RETRY_MARKER)) {
|
|
932
|
-
expireSession(response);
|
|
969
|
+
expireSession(response, "retry-marker");
|
|
933
970
|
return response;
|
|
934
971
|
}
|
|
935
972
|
const newToken = await tryRefresh();
|
|
936
973
|
if (!newToken) {
|
|
937
|
-
expireSession(response);
|
|
974
|
+
expireSession(response, "refresh-failed");
|
|
938
975
|
return response;
|
|
939
976
|
}
|
|
940
977
|
const retry = request.clone();
|
|
@@ -946,7 +983,7 @@ function installAuthOnClient(client2) {
|
|
|
946
983
|
}
|
|
947
984
|
try {
|
|
948
985
|
const retried = await fetch(retry);
|
|
949
|
-
if (retried.status === 401) expireSession(retried);
|
|
986
|
+
if (retried.status === 401) expireSession(retried, "retry-401");
|
|
950
987
|
return retried;
|
|
951
988
|
} catch {
|
|
952
989
|
return response;
|