@djangocfg/api 2.1.603 → 2.1.605
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 +126 -13
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.mjs +126 -13
- package/dist/auth.mjs.map +1 -1
- package/dist/clients.cjs +94 -13
- package/dist/clients.cjs.map +1 -1
- package/dist/clients.mjs +94 -13
- package/dist/clients.mjs.map +1 -1
- package/dist/hooks.cjs +94 -13
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.mjs +94 -13
- package/dist/hooks.mjs.map +1 -1
- package/dist/index.cjs +94 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -1
- package/dist/index.d.ts +20 -1
- package/dist/index.mjs +94 -13
- package/dist/index.mjs.map +1 -1
- package/dist/storage.cjs +67 -9
- package/dist/storage.cjs.map +1 -1
- package/dist/storage.d.cts +24 -2
- package/dist/storage.d.ts +24 -2
- package/dist/storage.mjs +67 -9
- package/dist/storage.mjs.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/sharedCookie.test.ts +112 -0
- package/src/_api/generated/helpers/auth.ts +58 -9
- package/src/_api/generated/helpers/keys.ts +74 -9
- package/src/auth/__tests__/legacyStorage.test.ts +21 -0
- package/src/auth/context/AccountsContext.tsx +6 -0
- package/src/auth/context/AuthContext.tsx +7 -0
- package/src/auth/hooks/legacyStorage.ts +32 -0
- package/src/cookies.ts +22 -0
- package/src/storage.ts +2 -0
package/dist/index.cjs
CHANGED
|
@@ -145,8 +145,8 @@ var NetworkError = class extends Error {
|
|
|
145
145
|
var k = /* @__PURE__ */ __name((key, store, personal) => ({ key, store, personal }), "k");
|
|
146
146
|
var f = /* @__PURE__ */ __name((prefix, store, personal) => ({ prefix, store, personal }), "f");
|
|
147
147
|
var CFG_KEYS = {
|
|
148
|
-
accessToken: k("cfg.auth.access_token", "
|
|
149
|
-
refreshToken: k("cfg.auth.refresh_token", "
|
|
148
|
+
accessToken: k("cfg.auth.access_token", "cookie", true),
|
|
149
|
+
refreshToken: k("cfg.auth.refresh_token", "cookie", true),
|
|
150
150
|
apiKey: k("cfg.auth.api_key", "local", true),
|
|
151
151
|
email: k("cfg.auth.email", "local", false),
|
|
152
152
|
emailTs: k("cfg.auth.email_ts", "local", false),
|
|
@@ -181,6 +181,31 @@ function normalizeSegment(raw) {
|
|
|
181
181
|
}
|
|
182
182
|
__name(normalizeSegment, "normalizeSegment");
|
|
183
183
|
var hasWindow = /* @__PURE__ */ __name(() => typeof window !== "undefined", "hasWindow");
|
|
184
|
+
var domainByHost = /* @__PURE__ */ new Map();
|
|
185
|
+
function detectCookieDomain() {
|
|
186
|
+
if (!hasWindow() || typeof document === "undefined") return null;
|
|
187
|
+
const host = window.location.hostname.toLowerCase();
|
|
188
|
+
if (!host || !host.includes(".") || host.includes(":") || /^[0-9.]+$/.test(host)) return null;
|
|
189
|
+
const cached = domainByHost.get(host);
|
|
190
|
+
if (cached !== void 0) return cached;
|
|
191
|
+
const labels = host.split(".");
|
|
192
|
+
const secure = window.location.protocol === "https:" ? "; Secure" : "";
|
|
193
|
+
let found = null;
|
|
194
|
+
try {
|
|
195
|
+
for (let i = labels.length - 2; i >= 0 && found === null; i -= 1) {
|
|
196
|
+
const candidate = labels.slice(i).join(".");
|
|
197
|
+
const probe = "cfg_probe_" + Math.random().toString(36).slice(2);
|
|
198
|
+
document.cookie = probe + "=1; Domain=" + candidate + "; Path=/; Max-Age=30; SameSite=Lax" + secure;
|
|
199
|
+
if (document.cookie.includes(probe + "=1")) found = candidate;
|
|
200
|
+
document.cookie = probe + "=; Domain=" + candidate + "; Path=/; Max-Age=0; SameSite=Lax" + secure;
|
|
201
|
+
}
|
|
202
|
+
} catch {
|
|
203
|
+
found = null;
|
|
204
|
+
}
|
|
205
|
+
domainByHost.set(host, found);
|
|
206
|
+
return found;
|
|
207
|
+
}
|
|
208
|
+
__name(detectCookieDomain, "detectCookieDomain");
|
|
184
209
|
function nativeStorage(store) {
|
|
185
210
|
if (!hasWindow()) return null;
|
|
186
211
|
try {
|
|
@@ -206,6 +231,12 @@ function createStorage(owner, options = {}) {
|
|
|
206
231
|
const prefix = `${owner}.`;
|
|
207
232
|
const pattern = owner === "cfg" ? /^cfg(\.[a-z0-9_]+)+$/ : new RegExp(`^(cfg|${owner})(\\.[a-z0-9_]+)+$`);
|
|
208
233
|
const cookieMaxAge = options.cookieMaxAgeSeconds ?? 60 * 60 * 24 * 30;
|
|
234
|
+
let cookiePolicy = options.cookieDomain ?? "auto";
|
|
235
|
+
const resolveCookieDomain = /* @__PURE__ */ __name(() => cookiePolicy === false ? null : cookiePolicy === "auto" ? detectCookieDomain() : cookiePolicy, "resolveCookieDomain");
|
|
236
|
+
const expireCookie = /* @__PURE__ */ __name((key, domain) => {
|
|
237
|
+
const secure = window.location.protocol === "https:" ? "; Secure" : "";
|
|
238
|
+
document.cookie = encodeURIComponent(key) + "=; Path=/; Max-Age=0; SameSite=Lax" + (domain ? "; Domain=" + domain : "") + secure;
|
|
239
|
+
}, "expireCookie");
|
|
209
240
|
const specs = Object.values(options.keys ?? {});
|
|
210
241
|
const families = Object.values(options.families ?? {});
|
|
211
242
|
const specByKey = /* @__PURE__ */ new Map();
|
|
@@ -242,12 +273,15 @@ function createStorage(owner, options = {}) {
|
|
|
242
273
|
return memory[store].get(key) ?? null;
|
|
243
274
|
}
|
|
244
275
|
__name(rawGet, "rawGet");
|
|
245
|
-
function rawSet(store, key, value) {
|
|
276
|
+
function rawSet(store, key, value, maxAgeSeconds) {
|
|
246
277
|
if (!hasWindow()) return false;
|
|
247
278
|
try {
|
|
248
279
|
if (store === "cookie") {
|
|
249
280
|
const secure = window.location.protocol === "https:" ? "; Secure" : "";
|
|
250
|
-
|
|
281
|
+
const domain = resolveCookieDomain();
|
|
282
|
+
const domainPart = domain ? `; Domain=${domain}` : "";
|
|
283
|
+
document.cookie = `${encodeURIComponent(key)}=${encodeURIComponent(value)}; Path=/; Max-Age=${Math.max(1, Math.floor(maxAgeSeconds ?? cookieMaxAge))}; SameSite=Lax${domainPart}${secure}`;
|
|
284
|
+
if (domain) expireCookie(key, null);
|
|
251
285
|
if (rawGet("cookie", key) === value && !memory.cookie.has(key)) return true;
|
|
252
286
|
memory.cookie.set(key, value);
|
|
253
287
|
return false;
|
|
@@ -268,8 +302,9 @@ function createStorage(owner, options = {}) {
|
|
|
268
302
|
if (!hasWindow()) return;
|
|
269
303
|
try {
|
|
270
304
|
if (store === "cookie") {
|
|
271
|
-
|
|
272
|
-
|
|
305
|
+
expireCookie(key, null);
|
|
306
|
+
const domain = resolveCookieDomain();
|
|
307
|
+
if (domain) expireCookie(key, domain);
|
|
273
308
|
} else {
|
|
274
309
|
nativeStorage(store)?.removeItem(key);
|
|
275
310
|
}
|
|
@@ -318,10 +353,10 @@ function createStorage(owner, options = {}) {
|
|
|
318
353
|
const target = resolveStore(key, store);
|
|
319
354
|
return rawGet(target, key);
|
|
320
355
|
},
|
|
321
|
-
write(key, value, store) {
|
|
356
|
+
write(key, value, store, writeOptions) {
|
|
322
357
|
assertOwned(key);
|
|
323
358
|
const target = resolveStore(key, store);
|
|
324
|
-
return rawSet(target, key, value);
|
|
359
|
+
return rawSet(target, key, value, writeOptions?.maxAgeSeconds);
|
|
325
360
|
},
|
|
326
361
|
remove(key, store) {
|
|
327
362
|
assertOwned(key);
|
|
@@ -359,6 +394,10 @@ function createStorage(owner, options = {}) {
|
|
|
359
394
|
for (const name of cookieNames()) if (name.startsWith(prefix)) rawRemove("cookie", name);
|
|
360
395
|
}
|
|
361
396
|
},
|
|
397
|
+
setCookieDomain(domain) {
|
|
398
|
+
cookiePolicy = domain;
|
|
399
|
+
},
|
|
400
|
+
cookieDomain: resolveCookieDomain,
|
|
362
401
|
onChange(key, listener, store = "local") {
|
|
363
402
|
assertValid(key);
|
|
364
403
|
if (!hasWindow()) return () => {
|
|
@@ -385,6 +424,11 @@ var REFRESH_KEY = "cfg.auth.refresh_token";
|
|
|
385
424
|
var API_KEY_KEY = "cfg.auth.api_key";
|
|
386
425
|
var storage = true ? cfgStorage : createStorage2("cfg");
|
|
387
426
|
var isBrowser = typeof window !== "undefined";
|
|
427
|
+
function secondsUntilExp(token) {
|
|
428
|
+
const exp = jwtExpMs(token);
|
|
429
|
+
return exp === null ? void 0 : Math.max(1, Math.floor((exp - Date.now()) / 1e3));
|
|
430
|
+
}
|
|
431
|
+
__name(secondsUntilExp, "secondsUntilExp");
|
|
388
432
|
var STORE_OF = {
|
|
389
433
|
localStorage: "local",
|
|
390
434
|
sessionStorage: "session",
|
|
@@ -396,13 +440,31 @@ function backendFor(mode) {
|
|
|
396
440
|
get: /* @__PURE__ */ __name((key) => storage.read(key, store), "get"),
|
|
397
441
|
set(key, value) {
|
|
398
442
|
if (value === null) storage.remove(key, store);
|
|
399
|
-
else storage.write(key, value, store);
|
|
443
|
+
else storage.write(key, value, store, store === "cookie" && key === REFRESH_KEY ? { maxAgeSeconds: secondsUntilExp(value) } : void 0);
|
|
400
444
|
}
|
|
401
445
|
};
|
|
402
446
|
}
|
|
403
447
|
__name(backendFor, "backendFor");
|
|
404
|
-
var _storageMode = "
|
|
448
|
+
var _storageMode = "cookie";
|
|
405
449
|
var _storage = backendFor(_storageMode);
|
|
450
|
+
var _apiKeyStore = backendFor("localStorage");
|
|
451
|
+
function adoptLegacySession() {
|
|
452
|
+
if (!isBrowser || _storageMode !== "cookie") return;
|
|
453
|
+
try {
|
|
454
|
+
if (_storage.get(ACCESS_KEY) !== null || _storage.get(REFRESH_KEY) !== null) return;
|
|
455
|
+
const legacy = backendFor("localStorage");
|
|
456
|
+
const access = legacy.get(ACCESS_KEY);
|
|
457
|
+
const refresh = legacy.get(REFRESH_KEY);
|
|
458
|
+
if (access === null && refresh === null) return;
|
|
459
|
+
if (access !== null) _storage.set(ACCESS_KEY, access);
|
|
460
|
+
if (refresh !== null) _storage.set(REFRESH_KEY, refresh);
|
|
461
|
+
legacy.set(ACCESS_KEY, null);
|
|
462
|
+
legacy.set(REFRESH_KEY, null);
|
|
463
|
+
} catch {
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
__name(adoptLegacySession, "adoptLegacySession");
|
|
467
|
+
adoptLegacySession();
|
|
406
468
|
function detectLocale() {
|
|
407
469
|
try {
|
|
408
470
|
if (typeof document === "undefined") return null;
|
|
@@ -547,6 +609,14 @@ function ensureStorageSync() {
|
|
|
547
609
|
}
|
|
548
610
|
});
|
|
549
611
|
window.addEventListener(SESSION_SYNC_EVENT, () => notifySessionChanged());
|
|
612
|
+
window.addEventListener("focus", () => notifySessionChanged());
|
|
613
|
+
document.addEventListener("visibilitychange", () => {
|
|
614
|
+
if (document.visibilityState === "visible") notifySessionChanged();
|
|
615
|
+
});
|
|
616
|
+
try {
|
|
617
|
+
window.cookieStore?.addEventListener("change", () => notifySessionChanged());
|
|
618
|
+
} catch {
|
|
619
|
+
}
|
|
550
620
|
}
|
|
551
621
|
__name(ensureStorageSync, "ensureStorageSync");
|
|
552
622
|
var SESSION_EXPIRED_REGISTRY = `cfg-auth:expired-handlers:${ACCESS_KEY}`;
|
|
@@ -580,6 +650,17 @@ var auth = {
|
|
|
580
650
|
_storage = backendFor(mode);
|
|
581
651
|
notifySessionChanged();
|
|
582
652
|
},
|
|
653
|
+
// ── Shared cookie domain ──────────────────────────────────────────
|
|
654
|
+
/** `'auto'` (default): the registrable domain of the page. A domain forces it; `null` keeps
|
|
655
|
+
* cookies host-only (no sign-in sharing between subdomains). Call before sign-in. */
|
|
656
|
+
setCookieDomain(domain) {
|
|
657
|
+
storage.setCookieDomain(domain === null ? false : domain);
|
|
658
|
+
notifySessionChanged();
|
|
659
|
+
},
|
|
660
|
+
/** The `Domain` the session cookie is written with; `null` = host-only. */
|
|
661
|
+
getCookieDomain() {
|
|
662
|
+
return storage.cookieDomain();
|
|
663
|
+
},
|
|
583
664
|
// ── Bearer token ──────────────────────────────────────────────────
|
|
584
665
|
getToken() {
|
|
585
666
|
return _storage.get(ACCESS_KEY);
|
|
@@ -666,18 +747,18 @@ var auth = {
|
|
|
666
747
|
},
|
|
667
748
|
// ── API key ───────────────────────────────────────────────────────
|
|
668
749
|
getApiKey() {
|
|
669
|
-
return _apiKeyOverride ??
|
|
750
|
+
return _apiKeyOverride ?? _apiKeyStore.get(API_KEY_KEY) ?? defaultApiKey();
|
|
670
751
|
},
|
|
671
752
|
setApiKey(key) {
|
|
672
753
|
_apiKeyOverride = key;
|
|
673
754
|
},
|
|
674
755
|
setApiKeyPersist(key) {
|
|
675
756
|
_apiKeyOverride = key;
|
|
676
|
-
|
|
757
|
+
_apiKeyStore.set(API_KEY_KEY, key);
|
|
677
758
|
},
|
|
678
759
|
clearApiKey() {
|
|
679
760
|
_apiKeyOverride = null;
|
|
680
|
-
|
|
761
|
+
_apiKeyStore.set(API_KEY_KEY, null);
|
|
681
762
|
},
|
|
682
763
|
// ── Locale ────────────────────────────────────────────────────────
|
|
683
764
|
getLocale() {
|