@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.cjs
CHANGED
|
@@ -376,6 +376,29 @@ var REFRESH_KEY = "cfg.auth.refresh_token";
|
|
|
376
376
|
var API_KEY_KEY = "cfg.auth.api_key";
|
|
377
377
|
var storage = true ? cfgStorage : createStorage2("cfg");
|
|
378
378
|
var isBrowser = typeof window !== "undefined";
|
|
379
|
+
function trace(ev, fields) {
|
|
380
|
+
try {
|
|
381
|
+
const g = globalThis;
|
|
382
|
+
const sink = g.__cfgAuthTrace;
|
|
383
|
+
if (sink) {
|
|
384
|
+
sink(ev, fields);
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
const queue = g.__cfgAuthTraceQ ?? [];
|
|
388
|
+
g.__cfgAuthTraceQ = queue;
|
|
389
|
+
if (queue.length < 100) queue.push([Date.now(), ev, fields]);
|
|
390
|
+
} catch {
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
__name(trace, "trace");
|
|
394
|
+
function pathOf(url) {
|
|
395
|
+
try {
|
|
396
|
+
return new URL(url, "http://x").pathname;
|
|
397
|
+
} catch {
|
|
398
|
+
return "";
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
__name(pathOf, "pathOf");
|
|
379
402
|
function secondsUntilExp(token) {
|
|
380
403
|
const exp = jwtExpMs(token);
|
|
381
404
|
return exp === null ? void 0 : Math.max(1, Math.floor((exp - Date.now()) / 1e3));
|
|
@@ -535,7 +558,10 @@ __name(scheduleExpiryFlip, "scheduleExpiryFlip");
|
|
|
535
558
|
function notifySessionChanged() {
|
|
536
559
|
const next = computeSnapshot();
|
|
537
560
|
const changed = next.status !== _snapshot.status || next.accessExpiresAt !== _snapshot.accessExpiresAt;
|
|
538
|
-
if (changed)
|
|
561
|
+
if (changed) {
|
|
562
|
+
_snapshot = next;
|
|
563
|
+
trace("store.snapshot", { status: next.status });
|
|
564
|
+
}
|
|
539
565
|
scheduleExpiryFlip();
|
|
540
566
|
if (!changed) return;
|
|
541
567
|
for (const listener of Array.from(_sessionListeners)) {
|
|
@@ -618,6 +644,7 @@ var auth = {
|
|
|
618
644
|
return _storage.get(ACCESS_KEY);
|
|
619
645
|
},
|
|
620
646
|
setToken(token) {
|
|
647
|
+
trace("store.setToken", { present: token !== null });
|
|
621
648
|
_storage.set(ACCESS_KEY, token);
|
|
622
649
|
notifySessionChanged();
|
|
623
650
|
},
|
|
@@ -625,10 +652,12 @@ var auth = {
|
|
|
625
652
|
return _storage.get(REFRESH_KEY);
|
|
626
653
|
},
|
|
627
654
|
setRefreshToken(token) {
|
|
655
|
+
trace("store.setRefreshToken", { present: token !== null });
|
|
628
656
|
_storage.set(REFRESH_KEY, token);
|
|
629
657
|
notifySessionChanged();
|
|
630
658
|
},
|
|
631
659
|
clearTokens() {
|
|
660
|
+
trace("store.clearTokens");
|
|
632
661
|
for (const mode of ["localStorage", "sessionStorage", "cookie"]) {
|
|
633
662
|
const backend = backendFor(mode);
|
|
634
663
|
backend.set(ACCESS_KEY, null);
|
|
@@ -651,6 +680,7 @@ var auth = {
|
|
|
651
680
|
* rotation); `refresh: null` explicitly drops it.
|
|
652
681
|
*/
|
|
653
682
|
setSession(tokens) {
|
|
683
|
+
trace("store.setSession", { refresh: tokens.refresh === void 0 ? "kept" : tokens.refresh === null ? "dropped" : "set" });
|
|
654
684
|
_storage.set(ACCESS_KEY, tokens.access);
|
|
655
685
|
if (tokens.refresh !== void 0) _storage.set(REFRESH_KEY, tokens.refresh);
|
|
656
686
|
notifySessionChanged();
|
|
@@ -789,7 +819,11 @@ async function tryRefresh() {
|
|
|
789
819
|
const refresh = auth.getRefreshToken();
|
|
790
820
|
if (!refresh) return null;
|
|
791
821
|
const result = await _refreshHandler(refresh);
|
|
792
|
-
if (!result?.access)
|
|
822
|
+
if (!result?.access) {
|
|
823
|
+
trace("refresh", { ok: false, why: "no-access" });
|
|
824
|
+
return null;
|
|
825
|
+
}
|
|
826
|
+
trace("refresh", { ok: true, rotated: Boolean(result.refresh) });
|
|
793
827
|
auth.setToken(result.access);
|
|
794
828
|
if (result.refresh) auth.setRefreshToken(result.refresh);
|
|
795
829
|
return result.access;
|
|
@@ -802,6 +836,7 @@ async function tryRefresh() {
|
|
|
802
836
|
}
|
|
803
837
|
return await runRefresh();
|
|
804
838
|
} catch {
|
|
839
|
+
trace("refresh", { ok: false, why: "threw" });
|
|
805
840
|
return null;
|
|
806
841
|
} finally {
|
|
807
842
|
_refreshInflight = null;
|
|
@@ -810,7 +845,8 @@ async function tryRefresh() {
|
|
|
810
845
|
return _refreshInflight;
|
|
811
846
|
}
|
|
812
847
|
__name(tryRefresh, "tryRefresh");
|
|
813
|
-
function expireSession(response) {
|
|
848
|
+
function expireSession(response, why) {
|
|
849
|
+
trace("store.expire", { why, status: response.status, path: pathOf(response.url), handlers: _sessionExpiredHandlers.size });
|
|
814
850
|
auth.clearTokens();
|
|
815
851
|
for (const cb of Array.from(_sessionExpiredHandlers)) {
|
|
816
852
|
try {
|
|
@@ -953,15 +989,16 @@ function installAuthOnClient(client2) {
|
|
|
953
989
|
client2.interceptors.response.use(async (response, request) => {
|
|
954
990
|
if (response.status !== 401) return response;
|
|
955
991
|
if (/\/accounts\/(otp|oauth|login|register|token)\b/.test(request.url)) {
|
|
992
|
+
trace("401.passthrough", { path: pathOf(request.url) });
|
|
956
993
|
return response;
|
|
957
994
|
}
|
|
958
995
|
if (request.headers.get(RETRY_MARKER)) {
|
|
959
|
-
expireSession(response);
|
|
996
|
+
expireSession(response, "retry-marker");
|
|
960
997
|
return response;
|
|
961
998
|
}
|
|
962
999
|
const newToken = await tryRefresh();
|
|
963
1000
|
if (!newToken) {
|
|
964
|
-
expireSession(response);
|
|
1001
|
+
expireSession(response, "refresh-failed");
|
|
965
1002
|
return response;
|
|
966
1003
|
}
|
|
967
1004
|
const retry = request.clone();
|
|
@@ -973,7 +1010,7 @@ function installAuthOnClient(client2) {
|
|
|
973
1010
|
}
|
|
974
1011
|
try {
|
|
975
1012
|
const retried = await fetch(retry);
|
|
976
|
-
if (retried.status === 401) expireSession(retried);
|
|
1013
|
+
if (retried.status === 401) expireSession(retried, "retry-401");
|
|
977
1014
|
return retried;
|
|
978
1015
|
} catch {
|
|
979
1016
|
return response;
|