@djangocfg/api 2.1.619 → 2.1.621

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/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) _snapshot = next;
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) return null;
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;