@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/hooks.mjs
CHANGED
|
@@ -1147,6 +1147,29 @@ var REFRESH_KEY = "cfg.auth.refresh_token";
|
|
|
1147
1147
|
var API_KEY_KEY = "cfg.auth.api_key";
|
|
1148
1148
|
var storage = true ? cfgStorage : createStorage2("cfg");
|
|
1149
1149
|
var isBrowser = typeof window !== "undefined";
|
|
1150
|
+
function trace(ev, fields) {
|
|
1151
|
+
try {
|
|
1152
|
+
const g = globalThis;
|
|
1153
|
+
const sink = g.__cfgAuthTrace;
|
|
1154
|
+
if (sink) {
|
|
1155
|
+
sink(ev, fields);
|
|
1156
|
+
return;
|
|
1157
|
+
}
|
|
1158
|
+
const queue = g.__cfgAuthTraceQ ?? [];
|
|
1159
|
+
g.__cfgAuthTraceQ = queue;
|
|
1160
|
+
if (queue.length < 100) queue.push([Date.now(), ev, fields]);
|
|
1161
|
+
} catch {
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
__name(trace, "trace");
|
|
1165
|
+
function pathOf(url) {
|
|
1166
|
+
try {
|
|
1167
|
+
return new URL(url, "http://x").pathname;
|
|
1168
|
+
} catch {
|
|
1169
|
+
return "";
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
__name(pathOf, "pathOf");
|
|
1150
1173
|
function secondsUntilExp(token) {
|
|
1151
1174
|
const exp = jwtExpMs(token);
|
|
1152
1175
|
return exp === null ? void 0 : Math.max(1, Math.floor((exp - Date.now()) / 1e3));
|
|
@@ -1306,7 +1329,10 @@ __name(scheduleExpiryFlip, "scheduleExpiryFlip");
|
|
|
1306
1329
|
function notifySessionChanged() {
|
|
1307
1330
|
const next = computeSnapshot();
|
|
1308
1331
|
const changed = next.status !== _snapshot.status || next.accessExpiresAt !== _snapshot.accessExpiresAt;
|
|
1309
|
-
if (changed)
|
|
1332
|
+
if (changed) {
|
|
1333
|
+
_snapshot = next;
|
|
1334
|
+
trace("store.snapshot", { status: next.status });
|
|
1335
|
+
}
|
|
1310
1336
|
scheduleExpiryFlip();
|
|
1311
1337
|
if (!changed) return;
|
|
1312
1338
|
for (const listener of Array.from(_sessionListeners)) {
|
|
@@ -1389,6 +1415,7 @@ var auth = {
|
|
|
1389
1415
|
return _storage.get(ACCESS_KEY);
|
|
1390
1416
|
},
|
|
1391
1417
|
setToken(token) {
|
|
1418
|
+
trace("store.setToken", { present: token !== null });
|
|
1392
1419
|
_storage.set(ACCESS_KEY, token);
|
|
1393
1420
|
notifySessionChanged();
|
|
1394
1421
|
},
|
|
@@ -1396,10 +1423,12 @@ var auth = {
|
|
|
1396
1423
|
return _storage.get(REFRESH_KEY);
|
|
1397
1424
|
},
|
|
1398
1425
|
setRefreshToken(token) {
|
|
1426
|
+
trace("store.setRefreshToken", { present: token !== null });
|
|
1399
1427
|
_storage.set(REFRESH_KEY, token);
|
|
1400
1428
|
notifySessionChanged();
|
|
1401
1429
|
},
|
|
1402
1430
|
clearTokens() {
|
|
1431
|
+
trace("store.clearTokens");
|
|
1403
1432
|
for (const mode of ["localStorage", "sessionStorage", "cookie"]) {
|
|
1404
1433
|
const backend = backendFor(mode);
|
|
1405
1434
|
backend.set(ACCESS_KEY, null);
|
|
@@ -1422,6 +1451,7 @@ var auth = {
|
|
|
1422
1451
|
* rotation); `refresh: null` explicitly drops it.
|
|
1423
1452
|
*/
|
|
1424
1453
|
setSession(tokens) {
|
|
1454
|
+
trace("store.setSession", { refresh: tokens.refresh === void 0 ? "kept" : tokens.refresh === null ? "dropped" : "set" });
|
|
1425
1455
|
_storage.set(ACCESS_KEY, tokens.access);
|
|
1426
1456
|
if (tokens.refresh !== void 0) _storage.set(REFRESH_KEY, tokens.refresh);
|
|
1427
1457
|
notifySessionChanged();
|
|
@@ -1560,7 +1590,11 @@ async function tryRefresh() {
|
|
|
1560
1590
|
const refresh = auth.getRefreshToken();
|
|
1561
1591
|
if (!refresh) return null;
|
|
1562
1592
|
const result = await _refreshHandler(refresh);
|
|
1563
|
-
if (!result?.access)
|
|
1593
|
+
if (!result?.access) {
|
|
1594
|
+
trace("refresh", { ok: false, why: "no-access" });
|
|
1595
|
+
return null;
|
|
1596
|
+
}
|
|
1597
|
+
trace("refresh", { ok: true, rotated: Boolean(result.refresh) });
|
|
1564
1598
|
auth.setToken(result.access);
|
|
1565
1599
|
if (result.refresh) auth.setRefreshToken(result.refresh);
|
|
1566
1600
|
return result.access;
|
|
@@ -1573,6 +1607,7 @@ async function tryRefresh() {
|
|
|
1573
1607
|
}
|
|
1574
1608
|
return await runRefresh();
|
|
1575
1609
|
} catch {
|
|
1610
|
+
trace("refresh", { ok: false, why: "threw" });
|
|
1576
1611
|
return null;
|
|
1577
1612
|
} finally {
|
|
1578
1613
|
_refreshInflight = null;
|
|
@@ -1581,7 +1616,8 @@ async function tryRefresh() {
|
|
|
1581
1616
|
return _refreshInflight;
|
|
1582
1617
|
}
|
|
1583
1618
|
__name(tryRefresh, "tryRefresh");
|
|
1584
|
-
function expireSession(response) {
|
|
1619
|
+
function expireSession(response, why) {
|
|
1620
|
+
trace("store.expire", { why, status: response.status, path: pathOf(response.url), handlers: _sessionExpiredHandlers.size });
|
|
1585
1621
|
auth.clearTokens();
|
|
1586
1622
|
for (const cb of Array.from(_sessionExpiredHandlers)) {
|
|
1587
1623
|
try {
|
|
@@ -1724,15 +1760,16 @@ function installAuthOnClient(client2) {
|
|
|
1724
1760
|
client2.interceptors.response.use(async (response, request) => {
|
|
1725
1761
|
if (response.status !== 401) return response;
|
|
1726
1762
|
if (/\/accounts\/(otp|oauth|login|register|token)\b/.test(request.url)) {
|
|
1763
|
+
trace("401.passthrough", { path: pathOf(request.url) });
|
|
1727
1764
|
return response;
|
|
1728
1765
|
}
|
|
1729
1766
|
if (request.headers.get(RETRY_MARKER)) {
|
|
1730
|
-
expireSession(response);
|
|
1767
|
+
expireSession(response, "retry-marker");
|
|
1731
1768
|
return response;
|
|
1732
1769
|
}
|
|
1733
1770
|
const newToken = await tryRefresh();
|
|
1734
1771
|
if (!newToken) {
|
|
1735
|
-
expireSession(response);
|
|
1772
|
+
expireSession(response, "refresh-failed");
|
|
1736
1773
|
return response;
|
|
1737
1774
|
}
|
|
1738
1775
|
const retry = request.clone();
|
|
@@ -1744,7 +1781,7 @@ function installAuthOnClient(client2) {
|
|
|
1744
1781
|
}
|
|
1745
1782
|
try {
|
|
1746
1783
|
const retried = await fetch(retry);
|
|
1747
|
-
if (retried.status === 401) expireSession(retried);
|
|
1784
|
+
if (retried.status === 401) expireSession(retried, "retry-401");
|
|
1748
1785
|
return retried;
|
|
1749
1786
|
} catch {
|
|
1750
1787
|
return response;
|