@djangocfg/api 2.1.484 → 2.1.486

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djangocfg/api",
3
- "version": "2.1.484",
3
+ "version": "2.1.486",
4
4
  "description": "Auto-generated TypeScript API client with React hooks, SWR integration, and Zod validation for Django REST Framework backends",
5
5
  "keywords": [
6
6
  "django",
@@ -84,7 +84,7 @@
84
84
  "zod": "^4.3.6"
85
85
  },
86
86
  "devDependencies": {
87
- "@djangocfg/typescript-config": "^2.1.484",
87
+ "@djangocfg/typescript-config": "^2.1.486",
88
88
  "@testing-library/react": "^16.3.2",
89
89
  "@types/node": "^25.9.5",
90
90
  "@types/react": "19.2.15",
@@ -77,8 +77,41 @@ const cookieBackend: KVStore = {
77
77
  },
78
78
  };
79
79
 
80
- let _storage: KVStore = localStorageBackend;
81
- let _storageMode: StorageMode = 'localStorage';
80
+ function backendFor(mode: StorageMode): KVStore {
81
+ return mode === 'cookie'
82
+ ? cookieBackend
83
+ : mode === 'sessionStorage'
84
+ ? sessionStorageBackend
85
+ : localStorageBackend;
86
+ }
87
+
88
+ /**
89
+ * Which backend holds the session — persisted, because the mode has to outlive
90
+ * the module.
91
+ *
92
+ * A non-persistent sign-in ("remember me" unchecked) writes its tokens to
93
+ * `sessionStorage`. Without this marker the next page load would start from the
94
+ * `localStorage` default and look there instead — finding nothing, and silently
95
+ * bouncing an authenticated user back to the login form. The marker itself is
96
+ * NOT the session: it lives in `localStorage` (a plain enum, no credential), so
97
+ * only the tokens follow the tab's lifetime.
98
+ */
99
+ const STORAGE_MODE_KEY = 'cfg.access_token.storage_mode';
100
+
101
+ function readPersistedMode(): StorageMode {
102
+ if (!isBrowser) return 'localStorage';
103
+ try {
104
+ const raw = window.localStorage.getItem(STORAGE_MODE_KEY);
105
+ return raw === 'sessionStorage' || raw === 'cookie' || raw === 'localStorage'
106
+ ? raw
107
+ : 'localStorage';
108
+ } catch {
109
+ return 'localStorage';
110
+ }
111
+ }
112
+
113
+ let _storageMode: StorageMode = readPersistedMode();
114
+ let _storage: KVStore = backendFor(_storageMode);
82
115
 
83
116
  /** Detect locale from `NEXT_LOCALE` cookie or `navigator.language`. */
84
117
  function detectLocale(): string | null {
@@ -326,11 +359,11 @@ export const auth = {
326
359
  getStorageMode(): StorageMode { return _storageMode; },
327
360
  setStorageMode(mode: StorageMode): void {
328
361
  _storageMode = mode;
329
- _storage = mode === 'cookie'
330
- ? cookieBackend
331
- : mode === 'sessionStorage'
332
- ? sessionStorageBackend
333
- : localStorageBackend;
362
+ _storage = backendFor(mode);
363
+ // Persist the choice so the next page load reads from the same backend.
364
+ if (isBrowser) {
365
+ try { window.localStorage.setItem(STORAGE_MODE_KEY, mode); } catch {}
366
+ }
334
367
  notifySessionChanged();
335
368
  },
336
369
 
@@ -346,8 +379,19 @@ export const auth = {
346
379
  notifySessionChanged();
347
380
  },
348
381
  clearTokens(): void {
349
- _storage.set(ACCESS_KEY, null);
350
- _storage.set(REFRESH_KEY, null);
382
+ // Clear every backend, not just the active one: a sign-out must not leave a
383
+ // stale token behind in the backend the PREVIOUS session used, or the next
384
+ // page load would resurrect it.
385
+ for (const backend of [localStorageBackend, sessionStorageBackend, cookieBackend]) {
386
+ backend.set(ACCESS_KEY, null);
387
+ backend.set(REFRESH_KEY, null);
388
+ }
389
+ // Back to the default, so the next sign-in starts from a known mode.
390
+ _storageMode = 'localStorage';
391
+ _storage = localStorageBackend;
392
+ if (isBrowser) {
393
+ try { window.localStorage.removeItem(STORAGE_MODE_KEY); } catch {}
394
+ }
351
395
  notifySessionChanged();
352
396
  },
353
397
  /** Session-aware: token PRESENT and not past its `exp` (or a live refresh