@djangocfg/api 2.1.621 → 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 +147 -80
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +6 -1
- package/dist/auth.d.ts +6 -1
- package/dist/auth.mjs +94 -29
- package/dist/auth.mjs.map +1 -1
- package/dist/index.cjs +72 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +72 -20
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/auth/__tests__/sharedContext.test.ts +16 -0
- package/src/auth/__tests__/trace.test.ts +38 -0
- package/src/auth/context/AccountsContext.tsx +3 -2
- package/src/auth/context/AuthContext.tsx +2 -2
- package/src/auth/context/sharedContext.ts +16 -0
- package/src/auth/trace.ts +75 -5
package/dist/index.cjs
CHANGED
|
@@ -69,7 +69,10 @@ var KEY = "cfg.auth.trace";
|
|
|
69
69
|
var MAX = 200;
|
|
70
70
|
var MAX_STRING = 120;
|
|
71
71
|
var SENSITIVE = /token|otp|code|email|password|secret|cookie|authorization|key|identifier/i;
|
|
72
|
-
var TAB =
|
|
72
|
+
var TAB = (() => {
|
|
73
|
+
const g = globalThis;
|
|
74
|
+
return g.__cfgAuthTab ??= Math.random().toString(36).slice(2, 6);
|
|
75
|
+
})();
|
|
73
76
|
var hasWindow = typeof window !== "undefined";
|
|
74
77
|
var memory = [];
|
|
75
78
|
var loaded = false;
|
|
@@ -118,10 +121,30 @@ function clean(fields) {
|
|
|
118
121
|
return Object.keys(out).length ? out : void 0;
|
|
119
122
|
}
|
|
120
123
|
__name(clean, "clean");
|
|
124
|
+
function refresh() {
|
|
125
|
+
try {
|
|
126
|
+
const raw = backend()?.getItem(KEY);
|
|
127
|
+
const parsed = raw ? JSON.parse(raw) : null;
|
|
128
|
+
if (Array.isArray(parsed)) memory = parsed.filter((e) => typeof e === "object" && e !== null);
|
|
129
|
+
} catch {
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
__name(refresh, "refresh");
|
|
121
133
|
function record(at, ev, fields) {
|
|
122
|
-
|
|
134
|
+
load();
|
|
135
|
+
refresh();
|
|
136
|
+
const entries = memory;
|
|
123
137
|
const p = hasWindow && typeof performance !== "undefined" ? Math.round(performance.now()) : 0;
|
|
124
|
-
|
|
138
|
+
const f2 = clean(fields);
|
|
139
|
+
const last = entries[entries.length - 1];
|
|
140
|
+
if (last && last.tab === TAB && last.ev === ev && JSON.stringify(last.f) === JSON.stringify(f2)) {
|
|
141
|
+
last.n = (last.n ?? 1) + 1;
|
|
142
|
+
last.t = at;
|
|
143
|
+
last.p = p;
|
|
144
|
+
persist();
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
entries.push({ t: at, p, tab: TAB, ev, f: f2 });
|
|
125
148
|
if (entries.length > MAX) entries.splice(0, entries.length - MAX);
|
|
126
149
|
persist();
|
|
127
150
|
}
|
|
@@ -149,7 +172,8 @@ function clearAuthTrace() {
|
|
|
149
172
|
__name(clearAuthTrace, "clearAuthTrace");
|
|
150
173
|
function context() {
|
|
151
174
|
if (!hasWindow) return [];
|
|
152
|
-
const
|
|
175
|
+
const copies = globalThis.__cfgAuthCopies ?? 1;
|
|
176
|
+
const lines = [`url: ${window.location.href.split("?")[0]}`, `copies: ${String(copies)}`, `online: ${navigator.onLine}`, `ua: ${navigator.userAgent}`];
|
|
153
177
|
try {
|
|
154
178
|
const auth2 = globalThis.__cfgAuthNow;
|
|
155
179
|
const now = auth2?.();
|
|
@@ -165,7 +189,7 @@ function dumpAuthTrace() {
|
|
|
165
189
|
const rows = entries.map((e) => {
|
|
166
190
|
const fields = e.f ? ` ${Object.entries(e.f).map(([k2, v]) => `${k2}=${String(v)}`).join(" ")}` : "";
|
|
167
191
|
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}`;
|
|
192
|
+
return `${at} +${String(e.t - first).padStart(6)}ms [${e.tab} p${e.p}] ${e.ev}${fields}${e.n && e.n > 1 ? ` x${e.n}` : ""}`;
|
|
169
193
|
});
|
|
170
194
|
return [`# cfg auth trace, ${entries.length} events`, ...context(), "", ...rows].join("\n");
|
|
171
195
|
}
|
|
@@ -181,7 +205,21 @@ function installAuthTrace() {
|
|
|
181
205
|
console.log(text);
|
|
182
206
|
return text;
|
|
183
207
|
}, "dump"),
|
|
184
|
-
clear: clearAuthTrace
|
|
208
|
+
clear: clearAuthTrace,
|
|
209
|
+
/** Put the dump on the clipboard (works when the console output is blocked or too long to select). */
|
|
210
|
+
copy: /* @__PURE__ */ __name(() => {
|
|
211
|
+
const text = dumpAuthTrace();
|
|
212
|
+
void navigator.clipboard?.writeText(text);
|
|
213
|
+
return `${text.split("\n").length} lines copied`;
|
|
214
|
+
}, "copy"),
|
|
215
|
+
/** Download the raw trace as a JSON file. */
|
|
216
|
+
download: /* @__PURE__ */ __name(() => {
|
|
217
|
+
const blob = new Blob([JSON.stringify(readAuthTrace(), null, 1)], { type: "application/json" });
|
|
218
|
+
const a = document.createElement("a");
|
|
219
|
+
a.href = URL.createObjectURL(blob);
|
|
220
|
+
a.download = `auth-trace-${Date.now()}.json`;
|
|
221
|
+
a.click();
|
|
222
|
+
}, "download")
|
|
185
223
|
};
|
|
186
224
|
const queued = g.__cfgAuthTraceQ;
|
|
187
225
|
if (Array.isArray(queued)) {
|
|
@@ -197,6 +235,20 @@ function installAuthTrace() {
|
|
|
197
235
|
}
|
|
198
236
|
}
|
|
199
237
|
__name(installAuthTrace, "installAuthTrace");
|
|
238
|
+
function registerCopy() {
|
|
239
|
+
if (!hasWindow) return;
|
|
240
|
+
const g = globalThis;
|
|
241
|
+
const n = (g.__cfgAuthCopies ?? 0) + 1;
|
|
242
|
+
g.__cfgAuthCopies = n;
|
|
243
|
+
if (n > 1) {
|
|
244
|
+
authTrace("dup.copy", { copies: n });
|
|
245
|
+
if (n === 2) {
|
|
246
|
+
console.warn("[@djangocfg/api] more than one copy of the auth package is loaded; see __cfgAuth.dump() (dup.copy). Align the peer set so pnpm installs one instance.");
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
__name(registerCopy, "registerCopy");
|
|
251
|
+
registerCopy();
|
|
200
252
|
installAuthTrace();
|
|
201
253
|
|
|
202
254
|
// src/_api/generated/helpers/errors.ts
|
|
@@ -612,10 +664,10 @@ function adoptLegacySession() {
|
|
|
612
664
|
if (_storage.get(ACCESS_KEY) !== null || _storage.get(REFRESH_KEY) !== null) return;
|
|
613
665
|
const legacy = backendFor("localStorage");
|
|
614
666
|
const access = legacy.get(ACCESS_KEY);
|
|
615
|
-
const
|
|
616
|
-
if (access === null &&
|
|
667
|
+
const refresh2 = legacy.get(REFRESH_KEY);
|
|
668
|
+
if (access === null && refresh2 === null) return;
|
|
617
669
|
if (access !== null) _storage.set(ACCESS_KEY, access);
|
|
618
|
-
if (
|
|
670
|
+
if (refresh2 !== null) _storage.set(REFRESH_KEY, refresh2);
|
|
619
671
|
legacy.set(ACCESS_KEY, null);
|
|
620
672
|
legacy.set(REFRESH_KEY, null);
|
|
621
673
|
} catch {
|
|
@@ -700,12 +752,12 @@ function jwtExpMs(token) {
|
|
|
700
752
|
__name(jwtExpMs, "jwtExpMs");
|
|
701
753
|
function computeSnapshot() {
|
|
702
754
|
const access = _storage.get(ACCESS_KEY);
|
|
703
|
-
const
|
|
755
|
+
const refresh2 = _storage.get(REFRESH_KEY);
|
|
704
756
|
const now = Date.now();
|
|
705
757
|
const accessExp = access ? jwtExpMs(access) : null;
|
|
706
758
|
const accessAlive = access !== null && (accessExp === null || accessExp > now);
|
|
707
|
-
const refreshExp =
|
|
708
|
-
const refreshAlive =
|
|
759
|
+
const refreshExp = refresh2 ? jwtExpMs(refresh2) : null;
|
|
760
|
+
const refreshAlive = refresh2 !== null && (refreshExp === null || refreshExp > now);
|
|
709
761
|
return {
|
|
710
762
|
status: accessAlive || refreshAlive ? "authenticated" : "anonymous",
|
|
711
763
|
accessExpiresAt: accessExp
|
|
@@ -728,9 +780,9 @@ function scheduleExpiryFlip() {
|
|
|
728
780
|
const now = Date.now();
|
|
729
781
|
const exps = [];
|
|
730
782
|
const access = _storage.get(ACCESS_KEY);
|
|
731
|
-
const
|
|
783
|
+
const refresh2 = _storage.get(REFRESH_KEY);
|
|
732
784
|
const accessExp = access ? jwtExpMs(access) : null;
|
|
733
|
-
const refreshExp =
|
|
785
|
+
const refreshExp = refresh2 ? jwtExpMs(refresh2) : null;
|
|
734
786
|
if (accessExp !== null && accessExp > now) exps.push(accessExp);
|
|
735
787
|
if (refreshExp !== null && refreshExp > now) exps.push(refreshExp);
|
|
736
788
|
if (!exps.length) return;
|
|
@@ -999,9 +1051,9 @@ async function tryRefresh() {
|
|
|
999
1051
|
if (_refreshInflight) return _refreshInflight;
|
|
1000
1052
|
if (!_refreshHandler) return null;
|
|
1001
1053
|
const runRefresh = /* @__PURE__ */ __name(async () => {
|
|
1002
|
-
const
|
|
1003
|
-
if (!
|
|
1004
|
-
const result = await _refreshHandler(
|
|
1054
|
+
const refresh2 = auth.getRefreshToken();
|
|
1055
|
+
if (!refresh2) return null;
|
|
1056
|
+
const result = await _refreshHandler(refresh2);
|
|
1005
1057
|
if (!result?.access) {
|
|
1006
1058
|
trace("refresh", { ok: false, why: "no-access" });
|
|
1007
1059
|
return null;
|
|
@@ -1202,7 +1254,7 @@ function installAuthOnClient(client2) {
|
|
|
1202
1254
|
}
|
|
1203
1255
|
__name(installAuthOnClient, "installAuthOnClient");
|
|
1204
1256
|
var REFRESH_ENDPOINT = "/cfg/accounts/token/refresh/";
|
|
1205
|
-
auth.setRefreshHandler(async (
|
|
1257
|
+
auth.setRefreshHandler(async (refresh2) => {
|
|
1206
1258
|
try {
|
|
1207
1259
|
const url = `${auth.getBaseUrl()}${REFRESH_ENDPOINT}`;
|
|
1208
1260
|
const headers = { "Content-Type": "application/json" };
|
|
@@ -1214,11 +1266,11 @@ auth.setRefreshHandler(async (refresh) => {
|
|
|
1214
1266
|
method: "POST",
|
|
1215
1267
|
headers,
|
|
1216
1268
|
credentials: auth.getWithCredentials() ? "include" : "same-origin",
|
|
1217
|
-
body: JSON.stringify({ refresh })
|
|
1269
|
+
body: JSON.stringify({ refresh: refresh2 })
|
|
1218
1270
|
});
|
|
1219
1271
|
if (!res.ok) return null;
|
|
1220
1272
|
const data = await res.json();
|
|
1221
|
-
return data?.access ? { access: data.access, refresh: data.refresh ??
|
|
1273
|
+
return data?.access ? { access: data.access, refresh: data.refresh ?? refresh2 } : null;
|
|
1222
1274
|
} catch {
|
|
1223
1275
|
return null;
|
|
1224
1276
|
}
|