@djangocfg/api 2.1.618 → 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 +311 -39
- 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 +311 -39
- package/dist/auth.mjs.map +1 -1
- package/dist/clients.cjs +46 -6
- package/dist/clients.cjs.map +1 -1
- package/dist/clients.mjs +46 -6
- package/dist/clients.mjs.map +1 -1
- package/dist/hooks.cjs +46 -6
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.mjs +46 -6
- package/dist/hooks.mjs.map +1 -1
- package/dist/index.cjs +201 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +201 -26
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/_api/generated/helpers/auth.ts +39 -6
- package/src/auth/__tests__/authState.test.ts +46 -0
- package/src/auth/__tests__/formatAuthError.test.ts +7 -0
- package/src/auth/__tests__/signInRefusal.test.ts +52 -0
- package/src/auth/context/AccountsContext.tsx +3 -0
- package/src/auth/context/AuthContext.tsx +61 -4
- 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.cjs
CHANGED
|
@@ -64,6 +64,141 @@ __export(index_exports, {
|
|
|
64
64
|
});
|
|
65
65
|
module.exports = __toCommonJS(index_exports);
|
|
66
66
|
|
|
67
|
+
// src/auth/trace.ts
|
|
68
|
+
var KEY = "cfg.auth.trace";
|
|
69
|
+
var MAX = 200;
|
|
70
|
+
var MAX_STRING = 120;
|
|
71
|
+
var SENSITIVE = /token|otp|code|email|password|secret|cookie|authorization|key|identifier/i;
|
|
72
|
+
var TAB = Math.random().toString(36).slice(2, 6);
|
|
73
|
+
var hasWindow = typeof window !== "undefined";
|
|
74
|
+
var memory = [];
|
|
75
|
+
var loaded = false;
|
|
76
|
+
function backend() {
|
|
77
|
+
if (!hasWindow) return null;
|
|
78
|
+
for (const name of ["localStorage", "sessionStorage"]) {
|
|
79
|
+
try {
|
|
80
|
+
const s = window[name];
|
|
81
|
+
s.setItem("__cfg_probe", "1");
|
|
82
|
+
s.removeItem("__cfg_probe");
|
|
83
|
+
return s;
|
|
84
|
+
} catch {
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
__name(backend, "backend");
|
|
90
|
+
function load() {
|
|
91
|
+
if (loaded) return memory;
|
|
92
|
+
loaded = true;
|
|
93
|
+
try {
|
|
94
|
+
const raw = backend()?.getItem(KEY);
|
|
95
|
+
const parsed = raw ? JSON.parse(raw) : [];
|
|
96
|
+
if (Array.isArray(parsed)) memory = parsed.filter((e) => typeof e === "object" && e !== null);
|
|
97
|
+
} catch {
|
|
98
|
+
memory = [];
|
|
99
|
+
}
|
|
100
|
+
return memory;
|
|
101
|
+
}
|
|
102
|
+
__name(load, "load");
|
|
103
|
+
function persist() {
|
|
104
|
+
try {
|
|
105
|
+
backend()?.setItem(KEY, JSON.stringify(memory));
|
|
106
|
+
} catch {
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
__name(persist, "persist");
|
|
110
|
+
function clean(fields) {
|
|
111
|
+
if (!fields) return void 0;
|
|
112
|
+
const out = {};
|
|
113
|
+
for (const [k2, v] of Object.entries(fields)) {
|
|
114
|
+
if (SENSITIVE.test(k2)) continue;
|
|
115
|
+
if (typeof v === "string") out[k2] = v.length > MAX_STRING ? `${v.slice(0, MAX_STRING)}\u2026` : v;
|
|
116
|
+
else if (typeof v === "number" || typeof v === "boolean" || v === null) out[k2] = v;
|
|
117
|
+
}
|
|
118
|
+
return Object.keys(out).length ? out : void 0;
|
|
119
|
+
}
|
|
120
|
+
__name(clean, "clean");
|
|
121
|
+
function record(at, ev, fields) {
|
|
122
|
+
const entries = load();
|
|
123
|
+
const p = hasWindow && typeof performance !== "undefined" ? Math.round(performance.now()) : 0;
|
|
124
|
+
entries.push({ t: at, p, tab: TAB, ev, f: clean(fields) });
|
|
125
|
+
if (entries.length > MAX) entries.splice(0, entries.length - MAX);
|
|
126
|
+
persist();
|
|
127
|
+
}
|
|
128
|
+
__name(record, "record");
|
|
129
|
+
function authTrace(ev, fields) {
|
|
130
|
+
if (!hasWindow) return;
|
|
131
|
+
try {
|
|
132
|
+
record(Date.now(), ev, fields);
|
|
133
|
+
} catch {
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
__name(authTrace, "authTrace");
|
|
137
|
+
function readAuthTrace() {
|
|
138
|
+
return load().slice();
|
|
139
|
+
}
|
|
140
|
+
__name(readAuthTrace, "readAuthTrace");
|
|
141
|
+
function clearAuthTrace() {
|
|
142
|
+
memory = [];
|
|
143
|
+
loaded = true;
|
|
144
|
+
try {
|
|
145
|
+
backend()?.removeItem(KEY);
|
|
146
|
+
} catch {
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
__name(clearAuthTrace, "clearAuthTrace");
|
|
150
|
+
function context() {
|
|
151
|
+
if (!hasWindow) return [];
|
|
152
|
+
const lines = [`url: ${window.location.href.split("?")[0]}`, `online: ${navigator.onLine}`, `ua: ${navigator.userAgent}`];
|
|
153
|
+
try {
|
|
154
|
+
const auth2 = globalThis.__cfgAuthNow;
|
|
155
|
+
const now = auth2?.();
|
|
156
|
+
if (now) lines.push(`now: ${Object.entries(now).map(([k2, v]) => `${k2}=${String(v)}`).join(" ")}`);
|
|
157
|
+
} catch {
|
|
158
|
+
}
|
|
159
|
+
return lines;
|
|
160
|
+
}
|
|
161
|
+
__name(context, "context");
|
|
162
|
+
function dumpAuthTrace() {
|
|
163
|
+
const entries = load();
|
|
164
|
+
const first = entries[0]?.t ?? Date.now();
|
|
165
|
+
const rows = entries.map((e) => {
|
|
166
|
+
const fields = e.f ? ` ${Object.entries(e.f).map(([k2, v]) => `${k2}=${String(v)}`).join(" ")}` : "";
|
|
167
|
+
const at = new Date(e.t).toISOString().slice(11, 23);
|
|
168
|
+
return `${at} +${String(e.t - first).padStart(6)}ms [${e.tab} p${e.p}] ${e.ev}${fields}`;
|
|
169
|
+
});
|
|
170
|
+
return [`# cfg auth trace, ${entries.length} events`, ...context(), "", ...rows].join("\n");
|
|
171
|
+
}
|
|
172
|
+
__name(dumpAuthTrace, "dumpAuthTrace");
|
|
173
|
+
function installAuthTrace() {
|
|
174
|
+
if (!hasWindow) return;
|
|
175
|
+
const g = globalThis;
|
|
176
|
+
g.__cfgAuthTrace = authTrace;
|
|
177
|
+
g.__cfgAuth = {
|
|
178
|
+
trace: readAuthTrace,
|
|
179
|
+
dump: /* @__PURE__ */ __name(() => {
|
|
180
|
+
const text = dumpAuthTrace();
|
|
181
|
+
console.log(text);
|
|
182
|
+
return text;
|
|
183
|
+
}, "dump"),
|
|
184
|
+
clear: clearAuthTrace
|
|
185
|
+
};
|
|
186
|
+
const queued = g.__cfgAuthTraceQ;
|
|
187
|
+
if (Array.isArray(queued)) {
|
|
188
|
+
g.__cfgAuthTraceQ = [];
|
|
189
|
+
for (const item of queued) {
|
|
190
|
+
if (Array.isArray(item) && typeof item[1] === "string") {
|
|
191
|
+
try {
|
|
192
|
+
record(Number(item[0]) || Date.now(), item[1], item[2]);
|
|
193
|
+
} catch {
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
__name(installAuthTrace, "installAuthTrace");
|
|
200
|
+
installAuthTrace();
|
|
201
|
+
|
|
67
202
|
// src/_api/generated/helpers/errors.ts
|
|
68
203
|
var APIError = class extends Error {
|
|
69
204
|
constructor(statusCode, statusText, response, url, message) {
|
|
@@ -180,10 +315,10 @@ function normalizeSegment(raw) {
|
|
|
180
315
|
return raw.trim().toLowerCase().replace(/[^a-z0-9_]+/g, "_").replace(/^_+|_+$/g, "");
|
|
181
316
|
}
|
|
182
317
|
__name(normalizeSegment, "normalizeSegment");
|
|
183
|
-
var
|
|
318
|
+
var hasWindow2 = /* @__PURE__ */ __name(() => typeof window !== "undefined", "hasWindow");
|
|
184
319
|
var domainByHost = /* @__PURE__ */ new Map();
|
|
185
320
|
function detectCookieDomain() {
|
|
186
|
-
if (!
|
|
321
|
+
if (!hasWindow2() || typeof document === "undefined") return null;
|
|
187
322
|
const host = window.location.hostname.toLowerCase();
|
|
188
323
|
if (!host || !host.includes(".") || host.includes(":") || /^[0-9.]+$/.test(host)) return null;
|
|
189
324
|
const cached = domainByHost.get(host);
|
|
@@ -207,7 +342,7 @@ function detectCookieDomain() {
|
|
|
207
342
|
}
|
|
208
343
|
__name(detectCookieDomain, "detectCookieDomain");
|
|
209
344
|
function nativeStorage(store) {
|
|
210
|
-
if (!
|
|
345
|
+
if (!hasWindow2()) return null;
|
|
211
346
|
try {
|
|
212
347
|
return store === "session" ? window.sessionStorage : window.localStorage;
|
|
213
348
|
} catch {
|
|
@@ -216,7 +351,7 @@ function nativeStorage(store) {
|
|
|
216
351
|
}
|
|
217
352
|
__name(nativeStorage, "nativeStorage");
|
|
218
353
|
function cookieNames() {
|
|
219
|
-
if (!
|
|
354
|
+
if (!hasWindow2()) return [];
|
|
220
355
|
try {
|
|
221
356
|
return document.cookie.split("; ").map((part) => decodeURIComponent(part.split("=")[0] ?? "")).filter(Boolean);
|
|
222
357
|
} catch {
|
|
@@ -241,7 +376,7 @@ function createStorage(owner, options = {}) {
|
|
|
241
376
|
const families = Object.values(options.families ?? {});
|
|
242
377
|
const specByKey = /* @__PURE__ */ new Map();
|
|
243
378
|
for (const spec of specs) specByKey.set(spec.key, [...specByKey.get(spec.key) ?? [], spec]);
|
|
244
|
-
const
|
|
379
|
+
const memory2 = {
|
|
245
380
|
local: /* @__PURE__ */ new Map(),
|
|
246
381
|
session: /* @__PURE__ */ new Map(),
|
|
247
382
|
cookie: /* @__PURE__ */ new Map()
|
|
@@ -255,7 +390,7 @@ function createStorage(owner, options = {}) {
|
|
|
255
390
|
if (!key.startsWith(prefix)) throw new TypeError(`storage key "${key}" is not owned by "${owner}"`);
|
|
256
391
|
}, "assertOwned");
|
|
257
392
|
function rawGet(store, key) {
|
|
258
|
-
if (!
|
|
393
|
+
if (!hasWindow2()) return null;
|
|
259
394
|
if (store === "cookie") {
|
|
260
395
|
try {
|
|
261
396
|
const escaped = encodeURIComponent(key).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -263,18 +398,18 @@ function createStorage(owner, options = {}) {
|
|
|
263
398
|
if (match?.[1] !== void 0) return decodeURIComponent(match[1]);
|
|
264
399
|
} catch {
|
|
265
400
|
}
|
|
266
|
-
return
|
|
401
|
+
return memory2.cookie.get(key) ?? null;
|
|
267
402
|
}
|
|
268
403
|
try {
|
|
269
404
|
const value = nativeStorage(store)?.getItem(key) ?? null;
|
|
270
405
|
if (value !== null) return value;
|
|
271
406
|
} catch {
|
|
272
407
|
}
|
|
273
|
-
return
|
|
408
|
+
return memory2[store].get(key) ?? null;
|
|
274
409
|
}
|
|
275
410
|
__name(rawGet, "rawGet");
|
|
276
411
|
function rawSet(store, key, value, maxAgeSeconds) {
|
|
277
|
-
if (!
|
|
412
|
+
if (!hasWindow2()) return false;
|
|
278
413
|
try {
|
|
279
414
|
if (store === "cookie") {
|
|
280
415
|
const secure = window.location.protocol === "https:" ? "; Secure" : "";
|
|
@@ -282,24 +417,24 @@ function createStorage(owner, options = {}) {
|
|
|
282
417
|
const domainPart = domain ? `; Domain=${domain}` : "";
|
|
283
418
|
document.cookie = `${encodeURIComponent(key)}=${encodeURIComponent(value)}; Path=/; Max-Age=${Math.max(1, Math.floor(maxAgeSeconds ?? cookieMaxAge))}; SameSite=Lax${domainPart}${secure}`;
|
|
284
419
|
if (domain) expireCookie(key, null);
|
|
285
|
-
if (rawGet("cookie", key) === value && !
|
|
286
|
-
|
|
420
|
+
if (rawGet("cookie", key) === value && !memory2.cookie.has(key)) return true;
|
|
421
|
+
memory2.cookie.set(key, value);
|
|
287
422
|
return false;
|
|
288
423
|
}
|
|
289
424
|
const native = nativeStorage(store);
|
|
290
425
|
if (!native) throw new Error("storage unavailable");
|
|
291
426
|
native.setItem(key, value);
|
|
292
|
-
|
|
427
|
+
memory2[store].delete(key);
|
|
293
428
|
return true;
|
|
294
429
|
} catch {
|
|
295
|
-
|
|
430
|
+
memory2[store].set(key, value);
|
|
296
431
|
return false;
|
|
297
432
|
}
|
|
298
433
|
}
|
|
299
434
|
__name(rawSet, "rawSet");
|
|
300
435
|
function rawRemove(store, key) {
|
|
301
|
-
|
|
302
|
-
if (!
|
|
436
|
+
memory2[store].delete(key);
|
|
437
|
+
if (!hasWindow2()) return;
|
|
303
438
|
try {
|
|
304
439
|
if (store === "cookie") {
|
|
305
440
|
expireCookie(key, null);
|
|
@@ -328,7 +463,7 @@ function createStorage(owner, options = {}) {
|
|
|
328
463
|
}
|
|
329
464
|
} catch {
|
|
330
465
|
}
|
|
331
|
-
for (const name of
|
|
466
|
+
for (const name of memory2[store].keys()) if (name.startsWith(startsWith) && !out.includes(name)) out.push(name);
|
|
332
467
|
return out;
|
|
333
468
|
}
|
|
334
469
|
__name(listKeys, "listKeys");
|
|
@@ -400,7 +535,7 @@ function createStorage(owner, options = {}) {
|
|
|
400
535
|
cookieDomain: resolveCookieDomain,
|
|
401
536
|
onChange(key, listener, store = "local") {
|
|
402
537
|
assertValid(key);
|
|
403
|
-
if (!
|
|
538
|
+
if (!hasWindow2()) return () => {
|
|
404
539
|
};
|
|
405
540
|
const handler = /* @__PURE__ */ __name((event) => {
|
|
406
541
|
if (event.storageArea !== nativeStorage(store)) return;
|
|
@@ -424,6 +559,29 @@ var REFRESH_KEY = "cfg.auth.refresh_token";
|
|
|
424
559
|
var API_KEY_KEY = "cfg.auth.api_key";
|
|
425
560
|
var storage = true ? cfgStorage : createStorage2("cfg");
|
|
426
561
|
var isBrowser = typeof window !== "undefined";
|
|
562
|
+
function trace(ev, fields) {
|
|
563
|
+
try {
|
|
564
|
+
const g = globalThis;
|
|
565
|
+
const sink = g.__cfgAuthTrace;
|
|
566
|
+
if (sink) {
|
|
567
|
+
sink(ev, fields);
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
const queue = g.__cfgAuthTraceQ ?? [];
|
|
571
|
+
g.__cfgAuthTraceQ = queue;
|
|
572
|
+
if (queue.length < 100) queue.push([Date.now(), ev, fields]);
|
|
573
|
+
} catch {
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
__name(trace, "trace");
|
|
577
|
+
function pathOf(url) {
|
|
578
|
+
try {
|
|
579
|
+
return new URL(url, "http://x").pathname;
|
|
580
|
+
} catch {
|
|
581
|
+
return "";
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
__name(pathOf, "pathOf");
|
|
427
585
|
function secondsUntilExp(token) {
|
|
428
586
|
const exp = jwtExpMs(token);
|
|
429
587
|
return exp === null ? void 0 : Math.max(1, Math.floor((exp - Date.now()) / 1e3));
|
|
@@ -583,7 +741,10 @@ __name(scheduleExpiryFlip, "scheduleExpiryFlip");
|
|
|
583
741
|
function notifySessionChanged() {
|
|
584
742
|
const next = computeSnapshot();
|
|
585
743
|
const changed = next.status !== _snapshot.status || next.accessExpiresAt !== _snapshot.accessExpiresAt;
|
|
586
|
-
if (changed)
|
|
744
|
+
if (changed) {
|
|
745
|
+
_snapshot = next;
|
|
746
|
+
trace("store.snapshot", { status: next.status });
|
|
747
|
+
}
|
|
587
748
|
scheduleExpiryFlip();
|
|
588
749
|
if (!changed) return;
|
|
589
750
|
for (const listener of Array.from(_sessionListeners)) {
|
|
@@ -666,6 +827,7 @@ var auth = {
|
|
|
666
827
|
return _storage.get(ACCESS_KEY);
|
|
667
828
|
},
|
|
668
829
|
setToken(token) {
|
|
830
|
+
trace("store.setToken", { present: token !== null });
|
|
669
831
|
_storage.set(ACCESS_KEY, token);
|
|
670
832
|
notifySessionChanged();
|
|
671
833
|
},
|
|
@@ -673,14 +835,16 @@ var auth = {
|
|
|
673
835
|
return _storage.get(REFRESH_KEY);
|
|
674
836
|
},
|
|
675
837
|
setRefreshToken(token) {
|
|
838
|
+
trace("store.setRefreshToken", { present: token !== null });
|
|
676
839
|
_storage.set(REFRESH_KEY, token);
|
|
677
840
|
notifySessionChanged();
|
|
678
841
|
},
|
|
679
842
|
clearTokens() {
|
|
843
|
+
trace("store.clearTokens");
|
|
680
844
|
for (const mode of ["localStorage", "sessionStorage", "cookie"]) {
|
|
681
|
-
const
|
|
682
|
-
|
|
683
|
-
|
|
845
|
+
const backend2 = backendFor(mode);
|
|
846
|
+
backend2.set(ACCESS_KEY, null);
|
|
847
|
+
backend2.set(REFRESH_KEY, null);
|
|
684
848
|
}
|
|
685
849
|
storage.clearAll();
|
|
686
850
|
notifySessionChanged();
|
|
@@ -699,6 +863,7 @@ var auth = {
|
|
|
699
863
|
* rotation); `refresh: null` explicitly drops it.
|
|
700
864
|
*/
|
|
701
865
|
setSession(tokens) {
|
|
866
|
+
trace("store.setSession", { refresh: tokens.refresh === void 0 ? "kept" : tokens.refresh === null ? "dropped" : "set" });
|
|
702
867
|
_storage.set(ACCESS_KEY, tokens.access);
|
|
703
868
|
if (tokens.refresh !== void 0) _storage.set(REFRESH_KEY, tokens.refresh);
|
|
704
869
|
notifySessionChanged();
|
|
@@ -837,7 +1002,11 @@ async function tryRefresh() {
|
|
|
837
1002
|
const refresh = auth.getRefreshToken();
|
|
838
1003
|
if (!refresh) return null;
|
|
839
1004
|
const result = await _refreshHandler(refresh);
|
|
840
|
-
if (!result?.access)
|
|
1005
|
+
if (!result?.access) {
|
|
1006
|
+
trace("refresh", { ok: false, why: "no-access" });
|
|
1007
|
+
return null;
|
|
1008
|
+
}
|
|
1009
|
+
trace("refresh", { ok: true, rotated: Boolean(result.refresh) });
|
|
841
1010
|
auth.setToken(result.access);
|
|
842
1011
|
if (result.refresh) auth.setRefreshToken(result.refresh);
|
|
843
1012
|
return result.access;
|
|
@@ -850,6 +1019,7 @@ async function tryRefresh() {
|
|
|
850
1019
|
}
|
|
851
1020
|
return await runRefresh();
|
|
852
1021
|
} catch {
|
|
1022
|
+
trace("refresh", { ok: false, why: "threw" });
|
|
853
1023
|
return null;
|
|
854
1024
|
} finally {
|
|
855
1025
|
_refreshInflight = null;
|
|
@@ -858,7 +1028,8 @@ async function tryRefresh() {
|
|
|
858
1028
|
return _refreshInflight;
|
|
859
1029
|
}
|
|
860
1030
|
__name(tryRefresh, "tryRefresh");
|
|
861
|
-
function expireSession(response) {
|
|
1031
|
+
function expireSession(response, why) {
|
|
1032
|
+
trace("store.expire", { why, status: response.status, path: pathOf(response.url), handlers: _sessionExpiredHandlers.size });
|
|
862
1033
|
auth.clearTokens();
|
|
863
1034
|
for (const cb of Array.from(_sessionExpiredHandlers)) {
|
|
864
1035
|
try {
|
|
@@ -1000,13 +1171,17 @@ function installAuthOnClient(client2) {
|
|
|
1000
1171
|
});
|
|
1001
1172
|
client2.interceptors.response.use(async (response, request) => {
|
|
1002
1173
|
if (response.status !== 401) return response;
|
|
1174
|
+
if (/\/accounts\/(otp|oauth|login|register|token)\b/.test(request.url)) {
|
|
1175
|
+
trace("401.passthrough", { path: pathOf(request.url) });
|
|
1176
|
+
return response;
|
|
1177
|
+
}
|
|
1003
1178
|
if (request.headers.get(RETRY_MARKER)) {
|
|
1004
|
-
expireSession(response);
|
|
1179
|
+
expireSession(response, "retry-marker");
|
|
1005
1180
|
return response;
|
|
1006
1181
|
}
|
|
1007
1182
|
const newToken = await tryRefresh();
|
|
1008
1183
|
if (!newToken) {
|
|
1009
|
-
expireSession(response);
|
|
1184
|
+
expireSession(response, "refresh-failed");
|
|
1010
1185
|
return response;
|
|
1011
1186
|
}
|
|
1012
1187
|
const retry = request.clone();
|
|
@@ -1018,7 +1193,7 @@ function installAuthOnClient(client2) {
|
|
|
1018
1193
|
}
|
|
1019
1194
|
try {
|
|
1020
1195
|
const retried = await fetch(retry);
|
|
1021
|
-
if (retried.status === 401) expireSession(retried);
|
|
1196
|
+
if (retried.status === 401) expireSession(retried, "retry-401");
|
|
1022
1197
|
return retried;
|
|
1023
1198
|
} catch {
|
|
1024
1199
|
return response;
|