@djangocfg/api 2.1.333 → 2.1.335
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-server.cjs +113 -6
- package/dist/auth-server.cjs.map +1 -1
- package/dist/auth-server.mjs +113 -6
- package/dist/auth-server.mjs.map +1 -1
- package/dist/auth.cjs +113 -6
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.mjs +113 -6
- package/dist/auth.mjs.map +1 -1
- package/dist/clients.cjs +50 -0
- package/dist/clients.cjs.map +1 -1
- package/dist/clients.d.cts +21 -0
- package/dist/clients.d.ts +21 -0
- package/dist/clients.mjs +50 -0
- package/dist/clients.mjs.map +1 -1
- package/dist/index.cjs +113 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +51 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.mjs +113 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/_api/generated/_cfg_accounts/api.ts +12 -0
- package/src/_api/generated/_cfg_centrifugo/api.ts +12 -0
- package/src/_api/generated/_cfg_totp/api.ts +12 -0
- package/src/_api/generated/helpers/auth.ts +103 -4
package/dist/index.d.cts
CHANGED
|
@@ -2,6 +2,16 @@ import { ConsolaInstance } from 'consola';
|
|
|
2
2
|
import { ZodError } from 'zod';
|
|
3
3
|
|
|
4
4
|
type StorageMode = 'localStorage' | 'cookie';
|
|
5
|
+
/**
|
|
6
|
+
* User-supplied refresh handler. Receives the current refresh token,
|
|
7
|
+
* must return a fresh access (and optional refresh) pair or null on failure.
|
|
8
|
+
* Set once at app bootstrap via `auth.setRefreshHandler(...)`.
|
|
9
|
+
*/
|
|
10
|
+
type RefreshResult = {
|
|
11
|
+
access: string;
|
|
12
|
+
refresh?: string;
|
|
13
|
+
} | null;
|
|
14
|
+
type RefreshHandler = (refreshToken: string) => Promise<RefreshResult>;
|
|
5
15
|
/**
|
|
6
16
|
* Global auth/config store. All getters read live state every call —
|
|
7
17
|
* the interceptor below uses these to attach headers per-request.
|
|
@@ -35,7 +45,27 @@ declare const auth: {
|
|
|
35
45
|
setBaseUrl(url: string | null): void;
|
|
36
46
|
getWithCredentials(): boolean;
|
|
37
47
|
setWithCredentials(value: boolean): void;
|
|
48
|
+
/**
|
|
49
|
+
* Fired when the server returns 401 AND no refresh path recovers it
|
|
50
|
+
* (no refresh token, no refresh handler, refresh failed, or retry
|
|
51
|
+
* still 401). The app should clear local state and redirect to login.
|
|
52
|
+
*
|
|
53
|
+
* NOT fired for 401 that gets transparently recovered by the refresh
|
|
54
|
+
* handler — those are invisible to callers.
|
|
55
|
+
*/
|
|
38
56
|
onUnauthorized(cb: ((response: Response) => void) | null): void;
|
|
57
|
+
/**
|
|
58
|
+
* Register the refresh strategy. The handler receives the current
|
|
59
|
+
* refresh token and must call your refresh endpoint, returning
|
|
60
|
+
* `{ access, refresh? }` on success or `null` on failure.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* auth.setRefreshHandler(async (refresh) => {
|
|
64
|
+
* const { data } = await Auth.tokenRefreshCreate({ body: { refresh } });
|
|
65
|
+
* return data ? { access: data.access, refresh: data.refresh } : null;
|
|
66
|
+
* });
|
|
67
|
+
*/
|
|
68
|
+
setRefreshHandler(fn: RefreshHandler | null): void;
|
|
39
69
|
};
|
|
40
70
|
|
|
41
71
|
interface RequestLog {
|
|
@@ -123,6 +153,13 @@ declare class API$2 {
|
|
|
123
153
|
setLocale(locale: string | null): void;
|
|
124
154
|
getApiKey(): string | null;
|
|
125
155
|
setApiKey(key: string | null): void;
|
|
156
|
+
/** Fired only on terminal 401 (after refresh+retry path is exhausted). */
|
|
157
|
+
onUnauthorized(cb: ((response: Response) => void) | null): void;
|
|
158
|
+
/** Provide a refresh strategy. See `auth.setRefreshHandler` for the contract. */
|
|
159
|
+
setRefreshHandler(fn: ((refreshToken: string) => Promise<{
|
|
160
|
+
access: string;
|
|
161
|
+
refresh?: string;
|
|
162
|
+
} | null>) | null): void;
|
|
126
163
|
}
|
|
127
164
|
|
|
128
165
|
interface StorageAdapter {
|
|
@@ -1386,6 +1423,13 @@ declare class API$1 {
|
|
|
1386
1423
|
setLocale(locale: string | null): void;
|
|
1387
1424
|
getApiKey(): string | null;
|
|
1388
1425
|
setApiKey(key: string | null): void;
|
|
1426
|
+
/** Fired only on terminal 401 (after refresh+retry path is exhausted). */
|
|
1427
|
+
onUnauthorized(cb: ((response: Response) => void) | null): void;
|
|
1428
|
+
/** Provide a refresh strategy. See `auth.setRefreshHandler` for the contract. */
|
|
1429
|
+
setRefreshHandler(fn: ((refreshToken: string) => Promise<{
|
|
1430
|
+
access: string;
|
|
1431
|
+
refresh?: string;
|
|
1432
|
+
} | null>) | null): void;
|
|
1389
1433
|
}
|
|
1390
1434
|
|
|
1391
1435
|
interface APIOptions {
|
|
@@ -1423,6 +1467,13 @@ declare class API {
|
|
|
1423
1467
|
setLocale(locale: string | null): void;
|
|
1424
1468
|
getApiKey(): string | null;
|
|
1425
1469
|
setApiKey(key: string | null): void;
|
|
1470
|
+
/** Fired only on terminal 401 (after refresh+retry path is exhausted). */
|
|
1471
|
+
onUnauthorized(cb: ((response: Response) => void) | null): void;
|
|
1472
|
+
/** Provide a refresh strategy. See `auth.setRefreshHandler` for the contract. */
|
|
1473
|
+
setRefreshHandler(fn: ((refreshToken: string) => Promise<{
|
|
1474
|
+
access: string;
|
|
1475
|
+
refresh?: string;
|
|
1476
|
+
} | null>) | null): void;
|
|
1426
1477
|
}
|
|
1427
1478
|
|
|
1428
1479
|
declare const CfgAccountsApi: API$2;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,16 @@ import { ConsolaInstance } from 'consola';
|
|
|
2
2
|
import { ZodError } from 'zod';
|
|
3
3
|
|
|
4
4
|
type StorageMode = 'localStorage' | 'cookie';
|
|
5
|
+
/**
|
|
6
|
+
* User-supplied refresh handler. Receives the current refresh token,
|
|
7
|
+
* must return a fresh access (and optional refresh) pair or null on failure.
|
|
8
|
+
* Set once at app bootstrap via `auth.setRefreshHandler(...)`.
|
|
9
|
+
*/
|
|
10
|
+
type RefreshResult = {
|
|
11
|
+
access: string;
|
|
12
|
+
refresh?: string;
|
|
13
|
+
} | null;
|
|
14
|
+
type RefreshHandler = (refreshToken: string) => Promise<RefreshResult>;
|
|
5
15
|
/**
|
|
6
16
|
* Global auth/config store. All getters read live state every call —
|
|
7
17
|
* the interceptor below uses these to attach headers per-request.
|
|
@@ -35,7 +45,27 @@ declare const auth: {
|
|
|
35
45
|
setBaseUrl(url: string | null): void;
|
|
36
46
|
getWithCredentials(): boolean;
|
|
37
47
|
setWithCredentials(value: boolean): void;
|
|
48
|
+
/**
|
|
49
|
+
* Fired when the server returns 401 AND no refresh path recovers it
|
|
50
|
+
* (no refresh token, no refresh handler, refresh failed, or retry
|
|
51
|
+
* still 401). The app should clear local state and redirect to login.
|
|
52
|
+
*
|
|
53
|
+
* NOT fired for 401 that gets transparently recovered by the refresh
|
|
54
|
+
* handler — those are invisible to callers.
|
|
55
|
+
*/
|
|
38
56
|
onUnauthorized(cb: ((response: Response) => void) | null): void;
|
|
57
|
+
/**
|
|
58
|
+
* Register the refresh strategy. The handler receives the current
|
|
59
|
+
* refresh token and must call your refresh endpoint, returning
|
|
60
|
+
* `{ access, refresh? }` on success or `null` on failure.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* auth.setRefreshHandler(async (refresh) => {
|
|
64
|
+
* const { data } = await Auth.tokenRefreshCreate({ body: { refresh } });
|
|
65
|
+
* return data ? { access: data.access, refresh: data.refresh } : null;
|
|
66
|
+
* });
|
|
67
|
+
*/
|
|
68
|
+
setRefreshHandler(fn: RefreshHandler | null): void;
|
|
39
69
|
};
|
|
40
70
|
|
|
41
71
|
interface RequestLog {
|
|
@@ -123,6 +153,13 @@ declare class API$2 {
|
|
|
123
153
|
setLocale(locale: string | null): void;
|
|
124
154
|
getApiKey(): string | null;
|
|
125
155
|
setApiKey(key: string | null): void;
|
|
156
|
+
/** Fired only on terminal 401 (after refresh+retry path is exhausted). */
|
|
157
|
+
onUnauthorized(cb: ((response: Response) => void) | null): void;
|
|
158
|
+
/** Provide a refresh strategy. See `auth.setRefreshHandler` for the contract. */
|
|
159
|
+
setRefreshHandler(fn: ((refreshToken: string) => Promise<{
|
|
160
|
+
access: string;
|
|
161
|
+
refresh?: string;
|
|
162
|
+
} | null>) | null): void;
|
|
126
163
|
}
|
|
127
164
|
|
|
128
165
|
interface StorageAdapter {
|
|
@@ -1386,6 +1423,13 @@ declare class API$1 {
|
|
|
1386
1423
|
setLocale(locale: string | null): void;
|
|
1387
1424
|
getApiKey(): string | null;
|
|
1388
1425
|
setApiKey(key: string | null): void;
|
|
1426
|
+
/** Fired only on terminal 401 (after refresh+retry path is exhausted). */
|
|
1427
|
+
onUnauthorized(cb: ((response: Response) => void) | null): void;
|
|
1428
|
+
/** Provide a refresh strategy. See `auth.setRefreshHandler` for the contract. */
|
|
1429
|
+
setRefreshHandler(fn: ((refreshToken: string) => Promise<{
|
|
1430
|
+
access: string;
|
|
1431
|
+
refresh?: string;
|
|
1432
|
+
} | null>) | null): void;
|
|
1389
1433
|
}
|
|
1390
1434
|
|
|
1391
1435
|
interface APIOptions {
|
|
@@ -1423,6 +1467,13 @@ declare class API {
|
|
|
1423
1467
|
setLocale(locale: string | null): void;
|
|
1424
1468
|
getApiKey(): string | null;
|
|
1425
1469
|
setApiKey(key: string | null): void;
|
|
1470
|
+
/** Fired only on terminal 401 (after refresh+retry path is exhausted). */
|
|
1471
|
+
onUnauthorized(cb: ((response: Response) => void) | null): void;
|
|
1472
|
+
/** Provide a refresh strategy. See `auth.setRefreshHandler` for the contract. */
|
|
1473
|
+
setRefreshHandler(fn: ((refreshToken: string) => Promise<{
|
|
1474
|
+
access: string;
|
|
1475
|
+
refresh?: string;
|
|
1476
|
+
} | null>) | null): void;
|
|
1426
1477
|
}
|
|
1427
1478
|
|
|
1428
1479
|
declare const CfgAccountsApi: API$2;
|
package/dist/index.mjs
CHANGED
|
@@ -93,6 +93,9 @@ var _apiKeyOverride = null;
|
|
|
93
93
|
var _baseUrlOverride = null;
|
|
94
94
|
var _withCredentials = true;
|
|
95
95
|
var _onUnauthorized = null;
|
|
96
|
+
var _refreshHandler = null;
|
|
97
|
+
var _refreshInflight = null;
|
|
98
|
+
var RETRY_MARKER = "X-Auth-Retry";
|
|
96
99
|
var _client = null;
|
|
97
100
|
function pushClientConfig() {
|
|
98
101
|
if (!_client) return;
|
|
@@ -171,10 +174,53 @@ var auth = {
|
|
|
171
174
|
pushClientConfig();
|
|
172
175
|
},
|
|
173
176
|
// ── 401 handler ───────────────────────────────────────────────────
|
|
177
|
+
/**
|
|
178
|
+
* Fired when the server returns 401 AND no refresh path recovers it
|
|
179
|
+
* (no refresh token, no refresh handler, refresh failed, or retry
|
|
180
|
+
* still 401). The app should clear local state and redirect to login.
|
|
181
|
+
*
|
|
182
|
+
* NOT fired for 401 that gets transparently recovered by the refresh
|
|
183
|
+
* handler — those are invisible to callers.
|
|
184
|
+
*/
|
|
174
185
|
onUnauthorized(cb) {
|
|
175
186
|
_onUnauthorized = cb;
|
|
187
|
+
},
|
|
188
|
+
/**
|
|
189
|
+
* Register the refresh strategy. The handler receives the current
|
|
190
|
+
* refresh token and must call your refresh endpoint, returning
|
|
191
|
+
* `{ access, refresh? }` on success or `null` on failure.
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* auth.setRefreshHandler(async (refresh) => {
|
|
195
|
+
* const { data } = await Auth.tokenRefreshCreate({ body: { refresh } });
|
|
196
|
+
* return data ? { access: data.access, refresh: data.refresh } : null;
|
|
197
|
+
* });
|
|
198
|
+
*/
|
|
199
|
+
setRefreshHandler(fn) {
|
|
200
|
+
_refreshHandler = fn;
|
|
176
201
|
}
|
|
177
202
|
};
|
|
203
|
+
async function tryRefresh() {
|
|
204
|
+
if (_refreshInflight) return _refreshInflight;
|
|
205
|
+
if (!_refreshHandler) return null;
|
|
206
|
+
const refresh = auth.getRefreshToken();
|
|
207
|
+
if (!refresh) return null;
|
|
208
|
+
_refreshInflight = (async () => {
|
|
209
|
+
try {
|
|
210
|
+
const result = await _refreshHandler(refresh);
|
|
211
|
+
if (!result?.access) return null;
|
|
212
|
+
auth.setToken(result.access);
|
|
213
|
+
if (result.refresh) auth.setRefreshToken(result.refresh);
|
|
214
|
+
return result.access;
|
|
215
|
+
} catch {
|
|
216
|
+
return null;
|
|
217
|
+
} finally {
|
|
218
|
+
_refreshInflight = null;
|
|
219
|
+
}
|
|
220
|
+
})();
|
|
221
|
+
return _refreshInflight;
|
|
222
|
+
}
|
|
223
|
+
__name(tryRefresh, "tryRefresh");
|
|
178
224
|
function installAuthOnClient(client2) {
|
|
179
225
|
if (_client) return;
|
|
180
226
|
_client = client2;
|
|
@@ -191,14 +237,48 @@ function installAuthOnClient(client2) {
|
|
|
191
237
|
if (apiKey) request.headers.set("X-API-Key", apiKey);
|
|
192
238
|
return request;
|
|
193
239
|
});
|
|
194
|
-
client2.interceptors.response.use((response) => {
|
|
195
|
-
if (response.status
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
240
|
+
client2.interceptors.response.use(async (response, request) => {
|
|
241
|
+
if (response.status !== 401) return response;
|
|
242
|
+
if (request.headers.get(RETRY_MARKER)) {
|
|
243
|
+
if (_onUnauthorized) {
|
|
244
|
+
try {
|
|
245
|
+
_onUnauthorized(response);
|
|
246
|
+
} catch {
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return response;
|
|
250
|
+
}
|
|
251
|
+
const newToken = await tryRefresh();
|
|
252
|
+
if (!newToken) {
|
|
253
|
+
if (_onUnauthorized) {
|
|
254
|
+
try {
|
|
255
|
+
_onUnauthorized(response);
|
|
256
|
+
} catch {
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return response;
|
|
260
|
+
}
|
|
261
|
+
const retry = request.clone();
|
|
262
|
+
retry.headers.set("Authorization", `Bearer ${newToken}`);
|
|
263
|
+
retry.headers.set(RETRY_MARKER, "1");
|
|
264
|
+
try {
|
|
265
|
+
const retried = await fetch(retry);
|
|
266
|
+
if (retried.status === 401 && _onUnauthorized) {
|
|
267
|
+
try {
|
|
268
|
+
_onUnauthorized(retried);
|
|
269
|
+
} catch {
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return retried;
|
|
273
|
+
} catch {
|
|
274
|
+
if (_onUnauthorized) {
|
|
275
|
+
try {
|
|
276
|
+
_onUnauthorized(response);
|
|
277
|
+
} catch {
|
|
278
|
+
}
|
|
199
279
|
}
|
|
280
|
+
return response;
|
|
200
281
|
}
|
|
201
|
-
return response;
|
|
202
282
|
});
|
|
203
283
|
}
|
|
204
284
|
__name(installAuthOnClient, "installAuthOnClient");
|
|
@@ -349,6 +429,15 @@ var API = class {
|
|
|
349
429
|
setApiKey(key) {
|
|
350
430
|
auth.setApiKey(key);
|
|
351
431
|
}
|
|
432
|
+
// ── 401 handling ────────────────────────────────────────────────────────
|
|
433
|
+
/** Fired only on terminal 401 (after refresh+retry path is exhausted). */
|
|
434
|
+
onUnauthorized(cb) {
|
|
435
|
+
auth.onUnauthorized(cb);
|
|
436
|
+
}
|
|
437
|
+
/** Provide a refresh strategy. See `auth.setRefreshHandler` for the contract. */
|
|
438
|
+
setRefreshHandler(fn) {
|
|
439
|
+
auth.setRefreshHandler(fn);
|
|
440
|
+
}
|
|
352
441
|
};
|
|
353
442
|
|
|
354
443
|
// src/_api/generated/helpers/storage.ts
|
|
@@ -601,6 +690,15 @@ var API2 = class {
|
|
|
601
690
|
setApiKey(key) {
|
|
602
691
|
auth.setApiKey(key);
|
|
603
692
|
}
|
|
693
|
+
// ── 401 handling ────────────────────────────────────────────────────────
|
|
694
|
+
/** Fired only on terminal 401 (after refresh+retry path is exhausted). */
|
|
695
|
+
onUnauthorized(cb) {
|
|
696
|
+
auth.onUnauthorized(cb);
|
|
697
|
+
}
|
|
698
|
+
/** Provide a refresh strategy. See `auth.setRefreshHandler` for the contract. */
|
|
699
|
+
setRefreshHandler(fn) {
|
|
700
|
+
auth.setRefreshHandler(fn);
|
|
701
|
+
}
|
|
604
702
|
};
|
|
605
703
|
|
|
606
704
|
// src/_api/generated/_cfg_totp/api.ts
|
|
@@ -655,6 +753,15 @@ var API3 = class {
|
|
|
655
753
|
setApiKey(key) {
|
|
656
754
|
auth.setApiKey(key);
|
|
657
755
|
}
|
|
756
|
+
// ── 401 handling ────────────────────────────────────────────────────────
|
|
757
|
+
/** Fired only on terminal 401 (after refresh+retry path is exhausted). */
|
|
758
|
+
onUnauthorized(cb) {
|
|
759
|
+
auth.onUnauthorized(cb);
|
|
760
|
+
}
|
|
761
|
+
/** Provide a refresh strategy. See `auth.setRefreshHandler` for the contract. */
|
|
762
|
+
setRefreshHandler(fn) {
|
|
763
|
+
auth.setRefreshHandler(fn);
|
|
764
|
+
}
|
|
658
765
|
};
|
|
659
766
|
|
|
660
767
|
// src/_api/generated/index.ts
|