@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/auth.cjs +308 -40
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +75 -2
- package/dist/auth.d.ts +75 -2
- package/dist/auth.mjs +308 -40
- 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 +198 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +198 -26
- 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/context/AccountsContext.tsx +3 -0
- package/src/auth/context/AuthContext.tsx +61 -8
- 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 +183 -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/index.mjs
CHANGED
|
@@ -1,6 +1,141 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
3
|
|
|
4
|
+
// src/auth/trace.ts
|
|
5
|
+
var KEY = "cfg.auth.trace";
|
|
6
|
+
var MAX = 200;
|
|
7
|
+
var MAX_STRING = 120;
|
|
8
|
+
var SENSITIVE = /token|otp|code|email|password|secret|cookie|authorization|key|identifier/i;
|
|
9
|
+
var TAB = Math.random().toString(36).slice(2, 6);
|
|
10
|
+
var hasWindow = typeof window !== "undefined";
|
|
11
|
+
var memory = [];
|
|
12
|
+
var loaded = false;
|
|
13
|
+
function backend() {
|
|
14
|
+
if (!hasWindow) return null;
|
|
15
|
+
for (const name of ["localStorage", "sessionStorage"]) {
|
|
16
|
+
try {
|
|
17
|
+
const s = window[name];
|
|
18
|
+
s.setItem("__cfg_probe", "1");
|
|
19
|
+
s.removeItem("__cfg_probe");
|
|
20
|
+
return s;
|
|
21
|
+
} catch {
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
__name(backend, "backend");
|
|
27
|
+
function load() {
|
|
28
|
+
if (loaded) return memory;
|
|
29
|
+
loaded = true;
|
|
30
|
+
try {
|
|
31
|
+
const raw = backend()?.getItem(KEY);
|
|
32
|
+
const parsed = raw ? JSON.parse(raw) : [];
|
|
33
|
+
if (Array.isArray(parsed)) memory = parsed.filter((e) => typeof e === "object" && e !== null);
|
|
34
|
+
} catch {
|
|
35
|
+
memory = [];
|
|
36
|
+
}
|
|
37
|
+
return memory;
|
|
38
|
+
}
|
|
39
|
+
__name(load, "load");
|
|
40
|
+
function persist() {
|
|
41
|
+
try {
|
|
42
|
+
backend()?.setItem(KEY, JSON.stringify(memory));
|
|
43
|
+
} catch {
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
__name(persist, "persist");
|
|
47
|
+
function clean(fields) {
|
|
48
|
+
if (!fields) return void 0;
|
|
49
|
+
const out = {};
|
|
50
|
+
for (const [k2, v] of Object.entries(fields)) {
|
|
51
|
+
if (SENSITIVE.test(k2)) continue;
|
|
52
|
+
if (typeof v === "string") out[k2] = v.length > MAX_STRING ? `${v.slice(0, MAX_STRING)}\u2026` : v;
|
|
53
|
+
else if (typeof v === "number" || typeof v === "boolean" || v === null) out[k2] = v;
|
|
54
|
+
}
|
|
55
|
+
return Object.keys(out).length ? out : void 0;
|
|
56
|
+
}
|
|
57
|
+
__name(clean, "clean");
|
|
58
|
+
function record(at, ev, fields) {
|
|
59
|
+
const entries = load();
|
|
60
|
+
const p = hasWindow && typeof performance !== "undefined" ? Math.round(performance.now()) : 0;
|
|
61
|
+
entries.push({ t: at, p, tab: TAB, ev, f: clean(fields) });
|
|
62
|
+
if (entries.length > MAX) entries.splice(0, entries.length - MAX);
|
|
63
|
+
persist();
|
|
64
|
+
}
|
|
65
|
+
__name(record, "record");
|
|
66
|
+
function authTrace(ev, fields) {
|
|
67
|
+
if (!hasWindow) return;
|
|
68
|
+
try {
|
|
69
|
+
record(Date.now(), ev, fields);
|
|
70
|
+
} catch {
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
__name(authTrace, "authTrace");
|
|
74
|
+
function readAuthTrace() {
|
|
75
|
+
return load().slice();
|
|
76
|
+
}
|
|
77
|
+
__name(readAuthTrace, "readAuthTrace");
|
|
78
|
+
function clearAuthTrace() {
|
|
79
|
+
memory = [];
|
|
80
|
+
loaded = true;
|
|
81
|
+
try {
|
|
82
|
+
backend()?.removeItem(KEY);
|
|
83
|
+
} catch {
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
__name(clearAuthTrace, "clearAuthTrace");
|
|
87
|
+
function context() {
|
|
88
|
+
if (!hasWindow) return [];
|
|
89
|
+
const lines = [`url: ${window.location.href.split("?")[0]}`, `online: ${navigator.onLine}`, `ua: ${navigator.userAgent}`];
|
|
90
|
+
try {
|
|
91
|
+
const auth2 = globalThis.__cfgAuthNow;
|
|
92
|
+
const now = auth2?.();
|
|
93
|
+
if (now) lines.push(`now: ${Object.entries(now).map(([k2, v]) => `${k2}=${String(v)}`).join(" ")}`);
|
|
94
|
+
} catch {
|
|
95
|
+
}
|
|
96
|
+
return lines;
|
|
97
|
+
}
|
|
98
|
+
__name(context, "context");
|
|
99
|
+
function dumpAuthTrace() {
|
|
100
|
+
const entries = load();
|
|
101
|
+
const first = entries[0]?.t ?? Date.now();
|
|
102
|
+
const rows = entries.map((e) => {
|
|
103
|
+
const fields = e.f ? ` ${Object.entries(e.f).map(([k2, v]) => `${k2}=${String(v)}`).join(" ")}` : "";
|
|
104
|
+
const at = new Date(e.t).toISOString().slice(11, 23);
|
|
105
|
+
return `${at} +${String(e.t - first).padStart(6)}ms [${e.tab} p${e.p}] ${e.ev}${fields}`;
|
|
106
|
+
});
|
|
107
|
+
return [`# cfg auth trace, ${entries.length} events`, ...context(), "", ...rows].join("\n");
|
|
108
|
+
}
|
|
109
|
+
__name(dumpAuthTrace, "dumpAuthTrace");
|
|
110
|
+
function installAuthTrace() {
|
|
111
|
+
if (!hasWindow) return;
|
|
112
|
+
const g = globalThis;
|
|
113
|
+
g.__cfgAuthTrace = authTrace;
|
|
114
|
+
g.__cfgAuth = {
|
|
115
|
+
trace: readAuthTrace,
|
|
116
|
+
dump: /* @__PURE__ */ __name(() => {
|
|
117
|
+
const text = dumpAuthTrace();
|
|
118
|
+
console.log(text);
|
|
119
|
+
return text;
|
|
120
|
+
}, "dump"),
|
|
121
|
+
clear: clearAuthTrace
|
|
122
|
+
};
|
|
123
|
+
const queued = g.__cfgAuthTraceQ;
|
|
124
|
+
if (Array.isArray(queued)) {
|
|
125
|
+
g.__cfgAuthTraceQ = [];
|
|
126
|
+
for (const item of queued) {
|
|
127
|
+
if (Array.isArray(item) && typeof item[1] === "string") {
|
|
128
|
+
try {
|
|
129
|
+
record(Number(item[0]) || Date.now(), item[1], item[2]);
|
|
130
|
+
} catch {
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
__name(installAuthTrace, "installAuthTrace");
|
|
137
|
+
installAuthTrace();
|
|
138
|
+
|
|
4
139
|
// src/_api/generated/helpers/errors.ts
|
|
5
140
|
var APIError = class extends Error {
|
|
6
141
|
constructor(statusCode, statusText, response, url, message) {
|
|
@@ -117,10 +252,10 @@ function normalizeSegment(raw) {
|
|
|
117
252
|
return raw.trim().toLowerCase().replace(/[^a-z0-9_]+/g, "_").replace(/^_+|_+$/g, "");
|
|
118
253
|
}
|
|
119
254
|
__name(normalizeSegment, "normalizeSegment");
|
|
120
|
-
var
|
|
255
|
+
var hasWindow2 = /* @__PURE__ */ __name(() => typeof window !== "undefined", "hasWindow");
|
|
121
256
|
var domainByHost = /* @__PURE__ */ new Map();
|
|
122
257
|
function detectCookieDomain() {
|
|
123
|
-
if (!
|
|
258
|
+
if (!hasWindow2() || typeof document === "undefined") return null;
|
|
124
259
|
const host = window.location.hostname.toLowerCase();
|
|
125
260
|
if (!host || !host.includes(".") || host.includes(":") || /^[0-9.]+$/.test(host)) return null;
|
|
126
261
|
const cached = domainByHost.get(host);
|
|
@@ -144,7 +279,7 @@ function detectCookieDomain() {
|
|
|
144
279
|
}
|
|
145
280
|
__name(detectCookieDomain, "detectCookieDomain");
|
|
146
281
|
function nativeStorage(store) {
|
|
147
|
-
if (!
|
|
282
|
+
if (!hasWindow2()) return null;
|
|
148
283
|
try {
|
|
149
284
|
return store === "session" ? window.sessionStorage : window.localStorage;
|
|
150
285
|
} catch {
|
|
@@ -153,7 +288,7 @@ function nativeStorage(store) {
|
|
|
153
288
|
}
|
|
154
289
|
__name(nativeStorage, "nativeStorage");
|
|
155
290
|
function cookieNames() {
|
|
156
|
-
if (!
|
|
291
|
+
if (!hasWindow2()) return [];
|
|
157
292
|
try {
|
|
158
293
|
return document.cookie.split("; ").map((part) => decodeURIComponent(part.split("=")[0] ?? "")).filter(Boolean);
|
|
159
294
|
} catch {
|
|
@@ -178,7 +313,7 @@ function createStorage(owner, options = {}) {
|
|
|
178
313
|
const families = Object.values(options.families ?? {});
|
|
179
314
|
const specByKey = /* @__PURE__ */ new Map();
|
|
180
315
|
for (const spec of specs) specByKey.set(spec.key, [...specByKey.get(spec.key) ?? [], spec]);
|
|
181
|
-
const
|
|
316
|
+
const memory2 = {
|
|
182
317
|
local: /* @__PURE__ */ new Map(),
|
|
183
318
|
session: /* @__PURE__ */ new Map(),
|
|
184
319
|
cookie: /* @__PURE__ */ new Map()
|
|
@@ -192,7 +327,7 @@ function createStorage(owner, options = {}) {
|
|
|
192
327
|
if (!key.startsWith(prefix)) throw new TypeError(`storage key "${key}" is not owned by "${owner}"`);
|
|
193
328
|
}, "assertOwned");
|
|
194
329
|
function rawGet(store, key) {
|
|
195
|
-
if (!
|
|
330
|
+
if (!hasWindow2()) return null;
|
|
196
331
|
if (store === "cookie") {
|
|
197
332
|
try {
|
|
198
333
|
const escaped = encodeURIComponent(key).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -200,18 +335,18 @@ function createStorage(owner, options = {}) {
|
|
|
200
335
|
if (match?.[1] !== void 0) return decodeURIComponent(match[1]);
|
|
201
336
|
} catch {
|
|
202
337
|
}
|
|
203
|
-
return
|
|
338
|
+
return memory2.cookie.get(key) ?? null;
|
|
204
339
|
}
|
|
205
340
|
try {
|
|
206
341
|
const value = nativeStorage(store)?.getItem(key) ?? null;
|
|
207
342
|
if (value !== null) return value;
|
|
208
343
|
} catch {
|
|
209
344
|
}
|
|
210
|
-
return
|
|
345
|
+
return memory2[store].get(key) ?? null;
|
|
211
346
|
}
|
|
212
347
|
__name(rawGet, "rawGet");
|
|
213
348
|
function rawSet(store, key, value, maxAgeSeconds) {
|
|
214
|
-
if (!
|
|
349
|
+
if (!hasWindow2()) return false;
|
|
215
350
|
try {
|
|
216
351
|
if (store === "cookie") {
|
|
217
352
|
const secure = window.location.protocol === "https:" ? "; Secure" : "";
|
|
@@ -219,24 +354,24 @@ function createStorage(owner, options = {}) {
|
|
|
219
354
|
const domainPart = domain ? `; Domain=${domain}` : "";
|
|
220
355
|
document.cookie = `${encodeURIComponent(key)}=${encodeURIComponent(value)}; Path=/; Max-Age=${Math.max(1, Math.floor(maxAgeSeconds ?? cookieMaxAge))}; SameSite=Lax${domainPart}${secure}`;
|
|
221
356
|
if (domain) expireCookie(key, null);
|
|
222
|
-
if (rawGet("cookie", key) === value && !
|
|
223
|
-
|
|
357
|
+
if (rawGet("cookie", key) === value && !memory2.cookie.has(key)) return true;
|
|
358
|
+
memory2.cookie.set(key, value);
|
|
224
359
|
return false;
|
|
225
360
|
}
|
|
226
361
|
const native = nativeStorage(store);
|
|
227
362
|
if (!native) throw new Error("storage unavailable");
|
|
228
363
|
native.setItem(key, value);
|
|
229
|
-
|
|
364
|
+
memory2[store].delete(key);
|
|
230
365
|
return true;
|
|
231
366
|
} catch {
|
|
232
|
-
|
|
367
|
+
memory2[store].set(key, value);
|
|
233
368
|
return false;
|
|
234
369
|
}
|
|
235
370
|
}
|
|
236
371
|
__name(rawSet, "rawSet");
|
|
237
372
|
function rawRemove(store, key) {
|
|
238
|
-
|
|
239
|
-
if (!
|
|
373
|
+
memory2[store].delete(key);
|
|
374
|
+
if (!hasWindow2()) return;
|
|
240
375
|
try {
|
|
241
376
|
if (store === "cookie") {
|
|
242
377
|
expireCookie(key, null);
|
|
@@ -265,7 +400,7 @@ function createStorage(owner, options = {}) {
|
|
|
265
400
|
}
|
|
266
401
|
} catch {
|
|
267
402
|
}
|
|
268
|
-
for (const name of
|
|
403
|
+
for (const name of memory2[store].keys()) if (name.startsWith(startsWith) && !out.includes(name)) out.push(name);
|
|
269
404
|
return out;
|
|
270
405
|
}
|
|
271
406
|
__name(listKeys, "listKeys");
|
|
@@ -337,7 +472,7 @@ function createStorage(owner, options = {}) {
|
|
|
337
472
|
cookieDomain: resolveCookieDomain,
|
|
338
473
|
onChange(key, listener, store = "local") {
|
|
339
474
|
assertValid(key);
|
|
340
|
-
if (!
|
|
475
|
+
if (!hasWindow2()) return () => {
|
|
341
476
|
};
|
|
342
477
|
const handler = /* @__PURE__ */ __name((event) => {
|
|
343
478
|
if (event.storageArea !== nativeStorage(store)) return;
|
|
@@ -361,6 +496,29 @@ var REFRESH_KEY = "cfg.auth.refresh_token";
|
|
|
361
496
|
var API_KEY_KEY = "cfg.auth.api_key";
|
|
362
497
|
var storage = true ? cfgStorage : createStorage2("cfg");
|
|
363
498
|
var isBrowser = typeof window !== "undefined";
|
|
499
|
+
function trace(ev, fields) {
|
|
500
|
+
try {
|
|
501
|
+
const g = globalThis;
|
|
502
|
+
const sink = g.__cfgAuthTrace;
|
|
503
|
+
if (sink) {
|
|
504
|
+
sink(ev, fields);
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
const queue = g.__cfgAuthTraceQ ?? [];
|
|
508
|
+
g.__cfgAuthTraceQ = queue;
|
|
509
|
+
if (queue.length < 100) queue.push([Date.now(), ev, fields]);
|
|
510
|
+
} catch {
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
__name(trace, "trace");
|
|
514
|
+
function pathOf(url) {
|
|
515
|
+
try {
|
|
516
|
+
return new URL(url, "http://x").pathname;
|
|
517
|
+
} catch {
|
|
518
|
+
return "";
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
__name(pathOf, "pathOf");
|
|
364
522
|
function secondsUntilExp(token) {
|
|
365
523
|
const exp = jwtExpMs(token);
|
|
366
524
|
return exp === null ? void 0 : Math.max(1, Math.floor((exp - Date.now()) / 1e3));
|
|
@@ -520,7 +678,10 @@ __name(scheduleExpiryFlip, "scheduleExpiryFlip");
|
|
|
520
678
|
function notifySessionChanged() {
|
|
521
679
|
const next = computeSnapshot();
|
|
522
680
|
const changed = next.status !== _snapshot.status || next.accessExpiresAt !== _snapshot.accessExpiresAt;
|
|
523
|
-
if (changed)
|
|
681
|
+
if (changed) {
|
|
682
|
+
_snapshot = next;
|
|
683
|
+
trace("store.snapshot", { status: next.status });
|
|
684
|
+
}
|
|
524
685
|
scheduleExpiryFlip();
|
|
525
686
|
if (!changed) return;
|
|
526
687
|
for (const listener of Array.from(_sessionListeners)) {
|
|
@@ -603,6 +764,7 @@ var auth = {
|
|
|
603
764
|
return _storage.get(ACCESS_KEY);
|
|
604
765
|
},
|
|
605
766
|
setToken(token) {
|
|
767
|
+
trace("store.setToken", { present: token !== null });
|
|
606
768
|
_storage.set(ACCESS_KEY, token);
|
|
607
769
|
notifySessionChanged();
|
|
608
770
|
},
|
|
@@ -610,14 +772,16 @@ var auth = {
|
|
|
610
772
|
return _storage.get(REFRESH_KEY);
|
|
611
773
|
},
|
|
612
774
|
setRefreshToken(token) {
|
|
775
|
+
trace("store.setRefreshToken", { present: token !== null });
|
|
613
776
|
_storage.set(REFRESH_KEY, token);
|
|
614
777
|
notifySessionChanged();
|
|
615
778
|
},
|
|
616
779
|
clearTokens() {
|
|
780
|
+
trace("store.clearTokens");
|
|
617
781
|
for (const mode of ["localStorage", "sessionStorage", "cookie"]) {
|
|
618
|
-
const
|
|
619
|
-
|
|
620
|
-
|
|
782
|
+
const backend2 = backendFor(mode);
|
|
783
|
+
backend2.set(ACCESS_KEY, null);
|
|
784
|
+
backend2.set(REFRESH_KEY, null);
|
|
621
785
|
}
|
|
622
786
|
storage.clearAll();
|
|
623
787
|
notifySessionChanged();
|
|
@@ -636,6 +800,7 @@ var auth = {
|
|
|
636
800
|
* rotation); `refresh: null` explicitly drops it.
|
|
637
801
|
*/
|
|
638
802
|
setSession(tokens) {
|
|
803
|
+
trace("store.setSession", { refresh: tokens.refresh === void 0 ? "kept" : tokens.refresh === null ? "dropped" : "set" });
|
|
639
804
|
_storage.set(ACCESS_KEY, tokens.access);
|
|
640
805
|
if (tokens.refresh !== void 0) _storage.set(REFRESH_KEY, tokens.refresh);
|
|
641
806
|
notifySessionChanged();
|
|
@@ -774,7 +939,11 @@ async function tryRefresh() {
|
|
|
774
939
|
const refresh = auth.getRefreshToken();
|
|
775
940
|
if (!refresh) return null;
|
|
776
941
|
const result = await _refreshHandler(refresh);
|
|
777
|
-
if (!result?.access)
|
|
942
|
+
if (!result?.access) {
|
|
943
|
+
trace("refresh", { ok: false, why: "no-access" });
|
|
944
|
+
return null;
|
|
945
|
+
}
|
|
946
|
+
trace("refresh", { ok: true, rotated: Boolean(result.refresh) });
|
|
778
947
|
auth.setToken(result.access);
|
|
779
948
|
if (result.refresh) auth.setRefreshToken(result.refresh);
|
|
780
949
|
return result.access;
|
|
@@ -787,6 +956,7 @@ async function tryRefresh() {
|
|
|
787
956
|
}
|
|
788
957
|
return await runRefresh();
|
|
789
958
|
} catch {
|
|
959
|
+
trace("refresh", { ok: false, why: "threw" });
|
|
790
960
|
return null;
|
|
791
961
|
} finally {
|
|
792
962
|
_refreshInflight = null;
|
|
@@ -795,7 +965,8 @@ async function tryRefresh() {
|
|
|
795
965
|
return _refreshInflight;
|
|
796
966
|
}
|
|
797
967
|
__name(tryRefresh, "tryRefresh");
|
|
798
|
-
function expireSession(response) {
|
|
968
|
+
function expireSession(response, why) {
|
|
969
|
+
trace("store.expire", { why, status: response.status, path: pathOf(response.url), handlers: _sessionExpiredHandlers.size });
|
|
799
970
|
auth.clearTokens();
|
|
800
971
|
for (const cb of Array.from(_sessionExpiredHandlers)) {
|
|
801
972
|
try {
|
|
@@ -938,15 +1109,16 @@ function installAuthOnClient(client2) {
|
|
|
938
1109
|
client2.interceptors.response.use(async (response, request) => {
|
|
939
1110
|
if (response.status !== 401) return response;
|
|
940
1111
|
if (/\/accounts\/(otp|oauth|login|register|token)\b/.test(request.url)) {
|
|
1112
|
+
trace("401.passthrough", { path: pathOf(request.url) });
|
|
941
1113
|
return response;
|
|
942
1114
|
}
|
|
943
1115
|
if (request.headers.get(RETRY_MARKER)) {
|
|
944
|
-
expireSession(response);
|
|
1116
|
+
expireSession(response, "retry-marker");
|
|
945
1117
|
return response;
|
|
946
1118
|
}
|
|
947
1119
|
const newToken = await tryRefresh();
|
|
948
1120
|
if (!newToken) {
|
|
949
|
-
expireSession(response);
|
|
1121
|
+
expireSession(response, "refresh-failed");
|
|
950
1122
|
return response;
|
|
951
1123
|
}
|
|
952
1124
|
const retry = request.clone();
|
|
@@ -958,7 +1130,7 @@ function installAuthOnClient(client2) {
|
|
|
958
1130
|
}
|
|
959
1131
|
try {
|
|
960
1132
|
const retried = await fetch(retry);
|
|
961
|
-
if (retried.status === 401) expireSession(retried);
|
|
1133
|
+
if (retried.status === 401) expireSession(retried, "retry-401");
|
|
962
1134
|
return retried;
|
|
963
1135
|
} catch {
|
|
964
1136
|
return response;
|