@djangocfg/api 2.1.486 → 2.1.488
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 +4 -29
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.mjs +4 -29
- package/dist/auth.mjs.map +1 -1
- package/dist/clients.cjs +4 -26
- package/dist/clients.cjs.map +1 -1
- package/dist/clients.mjs +4 -26
- package/dist/clients.mjs.map +1 -1
- package/dist/hooks.cjs +4 -26
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.mjs +4 -26
- package/dist/hooks.mjs.map +1 -1
- package/dist/index.cjs +4 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +4 -26
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/_api/generated/helpers/auth.ts +18 -36
- package/src/auth/context/AccountsContext.tsx +5 -1
- package/src/auth/hooks/useGithubAuth.ts +3 -2
- package/src/auth/hooks/useTwoFactorVerify.ts +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@djangocfg/api",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.488",
|
|
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.
|
|
87
|
+
"@djangocfg/typescript-config": "^2.1.488",
|
|
88
88
|
"@testing-library/react": "^16.3.2",
|
|
89
89
|
"@types/node": "^25.9.5",
|
|
90
90
|
"@types/react": "19.2.15",
|
|
@@ -86,31 +86,20 @@ function backendFor(mode: StorageMode): KVStore {
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
/**
|
|
89
|
-
*
|
|
90
|
-
* the module.
|
|
89
|
+
* The session backend. `localStorage` by default and for every login path.
|
|
91
90
|
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
91
|
+
* `setStorageMode` exists for a host that must relocate the whole session once
|
|
92
|
+
* at bootstrap — e.g. 'cookie' so Next.js `cookies()` can read the token during
|
|
93
|
+
* SSR. It is NOT a per-login switch: this value lives in module memory and
|
|
94
|
+
* resets to the default on every page load, so tokens written to a non-default
|
|
95
|
+
* backend after startup would be stranded — present in the browser, invisible
|
|
96
|
+
* to the client, and every request would go out unauthenticated.
|
|
97
|
+
*
|
|
98
|
+
* Session LENGTH is therefore not a client concern. The server decides it when
|
|
99
|
+
* minting the refresh token (`remember_me`); the client just stores whatever it
|
|
100
|
+
* was given, in one place.
|
|
98
101
|
*/
|
|
99
|
-
|
|
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();
|
|
102
|
+
let _storageMode: StorageMode = 'localStorage';
|
|
114
103
|
let _storage: KVStore = backendFor(_storageMode);
|
|
115
104
|
|
|
116
105
|
/** Detect locale from `NEXT_LOCALE` cookie or `navigator.language`. */
|
|
@@ -357,13 +346,12 @@ function pushClientConfig(): void {
|
|
|
357
346
|
export const auth = {
|
|
358
347
|
// ── Storage mode ──────────────────────────────────────────────────
|
|
359
348
|
getStorageMode(): StorageMode { return _storageMode; },
|
|
349
|
+
/** Relocate the session backend. Call once at bootstrap, before any sign-in:
|
|
350
|
+
* the mode is module state and resets on reload, so a later switch strands
|
|
351
|
+
* whatever was written after it. */
|
|
360
352
|
setStorageMode(mode: StorageMode): void {
|
|
361
353
|
_storageMode = mode;
|
|
362
354
|
_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
|
-
}
|
|
367
355
|
notifySessionChanged();
|
|
368
356
|
},
|
|
369
357
|
|
|
@@ -379,19 +367,13 @@ export const auth = {
|
|
|
379
367
|
notifySessionChanged();
|
|
380
368
|
},
|
|
381
369
|
clearTokens(): void {
|
|
382
|
-
// Clear every backend, not just the active one
|
|
383
|
-
//
|
|
384
|
-
// page load
|
|
370
|
+
// Clear every backend, not just the active one. Sign-out must leave nothing
|
|
371
|
+
// behind anywhere — including tokens an older build stranded in
|
|
372
|
+
// sessionStorage — or the next page load could resurrect a dead session.
|
|
385
373
|
for (const backend of [localStorageBackend, sessionStorageBackend, cookieBackend]) {
|
|
386
374
|
backend.set(ACCESS_KEY, null);
|
|
387
375
|
backend.set(REFRESH_KEY, null);
|
|
388
376
|
}
|
|
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
|
-
}
|
|
395
377
|
notifySessionChanged();
|
|
396
378
|
},
|
|
397
379
|
/** Session-aware: token PRESENT and not past its `exp` (or a live refresh
|
|
@@ -183,7 +183,11 @@ export function AccountsProvider({ children }: AccountsProviderProps) {
|
|
|
183
183
|
|
|
184
184
|
if (result.access && result.refresh) {
|
|
185
185
|
// The ONE write path — atomic pair, notifies every session subscriber.
|
|
186
|
-
|
|
186
|
+
// Storage is always localStorage: "remember me" is a TOKEN LIFETIME
|
|
187
|
+
// decision the server already made (`remember_me` → REMEMBER_ME_LIFETIME),
|
|
188
|
+
// not a storage decision. Switching the client to sessionStorage here used
|
|
189
|
+
// to strand the tokens — the module reinitializes to localStorage on the
|
|
190
|
+
// next page load and would never look at sessionStorage again.
|
|
187
191
|
auth.setSession({ access: result.access, refresh: result.refresh });
|
|
188
192
|
try {
|
|
189
193
|
await refreshProfile({ callerId: 'verifyOTP', force: true });
|
|
@@ -168,8 +168,9 @@ export const useGithubAuth = (options: UseGithubAuthOptions = {}): UseGithubAuth
|
|
|
168
168
|
|
|
169
169
|
authLogger.info('GitHub OAuth successful, user:', response.user);
|
|
170
170
|
|
|
171
|
-
|
|
172
|
-
//
|
|
171
|
+
// The ONE write path — atomic pair + session notification. Storage is
|
|
172
|
+
// always localStorage; session length is the server's call via
|
|
173
|
+
// `remember_me`. See AccountsContext.verifyOTP.
|
|
173
174
|
auth.setSession({ access: response.access, refresh: response.refresh });
|
|
174
175
|
|
|
175
176
|
// Track successful OAuth
|
|
@@ -71,8 +71,9 @@ export const useTwoFactorVerify = (
|
|
|
71
71
|
remaining_backup_codes?: number;
|
|
72
72
|
persistent_session: boolean;
|
|
73
73
|
}) => {
|
|
74
|
-
auth.setStorageMode(response.persistent_session ? 'localStorage' : 'sessionStorage');
|
|
75
74
|
// Save tokens — the ONE write path (atomic pair + session notification).
|
|
75
|
+
// Storage is always localStorage; session length is the server's call via
|
|
76
|
+
// `remember_me`. See AccountsContext.verifyOTP.
|
|
76
77
|
auth.setSession({ access: response.access_token, refresh: response.refresh_token });
|
|
77
78
|
|
|
78
79
|
if (response.warning) {
|