@djangocfg/api 2.1.456 → 2.1.457
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 +2109 -2380
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +24 -5
- package/dist/auth.d.ts +24 -5
- package/dist/auth.mjs +2229 -290
- package/dist/auth.mjs.map +1 -1
- package/dist/clients.cjs +1906 -2024
- package/dist/clients.cjs.map +1 -1
- package/dist/clients.mjs +2090 -14
- package/dist/clients.mjs.map +1 -1
- package/dist/hooks.cjs +1026 -1672
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.mjs +1543 -4
- package/dist/hooks.mjs.map +1 -1
- package/dist/index.cjs +1892 -2015
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +2105 -20
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/_api/generated/helpers/auth.ts +24 -12
- package/src/auth/constants.ts +5 -5
- package/src/auth/context/AuthContext.tsx +67 -28
- package/src/auth/context/types.ts +13 -0
- package/src/auth/hooks/index.ts +5 -1
- package/src/auth/hooks/useAuthRedirect.ts +17 -0
- package/src/auth/hooks/useTwoFactor.ts +4 -2
package/dist/auth.cjs
CHANGED
|
@@ -6,9 +6,6 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
8
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
9
|
-
var __esm = (fn, res) => function __init() {
|
|
10
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
11
|
-
};
|
|
12
9
|
var __export = (target, all) => {
|
|
13
10
|
for (var name in all)
|
|
14
11
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -31,1775 +28,552 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
31
28
|
));
|
|
32
29
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
33
30
|
|
|
34
|
-
// src/
|
|
35
|
-
var
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
get isAuthError() {
|
|
84
|
-
return this.statusCode === 401;
|
|
85
|
-
}
|
|
86
|
-
get isPermissionError() {
|
|
87
|
-
return this.statusCode === 403;
|
|
88
|
-
}
|
|
89
|
-
get isNotFoundError() {
|
|
90
|
-
return this.statusCode === 404;
|
|
91
|
-
}
|
|
92
|
-
get isServerError() {
|
|
93
|
-
return this.statusCode >= 500 && this.statusCode < 600;
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
}
|
|
31
|
+
// src/auth/index.ts
|
|
32
|
+
var auth_exports = {};
|
|
33
|
+
__export(auth_exports, {
|
|
34
|
+
AUTH_CONSTANTS: () => AUTH_CONSTANTS,
|
|
35
|
+
AccountsProvider: () => AccountsProvider,
|
|
36
|
+
Analytics: () => Analytics,
|
|
37
|
+
AnalyticsCategory: () => AnalyticsCategory,
|
|
38
|
+
AnalyticsEvent: () => AnalyticsEvent,
|
|
39
|
+
AuthContext: () => AuthContext_default,
|
|
40
|
+
AuthProvider: () => AuthProvider,
|
|
41
|
+
PatchedCfgUserUpdateRequestSchema: () => PatchedCfgUserUpdateRequestSchema,
|
|
42
|
+
authLogger: () => authLogger,
|
|
43
|
+
clearProfileCache: () => clearProfileCache,
|
|
44
|
+
consumeSavedRedirect: () => consumeSavedRedirect,
|
|
45
|
+
decodeBase64: () => decodeBase64,
|
|
46
|
+
encodeBase64: () => encodeBase64,
|
|
47
|
+
formatAuthError: () => formatAuthError,
|
|
48
|
+
getCacheMetadata: () => getCacheMetadata,
|
|
49
|
+
getCachedProfile: () => getCachedProfile,
|
|
50
|
+
hasValidCache: () => hasValidCache,
|
|
51
|
+
isAllowedAuthPath: () => isAllowedAuthPath,
|
|
52
|
+
logger: () => logger,
|
|
53
|
+
normalizePath: () => normalizePath,
|
|
54
|
+
peekSavedRedirect: () => peekSavedRedirect,
|
|
55
|
+
resolveGuardIsAuthenticated: () => resolveGuardIsAuthenticated,
|
|
56
|
+
resolveGuardIsLoading: () => resolveGuardIsLoading,
|
|
57
|
+
setCachedProfile: () => setCachedProfile,
|
|
58
|
+
shouldRedirectToAuth: () => shouldRedirectToAuth,
|
|
59
|
+
useAccountsContext: () => useAccountsContext,
|
|
60
|
+
useAuth: () => useAuth,
|
|
61
|
+
useAuthForm: () => useAuthForm,
|
|
62
|
+
useAuthFormState: () => useAuthFormState,
|
|
63
|
+
useAuthRedirectManager: () => useAuthRedirectManager,
|
|
64
|
+
useAuthValidation: () => useAuthValidation,
|
|
65
|
+
useAutoAuth: () => useAutoAuth,
|
|
66
|
+
useBase64: () => useBase64,
|
|
67
|
+
useCfgRouter: () => useCfgRouter,
|
|
68
|
+
useDeleteAccount: () => useDeleteAccount,
|
|
69
|
+
useGithubAuth: () => useGithubAuth,
|
|
70
|
+
useLocalStorage: () => useLocalStorage,
|
|
71
|
+
useQueryParams: () => useQueryParams,
|
|
72
|
+
useSession: () => useSession,
|
|
73
|
+
useSessionStorage: () => useSessionStorage,
|
|
74
|
+
useTwoFactor: () => useTwoFactor,
|
|
75
|
+
useTwoFactorSetup: () => useTwoFactorSetup,
|
|
76
|
+
useTwoFactorStatus: () => useTwoFactorStatus,
|
|
77
|
+
validateEmail: () => validateEmail,
|
|
78
|
+
validateIdentifier: () => validateIdentifier
|
|
97
79
|
});
|
|
80
|
+
module.exports = __toCommonJS(auth_exports);
|
|
98
81
|
|
|
99
|
-
// src/
|
|
100
|
-
var
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
} else {
|
|
109
|
-
data.append(key, JSON.stringify(value));
|
|
110
|
-
}
|
|
111
|
-
}, "serializeFormDataPair");
|
|
112
|
-
formDataBodySerializer = {
|
|
113
|
-
bodySerializer: /* @__PURE__ */ __name((body) => {
|
|
114
|
-
const data = new FormData();
|
|
115
|
-
Object.entries(body).forEach(([key, value]) => {
|
|
116
|
-
if (value === void 0 || value === null) {
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
if (Array.isArray(value)) {
|
|
120
|
-
value.forEach((v) => serializeFormDataPair(data, key, v));
|
|
121
|
-
} else {
|
|
122
|
-
serializeFormDataPair(data, key, value);
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
return data;
|
|
126
|
-
}, "bodySerializer")
|
|
127
|
-
};
|
|
128
|
-
jsonBodySerializer = {
|
|
129
|
-
bodySerializer: /* @__PURE__ */ __name((body) => JSON.stringify(body, (_key, value) => typeof value === "bigint" ? value.toString() : value), "bodySerializer")
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
});
|
|
82
|
+
// src/auth/constants.ts
|
|
83
|
+
var AUTH_CONSTANTS = {
|
|
84
|
+
/** Email OTP code length (numeric). */
|
|
85
|
+
EMAIL_OTP_LENGTH: 4,
|
|
86
|
+
/** TOTP code length (RFC 6238 — authenticator apps). */
|
|
87
|
+
TOTP_LENGTH: 6,
|
|
88
|
+
/** Backup code max length. */
|
|
89
|
+
BACKUP_CODE_MAX_LENGTH: 12
|
|
90
|
+
};
|
|
133
91
|
|
|
134
|
-
// src/
|
|
135
|
-
var
|
|
136
|
-
var
|
|
137
|
-
"src/_api/generated/core/params.gen.ts"() {
|
|
138
|
-
extraPrefixesMap = {
|
|
139
|
-
$body_: "body",
|
|
140
|
-
$headers_: "headers",
|
|
141
|
-
$path_: "path",
|
|
142
|
-
$query_: "query"
|
|
143
|
-
};
|
|
144
|
-
extraPrefixes = Object.entries(extraPrefixesMap);
|
|
145
|
-
}
|
|
146
|
-
});
|
|
92
|
+
// src/auth/context/AuthContext.tsx
|
|
93
|
+
var import_navigation4 = require("next/navigation");
|
|
94
|
+
var import_react16 = require("react");
|
|
147
95
|
|
|
148
|
-
// src/_api/generated/
|
|
149
|
-
var
|
|
150
|
-
|
|
96
|
+
// src/_api/generated/helpers/errors.ts
|
|
97
|
+
var APIError = class extends Error {
|
|
98
|
+
constructor(statusCode, statusText, response, url, message) {
|
|
99
|
+
super(message || `HTTP ${statusCode}: ${statusText}`);
|
|
100
|
+
this.statusCode = statusCode;
|
|
101
|
+
this.statusText = statusText;
|
|
102
|
+
this.response = response;
|
|
103
|
+
this.url = url;
|
|
104
|
+
this.name = "APIError";
|
|
151
105
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
onSseEvent,
|
|
159
|
-
responseTransformer,
|
|
160
|
-
responseValidator,
|
|
161
|
-
sseDefaultRetryDelay,
|
|
162
|
-
sseMaxRetryAttempts,
|
|
163
|
-
sseMaxRetryDelay,
|
|
164
|
-
sseSleepFn,
|
|
165
|
-
url,
|
|
166
|
-
...options
|
|
167
|
-
}) {
|
|
168
|
-
let lastEventId;
|
|
169
|
-
const sleep = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
170
|
-
const createStream = /* @__PURE__ */ __name(async function* () {
|
|
171
|
-
let retryDelay = sseDefaultRetryDelay ?? 3e3;
|
|
172
|
-
let attempt = 0;
|
|
173
|
-
const signal = options.signal ?? new AbortController().signal;
|
|
174
|
-
while (true) {
|
|
175
|
-
if (signal.aborted) break;
|
|
176
|
-
attempt++;
|
|
177
|
-
const headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers);
|
|
178
|
-
if (lastEventId !== void 0) {
|
|
179
|
-
headers.set("Last-Event-ID", lastEventId);
|
|
180
|
-
}
|
|
181
|
-
try {
|
|
182
|
-
const requestInit = {
|
|
183
|
-
redirect: "follow",
|
|
184
|
-
...options,
|
|
185
|
-
body: options.serializedBody,
|
|
186
|
-
headers,
|
|
187
|
-
signal
|
|
188
|
-
};
|
|
189
|
-
let request = new Request(url, requestInit);
|
|
190
|
-
if (onRequest) {
|
|
191
|
-
request = await onRequest(url, requestInit);
|
|
192
|
-
}
|
|
193
|
-
const _fetch = options.fetch ?? globalThis.fetch;
|
|
194
|
-
const response = await _fetch(request);
|
|
195
|
-
if (!response.ok) throw new Error(`SSE failed: ${response.status} ${response.statusText}`);
|
|
196
|
-
if (!response.body) throw new Error("No body in SSE response");
|
|
197
|
-
const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
|
|
198
|
-
let buffer = "";
|
|
199
|
-
const abortHandler = /* @__PURE__ */ __name(() => {
|
|
200
|
-
try {
|
|
201
|
-
reader.cancel();
|
|
202
|
-
} catch {
|
|
203
|
-
}
|
|
204
|
-
}, "abortHandler");
|
|
205
|
-
signal.addEventListener("abort", abortHandler);
|
|
206
|
-
try {
|
|
207
|
-
while (true) {
|
|
208
|
-
const { done, value } = await reader.read();
|
|
209
|
-
if (done) break;
|
|
210
|
-
buffer += value;
|
|
211
|
-
buffer = buffer.replace(/\r\n?/g, "\n");
|
|
212
|
-
const chunks = buffer.split("\n\n");
|
|
213
|
-
buffer = chunks.pop() ?? "";
|
|
214
|
-
for (const chunk of chunks) {
|
|
215
|
-
const lines = chunk.split("\n");
|
|
216
|
-
const dataLines = [];
|
|
217
|
-
let eventName;
|
|
218
|
-
for (const line of lines) {
|
|
219
|
-
if (line.startsWith("data:")) {
|
|
220
|
-
dataLines.push(line.replace(/^data:\s*/, ""));
|
|
221
|
-
} else if (line.startsWith("event:")) {
|
|
222
|
-
eventName = line.replace(/^event:\s*/, "");
|
|
223
|
-
} else if (line.startsWith("id:")) {
|
|
224
|
-
lastEventId = line.replace(/^id:\s*/, "");
|
|
225
|
-
} else if (line.startsWith("retry:")) {
|
|
226
|
-
const parsed = Number.parseInt(line.replace(/^retry:\s*/, ""), 10);
|
|
227
|
-
if (!Number.isNaN(parsed)) {
|
|
228
|
-
retryDelay = parsed;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
let data;
|
|
233
|
-
let parsedJson = false;
|
|
234
|
-
if (dataLines.length) {
|
|
235
|
-
const rawData = dataLines.join("\n");
|
|
236
|
-
try {
|
|
237
|
-
data = JSON.parse(rawData);
|
|
238
|
-
parsedJson = true;
|
|
239
|
-
} catch {
|
|
240
|
-
data = rawData;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
if (parsedJson) {
|
|
244
|
-
if (responseValidator) {
|
|
245
|
-
await responseValidator(data);
|
|
246
|
-
}
|
|
247
|
-
if (responseTransformer) {
|
|
248
|
-
data = await responseTransformer(data);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
onSseEvent?.({
|
|
252
|
-
data,
|
|
253
|
-
event: eventName,
|
|
254
|
-
id: lastEventId,
|
|
255
|
-
retry: retryDelay
|
|
256
|
-
});
|
|
257
|
-
if (dataLines.length) {
|
|
258
|
-
yield data;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
} finally {
|
|
263
|
-
signal.removeEventListener("abort", abortHandler);
|
|
264
|
-
reader.releaseLock();
|
|
265
|
-
}
|
|
266
|
-
break;
|
|
267
|
-
} catch (error) {
|
|
268
|
-
onSseError?.(error);
|
|
269
|
-
if (sseMaxRetryAttempts !== void 0 && attempt >= sseMaxRetryAttempts) {
|
|
270
|
-
break;
|
|
271
|
-
}
|
|
272
|
-
const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 3e4);
|
|
273
|
-
await sleep(backoff);
|
|
274
|
-
}
|
|
106
|
+
static {
|
|
107
|
+
__name(this, "APIError");
|
|
108
|
+
}
|
|
109
|
+
get details() {
|
|
110
|
+
if (typeof this.response === "object" && this.response !== null) {
|
|
111
|
+
return this.response;
|
|
275
112
|
}
|
|
276
|
-
|
|
277
|
-
const stream = createStream();
|
|
278
|
-
return { stream };
|
|
279
|
-
}
|
|
280
|
-
var init_serverSentEvents_gen = __esm({
|
|
281
|
-
"src/_api/generated/core/serverSentEvents.gen.ts"() {
|
|
282
|
-
__name(createSseClient, "createSseClient");
|
|
113
|
+
return null;
|
|
283
114
|
}
|
|
284
|
-
|
|
115
|
+
get fieldErrors() {
|
|
116
|
+
const details = this.details;
|
|
117
|
+
if (!details) return null;
|
|
118
|
+
const fieldErrors = {};
|
|
119
|
+
for (const [key, value] of Object.entries(details)) {
|
|
120
|
+
if (Array.isArray(value)) fieldErrors[key] = value;
|
|
121
|
+
}
|
|
122
|
+
return Object.keys(fieldErrors).length > 0 ? fieldErrors : null;
|
|
123
|
+
}
|
|
124
|
+
get errorMessage() {
|
|
125
|
+
const details = this.details;
|
|
126
|
+
if (!details) return this.message;
|
|
127
|
+
if (details.detail) {
|
|
128
|
+
return Array.isArray(details.detail) ? details.detail.join(", ") : String(details.detail);
|
|
129
|
+
}
|
|
130
|
+
if (details.error) return String(details.error);
|
|
131
|
+
if (details.message) return String(details.message);
|
|
132
|
+
const fieldErrors = this.fieldErrors;
|
|
133
|
+
if (fieldErrors) {
|
|
134
|
+
const firstField = Object.keys(fieldErrors)[0];
|
|
135
|
+
if (firstField) return `${firstField}: ${fieldErrors[firstField]?.join(", ")}`;
|
|
136
|
+
}
|
|
137
|
+
return this.message;
|
|
138
|
+
}
|
|
139
|
+
get isValidationError() {
|
|
140
|
+
return this.statusCode === 400;
|
|
141
|
+
}
|
|
142
|
+
get isAuthError() {
|
|
143
|
+
return this.statusCode === 401;
|
|
144
|
+
}
|
|
145
|
+
get isPermissionError() {
|
|
146
|
+
return this.statusCode === 403;
|
|
147
|
+
}
|
|
148
|
+
get isNotFoundError() {
|
|
149
|
+
return this.statusCode === 404;
|
|
150
|
+
}
|
|
151
|
+
get isServerError() {
|
|
152
|
+
return this.statusCode >= 500 && this.statusCode < 600;
|
|
153
|
+
}
|
|
154
|
+
};
|
|
285
155
|
|
|
286
|
-
// src/_api/generated/
|
|
287
|
-
var
|
|
288
|
-
var
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
156
|
+
// src/_api/generated/helpers/auth.ts
|
|
157
|
+
var ACCESS_KEY = "cfg.access_token";
|
|
158
|
+
var REFRESH_KEY = "cfg.refresh_token";
|
|
159
|
+
var API_KEY_KEY = "cfg.api_key";
|
|
160
|
+
var isBrowser = typeof window !== "undefined";
|
|
161
|
+
var localStorageBackend = {
|
|
162
|
+
get(key) {
|
|
163
|
+
if (!isBrowser) return null;
|
|
164
|
+
try {
|
|
165
|
+
return window.localStorage.getItem(key);
|
|
166
|
+
} catch {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
set(key, value) {
|
|
171
|
+
if (!isBrowser) return;
|
|
172
|
+
try {
|
|
173
|
+
if (value === null) window.localStorage.removeItem(key);
|
|
174
|
+
else window.localStorage.setItem(key, value);
|
|
175
|
+
} catch {
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
var COOKIE_MAX_AGE = 60 * 60 * 24 * 30;
|
|
180
|
+
var cookieBackend = {
|
|
181
|
+
get(key) {
|
|
182
|
+
if (!isBrowser) return null;
|
|
183
|
+
try {
|
|
184
|
+
const re = new RegExp(`(?:^|;\\s*)${encodeURIComponent(key)}=([^;]*)`);
|
|
185
|
+
const m = document.cookie.match(re);
|
|
186
|
+
return m ? decodeURIComponent(m[1]) : null;
|
|
187
|
+
} catch {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
set(key, value) {
|
|
192
|
+
if (!isBrowser) return;
|
|
193
|
+
try {
|
|
194
|
+
const k = encodeURIComponent(key);
|
|
195
|
+
const secure = window.location.protocol === "https:" ? "; Secure" : "";
|
|
196
|
+
if (value === null) {
|
|
197
|
+
document.cookie = `${k}=; Path=/; Max-Age=0; SameSite=Lax${secure}`;
|
|
198
|
+
} else {
|
|
199
|
+
const v = encodeURIComponent(value);
|
|
200
|
+
document.cookie = `${k}=${v}; Path=/; Max-Age=${COOKIE_MAX_AGE}; SameSite=Lax${secure}`;
|
|
312
201
|
}
|
|
313
|
-
}
|
|
314
|
-
separatorObjectExplode = /* @__PURE__ */ __name((style) => {
|
|
315
|
-
switch (style) {
|
|
316
|
-
case "label":
|
|
317
|
-
return ".";
|
|
318
|
-
case "matrix":
|
|
319
|
-
return ";";
|
|
320
|
-
case "simple":
|
|
321
|
-
return ",";
|
|
322
|
-
default:
|
|
323
|
-
return "&";
|
|
324
|
-
}
|
|
325
|
-
}, "separatorObjectExplode");
|
|
326
|
-
serializeArrayParam = /* @__PURE__ */ __name(({
|
|
327
|
-
allowReserved,
|
|
328
|
-
explode,
|
|
329
|
-
name,
|
|
330
|
-
style,
|
|
331
|
-
value
|
|
332
|
-
}) => {
|
|
333
|
-
if (!explode) {
|
|
334
|
-
const joinedValues2 = (allowReserved ? value : value.map((v) => encodeURIComponent(v))).join(separatorArrayNoExplode(style));
|
|
335
|
-
switch (style) {
|
|
336
|
-
case "label":
|
|
337
|
-
return `.${joinedValues2}`;
|
|
338
|
-
case "matrix":
|
|
339
|
-
return `;${name}=${joinedValues2}`;
|
|
340
|
-
case "simple":
|
|
341
|
-
return joinedValues2;
|
|
342
|
-
default:
|
|
343
|
-
return `${name}=${joinedValues2}`;
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
const separator = separatorArrayExplode(style);
|
|
347
|
-
const joinedValues = value.map((v) => {
|
|
348
|
-
if (style === "label" || style === "simple") {
|
|
349
|
-
return allowReserved ? v : encodeURIComponent(v);
|
|
350
|
-
}
|
|
351
|
-
return serializePrimitiveParam({
|
|
352
|
-
allowReserved,
|
|
353
|
-
name,
|
|
354
|
-
value: v
|
|
355
|
-
});
|
|
356
|
-
}).join(separator);
|
|
357
|
-
return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
|
|
358
|
-
}, "serializeArrayParam");
|
|
359
|
-
serializePrimitiveParam = /* @__PURE__ */ __name(({
|
|
360
|
-
allowReserved,
|
|
361
|
-
name,
|
|
362
|
-
value
|
|
363
|
-
}) => {
|
|
364
|
-
if (value === void 0 || value === null) {
|
|
365
|
-
return "";
|
|
366
|
-
}
|
|
367
|
-
if (typeof value === "object") {
|
|
368
|
-
throw new Error(
|
|
369
|
-
"Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these."
|
|
370
|
-
);
|
|
371
|
-
}
|
|
372
|
-
return `${name}=${allowReserved ? value : encodeURIComponent(value)}`;
|
|
373
|
-
}, "serializePrimitiveParam");
|
|
374
|
-
serializeObjectParam = /* @__PURE__ */ __name(({
|
|
375
|
-
allowReserved,
|
|
376
|
-
explode,
|
|
377
|
-
name,
|
|
378
|
-
style,
|
|
379
|
-
value,
|
|
380
|
-
valueOnly
|
|
381
|
-
}) => {
|
|
382
|
-
if (value instanceof Date) {
|
|
383
|
-
return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`;
|
|
384
|
-
}
|
|
385
|
-
if (style !== "deepObject" && !explode) {
|
|
386
|
-
let values = [];
|
|
387
|
-
Object.entries(value).forEach(([key, v]) => {
|
|
388
|
-
values = [...values, key, allowReserved ? v : encodeURIComponent(v)];
|
|
389
|
-
});
|
|
390
|
-
const joinedValues2 = values.join(",");
|
|
391
|
-
switch (style) {
|
|
392
|
-
case "form":
|
|
393
|
-
return `${name}=${joinedValues2}`;
|
|
394
|
-
case "label":
|
|
395
|
-
return `.${joinedValues2}`;
|
|
396
|
-
case "matrix":
|
|
397
|
-
return `;${name}=${joinedValues2}`;
|
|
398
|
-
default:
|
|
399
|
-
return joinedValues2;
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
const separator = separatorObjectExplode(style);
|
|
403
|
-
const joinedValues = Object.entries(value).map(
|
|
404
|
-
([key, v]) => serializePrimitiveParam({
|
|
405
|
-
allowReserved,
|
|
406
|
-
name: style === "deepObject" ? `${name}[${key}]` : key,
|
|
407
|
-
value: v
|
|
408
|
-
})
|
|
409
|
-
).join(separator);
|
|
410
|
-
return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
|
|
411
|
-
}, "serializeObjectParam");
|
|
412
|
-
}
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
// src/_api/generated/core/utils.gen.ts
|
|
416
|
-
function getValidRequestBody(options) {
|
|
417
|
-
const hasBody = options.body !== void 0;
|
|
418
|
-
const isSerializedBody = hasBody && options.bodySerializer;
|
|
419
|
-
if (isSerializedBody) {
|
|
420
|
-
if ("serializedBody" in options) {
|
|
421
|
-
const hasSerializedBody = options.serializedBody !== void 0 && options.serializedBody !== "";
|
|
422
|
-
return hasSerializedBody ? options.serializedBody : null;
|
|
202
|
+
} catch {
|
|
423
203
|
}
|
|
424
|
-
return options.body !== "" ? options.body : null;
|
|
425
204
|
}
|
|
426
|
-
|
|
427
|
-
|
|
205
|
+
};
|
|
206
|
+
var _storage = localStorageBackend;
|
|
207
|
+
var _storageMode = "localStorage";
|
|
208
|
+
function detectLocale() {
|
|
209
|
+
try {
|
|
210
|
+
if (typeof document !== "undefined") {
|
|
211
|
+
const m = document.cookie.match(/(?:^|;\s*)NEXT_LOCALE=([^;]*)/);
|
|
212
|
+
if (m) return decodeURIComponent(m[1]);
|
|
213
|
+
}
|
|
214
|
+
if (typeof navigator !== "undefined" && navigator.language) {
|
|
215
|
+
return navigator.language;
|
|
216
|
+
}
|
|
217
|
+
} catch {
|
|
428
218
|
}
|
|
429
|
-
return
|
|
219
|
+
return null;
|
|
430
220
|
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
"
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
for (const match of matches) {
|
|
441
|
-
let explode = false;
|
|
442
|
-
let name = match.substring(1, match.length - 1);
|
|
443
|
-
let style = "simple";
|
|
444
|
-
if (name.endsWith("*")) {
|
|
445
|
-
explode = true;
|
|
446
|
-
name = name.substring(0, name.length - 1);
|
|
447
|
-
}
|
|
448
|
-
if (name.startsWith(".")) {
|
|
449
|
-
name = name.substring(1);
|
|
450
|
-
style = "label";
|
|
451
|
-
} else if (name.startsWith(";")) {
|
|
452
|
-
name = name.substring(1);
|
|
453
|
-
style = "matrix";
|
|
454
|
-
}
|
|
455
|
-
const value = path[name];
|
|
456
|
-
if (value === void 0 || value === null) {
|
|
457
|
-
continue;
|
|
458
|
-
}
|
|
459
|
-
if (Array.isArray(value)) {
|
|
460
|
-
url = url.replace(match, serializeArrayParam({ explode, name, style, value }));
|
|
461
|
-
continue;
|
|
462
|
-
}
|
|
463
|
-
if (typeof value === "object") {
|
|
464
|
-
url = url.replace(
|
|
465
|
-
match,
|
|
466
|
-
serializeObjectParam({
|
|
467
|
-
explode,
|
|
468
|
-
name,
|
|
469
|
-
style,
|
|
470
|
-
value,
|
|
471
|
-
valueOnly: true
|
|
472
|
-
})
|
|
473
|
-
);
|
|
474
|
-
continue;
|
|
475
|
-
}
|
|
476
|
-
if (style === "matrix") {
|
|
477
|
-
url = url.replace(
|
|
478
|
-
match,
|
|
479
|
-
`;${serializePrimitiveParam({
|
|
480
|
-
name,
|
|
481
|
-
value
|
|
482
|
-
})}`
|
|
483
|
-
);
|
|
484
|
-
continue;
|
|
485
|
-
}
|
|
486
|
-
const replaceValue = encodeURIComponent(
|
|
487
|
-
style === "label" ? `.${value}` : value
|
|
488
|
-
);
|
|
489
|
-
url = url.replace(match, replaceValue);
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
return url;
|
|
493
|
-
}, "defaultPathSerializer");
|
|
494
|
-
getUrl = /* @__PURE__ */ __name(({
|
|
495
|
-
baseUrl,
|
|
496
|
-
path,
|
|
497
|
-
query,
|
|
498
|
-
querySerializer,
|
|
499
|
-
url: _url
|
|
500
|
-
}) => {
|
|
501
|
-
const pathUrl = _url.startsWith("/") ? _url : `/${_url}`;
|
|
502
|
-
let url = (baseUrl ?? "") + pathUrl;
|
|
503
|
-
if (path) {
|
|
504
|
-
url = defaultPathSerializer({ path, url });
|
|
505
|
-
}
|
|
506
|
-
let search = query ? querySerializer(query) : "";
|
|
507
|
-
if (search.startsWith("?")) {
|
|
508
|
-
search = search.substring(1);
|
|
509
|
-
}
|
|
510
|
-
if (search) {
|
|
511
|
-
url += `?${search}`;
|
|
221
|
+
__name(detectLocale, "detectLocale");
|
|
222
|
+
function defaultBaseUrl() {
|
|
223
|
+
if (typeof window !== "undefined") {
|
|
224
|
+
try {
|
|
225
|
+
if (typeof process !== "undefined" && process.env) {
|
|
226
|
+
if (process.env.NEXT_PUBLIC_STATIC_BUILD === "true") return "";
|
|
227
|
+
if (process.env.NEXT_PUBLIC_API_PROXY_URL !== void 0)
|
|
228
|
+
return process.env.NEXT_PUBLIC_API_PROXY_URL;
|
|
229
|
+
return process.env.NEXT_PUBLIC_API_URL || "";
|
|
512
230
|
}
|
|
513
|
-
|
|
514
|
-
}
|
|
515
|
-
|
|
231
|
+
} catch {
|
|
232
|
+
}
|
|
233
|
+
return "";
|
|
516
234
|
}
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
getAuthToken = /* @__PURE__ */ __name(async (auth2, callback) => {
|
|
524
|
-
const token = typeof callback === "function" ? await callback(auth2) : callback;
|
|
525
|
-
if (!token) {
|
|
526
|
-
return;
|
|
527
|
-
}
|
|
528
|
-
if (auth2.scheme === "bearer") {
|
|
529
|
-
return `Bearer ${token}`;
|
|
530
|
-
}
|
|
531
|
-
if (auth2.scheme === "basic") {
|
|
532
|
-
return `Basic ${btoa(token)}`;
|
|
533
|
-
}
|
|
534
|
-
return token;
|
|
535
|
-
}, "getAuthToken");
|
|
235
|
+
try {
|
|
236
|
+
if (typeof process !== "undefined" && process.env) {
|
|
237
|
+
if (process.env.NEXT_PUBLIC_STATIC_BUILD === "true") return "";
|
|
238
|
+
return process.env.NEXT_PUBLIC_API_URL || "";
|
|
239
|
+
}
|
|
240
|
+
} catch {
|
|
536
241
|
}
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
if (
|
|
543
|
-
|
|
242
|
+
return "";
|
|
243
|
+
}
|
|
244
|
+
__name(defaultBaseUrl, "defaultBaseUrl");
|
|
245
|
+
function defaultApiKey() {
|
|
246
|
+
try {
|
|
247
|
+
if (typeof process !== "undefined" && process.env?.NEXT_PUBLIC_API_KEY) {
|
|
248
|
+
return process.env.NEXT_PUBLIC_API_KEY;
|
|
544
249
|
}
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
250
|
+
} catch {
|
|
251
|
+
}
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
__name(defaultApiKey, "defaultApiKey");
|
|
255
|
+
var _localeOverride = null;
|
|
256
|
+
var _apiKeyOverride = null;
|
|
257
|
+
var _baseUrlOverride = null;
|
|
258
|
+
var _withCredentials = true;
|
|
259
|
+
var _onUnauthorized = null;
|
|
260
|
+
var _refreshHandler = null;
|
|
261
|
+
var _refreshInflight = null;
|
|
262
|
+
var RETRY_MARKER = "X-Auth-Retry";
|
|
263
|
+
function jwtExpMs(token) {
|
|
264
|
+
try {
|
|
265
|
+
const payload = token.split(".")[1];
|
|
266
|
+
if (!payload) return null;
|
|
267
|
+
const json = JSON.parse(atob(payload.replace(/-/g, "+").replace(/_/g, "/")));
|
|
268
|
+
return typeof json.exp === "number" ? json.exp * 1e3 : null;
|
|
269
|
+
} catch {
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
__name(jwtExpMs, "jwtExpMs");
|
|
274
|
+
function computeSnapshot() {
|
|
275
|
+
const access = _storage.get(ACCESS_KEY);
|
|
276
|
+
const refresh = _storage.get(REFRESH_KEY);
|
|
277
|
+
const now = Date.now();
|
|
278
|
+
const accessExp = access ? jwtExpMs(access) : null;
|
|
279
|
+
const accessAlive = access !== null && (accessExp === null || accessExp > now);
|
|
280
|
+
const refreshExp = refresh ? jwtExpMs(refresh) : null;
|
|
281
|
+
const refreshAlive = refresh !== null && (refreshExp === null || refreshExp > now);
|
|
282
|
+
return {
|
|
283
|
+
status: accessAlive || refreshAlive ? "authenticated" : "anonymous",
|
|
284
|
+
accessExpiresAt: accessExp
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
__name(computeSnapshot, "computeSnapshot");
|
|
288
|
+
var SERVER_SNAPSHOT = { status: "anonymous", accessExpiresAt: null };
|
|
289
|
+
var SESSION_SYNC_EVENT = `cfg-auth:changed:${ACCESS_KEY}`;
|
|
290
|
+
var _snapshot = computeSnapshot();
|
|
291
|
+
var _sessionListeners = /* @__PURE__ */ new Set();
|
|
292
|
+
var _expiryTimer = null;
|
|
293
|
+
var _storageListenerInstalled = false;
|
|
294
|
+
function scheduleExpiryFlip() {
|
|
295
|
+
if (!isBrowser) return;
|
|
296
|
+
if (_expiryTimer !== null) {
|
|
297
|
+
clearTimeout(_expiryTimer);
|
|
298
|
+
_expiryTimer = null;
|
|
299
|
+
}
|
|
300
|
+
if (_sessionListeners.size === 0) return;
|
|
301
|
+
const now = Date.now();
|
|
302
|
+
const exps = [];
|
|
303
|
+
const access = _storage.get(ACCESS_KEY);
|
|
304
|
+
const refresh = _storage.get(REFRESH_KEY);
|
|
305
|
+
const accessExp = access ? jwtExpMs(access) : null;
|
|
306
|
+
const refreshExp = refresh ? jwtExpMs(refresh) : null;
|
|
307
|
+
if (accessExp !== null && accessExp > now) exps.push(accessExp);
|
|
308
|
+
if (refreshExp !== null && refreshExp > now) exps.push(refreshExp);
|
|
309
|
+
if (!exps.length) return;
|
|
310
|
+
const delay = Math.min(Math.min(...exps) - now + 250, 2147483647);
|
|
311
|
+
_expiryTimer = setTimeout(notifySessionChanged, delay);
|
|
312
|
+
}
|
|
313
|
+
__name(scheduleExpiryFlip, "scheduleExpiryFlip");
|
|
314
|
+
function notifySessionChanged() {
|
|
315
|
+
const next = computeSnapshot();
|
|
316
|
+
const changed = next.status !== _snapshot.status || next.accessExpiresAt !== _snapshot.accessExpiresAt;
|
|
317
|
+
if (changed) _snapshot = next;
|
|
318
|
+
scheduleExpiryFlip();
|
|
319
|
+
if (!changed) return;
|
|
320
|
+
for (const listener of Array.from(_sessionListeners)) {
|
|
321
|
+
try {
|
|
322
|
+
listener();
|
|
323
|
+
} catch {
|
|
548
324
|
}
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
}
|
|
555
|
-
options.query[name] = token;
|
|
556
|
-
break;
|
|
557
|
-
case "cookie":
|
|
558
|
-
options.headers.append("Cookie", `${name}=${token}`);
|
|
559
|
-
break;
|
|
560
|
-
case "header":
|
|
561
|
-
default:
|
|
562
|
-
options.headers.set(name, token);
|
|
563
|
-
break;
|
|
325
|
+
}
|
|
326
|
+
if (isBrowser) {
|
|
327
|
+
try {
|
|
328
|
+
window.dispatchEvent(new Event(SESSION_SYNC_EVENT));
|
|
329
|
+
} catch {
|
|
564
330
|
}
|
|
565
331
|
}
|
|
566
332
|
}
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1);
|
|
664
|
-
}
|
|
665
|
-
config.headers = mergeHeaders(a.headers, b.headers);
|
|
666
|
-
return config;
|
|
667
|
-
}, "mergeConfigs");
|
|
668
|
-
headersEntries = /* @__PURE__ */ __name((headers) => {
|
|
669
|
-
const entries = [];
|
|
670
|
-
headers.forEach((value, key) => {
|
|
671
|
-
entries.push([key, value]);
|
|
672
|
-
});
|
|
673
|
-
return entries;
|
|
674
|
-
}, "headersEntries");
|
|
675
|
-
mergeHeaders = /* @__PURE__ */ __name((...headers) => {
|
|
676
|
-
const mergedHeaders = new Headers();
|
|
677
|
-
for (const header of headers) {
|
|
678
|
-
if (!header) {
|
|
679
|
-
continue;
|
|
680
|
-
}
|
|
681
|
-
const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header);
|
|
682
|
-
for (const [key, value] of iterator) {
|
|
683
|
-
if (value === null) {
|
|
684
|
-
mergedHeaders.delete(key);
|
|
685
|
-
} else if (Array.isArray(value)) {
|
|
686
|
-
for (const v of value) {
|
|
687
|
-
mergedHeaders.append(key, v);
|
|
688
|
-
}
|
|
689
|
-
} else if (value !== void 0) {
|
|
690
|
-
mergedHeaders.set(
|
|
691
|
-
key,
|
|
692
|
-
typeof value === "object" ? JSON.stringify(value) : value
|
|
693
|
-
);
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
return mergedHeaders;
|
|
698
|
-
}, "mergeHeaders");
|
|
699
|
-
Interceptors = class {
|
|
700
|
-
static {
|
|
701
|
-
__name(this, "Interceptors");
|
|
702
|
-
}
|
|
703
|
-
fns = [];
|
|
704
|
-
clear() {
|
|
705
|
-
this.fns = [];
|
|
706
|
-
}
|
|
707
|
-
eject(id) {
|
|
708
|
-
const index = this.getInterceptorIndex(id);
|
|
709
|
-
if (this.fns[index]) {
|
|
710
|
-
this.fns[index] = null;
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
exists(id) {
|
|
714
|
-
const index = this.getInterceptorIndex(id);
|
|
715
|
-
return Boolean(this.fns[index]);
|
|
716
|
-
}
|
|
717
|
-
getInterceptorIndex(id) {
|
|
718
|
-
if (typeof id === "number") {
|
|
719
|
-
return this.fns[id] ? id : -1;
|
|
720
|
-
}
|
|
721
|
-
return this.fns.indexOf(id);
|
|
722
|
-
}
|
|
723
|
-
update(id, fn) {
|
|
724
|
-
const index = this.getInterceptorIndex(id);
|
|
725
|
-
if (this.fns[index]) {
|
|
726
|
-
this.fns[index] = fn;
|
|
727
|
-
return id;
|
|
728
|
-
}
|
|
729
|
-
return false;
|
|
730
|
-
}
|
|
731
|
-
use(fn) {
|
|
732
|
-
this.fns.push(fn);
|
|
733
|
-
return this.fns.length - 1;
|
|
333
|
+
__name(notifySessionChanged, "notifySessionChanged");
|
|
334
|
+
function ensureStorageSync() {
|
|
335
|
+
if (!isBrowser || _storageListenerInstalled) return;
|
|
336
|
+
_storageListenerInstalled = true;
|
|
337
|
+
window.addEventListener("storage", (e) => {
|
|
338
|
+
if (e.key === null || e.key === ACCESS_KEY || e.key === REFRESH_KEY) {
|
|
339
|
+
notifySessionChanged();
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
window.addEventListener(SESSION_SYNC_EVENT, () => notifySessionChanged());
|
|
343
|
+
}
|
|
344
|
+
__name(ensureStorageSync, "ensureStorageSync");
|
|
345
|
+
var _sessionExpiredHandlers = /* @__PURE__ */ new Set();
|
|
346
|
+
var _client = null;
|
|
347
|
+
function pushClientConfig() {
|
|
348
|
+
if (!_client) return;
|
|
349
|
+
_client.setConfig({
|
|
350
|
+
baseUrl: auth.getBaseUrl(),
|
|
351
|
+
credentials: _withCredentials ? "include" : "same-origin"
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
__name(pushClientConfig, "pushClientConfig");
|
|
355
|
+
var auth = {
|
|
356
|
+
// ── Storage mode ──────────────────────────────────────────────────
|
|
357
|
+
getStorageMode() {
|
|
358
|
+
return _storageMode;
|
|
359
|
+
},
|
|
360
|
+
setStorageMode(mode) {
|
|
361
|
+
_storageMode = mode;
|
|
362
|
+
_storage = mode === "cookie" ? cookieBackend : localStorageBackend;
|
|
363
|
+
notifySessionChanged();
|
|
364
|
+
},
|
|
365
|
+
// ── Bearer token ──────────────────────────────────────────────────
|
|
366
|
+
getToken() {
|
|
367
|
+
return _storage.get(ACCESS_KEY);
|
|
368
|
+
},
|
|
369
|
+
setToken(token) {
|
|
370
|
+
_storage.set(ACCESS_KEY, token);
|
|
371
|
+
notifySessionChanged();
|
|
372
|
+
},
|
|
373
|
+
getRefreshToken() {
|
|
374
|
+
return _storage.get(REFRESH_KEY);
|
|
375
|
+
},
|
|
376
|
+
setRefreshToken(token) {
|
|
377
|
+
_storage.set(REFRESH_KEY, token);
|
|
378
|
+
notifySessionChanged();
|
|
379
|
+
},
|
|
380
|
+
clearTokens() {
|
|
381
|
+
_storage.set(ACCESS_KEY, null);
|
|
382
|
+
_storage.set(REFRESH_KEY, null);
|
|
383
|
+
notifySessionChanged();
|
|
384
|
+
},
|
|
385
|
+
/** Session-aware: token PRESENT and not past its `exp` (or a live refresh
|
|
386
|
+
* token exists that can mint one). Prefer `getSnapshot().status` in React. */
|
|
387
|
+
isAuthenticated() {
|
|
388
|
+
return computeSnapshot().status === "authenticated";
|
|
389
|
+
},
|
|
390
|
+
// ── Session (the ONE write path for login/logout flows) ──────────
|
|
391
|
+
/**
|
|
392
|
+
* Persist a token pair atomically. Every login flow (OTP verify, 2FA,
|
|
393
|
+
* OAuth callback) and the refresh handler should end here — do NOT
|
|
394
|
+
* scatter `setToken`/`setRefreshToken` pairs through app code.
|
|
395
|
+
* `refresh: undefined` keeps the current refresh token (access-only
|
|
396
|
+
* rotation); `refresh: null` explicitly drops it.
|
|
397
|
+
*/
|
|
398
|
+
setSession(tokens) {
|
|
399
|
+
_storage.set(ACCESS_KEY, tokens.access);
|
|
400
|
+
if (tokens.refresh !== void 0) _storage.set(REFRESH_KEY, tokens.refresh);
|
|
401
|
+
notifySessionChanged();
|
|
402
|
+
},
|
|
403
|
+
clearSession() {
|
|
404
|
+
auth.clearTokens();
|
|
405
|
+
},
|
|
406
|
+
// ── Reactive snapshot (for useSyncExternalStore) ──────────────────
|
|
407
|
+
/**
|
|
408
|
+
* @example React:
|
|
409
|
+
* const session = useSyncExternalStore(
|
|
410
|
+
* auth.subscribe, auth.getSnapshot, auth.getServerSnapshot,
|
|
411
|
+
* );
|
|
412
|
+
* const isAuthenticated = session.status === 'authenticated';
|
|
413
|
+
*/
|
|
414
|
+
getSnapshot() {
|
|
415
|
+
return _snapshot;
|
|
416
|
+
},
|
|
417
|
+
getServerSnapshot() {
|
|
418
|
+
return SERVER_SNAPSHOT;
|
|
419
|
+
},
|
|
420
|
+
subscribe(listener) {
|
|
421
|
+
ensureStorageSync();
|
|
422
|
+
_sessionListeners.add(listener);
|
|
423
|
+
notifySessionChanged();
|
|
424
|
+
return () => {
|
|
425
|
+
_sessionListeners.delete(listener);
|
|
426
|
+
if (_sessionListeners.size === 0 && _expiryTimer !== null) {
|
|
427
|
+
clearTimeout(_expiryTimer);
|
|
428
|
+
_expiryTimer = null;
|
|
734
429
|
}
|
|
735
430
|
};
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
explode: true,
|
|
749
|
-
style: "deepObject"
|
|
750
|
-
}
|
|
751
|
-
});
|
|
752
|
-
defaultHeaders = {
|
|
753
|
-
"Content-Type": "application/json"
|
|
431
|
+
},
|
|
432
|
+
/**
|
|
433
|
+
* Fired on TERMINAL 401 — after the refresh+retry path is exhausted.
|
|
434
|
+
* The store has already cleared the session before calling back, so
|
|
435
|
+
* handlers only need to route to login (no clear-then-redirect
|
|
436
|
+
* ordering to get wrong). Returns an unsubscribe function; multiple
|
|
437
|
+
* handlers compose (unlike the legacy single-slot `onUnauthorized`).
|
|
438
|
+
*/
|
|
439
|
+
onSessionExpired(cb) {
|
|
440
|
+
_sessionExpiredHandlers.add(cb);
|
|
441
|
+
return () => {
|
|
442
|
+
_sessionExpiredHandlers.delete(cb);
|
|
754
443
|
};
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
response
|
|
832
|
-
};
|
|
833
|
-
if (response.ok) {
|
|
834
|
-
const parseAs = (opts.parseAs === "auto" ? getParseAs(response.headers.get("Content-Type")) : opts.parseAs) ?? "json";
|
|
835
|
-
if (response.status === 204 || response.headers.get("Content-Length") === "0") {
|
|
836
|
-
let emptyData;
|
|
837
|
-
switch (parseAs) {
|
|
838
|
-
case "arrayBuffer":
|
|
839
|
-
case "blob":
|
|
840
|
-
case "text":
|
|
841
|
-
emptyData = await response[parseAs]();
|
|
842
|
-
break;
|
|
843
|
-
case "formData":
|
|
844
|
-
emptyData = new FormData();
|
|
845
|
-
break;
|
|
846
|
-
case "stream":
|
|
847
|
-
emptyData = response.body;
|
|
848
|
-
break;
|
|
849
|
-
case "json":
|
|
850
|
-
default:
|
|
851
|
-
emptyData = {};
|
|
852
|
-
break;
|
|
853
|
-
}
|
|
854
|
-
return opts.responseStyle === "data" ? emptyData : {
|
|
855
|
-
data: emptyData,
|
|
856
|
-
...result
|
|
857
|
-
};
|
|
858
|
-
}
|
|
859
|
-
let data;
|
|
860
|
-
switch (parseAs) {
|
|
861
|
-
case "arrayBuffer":
|
|
862
|
-
case "blob":
|
|
863
|
-
case "formData":
|
|
864
|
-
case "text":
|
|
865
|
-
data = await response[parseAs]();
|
|
866
|
-
break;
|
|
867
|
-
case "json": {
|
|
868
|
-
const text = await response.text();
|
|
869
|
-
data = text ? JSON.parse(text) : {};
|
|
870
|
-
break;
|
|
871
|
-
}
|
|
872
|
-
case "stream":
|
|
873
|
-
return opts.responseStyle === "data" ? response.body : {
|
|
874
|
-
data: response.body,
|
|
875
|
-
...result
|
|
876
|
-
};
|
|
877
|
-
}
|
|
878
|
-
if (parseAs === "json") {
|
|
879
|
-
if (opts.responseValidator) {
|
|
880
|
-
await opts.responseValidator(data);
|
|
881
|
-
}
|
|
882
|
-
if (opts.responseTransformer) {
|
|
883
|
-
data = await opts.responseTransformer(data);
|
|
884
|
-
}
|
|
885
|
-
}
|
|
886
|
-
return opts.responseStyle === "data" ? data : {
|
|
887
|
-
data,
|
|
888
|
-
...result
|
|
889
|
-
};
|
|
890
|
-
}
|
|
891
|
-
const textError = await response.text();
|
|
892
|
-
let jsonError;
|
|
893
|
-
try {
|
|
894
|
-
jsonError = JSON.parse(textError);
|
|
895
|
-
} catch {
|
|
896
|
-
}
|
|
897
|
-
throw jsonError ?? textError;
|
|
898
|
-
} catch (error) {
|
|
899
|
-
let finalError = error;
|
|
900
|
-
for (const fn of interceptors.error.fns) {
|
|
901
|
-
if (fn) {
|
|
902
|
-
finalError = await fn(finalError, response, request2, options);
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
finalError = finalError || {};
|
|
906
|
-
if (throwOnError) {
|
|
907
|
-
throw finalError;
|
|
908
|
-
}
|
|
909
|
-
return responseStyle === "data" ? void 0 : {
|
|
910
|
-
error: finalError,
|
|
911
|
-
request: request2,
|
|
912
|
-
response
|
|
913
|
-
};
|
|
914
|
-
}
|
|
915
|
-
}, "request");
|
|
916
|
-
const makeMethodFn = /* @__PURE__ */ __name((method) => (options) => request({ ...options, method }), "makeMethodFn");
|
|
917
|
-
const makeSseFn = /* @__PURE__ */ __name((method) => async (options) => {
|
|
918
|
-
const { opts, url } = await beforeRequest(options);
|
|
919
|
-
return createSseClient({
|
|
920
|
-
...opts,
|
|
921
|
-
body: opts.body,
|
|
922
|
-
method,
|
|
923
|
-
onRequest: /* @__PURE__ */ __name(async (url2, init) => {
|
|
924
|
-
let request2 = new Request(url2, init);
|
|
925
|
-
for (const fn of interceptors.request.fns) {
|
|
926
|
-
if (fn) {
|
|
927
|
-
request2 = await fn(request2, opts);
|
|
928
|
-
}
|
|
929
|
-
}
|
|
930
|
-
return request2;
|
|
931
|
-
}, "onRequest"),
|
|
932
|
-
serializedBody: getValidRequestBody(opts),
|
|
933
|
-
url
|
|
934
|
-
});
|
|
935
|
-
}, "makeSseFn");
|
|
936
|
-
const _buildUrl = /* @__PURE__ */ __name((options) => buildUrl({ ..._config, ...options }), "_buildUrl");
|
|
937
|
-
return {
|
|
938
|
-
buildUrl: _buildUrl,
|
|
939
|
-
connect: makeMethodFn("CONNECT"),
|
|
940
|
-
delete: makeMethodFn("DELETE"),
|
|
941
|
-
get: makeMethodFn("GET"),
|
|
942
|
-
getConfig,
|
|
943
|
-
head: makeMethodFn("HEAD"),
|
|
944
|
-
interceptors,
|
|
945
|
-
options: makeMethodFn("OPTIONS"),
|
|
946
|
-
patch: makeMethodFn("PATCH"),
|
|
947
|
-
post: makeMethodFn("POST"),
|
|
948
|
-
put: makeMethodFn("PUT"),
|
|
949
|
-
request,
|
|
950
|
-
setConfig,
|
|
951
|
-
sse: {
|
|
952
|
-
connect: makeSseFn("CONNECT"),
|
|
953
|
-
delete: makeSseFn("DELETE"),
|
|
954
|
-
get: makeSseFn("GET"),
|
|
955
|
-
head: makeSseFn("HEAD"),
|
|
956
|
-
options: makeSseFn("OPTIONS"),
|
|
957
|
-
patch: makeSseFn("PATCH"),
|
|
958
|
-
post: makeSseFn("POST"),
|
|
959
|
-
put: makeSseFn("PUT"),
|
|
960
|
-
trace: makeSseFn("TRACE")
|
|
961
|
-
},
|
|
962
|
-
trace: makeMethodFn("TRACE")
|
|
963
|
-
};
|
|
964
|
-
}, "createClient");
|
|
965
|
-
}
|
|
966
|
-
});
|
|
967
|
-
|
|
968
|
-
// src/_api/generated/client/index.ts
|
|
969
|
-
var init_client = __esm({
|
|
970
|
-
"src/_api/generated/client/index.ts"() {
|
|
971
|
-
init_bodySerializer_gen();
|
|
972
|
-
init_params_gen();
|
|
973
|
-
init_queryKeySerializer_gen();
|
|
974
|
-
init_client_gen();
|
|
975
|
-
init_utils_gen2();
|
|
976
|
-
}
|
|
977
|
-
});
|
|
978
|
-
|
|
979
|
-
// src/_api/generated/client.gen.ts
|
|
980
|
-
var client;
|
|
981
|
-
var init_client_gen2 = __esm({
|
|
982
|
-
"src/_api/generated/client.gen.ts"() {
|
|
983
|
-
init_client();
|
|
984
|
-
init_auth();
|
|
985
|
-
client = createClient(createConfig({ baseUrl: "http://localhost:8000" }));
|
|
986
|
-
installAuthOnClient(client);
|
|
444
|
+
},
|
|
445
|
+
// ── API key ───────────────────────────────────────────────────────
|
|
446
|
+
getApiKey() {
|
|
447
|
+
return _apiKeyOverride ?? _storage.get(API_KEY_KEY) ?? defaultApiKey();
|
|
448
|
+
},
|
|
449
|
+
setApiKey(key) {
|
|
450
|
+
_apiKeyOverride = key;
|
|
451
|
+
},
|
|
452
|
+
setApiKeyPersist(key) {
|
|
453
|
+
_apiKeyOverride = key;
|
|
454
|
+
_storage.set(API_KEY_KEY, key);
|
|
455
|
+
},
|
|
456
|
+
clearApiKey() {
|
|
457
|
+
_apiKeyOverride = null;
|
|
458
|
+
_storage.set(API_KEY_KEY, null);
|
|
459
|
+
},
|
|
460
|
+
// ── Locale ────────────────────────────────────────────────────────
|
|
461
|
+
getLocale() {
|
|
462
|
+
return _localeOverride ?? detectLocale();
|
|
463
|
+
},
|
|
464
|
+
setLocale(locale) {
|
|
465
|
+
_localeOverride = locale;
|
|
466
|
+
},
|
|
467
|
+
// ── Base URL ──────────────────────────────────────────────────────
|
|
468
|
+
getBaseUrl() {
|
|
469
|
+
const url = _baseUrlOverride ?? defaultBaseUrl();
|
|
470
|
+
return url.replace(/\/$/, "");
|
|
471
|
+
},
|
|
472
|
+
setBaseUrl(url) {
|
|
473
|
+
_baseUrlOverride = url ? url.replace(/\/$/, "") : null;
|
|
474
|
+
pushClientConfig();
|
|
475
|
+
},
|
|
476
|
+
// ── Credentials toggle ────────────────────────────────────────────
|
|
477
|
+
getWithCredentials() {
|
|
478
|
+
return _withCredentials;
|
|
479
|
+
},
|
|
480
|
+
setWithCredentials(value) {
|
|
481
|
+
_withCredentials = value;
|
|
482
|
+
pushClientConfig();
|
|
483
|
+
},
|
|
484
|
+
// ── 401 handler ───────────────────────────────────────────────────
|
|
485
|
+
/**
|
|
486
|
+
* Fired when the server returns 401 AND no refresh path recovers it
|
|
487
|
+
* (no refresh token, no refresh handler, refresh failed, or retry
|
|
488
|
+
* still 401). The app should clear local state and redirect to login.
|
|
489
|
+
*
|
|
490
|
+
* NOT fired for 401 that gets transparently recovered by the refresh
|
|
491
|
+
* handler — those are invisible to callers.
|
|
492
|
+
*/
|
|
493
|
+
onUnauthorized(cb) {
|
|
494
|
+
_onUnauthorized = cb;
|
|
495
|
+
},
|
|
496
|
+
/**
|
|
497
|
+
* Register the refresh strategy. The handler receives the current
|
|
498
|
+
* refresh token and must call your refresh endpoint, returning
|
|
499
|
+
* `{ access, refresh? }` on success or `null` on failure.
|
|
500
|
+
*
|
|
501
|
+
* @example
|
|
502
|
+
* auth.setRefreshHandler(async (refresh) => {
|
|
503
|
+
* const { data } = await Auth.tokenRefreshCreate({ body: { refresh } });
|
|
504
|
+
* return data ? { access: data.access, refresh: data.refresh } : null;
|
|
505
|
+
* });
|
|
506
|
+
*/
|
|
507
|
+
setRefreshHandler(fn) {
|
|
508
|
+
_refreshHandler = fn;
|
|
509
|
+
},
|
|
510
|
+
/**
|
|
511
|
+
* Proactively run the registered refresh handler right now, reusing the
|
|
512
|
+
* SAME single-flight promise as the 401-recovery interceptor. Callers
|
|
513
|
+
* (e.g. an expiry timer / focus / reconnect) get token rotation,
|
|
514
|
+
* de-duplication and rotated-token persistence for free — they must NOT
|
|
515
|
+
* re-implement any of it. Returns the fresh access token, or null if
|
|
516
|
+
* there is no handler / no refresh token / the refresh failed.
|
|
517
|
+
*/
|
|
518
|
+
refreshNow() {
|
|
519
|
+
return tryRefresh();
|
|
987
520
|
}
|
|
988
|
-
}
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
"src/_api/generated/sdk.gen.ts"() {
|
|
1007
|
-
init_client();
|
|
1008
|
-
init_client_gen2();
|
|
1009
|
-
CfgAccountsApiKey = class {
|
|
1010
|
-
static {
|
|
1011
|
-
__name(this, "CfgAccountsApiKey");
|
|
1012
|
-
}
|
|
1013
|
-
/**
|
|
1014
|
-
* Get API key details
|
|
1015
|
-
*
|
|
1016
|
-
* Retrieve the current user's API key (masked) and metadata.
|
|
1017
|
-
*/
|
|
1018
|
-
static cfgAccountsApiKeyRetrieve(options) {
|
|
1019
|
-
return (options?.client ?? client).get({
|
|
1020
|
-
security: [
|
|
1021
|
-
{ scheme: "bearer", type: "http" },
|
|
1022
|
-
{
|
|
1023
|
-
in: "cookie",
|
|
1024
|
-
name: "sessionid",
|
|
1025
|
-
type: "apiKey"
|
|
1026
|
-
},
|
|
1027
|
-
{ name: "X-API-Key", type: "apiKey" }
|
|
1028
|
-
],
|
|
1029
|
-
url: "/cfg/accounts/api-key/",
|
|
1030
|
-
...options
|
|
1031
|
-
});
|
|
1032
|
-
}
|
|
1033
|
-
/**
|
|
1034
|
-
* Regenerate API key
|
|
1035
|
-
*
|
|
1036
|
-
* Generate a new API key. The full key is returned only once.
|
|
1037
|
-
*/
|
|
1038
|
-
static cfgAccountsApiKeyRegenerateCreate(options) {
|
|
1039
|
-
return (options.client ?? client).post({
|
|
1040
|
-
security: [
|
|
1041
|
-
{ scheme: "bearer", type: "http" },
|
|
1042
|
-
{
|
|
1043
|
-
in: "cookie",
|
|
1044
|
-
name: "sessionid",
|
|
1045
|
-
type: "apiKey"
|
|
1046
|
-
},
|
|
1047
|
-
{ name: "X-API-Key", type: "apiKey" }
|
|
1048
|
-
],
|
|
1049
|
-
url: "/cfg/accounts/api-key/regenerate/",
|
|
1050
|
-
...options,
|
|
1051
|
-
headers: {
|
|
1052
|
-
"Content-Type": "application/json",
|
|
1053
|
-
...options.headers
|
|
1054
|
-
}
|
|
1055
|
-
});
|
|
1056
|
-
}
|
|
1057
|
-
/**
|
|
1058
|
-
* Reveal API key
|
|
1059
|
-
*
|
|
1060
|
-
* Return the current full API key WITHOUT rotating it. The same durable value every one of the user's agents uses — for the signed-in user to copy and paste into agent onboarding. Default GET stays masked; this is the explicit reveal action.
|
|
1061
|
-
*/
|
|
1062
|
-
static cfgAccountsApiKeyRevealCreate(options) {
|
|
1063
|
-
return (options.client ?? client).post({
|
|
1064
|
-
security: [
|
|
1065
|
-
{ scheme: "bearer", type: "http" },
|
|
1066
|
-
{
|
|
1067
|
-
in: "cookie",
|
|
1068
|
-
name: "sessionid",
|
|
1069
|
-
type: "apiKey"
|
|
1070
|
-
},
|
|
1071
|
-
{ name: "X-API-Key", type: "apiKey" }
|
|
1072
|
-
],
|
|
1073
|
-
url: "/cfg/accounts/api-key/reveal/",
|
|
1074
|
-
...options,
|
|
1075
|
-
headers: {
|
|
1076
|
-
"Content-Type": "application/json",
|
|
1077
|
-
...options.headers
|
|
1078
|
-
}
|
|
1079
|
-
});
|
|
1080
|
-
}
|
|
1081
|
-
/**
|
|
1082
|
-
* Test API key
|
|
1083
|
-
*
|
|
1084
|
-
* Test whether an API key is valid without consuming it.
|
|
1085
|
-
*/
|
|
1086
|
-
static cfgAccountsApiKeyTestCreate(options) {
|
|
1087
|
-
return (options.client ?? client).post({
|
|
1088
|
-
security: [
|
|
1089
|
-
{ scheme: "bearer", type: "http" },
|
|
1090
|
-
{
|
|
1091
|
-
in: "cookie",
|
|
1092
|
-
name: "sessionid",
|
|
1093
|
-
type: "apiKey"
|
|
1094
|
-
},
|
|
1095
|
-
{ name: "X-API-Key", type: "apiKey" }
|
|
1096
|
-
],
|
|
1097
|
-
url: "/cfg/accounts/api-key/test/",
|
|
1098
|
-
...options,
|
|
1099
|
-
headers: {
|
|
1100
|
-
"Content-Type": "application/json",
|
|
1101
|
-
...options.headers
|
|
1102
|
-
}
|
|
1103
|
-
});
|
|
1104
|
-
}
|
|
1105
|
-
};
|
|
1106
|
-
CfgAccountsOauth = class {
|
|
1107
|
-
static {
|
|
1108
|
-
__name(this, "CfgAccountsOauth");
|
|
1109
|
-
}
|
|
1110
|
-
/**
|
|
1111
|
-
* List OAuth connections
|
|
1112
|
-
*
|
|
1113
|
-
* Get all OAuth connections for the current user.
|
|
1114
|
-
*/
|
|
1115
|
-
static cfgAccountsOauthConnectionsList(options) {
|
|
1116
|
-
return (options?.client ?? client).get({
|
|
1117
|
-
security: [
|
|
1118
|
-
{ name: "X-API-Key", type: "apiKey" },
|
|
1119
|
-
{ scheme: "bearer", type: "http" },
|
|
1120
|
-
{ name: "Authorization", type: "apiKey" }
|
|
1121
|
-
],
|
|
1122
|
-
url: "/cfg/accounts/oauth/connections/",
|
|
1123
|
-
...options
|
|
1124
|
-
});
|
|
1125
|
-
}
|
|
1126
|
-
/**
|
|
1127
|
-
* Disconnect OAuth provider
|
|
1128
|
-
*
|
|
1129
|
-
* Remove OAuth connection for the specified provider.
|
|
1130
|
-
*/
|
|
1131
|
-
static cfgAccountsOauthDisconnectCreate(options) {
|
|
1132
|
-
return (options.client ?? client).post({
|
|
1133
|
-
security: [
|
|
1134
|
-
{ name: "X-API-Key", type: "apiKey" },
|
|
1135
|
-
{ scheme: "bearer", type: "http" },
|
|
1136
|
-
{ name: "Authorization", type: "apiKey" }
|
|
1137
|
-
],
|
|
1138
|
-
url: "/cfg/accounts/oauth/disconnect/",
|
|
1139
|
-
...options,
|
|
1140
|
-
headers: {
|
|
1141
|
-
"Content-Type": "application/json",
|
|
1142
|
-
...options.headers
|
|
1143
|
-
}
|
|
1144
|
-
});
|
|
1145
|
-
}
|
|
1146
|
-
/**
|
|
1147
|
-
* Start GitHub OAuth
|
|
1148
|
-
*
|
|
1149
|
-
* Generate GitHub OAuth authorization URL. Redirect user to this URL to start authentication.
|
|
1150
|
-
*/
|
|
1151
|
-
static cfgAccountsOauthGithubAuthorizeCreate(options) {
|
|
1152
|
-
return (options?.client ?? client).post({
|
|
1153
|
-
url: "/cfg/accounts/oauth/github/authorize/",
|
|
1154
|
-
...options,
|
|
1155
|
-
headers: {
|
|
1156
|
-
"Content-Type": "application/json",
|
|
1157
|
-
...options?.headers
|
|
1158
|
-
}
|
|
1159
|
-
});
|
|
1160
|
-
}
|
|
1161
|
-
/**
|
|
1162
|
-
* Complete GitHub OAuth
|
|
1163
|
-
*
|
|
1164
|
-
* Exchange authorization code for JWT tokens. Call this after GitHub redirects back with code.
|
|
1165
|
-
*/
|
|
1166
|
-
static cfgAccountsOauthGithubCallbackCreate(options) {
|
|
1167
|
-
return (options.client ?? client).post({
|
|
1168
|
-
url: "/cfg/accounts/oauth/github/callback/",
|
|
1169
|
-
...options,
|
|
1170
|
-
headers: {
|
|
1171
|
-
"Content-Type": "application/json",
|
|
1172
|
-
...options.headers
|
|
1173
|
-
}
|
|
1174
|
-
});
|
|
1175
|
-
}
|
|
1176
|
-
/**
|
|
1177
|
-
* List OAuth providers
|
|
1178
|
-
*
|
|
1179
|
-
* Get list of available OAuth providers for authentication.
|
|
1180
|
-
*/
|
|
1181
|
-
static cfgAccountsOauthProvidersRetrieve(options) {
|
|
1182
|
-
return (options?.client ?? client).get({ url: "/cfg/accounts/oauth/providers/", ...options });
|
|
1183
|
-
}
|
|
1184
|
-
};
|
|
1185
|
-
CfgAccounts = class {
|
|
1186
|
-
static {
|
|
1187
|
-
__name(this, "CfgAccounts");
|
|
1188
|
-
}
|
|
1189
|
-
/**
|
|
1190
|
-
* Request OTP code to email.
|
|
1191
|
-
*/
|
|
1192
|
-
static cfgAccountsOtpRequestCreate(options) {
|
|
1193
|
-
return (options.client ?? client).post({
|
|
1194
|
-
security: [
|
|
1195
|
-
{ name: "X-API-Key", type: "apiKey" },
|
|
1196
|
-
{ scheme: "bearer", type: "http" },
|
|
1197
|
-
{ name: "Authorization", type: "apiKey" }
|
|
1198
|
-
],
|
|
1199
|
-
url: "/cfg/accounts/otp/request/",
|
|
1200
|
-
...options,
|
|
1201
|
-
headers: {
|
|
1202
|
-
"Content-Type": "application/json",
|
|
1203
|
-
...options.headers
|
|
1204
|
-
}
|
|
1205
|
-
});
|
|
1206
|
-
}
|
|
1207
|
-
/**
|
|
1208
|
-
* Verify OTP code and return JWT tokens or 2FA session.
|
|
1209
|
-
*
|
|
1210
|
-
* If user has 2FA enabled:
|
|
1211
|
-
* - Returns requires_2fa=True with session_id
|
|
1212
|
-
* - Client must complete 2FA verification at /cfg/totp/verify/
|
|
1213
|
-
*
|
|
1214
|
-
* If user has no 2FA:
|
|
1215
|
-
* - Returns JWT tokens and user data directly
|
|
1216
|
-
*/
|
|
1217
|
-
static cfgAccountsOtpVerifyCreate(options) {
|
|
1218
|
-
return (options.client ?? client).post({
|
|
1219
|
-
security: [
|
|
1220
|
-
{ name: "X-API-Key", type: "apiKey" },
|
|
1221
|
-
{ scheme: "bearer", type: "http" },
|
|
1222
|
-
{ name: "Authorization", type: "apiKey" }
|
|
1223
|
-
],
|
|
1224
|
-
url: "/cfg/accounts/otp/verify/",
|
|
1225
|
-
...options,
|
|
1226
|
-
headers: {
|
|
1227
|
-
"Content-Type": "application/json",
|
|
1228
|
-
...options.headers
|
|
1229
|
-
}
|
|
1230
|
-
});
|
|
1231
|
-
}
|
|
1232
|
-
};
|
|
1233
|
-
CfgAccountsProfile = class {
|
|
1234
|
-
static {
|
|
1235
|
-
__name(this, "CfgAccountsProfile");
|
|
1236
|
-
}
|
|
1237
|
-
/**
|
|
1238
|
-
* Get current user profile
|
|
1239
|
-
*
|
|
1240
|
-
* Retrieve the current authenticated user's profile information.
|
|
1241
|
-
*/
|
|
1242
|
-
static cfgAccountsProfileRetrieve(options) {
|
|
1243
|
-
return (options?.client ?? client).get({
|
|
1244
|
-
security: [{ scheme: "bearer", type: "http" }, {
|
|
1245
|
-
in: "cookie",
|
|
1246
|
-
name: "sessionid",
|
|
1247
|
-
type: "apiKey"
|
|
1248
|
-
}],
|
|
1249
|
-
url: "/cfg/accounts/profile/",
|
|
1250
|
-
...options
|
|
1251
|
-
});
|
|
1252
|
-
}
|
|
1253
|
-
/**
|
|
1254
|
-
* Upload user avatar
|
|
1255
|
-
*
|
|
1256
|
-
* Upload avatar image for the current authenticated user. Accepts multipart/form-data with 'avatar' field.
|
|
1257
|
-
*/
|
|
1258
|
-
static cfgAccountsProfileAvatarCreate(options) {
|
|
1259
|
-
return (options?.client ?? client).post({
|
|
1260
|
-
...formDataBodySerializer,
|
|
1261
|
-
security: [
|
|
1262
|
-
{ name: "X-API-Key", type: "apiKey" },
|
|
1263
|
-
{ scheme: "bearer", type: "http" },
|
|
1264
|
-
{ name: "Authorization", type: "apiKey" }
|
|
1265
|
-
],
|
|
1266
|
-
url: "/cfg/accounts/profile/avatar/",
|
|
1267
|
-
...options,
|
|
1268
|
-
headers: {
|
|
1269
|
-
"Content-Type": null,
|
|
1270
|
-
...options?.headers
|
|
1271
|
-
}
|
|
1272
|
-
});
|
|
1273
|
-
}
|
|
1274
|
-
/**
|
|
1275
|
-
* Delete user account
|
|
1276
|
-
*
|
|
1277
|
-
*
|
|
1278
|
-
* Permanently delete the current user's account.
|
|
1279
|
-
*
|
|
1280
|
-
* This operation:
|
|
1281
|
-
* - Deactivates the account (user cannot log in)
|
|
1282
|
-
* - Anonymizes personal data (GDPR compliance)
|
|
1283
|
-
* - Frees up the email address for re-registration
|
|
1284
|
-
* - Preserves audit trail
|
|
1285
|
-
*
|
|
1286
|
-
* The account can be restored by an administrator if needed.
|
|
1287
|
-
*
|
|
1288
|
-
*/
|
|
1289
|
-
static cfgAccountsProfileDeleteCreate(options) {
|
|
1290
|
-
return (options?.client ?? client).post({
|
|
1291
|
-
security: [{ scheme: "bearer", type: "http" }, {
|
|
1292
|
-
in: "cookie",
|
|
1293
|
-
name: "sessionid",
|
|
1294
|
-
type: "apiKey"
|
|
1295
|
-
}],
|
|
1296
|
-
url: "/cfg/accounts/profile/delete/",
|
|
1297
|
-
...options
|
|
1298
|
-
});
|
|
1299
|
-
}
|
|
1300
|
-
/**
|
|
1301
|
-
* Partial update user profile
|
|
1302
|
-
*
|
|
1303
|
-
* Partially update the current authenticated user's profile information. Supports avatar upload.
|
|
1304
|
-
*/
|
|
1305
|
-
static cfgAccountsProfilePartialPartialUpdate(options) {
|
|
1306
|
-
return (options?.client ?? client).patch({
|
|
1307
|
-
security: [{ scheme: "bearer", type: "http" }, {
|
|
1308
|
-
in: "cookie",
|
|
1309
|
-
name: "sessionid",
|
|
1310
|
-
type: "apiKey"
|
|
1311
|
-
}],
|
|
1312
|
-
url: "/cfg/accounts/profile/partial/",
|
|
1313
|
-
...options,
|
|
1314
|
-
headers: {
|
|
1315
|
-
"Content-Type": "application/json",
|
|
1316
|
-
...options?.headers
|
|
1317
|
-
}
|
|
1318
|
-
});
|
|
1319
|
-
}
|
|
1320
|
-
/**
|
|
1321
|
-
* Partial update user profile
|
|
1322
|
-
*
|
|
1323
|
-
* Partially update the current authenticated user's profile information. Supports avatar upload.
|
|
1324
|
-
*/
|
|
1325
|
-
static cfgAccountsProfilePartialUpdate(options) {
|
|
1326
|
-
return (options?.client ?? client).put({
|
|
1327
|
-
security: [{ scheme: "bearer", type: "http" }, {
|
|
1328
|
-
in: "cookie",
|
|
1329
|
-
name: "sessionid",
|
|
1330
|
-
type: "apiKey"
|
|
1331
|
-
}],
|
|
1332
|
-
url: "/cfg/accounts/profile/partial/",
|
|
1333
|
-
...options,
|
|
1334
|
-
headers: {
|
|
1335
|
-
"Content-Type": "application/json",
|
|
1336
|
-
...options?.headers
|
|
1337
|
-
}
|
|
1338
|
-
});
|
|
1339
|
-
}
|
|
1340
|
-
/**
|
|
1341
|
-
* Update user profile
|
|
1342
|
-
*
|
|
1343
|
-
* Update the current authenticated user's profile information.
|
|
1344
|
-
*/
|
|
1345
|
-
static cfgAccountsProfileUpdatePartialUpdate(options) {
|
|
1346
|
-
return (options?.client ?? client).patch({
|
|
1347
|
-
security: [{ scheme: "bearer", type: "http" }, {
|
|
1348
|
-
in: "cookie",
|
|
1349
|
-
name: "sessionid",
|
|
1350
|
-
type: "apiKey"
|
|
1351
|
-
}],
|
|
1352
|
-
url: "/cfg/accounts/profile/update/",
|
|
1353
|
-
...options,
|
|
1354
|
-
headers: {
|
|
1355
|
-
"Content-Type": "application/json",
|
|
1356
|
-
...options?.headers
|
|
1357
|
-
}
|
|
1358
|
-
});
|
|
1359
|
-
}
|
|
1360
|
-
/**
|
|
1361
|
-
* Update user profile
|
|
1362
|
-
*
|
|
1363
|
-
* Update the current authenticated user's profile information.
|
|
1364
|
-
*/
|
|
1365
|
-
static cfgAccountsProfileUpdateUpdate(options) {
|
|
1366
|
-
return (options?.client ?? client).put({
|
|
1367
|
-
security: [{ scheme: "bearer", type: "http" }, {
|
|
1368
|
-
in: "cookie",
|
|
1369
|
-
name: "sessionid",
|
|
1370
|
-
type: "apiKey"
|
|
1371
|
-
}],
|
|
1372
|
-
url: "/cfg/accounts/profile/update/",
|
|
1373
|
-
...options,
|
|
1374
|
-
headers: {
|
|
1375
|
-
"Content-Type": "application/json",
|
|
1376
|
-
...options?.headers
|
|
1377
|
-
}
|
|
1378
|
-
});
|
|
1379
|
-
}
|
|
1380
|
-
};
|
|
1381
|
-
CfgAccountsAuth = class {
|
|
1382
|
-
static {
|
|
1383
|
-
__name(this, "CfgAccountsAuth");
|
|
1384
|
-
}
|
|
1385
|
-
/**
|
|
1386
|
-
* Revoke a refresh token (logout).
|
|
1387
|
-
*
|
|
1388
|
-
* Blacklists the posted refresh token so it can never mint another access
|
|
1389
|
-
* token. Called best-effort by the client's logout — without it, "logout"
|
|
1390
|
-
* is purely client-side and a stolen refresh token survives until expiry.
|
|
1391
|
-
*/
|
|
1392
|
-
static cfgAccountsTokenBlacklistCreate(options) {
|
|
1393
|
-
return (options.client ?? client).post({
|
|
1394
|
-
url: "/cfg/accounts/token/blacklist/",
|
|
1395
|
-
...options,
|
|
1396
|
-
headers: {
|
|
1397
|
-
"Content-Type": "application/json",
|
|
1398
|
-
...options.headers
|
|
1399
|
-
}
|
|
1400
|
-
});
|
|
1401
|
-
}
|
|
1402
|
-
/**
|
|
1403
|
-
* Refresh JWT token.
|
|
1404
|
-
*
|
|
1405
|
-
* DPoP-aware: when the incoming refresh token is key-bound (`cnf.jkt`), the
|
|
1406
|
-
* rotated access/refresh in the response are re-stamped with the same `cnf`
|
|
1407
|
-
* (stock SimpleJWT drops it from the derived access), and a matching DPoP
|
|
1408
|
-
* proof is required on the refresh request — so a stolen refresh token can't
|
|
1409
|
-
* be used to mint fresh tokens.
|
|
1410
|
-
*/
|
|
1411
|
-
static cfgAccountsTokenRefreshCreate(options) {
|
|
1412
|
-
return (options.client ?? client).post({
|
|
1413
|
-
url: "/cfg/accounts/token/refresh/",
|
|
1414
|
-
...options,
|
|
1415
|
-
headers: {
|
|
1416
|
-
"Content-Type": "application/json",
|
|
1417
|
-
...options.headers
|
|
1418
|
-
}
|
|
1419
|
-
});
|
|
1420
|
-
}
|
|
1421
|
-
};
|
|
1422
|
-
CfgCentrifugo = class {
|
|
1423
|
-
static {
|
|
1424
|
-
__name(this, "CfgCentrifugo");
|
|
1425
|
-
}
|
|
1426
|
-
/**
|
|
1427
|
-
* Get Centrifugo connection token
|
|
1428
|
-
*
|
|
1429
|
-
* Generate JWT token for WebSocket connection to Centrifugo. Token includes user's allowed channels based on their permissions. Requires authentication.
|
|
1430
|
-
*/
|
|
1431
|
-
static cfgCentrifugoAuthTokenRetrieve(options) {
|
|
1432
|
-
return (options?.client ?? client).get({
|
|
1433
|
-
security: [
|
|
1434
|
-
{ name: "X-API-Key", type: "apiKey" },
|
|
1435
|
-
{ scheme: "bearer", type: "http" },
|
|
1436
|
-
{ name: "Authorization", type: "apiKey" }
|
|
1437
|
-
],
|
|
1438
|
-
url: "/cfg/centrifugo/auth/token/",
|
|
1439
|
-
...options
|
|
1440
|
-
});
|
|
1441
|
-
}
|
|
1442
|
-
};
|
|
1443
|
-
CfgTotpBackupCodes = class {
|
|
1444
|
-
static {
|
|
1445
|
-
__name(this, "CfgTotpBackupCodes");
|
|
1446
|
-
}
|
|
1447
|
-
/**
|
|
1448
|
-
* Get backup codes status for user.
|
|
1449
|
-
*/
|
|
1450
|
-
static cfgTotpBackupCodesRetrieve(options) {
|
|
1451
|
-
return (options?.client ?? client).get({
|
|
1452
|
-
security: [
|
|
1453
|
-
{ name: "X-API-Key", type: "apiKey" },
|
|
1454
|
-
{ scheme: "bearer", type: "http" },
|
|
1455
|
-
{ name: "Authorization", type: "apiKey" }
|
|
1456
|
-
],
|
|
1457
|
-
url: "/cfg/totp/backup-codes/",
|
|
1458
|
-
...options
|
|
1459
|
-
});
|
|
1460
|
-
}
|
|
1461
|
-
/**
|
|
1462
|
-
* Regenerate backup codes.
|
|
1463
|
-
*
|
|
1464
|
-
* Requires TOTP code for verification.
|
|
1465
|
-
* Invalidates all existing codes.
|
|
1466
|
-
*/
|
|
1467
|
-
static cfgTotpBackupCodesRegenerateCreate(options) {
|
|
1468
|
-
return (options.client ?? client).post({
|
|
1469
|
-
security: [
|
|
1470
|
-
{ name: "X-API-Key", type: "apiKey" },
|
|
1471
|
-
{ scheme: "bearer", type: "http" },
|
|
1472
|
-
{ name: "Authorization", type: "apiKey" }
|
|
1473
|
-
],
|
|
1474
|
-
url: "/cfg/totp/backup-codes/regenerate/",
|
|
1475
|
-
...options,
|
|
1476
|
-
headers: {
|
|
1477
|
-
"Content-Type": "application/json",
|
|
1478
|
-
...options.headers
|
|
1479
|
-
}
|
|
1480
|
-
});
|
|
1481
|
-
}
|
|
1482
|
-
};
|
|
1483
|
-
CfgTotp = class {
|
|
1484
|
-
static {
|
|
1485
|
-
__name(this, "CfgTotp");
|
|
1486
|
-
}
|
|
1487
|
-
/**
|
|
1488
|
-
* List all TOTP devices for user.
|
|
1489
|
-
*/
|
|
1490
|
-
static cfgTotpDevicesRetrieve(options) {
|
|
1491
|
-
return (options?.client ?? client).get({
|
|
1492
|
-
security: [
|
|
1493
|
-
{ name: "X-API-Key", type: "apiKey" },
|
|
1494
|
-
{ scheme: "bearer", type: "http" },
|
|
1495
|
-
{ name: "Authorization", type: "apiKey" }
|
|
1496
|
-
],
|
|
1497
|
-
url: "/cfg/totp/devices/",
|
|
1498
|
-
...options
|
|
1499
|
-
});
|
|
1500
|
-
}
|
|
1501
|
-
/**
|
|
1502
|
-
* Delete a TOTP device.
|
|
1503
|
-
*
|
|
1504
|
-
* Requires verification code if removing the last/primary device.
|
|
1505
|
-
*/
|
|
1506
|
-
static cfgTotpDevicesDestroy(options) {
|
|
1507
|
-
return (options.client ?? client).delete({
|
|
1508
|
-
security: [
|
|
1509
|
-
{ name: "X-API-Key", type: "apiKey" },
|
|
1510
|
-
{ scheme: "bearer", type: "http" },
|
|
1511
|
-
{ name: "Authorization", type: "apiKey" }
|
|
1512
|
-
],
|
|
1513
|
-
url: "/cfg/totp/devices/{id}/",
|
|
1514
|
-
...options
|
|
1515
|
-
});
|
|
1516
|
-
}
|
|
1517
|
-
/**
|
|
1518
|
-
* Completely disable 2FA for account.
|
|
1519
|
-
*
|
|
1520
|
-
* Requires verification code.
|
|
1521
|
-
*/
|
|
1522
|
-
static cfgTotpDisableCreate(options) {
|
|
1523
|
-
return (options.client ?? client).post({
|
|
1524
|
-
security: [
|
|
1525
|
-
{ name: "X-API-Key", type: "apiKey" },
|
|
1526
|
-
{ scheme: "bearer", type: "http" },
|
|
1527
|
-
{ name: "Authorization", type: "apiKey" }
|
|
1528
|
-
],
|
|
1529
|
-
url: "/cfg/totp/disable/",
|
|
1530
|
-
...options,
|
|
1531
|
-
headers: {
|
|
1532
|
-
"Content-Type": "application/json",
|
|
1533
|
-
...options.headers
|
|
1534
|
-
}
|
|
1535
|
-
});
|
|
1536
|
-
}
|
|
1537
|
-
};
|
|
1538
|
-
CfgTotpSetup = class {
|
|
1539
|
-
static {
|
|
1540
|
-
__name(this, "CfgTotpSetup");
|
|
1541
|
-
}
|
|
1542
|
-
/**
|
|
1543
|
-
* Start 2FA setup process.
|
|
1544
|
-
*
|
|
1545
|
-
* Creates a new TOTP device and returns QR code for scanning.
|
|
1546
|
-
*/
|
|
1547
|
-
static cfgTotpSetupCreate(options) {
|
|
1548
|
-
return (options?.client ?? client).post({
|
|
1549
|
-
security: [
|
|
1550
|
-
{ name: "X-API-Key", type: "apiKey" },
|
|
1551
|
-
{ scheme: "bearer", type: "http" },
|
|
1552
|
-
{ name: "Authorization", type: "apiKey" }
|
|
1553
|
-
],
|
|
1554
|
-
url: "/cfg/totp/setup/",
|
|
1555
|
-
...options,
|
|
1556
|
-
headers: {
|
|
1557
|
-
"Content-Type": "application/json",
|
|
1558
|
-
...options?.headers
|
|
1559
|
-
}
|
|
1560
|
-
});
|
|
1561
|
-
}
|
|
1562
|
-
/**
|
|
1563
|
-
* Confirm 2FA setup with first valid code.
|
|
1564
|
-
*
|
|
1565
|
-
* Activates the device and generates backup codes.
|
|
1566
|
-
*/
|
|
1567
|
-
static cfgTotpSetupConfirmCreate(options) {
|
|
1568
|
-
return (options.client ?? client).post({
|
|
1569
|
-
security: [
|
|
1570
|
-
{ name: "X-API-Key", type: "apiKey" },
|
|
1571
|
-
{ scheme: "bearer", type: "http" },
|
|
1572
|
-
{ name: "Authorization", type: "apiKey" }
|
|
1573
|
-
],
|
|
1574
|
-
url: "/cfg/totp/setup/confirm/",
|
|
1575
|
-
...options,
|
|
1576
|
-
headers: {
|
|
1577
|
-
"Content-Type": "application/json",
|
|
1578
|
-
...options.headers
|
|
1579
|
-
}
|
|
1580
|
-
});
|
|
1581
|
-
}
|
|
1582
|
-
};
|
|
1583
|
-
CfgTotpVerify = class {
|
|
1584
|
-
static {
|
|
1585
|
-
__name(this, "CfgTotpVerify");
|
|
1586
|
-
}
|
|
1587
|
-
/**
|
|
1588
|
-
* Verify TOTP code for 2FA session.
|
|
1589
|
-
*
|
|
1590
|
-
* Completes authentication and returns JWT tokens on success.
|
|
1591
|
-
*/
|
|
1592
|
-
static cfgTotpVerifyCreate(options) {
|
|
1593
|
-
return (options.client ?? client).post({
|
|
1594
|
-
security: [
|
|
1595
|
-
{ name: "X-API-Key", type: "apiKey" },
|
|
1596
|
-
{ scheme: "bearer", type: "http" },
|
|
1597
|
-
{ name: "Authorization", type: "apiKey" }
|
|
1598
|
-
],
|
|
1599
|
-
url: "/cfg/totp/verify/",
|
|
1600
|
-
...options,
|
|
1601
|
-
headers: {
|
|
1602
|
-
"Content-Type": "application/json",
|
|
1603
|
-
...options.headers
|
|
1604
|
-
}
|
|
1605
|
-
});
|
|
1606
|
-
}
|
|
1607
|
-
/**
|
|
1608
|
-
* Verify backup recovery code for 2FA session.
|
|
1609
|
-
*
|
|
1610
|
-
* Alternative verification method when TOTP device unavailable.
|
|
1611
|
-
*/
|
|
1612
|
-
static cfgTotpVerifyBackupCreate(options) {
|
|
1613
|
-
return (options.client ?? client).post({
|
|
1614
|
-
security: [
|
|
1615
|
-
{ name: "X-API-Key", type: "apiKey" },
|
|
1616
|
-
{ scheme: "bearer", type: "http" },
|
|
1617
|
-
{ name: "Authorization", type: "apiKey" }
|
|
1618
|
-
],
|
|
1619
|
-
url: "/cfg/totp/verify/backup/",
|
|
1620
|
-
...options,
|
|
1621
|
-
headers: {
|
|
1622
|
-
"Content-Type": "application/json",
|
|
1623
|
-
...options.headers
|
|
1624
|
-
}
|
|
1625
|
-
});
|
|
521
|
+
};
|
|
522
|
+
async function tryRefresh() {
|
|
523
|
+
if (_refreshInflight) return _refreshInflight;
|
|
524
|
+
if (!_refreshHandler) return null;
|
|
525
|
+
const runRefresh = /* @__PURE__ */ __name(async () => {
|
|
526
|
+
const refresh = auth.getRefreshToken();
|
|
527
|
+
if (!refresh) return null;
|
|
528
|
+
const result = await _refreshHandler(refresh);
|
|
529
|
+
if (!result?.access) return null;
|
|
530
|
+
auth.setToken(result.access);
|
|
531
|
+
if (result.refresh) auth.setRefreshToken(result.refresh);
|
|
532
|
+
return result.access;
|
|
533
|
+
}, "runRefresh");
|
|
534
|
+
_refreshInflight = (async () => {
|
|
535
|
+
try {
|
|
536
|
+
const locks = typeof navigator !== "undefined" ? navigator.locks : void 0;
|
|
537
|
+
if (locks?.request) {
|
|
538
|
+
return await locks.request(`${REFRESH_KEY}:refresh`, runRefresh);
|
|
1626
539
|
}
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
function detectLocale() {
|
|
1633
|
-
try {
|
|
1634
|
-
if (typeof document !== "undefined") {
|
|
1635
|
-
const m = document.cookie.match(/(?:^|;\s*)NEXT_LOCALE=([^;]*)/);
|
|
1636
|
-
if (m) return decodeURIComponent(m[1]);
|
|
1637
|
-
}
|
|
1638
|
-
if (typeof navigator !== "undefined" && navigator.language) {
|
|
1639
|
-
return navigator.language;
|
|
540
|
+
return await runRefresh();
|
|
541
|
+
} catch {
|
|
542
|
+
return null;
|
|
543
|
+
} finally {
|
|
544
|
+
_refreshInflight = null;
|
|
1640
545
|
}
|
|
1641
|
-
}
|
|
1642
|
-
|
|
1643
|
-
return null;
|
|
546
|
+
})();
|
|
547
|
+
return _refreshInflight;
|
|
1644
548
|
}
|
|
1645
|
-
|
|
1646
|
-
|
|
549
|
+
__name(tryRefresh, "tryRefresh");
|
|
550
|
+
function expireSession(response) {
|
|
551
|
+
auth.clearTokens();
|
|
552
|
+
for (const cb of Array.from(_sessionExpiredHandlers)) {
|
|
1647
553
|
try {
|
|
1648
|
-
|
|
1649
|
-
if (process.env.NEXT_PUBLIC_STATIC_BUILD === "true") return "";
|
|
1650
|
-
if (process.env.NEXT_PUBLIC_API_PROXY_URL !== void 0)
|
|
1651
|
-
return process.env.NEXT_PUBLIC_API_PROXY_URL;
|
|
1652
|
-
return process.env.NEXT_PUBLIC_API_URL || "";
|
|
1653
|
-
}
|
|
554
|
+
cb(response);
|
|
1654
555
|
} catch {
|
|
1655
556
|
}
|
|
1656
|
-
return "";
|
|
1657
557
|
}
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
558
|
+
if (_onUnauthorized) {
|
|
559
|
+
try {
|
|
560
|
+
_onUnauthorized(response);
|
|
561
|
+
} catch {
|
|
1662
562
|
}
|
|
1663
|
-
} catch {
|
|
1664
563
|
}
|
|
1665
|
-
return "";
|
|
1666
564
|
}
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
if (typeof process !== "undefined" && process.env?.NEXT_PUBLIC_API_KEY) {
|
|
1670
|
-
return process.env.NEXT_PUBLIC_API_KEY;
|
|
1671
|
-
}
|
|
1672
|
-
} catch {
|
|
1673
|
-
}
|
|
1674
|
-
return null;
|
|
1675
|
-
}
|
|
1676
|
-
function jwtExpMs(token) {
|
|
1677
|
-
try {
|
|
1678
|
-
const payload = token.split(".")[1];
|
|
1679
|
-
if (!payload) return null;
|
|
1680
|
-
const json = JSON.parse(atob(payload.replace(/-/g, "+").replace(/_/g, "/")));
|
|
1681
|
-
return typeof json.exp === "number" ? json.exp * 1e3 : null;
|
|
1682
|
-
} catch {
|
|
1683
|
-
return null;
|
|
1684
|
-
}
|
|
1685
|
-
}
|
|
1686
|
-
function computeSnapshot() {
|
|
1687
|
-
const access = _storage.get(ACCESS_KEY);
|
|
1688
|
-
const refresh = _storage.get(REFRESH_KEY);
|
|
1689
|
-
const now = Date.now();
|
|
1690
|
-
const accessExp = access ? jwtExpMs(access) : null;
|
|
1691
|
-
const accessAlive = access !== null && (accessExp === null || accessExp > now);
|
|
1692
|
-
const refreshExp = refresh ? jwtExpMs(refresh) : null;
|
|
1693
|
-
const refreshAlive = refresh !== null && (refreshExp === null || refreshExp > now);
|
|
1694
|
-
return {
|
|
1695
|
-
status: accessAlive || refreshAlive ? "authenticated" : "anonymous",
|
|
1696
|
-
accessExpiresAt: accessExp
|
|
1697
|
-
};
|
|
1698
|
-
}
|
|
1699
|
-
function scheduleExpiryFlip() {
|
|
1700
|
-
if (!isBrowser) return;
|
|
1701
|
-
if (_expiryTimer !== null) {
|
|
1702
|
-
clearTimeout(_expiryTimer);
|
|
1703
|
-
_expiryTimer = null;
|
|
1704
|
-
}
|
|
1705
|
-
if (_sessionListeners.size === 0) return;
|
|
1706
|
-
const now = Date.now();
|
|
1707
|
-
const exps = [];
|
|
1708
|
-
const access = _storage.get(ACCESS_KEY);
|
|
1709
|
-
const refresh = _storage.get(REFRESH_KEY);
|
|
1710
|
-
const accessExp = access ? jwtExpMs(access) : null;
|
|
1711
|
-
const refreshExp = refresh ? jwtExpMs(refresh) : null;
|
|
1712
|
-
if (accessExp !== null && accessExp > now) exps.push(accessExp);
|
|
1713
|
-
if (refreshExp !== null && refreshExp > now) exps.push(refreshExp);
|
|
1714
|
-
if (!exps.length) return;
|
|
1715
|
-
const delay = Math.min(Math.min(...exps) - now + 250, 2147483647);
|
|
1716
|
-
_expiryTimer = setTimeout(notifySessionChanged, delay);
|
|
1717
|
-
}
|
|
1718
|
-
function notifySessionChanged() {
|
|
1719
|
-
const next = computeSnapshot();
|
|
1720
|
-
const changed = next.status !== _snapshot.status || next.accessExpiresAt !== _snapshot.accessExpiresAt;
|
|
1721
|
-
if (changed) _snapshot = next;
|
|
1722
|
-
scheduleExpiryFlip();
|
|
1723
|
-
if (!changed) return;
|
|
1724
|
-
for (const listener of Array.from(_sessionListeners)) {
|
|
1725
|
-
try {
|
|
1726
|
-
listener();
|
|
1727
|
-
} catch {
|
|
1728
|
-
}
|
|
1729
|
-
}
|
|
1730
|
-
if (isBrowser) {
|
|
1731
|
-
try {
|
|
1732
|
-
window.dispatchEvent(new Event(SESSION_SYNC_EVENT));
|
|
1733
|
-
} catch {
|
|
1734
|
-
}
|
|
1735
|
-
}
|
|
1736
|
-
}
|
|
1737
|
-
function ensureStorageSync() {
|
|
1738
|
-
if (!isBrowser || _storageListenerInstalled) return;
|
|
1739
|
-
_storageListenerInstalled = true;
|
|
1740
|
-
window.addEventListener("storage", (e) => {
|
|
1741
|
-
if (e.key === null || e.key === ACCESS_KEY || e.key === REFRESH_KEY) {
|
|
1742
|
-
notifySessionChanged();
|
|
1743
|
-
}
|
|
1744
|
-
});
|
|
1745
|
-
window.addEventListener(SESSION_SYNC_EVENT, () => notifySessionChanged());
|
|
1746
|
-
}
|
|
1747
|
-
function pushClientConfig() {
|
|
1748
|
-
if (!_client) return;
|
|
1749
|
-
_client.setConfig({
|
|
1750
|
-
baseUrl: auth.getBaseUrl(),
|
|
1751
|
-
credentials: _withCredentials ? "include" : "same-origin"
|
|
1752
|
-
});
|
|
1753
|
-
}
|
|
1754
|
-
async function tryRefresh() {
|
|
1755
|
-
if (_refreshInflight) return _refreshInflight;
|
|
1756
|
-
if (!_refreshHandler) return null;
|
|
1757
|
-
const runRefresh = /* @__PURE__ */ __name(async () => {
|
|
1758
|
-
const refresh = auth.getRefreshToken();
|
|
1759
|
-
if (!refresh) return null;
|
|
1760
|
-
const result = await _refreshHandler(refresh);
|
|
1761
|
-
if (!result?.access) return null;
|
|
1762
|
-
auth.setToken(result.access);
|
|
1763
|
-
if (result.refresh) auth.setRefreshToken(result.refresh);
|
|
1764
|
-
return result.access;
|
|
1765
|
-
}, "runRefresh");
|
|
1766
|
-
_refreshInflight = (async () => {
|
|
1767
|
-
try {
|
|
1768
|
-
const locks = typeof navigator !== "undefined" ? navigator.locks : void 0;
|
|
1769
|
-
if (locks?.request) {
|
|
1770
|
-
return await locks.request(`${REFRESH_KEY}:refresh`, runRefresh);
|
|
1771
|
-
}
|
|
1772
|
-
return await runRefresh();
|
|
1773
|
-
} catch {
|
|
1774
|
-
return null;
|
|
1775
|
-
} finally {
|
|
1776
|
-
_refreshInflight = null;
|
|
1777
|
-
}
|
|
1778
|
-
})();
|
|
1779
|
-
return _refreshInflight;
|
|
1780
|
-
}
|
|
1781
|
-
function expireSession(response) {
|
|
1782
|
-
auth.clearTokens();
|
|
1783
|
-
for (const cb of Array.from(_sessionExpiredHandlers)) {
|
|
1784
|
-
try {
|
|
1785
|
-
cb(response);
|
|
1786
|
-
} catch {
|
|
1787
|
-
}
|
|
1788
|
-
}
|
|
1789
|
-
if (_onUnauthorized) {
|
|
1790
|
-
try {
|
|
1791
|
-
_onUnauthorized(response);
|
|
1792
|
-
} catch {
|
|
1793
|
-
}
|
|
1794
|
-
}
|
|
1795
|
-
}
|
|
1796
|
-
function dpopEnabled() {
|
|
565
|
+
__name(expireSession, "expireSession");
|
|
566
|
+
function dpopEnabled() {
|
|
1797
567
|
try {
|
|
1798
568
|
return typeof process !== "undefined" && process.env?.NEXT_PUBLIC_DPOP_ENABLED === "true";
|
|
1799
569
|
} catch {
|
|
1800
570
|
return false;
|
|
1801
571
|
}
|
|
1802
572
|
}
|
|
573
|
+
__name(dpopEnabled, "dpopEnabled");
|
|
574
|
+
var _DPOP_DB = "cfg-auth";
|
|
575
|
+
var _DPOP_STORE = "keys";
|
|
576
|
+
var _DPOP_KEY_ID = "dpop-ec-p256";
|
|
1803
577
|
function _idbOpen() {
|
|
1804
578
|
return new Promise((resolve, reject) => {
|
|
1805
579
|
const req = indexedDB.open(_DPOP_DB, 1);
|
|
@@ -1808,6 +582,7 @@ function _idbOpen() {
|
|
|
1808
582
|
req.onerror = () => reject(req.error);
|
|
1809
583
|
});
|
|
1810
584
|
}
|
|
585
|
+
__name(_idbOpen, "_idbOpen");
|
|
1811
586
|
function _idbGet(key) {
|
|
1812
587
|
return _idbOpen().then((db) => new Promise((resolve, reject) => {
|
|
1813
588
|
const tx = db.transaction(_DPOP_STORE, "readonly");
|
|
@@ -1816,6 +591,7 @@ function _idbGet(key) {
|
|
|
1816
591
|
req.onerror = () => reject(req.error);
|
|
1817
592
|
}));
|
|
1818
593
|
}
|
|
594
|
+
__name(_idbGet, "_idbGet");
|
|
1819
595
|
function _idbPut(key, value) {
|
|
1820
596
|
return _idbOpen().then((db) => new Promise((resolve, reject) => {
|
|
1821
597
|
const tx = db.transaction(_DPOP_STORE, "readwrite");
|
|
@@ -1824,6 +600,8 @@ function _idbPut(key, value) {
|
|
|
1824
600
|
tx.onerror = () => reject(tx.error);
|
|
1825
601
|
}));
|
|
1826
602
|
}
|
|
603
|
+
__name(_idbPut, "_idbPut");
|
|
604
|
+
var _dpopKeyPromise = null;
|
|
1827
605
|
function _getDpopKeyPair() {
|
|
1828
606
|
if (_dpopKeyPromise) return _dpopKeyPromise;
|
|
1829
607
|
_dpopKeyPromise = (async () => {
|
|
@@ -1841,19 +619,23 @@ function _getDpopKeyPair() {
|
|
|
1841
619
|
})();
|
|
1842
620
|
return _dpopKeyPromise;
|
|
1843
621
|
}
|
|
622
|
+
__name(_getDpopKeyPair, "_getDpopKeyPair");
|
|
1844
623
|
function _b64urlFromBytes(bytes) {
|
|
1845
624
|
const arr = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
|
|
1846
625
|
let s = "";
|
|
1847
626
|
for (let i = 0; i < arr.length; i++) s += String.fromCharCode(arr[i]);
|
|
1848
627
|
return btoa(s).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
1849
628
|
}
|
|
629
|
+
__name(_b64urlFromBytes, "_b64urlFromBytes");
|
|
1850
630
|
function _b64urlFromString(str) {
|
|
1851
631
|
return _b64urlFromBytes(new TextEncoder().encode(str));
|
|
1852
632
|
}
|
|
633
|
+
__name(_b64urlFromString, "_b64urlFromString");
|
|
1853
634
|
async function _publicJwk(pub) {
|
|
1854
635
|
const jwk = await crypto.subtle.exportKey("jwk", pub);
|
|
1855
636
|
return { kty: "EC", crv: "P-256", x: jwk.x, y: jwk.y };
|
|
1856
637
|
}
|
|
638
|
+
__name(_publicJwk, "_publicJwk");
|
|
1857
639
|
async function _makeDpopProof(method, url) {
|
|
1858
640
|
try {
|
|
1859
641
|
const pair = await _getDpopKeyPair();
|
|
@@ -1873,6 +655,7 @@ async function _makeDpopProof(method, url) {
|
|
|
1873
655
|
return null;
|
|
1874
656
|
}
|
|
1875
657
|
}
|
|
658
|
+
__name(_makeDpopProof, "_makeDpopProof");
|
|
1876
659
|
function installAuthOnClient(client2) {
|
|
1877
660
|
if (_client) return;
|
|
1878
661
|
_client = client2;
|
|
@@ -1933,356 +716,30 @@ function installAuthOnClient(client2) {
|
|
|
1933
716
|
}
|
|
1934
717
|
});
|
|
1935
718
|
}
|
|
1936
|
-
|
|
1937
|
-
var
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
}
|
|
1952
|
-
},
|
|
1953
|
-
set(key, value) {
|
|
1954
|
-
if (!isBrowser) return;
|
|
1955
|
-
try {
|
|
1956
|
-
if (value === null) window.localStorage.removeItem(key);
|
|
1957
|
-
else window.localStorage.setItem(key, value);
|
|
1958
|
-
} catch {
|
|
1959
|
-
}
|
|
1960
|
-
}
|
|
1961
|
-
};
|
|
1962
|
-
COOKIE_MAX_AGE = 60 * 60 * 24 * 30;
|
|
1963
|
-
cookieBackend = {
|
|
1964
|
-
get(key) {
|
|
1965
|
-
if (!isBrowser) return null;
|
|
1966
|
-
try {
|
|
1967
|
-
const re = new RegExp(`(?:^|;\\s*)${encodeURIComponent(key)}=([^;]*)`);
|
|
1968
|
-
const m = document.cookie.match(re);
|
|
1969
|
-
return m ? decodeURIComponent(m[1]) : null;
|
|
1970
|
-
} catch {
|
|
1971
|
-
return null;
|
|
1972
|
-
}
|
|
1973
|
-
},
|
|
1974
|
-
set(key, value) {
|
|
1975
|
-
if (!isBrowser) return;
|
|
1976
|
-
try {
|
|
1977
|
-
const k = encodeURIComponent(key);
|
|
1978
|
-
const secure = window.location.protocol === "https:" ? "; Secure" : "";
|
|
1979
|
-
if (value === null) {
|
|
1980
|
-
document.cookie = `${k}=; Path=/; Max-Age=0; SameSite=Lax${secure}`;
|
|
1981
|
-
} else {
|
|
1982
|
-
const v = encodeURIComponent(value);
|
|
1983
|
-
document.cookie = `${k}=${v}; Path=/; Max-Age=${COOKIE_MAX_AGE}; SameSite=Lax${secure}`;
|
|
1984
|
-
}
|
|
1985
|
-
} catch {
|
|
1986
|
-
}
|
|
1987
|
-
}
|
|
1988
|
-
};
|
|
1989
|
-
_storage = localStorageBackend;
|
|
1990
|
-
_storageMode = "localStorage";
|
|
1991
|
-
__name(detectLocale, "detectLocale");
|
|
1992
|
-
__name(defaultBaseUrl, "defaultBaseUrl");
|
|
1993
|
-
__name(defaultApiKey, "defaultApiKey");
|
|
1994
|
-
_localeOverride = null;
|
|
1995
|
-
_apiKeyOverride = null;
|
|
1996
|
-
_baseUrlOverride = null;
|
|
1997
|
-
_withCredentials = true;
|
|
1998
|
-
_onUnauthorized = null;
|
|
1999
|
-
_refreshHandler = null;
|
|
2000
|
-
_refreshInflight = null;
|
|
2001
|
-
RETRY_MARKER = "X-Auth-Retry";
|
|
2002
|
-
__name(jwtExpMs, "jwtExpMs");
|
|
2003
|
-
__name(computeSnapshot, "computeSnapshot");
|
|
2004
|
-
SERVER_SNAPSHOT = { status: "anonymous", accessExpiresAt: null };
|
|
2005
|
-
SESSION_SYNC_EVENT = `cfg-auth:changed:${ACCESS_KEY}`;
|
|
2006
|
-
_snapshot = computeSnapshot();
|
|
2007
|
-
_sessionListeners = /* @__PURE__ */ new Set();
|
|
2008
|
-
_expiryTimer = null;
|
|
2009
|
-
_storageListenerInstalled = false;
|
|
2010
|
-
__name(scheduleExpiryFlip, "scheduleExpiryFlip");
|
|
2011
|
-
__name(notifySessionChanged, "notifySessionChanged");
|
|
2012
|
-
__name(ensureStorageSync, "ensureStorageSync");
|
|
2013
|
-
_sessionExpiredHandlers = /* @__PURE__ */ new Set();
|
|
2014
|
-
_client = null;
|
|
2015
|
-
__name(pushClientConfig, "pushClientConfig");
|
|
2016
|
-
auth = {
|
|
2017
|
-
// ── Storage mode ──────────────────────────────────────────────────
|
|
2018
|
-
getStorageMode() {
|
|
2019
|
-
return _storageMode;
|
|
2020
|
-
},
|
|
2021
|
-
setStorageMode(mode) {
|
|
2022
|
-
_storageMode = mode;
|
|
2023
|
-
_storage = mode === "cookie" ? cookieBackend : localStorageBackend;
|
|
2024
|
-
notifySessionChanged();
|
|
2025
|
-
},
|
|
2026
|
-
// ── Bearer token ──────────────────────────────────────────────────
|
|
2027
|
-
getToken() {
|
|
2028
|
-
return _storage.get(ACCESS_KEY);
|
|
2029
|
-
},
|
|
2030
|
-
setToken(token) {
|
|
2031
|
-
_storage.set(ACCESS_KEY, token);
|
|
2032
|
-
notifySessionChanged();
|
|
2033
|
-
},
|
|
2034
|
-
getRefreshToken() {
|
|
2035
|
-
return _storage.get(REFRESH_KEY);
|
|
2036
|
-
},
|
|
2037
|
-
setRefreshToken(token) {
|
|
2038
|
-
_storage.set(REFRESH_KEY, token);
|
|
2039
|
-
notifySessionChanged();
|
|
2040
|
-
},
|
|
2041
|
-
clearTokens() {
|
|
2042
|
-
_storage.set(ACCESS_KEY, null);
|
|
2043
|
-
_storage.set(REFRESH_KEY, null);
|
|
2044
|
-
notifySessionChanged();
|
|
2045
|
-
},
|
|
2046
|
-
/** Session-aware: token PRESENT and not past its `exp` (or a live refresh
|
|
2047
|
-
* token exists that can mint one). Prefer `getSnapshot().status` in React. */
|
|
2048
|
-
isAuthenticated() {
|
|
2049
|
-
return computeSnapshot().status === "authenticated";
|
|
2050
|
-
},
|
|
2051
|
-
// ── Session (the ONE write path for login/logout flows) ──────────
|
|
2052
|
-
/**
|
|
2053
|
-
* Persist a token pair atomically. Every login flow (OTP verify, 2FA,
|
|
2054
|
-
* OAuth callback) and the refresh handler should end here — do NOT
|
|
2055
|
-
* scatter `setToken`/`setRefreshToken` pairs through app code.
|
|
2056
|
-
* `refresh: undefined` keeps the current refresh token (access-only
|
|
2057
|
-
* rotation); `refresh: null` explicitly drops it.
|
|
2058
|
-
*/
|
|
2059
|
-
setSession(tokens) {
|
|
2060
|
-
_storage.set(ACCESS_KEY, tokens.access);
|
|
2061
|
-
if (tokens.refresh !== void 0) _storage.set(REFRESH_KEY, tokens.refresh);
|
|
2062
|
-
notifySessionChanged();
|
|
2063
|
-
},
|
|
2064
|
-
clearSession() {
|
|
2065
|
-
auth.clearTokens();
|
|
2066
|
-
},
|
|
2067
|
-
// ── Reactive snapshot (for useSyncExternalStore) ──────────────────
|
|
2068
|
-
/**
|
|
2069
|
-
* @example React:
|
|
2070
|
-
* const session = useSyncExternalStore(
|
|
2071
|
-
* auth.subscribe, auth.getSnapshot, auth.getServerSnapshot,
|
|
2072
|
-
* );
|
|
2073
|
-
* const isAuthenticated = session.status === 'authenticated';
|
|
2074
|
-
*/
|
|
2075
|
-
getSnapshot() {
|
|
2076
|
-
return _snapshot;
|
|
2077
|
-
},
|
|
2078
|
-
getServerSnapshot() {
|
|
2079
|
-
return SERVER_SNAPSHOT;
|
|
2080
|
-
},
|
|
2081
|
-
subscribe(listener) {
|
|
2082
|
-
ensureStorageSync();
|
|
2083
|
-
_sessionListeners.add(listener);
|
|
2084
|
-
notifySessionChanged();
|
|
2085
|
-
return () => {
|
|
2086
|
-
_sessionListeners.delete(listener);
|
|
2087
|
-
if (_sessionListeners.size === 0 && _expiryTimer !== null) {
|
|
2088
|
-
clearTimeout(_expiryTimer);
|
|
2089
|
-
_expiryTimer = null;
|
|
2090
|
-
}
|
|
2091
|
-
};
|
|
2092
|
-
},
|
|
2093
|
-
/**
|
|
2094
|
-
* Fired on TERMINAL 401 — after the refresh+retry path is exhausted.
|
|
2095
|
-
* The store has already cleared the session before calling back, so
|
|
2096
|
-
* handlers only need to route to login (no clear-then-redirect
|
|
2097
|
-
* ordering to get wrong). Returns an unsubscribe function; multiple
|
|
2098
|
-
* handlers compose (unlike the legacy single-slot `onUnauthorized`).
|
|
2099
|
-
*/
|
|
2100
|
-
onSessionExpired(cb) {
|
|
2101
|
-
_sessionExpiredHandlers.add(cb);
|
|
2102
|
-
return () => {
|
|
2103
|
-
_sessionExpiredHandlers.delete(cb);
|
|
2104
|
-
};
|
|
2105
|
-
},
|
|
2106
|
-
// ── API key ───────────────────────────────────────────────────────
|
|
2107
|
-
getApiKey() {
|
|
2108
|
-
return _apiKeyOverride ?? _storage.get(API_KEY_KEY) ?? defaultApiKey();
|
|
2109
|
-
},
|
|
2110
|
-
setApiKey(key) {
|
|
2111
|
-
_apiKeyOverride = key;
|
|
2112
|
-
},
|
|
2113
|
-
setApiKeyPersist(key) {
|
|
2114
|
-
_apiKeyOverride = key;
|
|
2115
|
-
_storage.set(API_KEY_KEY, key);
|
|
2116
|
-
},
|
|
2117
|
-
clearApiKey() {
|
|
2118
|
-
_apiKeyOverride = null;
|
|
2119
|
-
_storage.set(API_KEY_KEY, null);
|
|
2120
|
-
},
|
|
2121
|
-
// ── Locale ────────────────────────────────────────────────────────
|
|
2122
|
-
getLocale() {
|
|
2123
|
-
return _localeOverride ?? detectLocale();
|
|
2124
|
-
},
|
|
2125
|
-
setLocale(locale) {
|
|
2126
|
-
_localeOverride = locale;
|
|
2127
|
-
},
|
|
2128
|
-
// ── Base URL ──────────────────────────────────────────────────────
|
|
2129
|
-
getBaseUrl() {
|
|
2130
|
-
const url = _baseUrlOverride ?? defaultBaseUrl();
|
|
2131
|
-
return url.replace(/\/$/, "");
|
|
2132
|
-
},
|
|
2133
|
-
setBaseUrl(url) {
|
|
2134
|
-
_baseUrlOverride = url ? url.replace(/\/$/, "") : null;
|
|
2135
|
-
pushClientConfig();
|
|
2136
|
-
},
|
|
2137
|
-
// ── Credentials toggle ────────────────────────────────────────────
|
|
2138
|
-
getWithCredentials() {
|
|
2139
|
-
return _withCredentials;
|
|
2140
|
-
},
|
|
2141
|
-
setWithCredentials(value) {
|
|
2142
|
-
_withCredentials = value;
|
|
2143
|
-
pushClientConfig();
|
|
2144
|
-
},
|
|
2145
|
-
// ── 401 handler ───────────────────────────────────────────────────
|
|
2146
|
-
/**
|
|
2147
|
-
* Fired when the server returns 401 AND no refresh path recovers it
|
|
2148
|
-
* (no refresh token, no refresh handler, refresh failed, or retry
|
|
2149
|
-
* still 401). The app should clear local state and redirect to login.
|
|
2150
|
-
*
|
|
2151
|
-
* NOT fired for 401 that gets transparently recovered by the refresh
|
|
2152
|
-
* handler — those are invisible to callers.
|
|
2153
|
-
*/
|
|
2154
|
-
onUnauthorized(cb) {
|
|
2155
|
-
_onUnauthorized = cb;
|
|
2156
|
-
},
|
|
2157
|
-
/**
|
|
2158
|
-
* Register the refresh strategy. The handler receives the current
|
|
2159
|
-
* refresh token and must call your refresh endpoint, returning
|
|
2160
|
-
* `{ access, refresh? }` on success or `null` on failure.
|
|
2161
|
-
*
|
|
2162
|
-
* @example
|
|
2163
|
-
* auth.setRefreshHandler(async (refresh) => {
|
|
2164
|
-
* const { data } = await Auth.tokenRefreshCreate({ body: { refresh } });
|
|
2165
|
-
* return data ? { access: data.access, refresh: data.refresh } : null;
|
|
2166
|
-
* });
|
|
2167
|
-
*/
|
|
2168
|
-
setRefreshHandler(fn) {
|
|
2169
|
-
_refreshHandler = fn;
|
|
2170
|
-
},
|
|
2171
|
-
/**
|
|
2172
|
-
* Proactively run the registered refresh handler right now, reusing the
|
|
2173
|
-
* SAME single-flight promise as the 401-recovery interceptor. Callers
|
|
2174
|
-
* (e.g. an expiry timer / focus / reconnect) get token rotation,
|
|
2175
|
-
* de-duplication and rotated-token persistence for free — they must NOT
|
|
2176
|
-
* re-implement any of it. Returns the fresh access token, or null if
|
|
2177
|
-
* there is no handler / no refresh token / the refresh failed.
|
|
2178
|
-
*/
|
|
2179
|
-
refreshNow() {
|
|
2180
|
-
return tryRefresh();
|
|
2181
|
-
}
|
|
2182
|
-
};
|
|
2183
|
-
__name(tryRefresh, "tryRefresh");
|
|
2184
|
-
__name(expireSession, "expireSession");
|
|
2185
|
-
__name(dpopEnabled, "dpopEnabled");
|
|
2186
|
-
_DPOP_DB = "cfg-auth";
|
|
2187
|
-
_DPOP_STORE = "keys";
|
|
2188
|
-
_DPOP_KEY_ID = "dpop-ec-p256";
|
|
2189
|
-
__name(_idbOpen, "_idbOpen");
|
|
2190
|
-
__name(_idbGet, "_idbGet");
|
|
2191
|
-
__name(_idbPut, "_idbPut");
|
|
2192
|
-
_dpopKeyPromise = null;
|
|
2193
|
-
__name(_getDpopKeyPair, "_getDpopKeyPair");
|
|
2194
|
-
__name(_b64urlFromBytes, "_b64urlFromBytes");
|
|
2195
|
-
__name(_b64urlFromString, "_b64urlFromString");
|
|
2196
|
-
__name(_publicJwk, "_publicJwk");
|
|
2197
|
-
__name(_makeDpopProof, "_makeDpopProof");
|
|
2198
|
-
__name(installAuthOnClient, "installAuthOnClient");
|
|
2199
|
-
auth.setRefreshHandler(async (refresh) => {
|
|
2200
|
-
try {
|
|
2201
|
-
const { CfgAccountsAuth: CfgAccountsAuth2 } = await Promise.resolve().then(() => (init_sdk_gen(), sdk_gen_exports));
|
|
2202
|
-
const { data } = await CfgAccountsAuth2.cfgAccountsTokenRefreshCreate({
|
|
2203
|
-
body: { refresh },
|
|
2204
|
-
throwOnError: true
|
|
2205
|
-
});
|
|
2206
|
-
return data?.access ? { access: data.access, refresh: data.refresh ?? refresh } : null;
|
|
2207
|
-
} catch {
|
|
2208
|
-
return null;
|
|
2209
|
-
}
|
|
719
|
+
__name(installAuthOnClient, "installAuthOnClient");
|
|
720
|
+
var REFRESH_ENDPOINT = "/cfg/accounts/token/refresh/";
|
|
721
|
+
auth.setRefreshHandler(async (refresh) => {
|
|
722
|
+
try {
|
|
723
|
+
const url = `${auth.getBaseUrl()}${REFRESH_ENDPOINT}`;
|
|
724
|
+
const headers = { "Content-Type": "application/json" };
|
|
725
|
+
if (dpopEnabled() && typeof window !== "undefined") {
|
|
726
|
+
const proof = await _makeDpopProof("POST", url);
|
|
727
|
+
if (proof) headers["DPoP"] = proof;
|
|
728
|
+
}
|
|
729
|
+
const res = await fetch(url, {
|
|
730
|
+
method: "POST",
|
|
731
|
+
headers,
|
|
732
|
+
credentials: auth.getWithCredentials() ? "include" : "same-origin",
|
|
733
|
+
body: JSON.stringify({ refresh })
|
|
2210
734
|
});
|
|
735
|
+
if (!res.ok) return null;
|
|
736
|
+
const data = await res.json();
|
|
737
|
+
return data?.access ? { access: data.access, refresh: data.refresh ?? refresh } : null;
|
|
738
|
+
} catch {
|
|
739
|
+
return null;
|
|
2211
740
|
}
|
|
2212
741
|
});
|
|
2213
742
|
|
|
2214
|
-
// src/auth/index.ts
|
|
2215
|
-
var auth_exports = {};
|
|
2216
|
-
__export(auth_exports, {
|
|
2217
|
-
AUTH_CONSTANTS: () => AUTH_CONSTANTS,
|
|
2218
|
-
AccountsProvider: () => AccountsProvider,
|
|
2219
|
-
Analytics: () => Analytics,
|
|
2220
|
-
AnalyticsCategory: () => AnalyticsCategory,
|
|
2221
|
-
AnalyticsEvent: () => AnalyticsEvent,
|
|
2222
|
-
AuthContext: () => AuthContext_default,
|
|
2223
|
-
AuthProvider: () => AuthProvider,
|
|
2224
|
-
DEFAULT_AUTH_PATH: () => DEFAULT_AUTH_PATH,
|
|
2225
|
-
DEFAULT_CALLBACK_PATH: () => DEFAULT_CALLBACK_PATH,
|
|
2226
|
-
PatchedCfgUserUpdateRequestSchema: () => PatchedCfgUserUpdateRequestSchema,
|
|
2227
|
-
authLogger: () => authLogger,
|
|
2228
|
-
clearProfileCache: () => clearProfileCache,
|
|
2229
|
-
decodeBase64: () => decodeBase64,
|
|
2230
|
-
encodeBase64: () => encodeBase64,
|
|
2231
|
-
formatAuthError: () => formatAuthError,
|
|
2232
|
-
getCacheMetadata: () => getCacheMetadata,
|
|
2233
|
-
getCachedProfile: () => getCachedProfile,
|
|
2234
|
-
hasValidCache: () => hasValidCache,
|
|
2235
|
-
isAllowedAuthPath: () => isAllowedAuthPath,
|
|
2236
|
-
logger: () => logger,
|
|
2237
|
-
normalizePath: () => normalizePath,
|
|
2238
|
-
resolveGuardIsAuthenticated: () => resolveGuardIsAuthenticated,
|
|
2239
|
-
resolveGuardIsLoading: () => resolveGuardIsLoading,
|
|
2240
|
-
setCachedProfile: () => setCachedProfile,
|
|
2241
|
-
shouldRedirectToAuth: () => shouldRedirectToAuth,
|
|
2242
|
-
useAccountsContext: () => useAccountsContext,
|
|
2243
|
-
useAuth: () => useAuth,
|
|
2244
|
-
useAuthForm: () => useAuthForm,
|
|
2245
|
-
useAuthFormState: () => useAuthFormState,
|
|
2246
|
-
useAuthRedirectManager: () => useAuthRedirectManager,
|
|
2247
|
-
useAuthValidation: () => useAuthValidation,
|
|
2248
|
-
useAutoAuth: () => useAutoAuth,
|
|
2249
|
-
useBase64: () => useBase64,
|
|
2250
|
-
useCfgRouter: () => useCfgRouter,
|
|
2251
|
-
useDeleteAccount: () => useDeleteAccount,
|
|
2252
|
-
useGithubAuth: () => useGithubAuth,
|
|
2253
|
-
useLocalStorage: () => useLocalStorage,
|
|
2254
|
-
useQueryParams: () => useQueryParams,
|
|
2255
|
-
useSession: () => useSession,
|
|
2256
|
-
useSessionStorage: () => useSessionStorage,
|
|
2257
|
-
useTwoFactor: () => useTwoFactor,
|
|
2258
|
-
useTwoFactorSetup: () => useTwoFactorSetup,
|
|
2259
|
-
useTwoFactorStatus: () => useTwoFactorStatus,
|
|
2260
|
-
validateEmail: () => validateEmail,
|
|
2261
|
-
validateIdentifier: () => validateIdentifier
|
|
2262
|
-
});
|
|
2263
|
-
module.exports = __toCommonJS(auth_exports);
|
|
2264
|
-
|
|
2265
|
-
// src/auth/constants.ts
|
|
2266
|
-
var AUTH_CONSTANTS = {
|
|
2267
|
-
/** Email OTP code length (numeric). */
|
|
2268
|
-
EMAIL_OTP_LENGTH: 4,
|
|
2269
|
-
/** TOTP code length (RFC 6238 — authenticator apps). */
|
|
2270
|
-
TOTP_LENGTH: 6,
|
|
2271
|
-
/** Backup code max length. */
|
|
2272
|
-
BACKUP_CODE_MAX_LENGTH: 12
|
|
2273
|
-
};
|
|
2274
|
-
var DEFAULT_AUTH_PATH = "/auth";
|
|
2275
|
-
var DEFAULT_CALLBACK_PATH = "/dashboard";
|
|
2276
|
-
|
|
2277
|
-
// src/auth/context/AuthContext.tsx
|
|
2278
|
-
var import_navigation4 = require("next/navigation");
|
|
2279
|
-
var import_react16 = require("react");
|
|
2280
|
-
init_auth();
|
|
2281
|
-
|
|
2282
|
-
// src/_api/generated/helpers/index.ts
|
|
2283
|
-
init_auth();
|
|
2284
|
-
init_errors();
|
|
2285
|
-
|
|
2286
743
|
// src/_api/generated/helpers/logger.ts
|
|
2287
744
|
var import_consola = require("consola");
|
|
2288
745
|
var DEFAULT_CONFIG = {
|
|
@@ -2423,7 +880,6 @@ __name(applyRoleLogPolicy, "applyRoleLogPolicy");
|
|
|
2423
880
|
|
|
2424
881
|
// src/auth/hooks/useSession.ts
|
|
2425
882
|
var import_react = require("react");
|
|
2426
|
-
init_auth();
|
|
2427
883
|
function useSession() {
|
|
2428
884
|
return (0, import_react.useSyncExternalStore)(auth.subscribe, auth.getSnapshot, auth.getServerSnapshot);
|
|
2429
885
|
}
|
|
@@ -2628,7 +1084,7 @@ var useAuthValidation = /* @__PURE__ */ __name(() => {
|
|
|
2628
1084
|
var validateIdentifier = /* @__PURE__ */ __name((id) => EMAIL_REGEX.test(id), "validateIdentifier");
|
|
2629
1085
|
|
|
2630
1086
|
// src/auth/hooks/useAuthForm.ts
|
|
2631
|
-
var
|
|
1087
|
+
var import_react9 = require("react");
|
|
2632
1088
|
|
|
2633
1089
|
// src/auth/utils/logger.ts
|
|
2634
1090
|
var import_consola2 = require("consola");
|
|
@@ -2694,9 +1150,1290 @@ var useAutoAuth = /* @__PURE__ */ __name((options = {}) => {
|
|
|
2694
1150
|
}, "useAutoAuth");
|
|
2695
1151
|
|
|
2696
1152
|
// src/auth/hooks/useTwoFactor.ts
|
|
2697
|
-
var
|
|
2698
|
-
|
|
2699
|
-
|
|
1153
|
+
var import_react8 = require("react");
|
|
1154
|
+
|
|
1155
|
+
// src/_api/generated/core/bodySerializer.gen.ts
|
|
1156
|
+
var serializeFormDataPair = /* @__PURE__ */ __name((data, key, value) => {
|
|
1157
|
+
if (typeof value === "string" || value instanceof Blob) {
|
|
1158
|
+
data.append(key, value);
|
|
1159
|
+
} else if (value instanceof Date) {
|
|
1160
|
+
data.append(key, value.toISOString());
|
|
1161
|
+
} else {
|
|
1162
|
+
data.append(key, JSON.stringify(value));
|
|
1163
|
+
}
|
|
1164
|
+
}, "serializeFormDataPair");
|
|
1165
|
+
var formDataBodySerializer = {
|
|
1166
|
+
bodySerializer: /* @__PURE__ */ __name((body) => {
|
|
1167
|
+
const data = new FormData();
|
|
1168
|
+
Object.entries(body).forEach(([key, value]) => {
|
|
1169
|
+
if (value === void 0 || value === null) {
|
|
1170
|
+
return;
|
|
1171
|
+
}
|
|
1172
|
+
if (Array.isArray(value)) {
|
|
1173
|
+
value.forEach((v) => serializeFormDataPair(data, key, v));
|
|
1174
|
+
} else {
|
|
1175
|
+
serializeFormDataPair(data, key, value);
|
|
1176
|
+
}
|
|
1177
|
+
});
|
|
1178
|
+
return data;
|
|
1179
|
+
}, "bodySerializer")
|
|
1180
|
+
};
|
|
1181
|
+
var jsonBodySerializer = {
|
|
1182
|
+
bodySerializer: /* @__PURE__ */ __name((body) => JSON.stringify(body, (_key, value) => typeof value === "bigint" ? value.toString() : value), "bodySerializer")
|
|
1183
|
+
};
|
|
1184
|
+
|
|
1185
|
+
// src/_api/generated/core/params.gen.ts
|
|
1186
|
+
var extraPrefixesMap = {
|
|
1187
|
+
$body_: "body",
|
|
1188
|
+
$headers_: "headers",
|
|
1189
|
+
$path_: "path",
|
|
1190
|
+
$query_: "query"
|
|
1191
|
+
};
|
|
1192
|
+
var extraPrefixes = Object.entries(extraPrefixesMap);
|
|
1193
|
+
|
|
1194
|
+
// src/_api/generated/core/serverSentEvents.gen.ts
|
|
1195
|
+
function createSseClient({
|
|
1196
|
+
onRequest,
|
|
1197
|
+
onSseError,
|
|
1198
|
+
onSseEvent,
|
|
1199
|
+
responseTransformer,
|
|
1200
|
+
responseValidator,
|
|
1201
|
+
sseDefaultRetryDelay,
|
|
1202
|
+
sseMaxRetryAttempts,
|
|
1203
|
+
sseMaxRetryDelay,
|
|
1204
|
+
sseSleepFn,
|
|
1205
|
+
url,
|
|
1206
|
+
...options
|
|
1207
|
+
}) {
|
|
1208
|
+
let lastEventId;
|
|
1209
|
+
const sleep = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
1210
|
+
const createStream = /* @__PURE__ */ __name(async function* () {
|
|
1211
|
+
let retryDelay = sseDefaultRetryDelay ?? 3e3;
|
|
1212
|
+
let attempt = 0;
|
|
1213
|
+
const signal = options.signal ?? new AbortController().signal;
|
|
1214
|
+
while (true) {
|
|
1215
|
+
if (signal.aborted) break;
|
|
1216
|
+
attempt++;
|
|
1217
|
+
const headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers);
|
|
1218
|
+
if (lastEventId !== void 0) {
|
|
1219
|
+
headers.set("Last-Event-ID", lastEventId);
|
|
1220
|
+
}
|
|
1221
|
+
try {
|
|
1222
|
+
const requestInit = {
|
|
1223
|
+
redirect: "follow",
|
|
1224
|
+
...options,
|
|
1225
|
+
body: options.serializedBody,
|
|
1226
|
+
headers,
|
|
1227
|
+
signal
|
|
1228
|
+
};
|
|
1229
|
+
let request = new Request(url, requestInit);
|
|
1230
|
+
if (onRequest) {
|
|
1231
|
+
request = await onRequest(url, requestInit);
|
|
1232
|
+
}
|
|
1233
|
+
const _fetch = options.fetch ?? globalThis.fetch;
|
|
1234
|
+
const response = await _fetch(request);
|
|
1235
|
+
if (!response.ok) throw new Error(`SSE failed: ${response.status} ${response.statusText}`);
|
|
1236
|
+
if (!response.body) throw new Error("No body in SSE response");
|
|
1237
|
+
const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
|
|
1238
|
+
let buffer = "";
|
|
1239
|
+
const abortHandler = /* @__PURE__ */ __name(() => {
|
|
1240
|
+
try {
|
|
1241
|
+
reader.cancel();
|
|
1242
|
+
} catch {
|
|
1243
|
+
}
|
|
1244
|
+
}, "abortHandler");
|
|
1245
|
+
signal.addEventListener("abort", abortHandler);
|
|
1246
|
+
try {
|
|
1247
|
+
while (true) {
|
|
1248
|
+
const { done, value } = await reader.read();
|
|
1249
|
+
if (done) break;
|
|
1250
|
+
buffer += value;
|
|
1251
|
+
buffer = buffer.replace(/\r\n?/g, "\n");
|
|
1252
|
+
const chunks = buffer.split("\n\n");
|
|
1253
|
+
buffer = chunks.pop() ?? "";
|
|
1254
|
+
for (const chunk of chunks) {
|
|
1255
|
+
const lines = chunk.split("\n");
|
|
1256
|
+
const dataLines = [];
|
|
1257
|
+
let eventName;
|
|
1258
|
+
for (const line of lines) {
|
|
1259
|
+
if (line.startsWith("data:")) {
|
|
1260
|
+
dataLines.push(line.replace(/^data:\s*/, ""));
|
|
1261
|
+
} else if (line.startsWith("event:")) {
|
|
1262
|
+
eventName = line.replace(/^event:\s*/, "");
|
|
1263
|
+
} else if (line.startsWith("id:")) {
|
|
1264
|
+
lastEventId = line.replace(/^id:\s*/, "");
|
|
1265
|
+
} else if (line.startsWith("retry:")) {
|
|
1266
|
+
const parsed = Number.parseInt(line.replace(/^retry:\s*/, ""), 10);
|
|
1267
|
+
if (!Number.isNaN(parsed)) {
|
|
1268
|
+
retryDelay = parsed;
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
let data;
|
|
1273
|
+
let parsedJson = false;
|
|
1274
|
+
if (dataLines.length) {
|
|
1275
|
+
const rawData = dataLines.join("\n");
|
|
1276
|
+
try {
|
|
1277
|
+
data = JSON.parse(rawData);
|
|
1278
|
+
parsedJson = true;
|
|
1279
|
+
} catch {
|
|
1280
|
+
data = rawData;
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
if (parsedJson) {
|
|
1284
|
+
if (responseValidator) {
|
|
1285
|
+
await responseValidator(data);
|
|
1286
|
+
}
|
|
1287
|
+
if (responseTransformer) {
|
|
1288
|
+
data = await responseTransformer(data);
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
onSseEvent?.({
|
|
1292
|
+
data,
|
|
1293
|
+
event: eventName,
|
|
1294
|
+
id: lastEventId,
|
|
1295
|
+
retry: retryDelay
|
|
1296
|
+
});
|
|
1297
|
+
if (dataLines.length) {
|
|
1298
|
+
yield data;
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
} finally {
|
|
1303
|
+
signal.removeEventListener("abort", abortHandler);
|
|
1304
|
+
reader.releaseLock();
|
|
1305
|
+
}
|
|
1306
|
+
break;
|
|
1307
|
+
} catch (error) {
|
|
1308
|
+
onSseError?.(error);
|
|
1309
|
+
if (sseMaxRetryAttempts !== void 0 && attempt >= sseMaxRetryAttempts) {
|
|
1310
|
+
break;
|
|
1311
|
+
}
|
|
1312
|
+
const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 3e4);
|
|
1313
|
+
await sleep(backoff);
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
}, "createStream");
|
|
1317
|
+
const stream = createStream();
|
|
1318
|
+
return { stream };
|
|
1319
|
+
}
|
|
1320
|
+
__name(createSseClient, "createSseClient");
|
|
1321
|
+
|
|
1322
|
+
// src/_api/generated/core/pathSerializer.gen.ts
|
|
1323
|
+
var separatorArrayExplode = /* @__PURE__ */ __name((style) => {
|
|
1324
|
+
switch (style) {
|
|
1325
|
+
case "label":
|
|
1326
|
+
return ".";
|
|
1327
|
+
case "matrix":
|
|
1328
|
+
return ";";
|
|
1329
|
+
case "simple":
|
|
1330
|
+
return ",";
|
|
1331
|
+
default:
|
|
1332
|
+
return "&";
|
|
1333
|
+
}
|
|
1334
|
+
}, "separatorArrayExplode");
|
|
1335
|
+
var separatorArrayNoExplode = /* @__PURE__ */ __name((style) => {
|
|
1336
|
+
switch (style) {
|
|
1337
|
+
case "form":
|
|
1338
|
+
return ",";
|
|
1339
|
+
case "pipeDelimited":
|
|
1340
|
+
return "|";
|
|
1341
|
+
case "spaceDelimited":
|
|
1342
|
+
return "%20";
|
|
1343
|
+
default:
|
|
1344
|
+
return ",";
|
|
1345
|
+
}
|
|
1346
|
+
}, "separatorArrayNoExplode");
|
|
1347
|
+
var separatorObjectExplode = /* @__PURE__ */ __name((style) => {
|
|
1348
|
+
switch (style) {
|
|
1349
|
+
case "label":
|
|
1350
|
+
return ".";
|
|
1351
|
+
case "matrix":
|
|
1352
|
+
return ";";
|
|
1353
|
+
case "simple":
|
|
1354
|
+
return ",";
|
|
1355
|
+
default:
|
|
1356
|
+
return "&";
|
|
1357
|
+
}
|
|
1358
|
+
}, "separatorObjectExplode");
|
|
1359
|
+
var serializeArrayParam = /* @__PURE__ */ __name(({
|
|
1360
|
+
allowReserved,
|
|
1361
|
+
explode,
|
|
1362
|
+
name,
|
|
1363
|
+
style,
|
|
1364
|
+
value
|
|
1365
|
+
}) => {
|
|
1366
|
+
if (!explode) {
|
|
1367
|
+
const joinedValues2 = (allowReserved ? value : value.map((v) => encodeURIComponent(v))).join(separatorArrayNoExplode(style));
|
|
1368
|
+
switch (style) {
|
|
1369
|
+
case "label":
|
|
1370
|
+
return `.${joinedValues2}`;
|
|
1371
|
+
case "matrix":
|
|
1372
|
+
return `;${name}=${joinedValues2}`;
|
|
1373
|
+
case "simple":
|
|
1374
|
+
return joinedValues2;
|
|
1375
|
+
default:
|
|
1376
|
+
return `${name}=${joinedValues2}`;
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
const separator = separatorArrayExplode(style);
|
|
1380
|
+
const joinedValues = value.map((v) => {
|
|
1381
|
+
if (style === "label" || style === "simple") {
|
|
1382
|
+
return allowReserved ? v : encodeURIComponent(v);
|
|
1383
|
+
}
|
|
1384
|
+
return serializePrimitiveParam({
|
|
1385
|
+
allowReserved,
|
|
1386
|
+
name,
|
|
1387
|
+
value: v
|
|
1388
|
+
});
|
|
1389
|
+
}).join(separator);
|
|
1390
|
+
return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
|
|
1391
|
+
}, "serializeArrayParam");
|
|
1392
|
+
var serializePrimitiveParam = /* @__PURE__ */ __name(({
|
|
1393
|
+
allowReserved,
|
|
1394
|
+
name,
|
|
1395
|
+
value
|
|
1396
|
+
}) => {
|
|
1397
|
+
if (value === void 0 || value === null) {
|
|
1398
|
+
return "";
|
|
1399
|
+
}
|
|
1400
|
+
if (typeof value === "object") {
|
|
1401
|
+
throw new Error(
|
|
1402
|
+
"Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these."
|
|
1403
|
+
);
|
|
1404
|
+
}
|
|
1405
|
+
return `${name}=${allowReserved ? value : encodeURIComponent(value)}`;
|
|
1406
|
+
}, "serializePrimitiveParam");
|
|
1407
|
+
var serializeObjectParam = /* @__PURE__ */ __name(({
|
|
1408
|
+
allowReserved,
|
|
1409
|
+
explode,
|
|
1410
|
+
name,
|
|
1411
|
+
style,
|
|
1412
|
+
value,
|
|
1413
|
+
valueOnly
|
|
1414
|
+
}) => {
|
|
1415
|
+
if (value instanceof Date) {
|
|
1416
|
+
return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`;
|
|
1417
|
+
}
|
|
1418
|
+
if (style !== "deepObject" && !explode) {
|
|
1419
|
+
let values = [];
|
|
1420
|
+
Object.entries(value).forEach(([key, v]) => {
|
|
1421
|
+
values = [...values, key, allowReserved ? v : encodeURIComponent(v)];
|
|
1422
|
+
});
|
|
1423
|
+
const joinedValues2 = values.join(",");
|
|
1424
|
+
switch (style) {
|
|
1425
|
+
case "form":
|
|
1426
|
+
return `${name}=${joinedValues2}`;
|
|
1427
|
+
case "label":
|
|
1428
|
+
return `.${joinedValues2}`;
|
|
1429
|
+
case "matrix":
|
|
1430
|
+
return `;${name}=${joinedValues2}`;
|
|
1431
|
+
default:
|
|
1432
|
+
return joinedValues2;
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
const separator = separatorObjectExplode(style);
|
|
1436
|
+
const joinedValues = Object.entries(value).map(
|
|
1437
|
+
([key, v]) => serializePrimitiveParam({
|
|
1438
|
+
allowReserved,
|
|
1439
|
+
name: style === "deepObject" ? `${name}[${key}]` : key,
|
|
1440
|
+
value: v
|
|
1441
|
+
})
|
|
1442
|
+
).join(separator);
|
|
1443
|
+
return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
|
|
1444
|
+
}, "serializeObjectParam");
|
|
1445
|
+
|
|
1446
|
+
// src/_api/generated/core/utils.gen.ts
|
|
1447
|
+
var PATH_PARAM_RE = /\{[^{}]+\}/g;
|
|
1448
|
+
var defaultPathSerializer = /* @__PURE__ */ __name(({ path, url: _url }) => {
|
|
1449
|
+
let url = _url;
|
|
1450
|
+
const matches = _url.match(PATH_PARAM_RE);
|
|
1451
|
+
if (matches) {
|
|
1452
|
+
for (const match of matches) {
|
|
1453
|
+
let explode = false;
|
|
1454
|
+
let name = match.substring(1, match.length - 1);
|
|
1455
|
+
let style = "simple";
|
|
1456
|
+
if (name.endsWith("*")) {
|
|
1457
|
+
explode = true;
|
|
1458
|
+
name = name.substring(0, name.length - 1);
|
|
1459
|
+
}
|
|
1460
|
+
if (name.startsWith(".")) {
|
|
1461
|
+
name = name.substring(1);
|
|
1462
|
+
style = "label";
|
|
1463
|
+
} else if (name.startsWith(";")) {
|
|
1464
|
+
name = name.substring(1);
|
|
1465
|
+
style = "matrix";
|
|
1466
|
+
}
|
|
1467
|
+
const value = path[name];
|
|
1468
|
+
if (value === void 0 || value === null) {
|
|
1469
|
+
continue;
|
|
1470
|
+
}
|
|
1471
|
+
if (Array.isArray(value)) {
|
|
1472
|
+
url = url.replace(match, serializeArrayParam({ explode, name, style, value }));
|
|
1473
|
+
continue;
|
|
1474
|
+
}
|
|
1475
|
+
if (typeof value === "object") {
|
|
1476
|
+
url = url.replace(
|
|
1477
|
+
match,
|
|
1478
|
+
serializeObjectParam({
|
|
1479
|
+
explode,
|
|
1480
|
+
name,
|
|
1481
|
+
style,
|
|
1482
|
+
value,
|
|
1483
|
+
valueOnly: true
|
|
1484
|
+
})
|
|
1485
|
+
);
|
|
1486
|
+
continue;
|
|
1487
|
+
}
|
|
1488
|
+
if (style === "matrix") {
|
|
1489
|
+
url = url.replace(
|
|
1490
|
+
match,
|
|
1491
|
+
`;${serializePrimitiveParam({
|
|
1492
|
+
name,
|
|
1493
|
+
value
|
|
1494
|
+
})}`
|
|
1495
|
+
);
|
|
1496
|
+
continue;
|
|
1497
|
+
}
|
|
1498
|
+
const replaceValue = encodeURIComponent(
|
|
1499
|
+
style === "label" ? `.${value}` : value
|
|
1500
|
+
);
|
|
1501
|
+
url = url.replace(match, replaceValue);
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
return url;
|
|
1505
|
+
}, "defaultPathSerializer");
|
|
1506
|
+
var getUrl = /* @__PURE__ */ __name(({
|
|
1507
|
+
baseUrl,
|
|
1508
|
+
path,
|
|
1509
|
+
query,
|
|
1510
|
+
querySerializer,
|
|
1511
|
+
url: _url
|
|
1512
|
+
}) => {
|
|
1513
|
+
const pathUrl = _url.startsWith("/") ? _url : `/${_url}`;
|
|
1514
|
+
let url = (baseUrl ?? "") + pathUrl;
|
|
1515
|
+
if (path) {
|
|
1516
|
+
url = defaultPathSerializer({ path, url });
|
|
1517
|
+
}
|
|
1518
|
+
let search = query ? querySerializer(query) : "";
|
|
1519
|
+
if (search.startsWith("?")) {
|
|
1520
|
+
search = search.substring(1);
|
|
1521
|
+
}
|
|
1522
|
+
if (search) {
|
|
1523
|
+
url += `?${search}`;
|
|
1524
|
+
}
|
|
1525
|
+
return url;
|
|
1526
|
+
}, "getUrl");
|
|
1527
|
+
function getValidRequestBody(options) {
|
|
1528
|
+
const hasBody = options.body !== void 0;
|
|
1529
|
+
const isSerializedBody = hasBody && options.bodySerializer;
|
|
1530
|
+
if (isSerializedBody) {
|
|
1531
|
+
if ("serializedBody" in options) {
|
|
1532
|
+
const hasSerializedBody = options.serializedBody !== void 0 && options.serializedBody !== "";
|
|
1533
|
+
return hasSerializedBody ? options.serializedBody : null;
|
|
1534
|
+
}
|
|
1535
|
+
return options.body !== "" ? options.body : null;
|
|
1536
|
+
}
|
|
1537
|
+
if (hasBody) {
|
|
1538
|
+
return options.body;
|
|
1539
|
+
}
|
|
1540
|
+
return void 0;
|
|
1541
|
+
}
|
|
1542
|
+
__name(getValidRequestBody, "getValidRequestBody");
|
|
1543
|
+
|
|
1544
|
+
// src/_api/generated/core/auth.gen.ts
|
|
1545
|
+
var getAuthToken = /* @__PURE__ */ __name(async (auth2, callback) => {
|
|
1546
|
+
const token = typeof callback === "function" ? await callback(auth2) : callback;
|
|
1547
|
+
if (!token) {
|
|
1548
|
+
return;
|
|
1549
|
+
}
|
|
1550
|
+
if (auth2.scheme === "bearer") {
|
|
1551
|
+
return `Bearer ${token}`;
|
|
1552
|
+
}
|
|
1553
|
+
if (auth2.scheme === "basic") {
|
|
1554
|
+
return `Basic ${btoa(token)}`;
|
|
1555
|
+
}
|
|
1556
|
+
return token;
|
|
1557
|
+
}, "getAuthToken");
|
|
1558
|
+
|
|
1559
|
+
// src/_api/generated/client/utils.gen.ts
|
|
1560
|
+
var createQuerySerializer = /* @__PURE__ */ __name(({
|
|
1561
|
+
parameters = {},
|
|
1562
|
+
...args
|
|
1563
|
+
} = {}) => {
|
|
1564
|
+
const querySerializer = /* @__PURE__ */ __name((queryParams) => {
|
|
1565
|
+
const search = [];
|
|
1566
|
+
if (queryParams && typeof queryParams === "object") {
|
|
1567
|
+
for (const name in queryParams) {
|
|
1568
|
+
const value = queryParams[name];
|
|
1569
|
+
if (value === void 0 || value === null) {
|
|
1570
|
+
continue;
|
|
1571
|
+
}
|
|
1572
|
+
const options = parameters[name] || args;
|
|
1573
|
+
if (Array.isArray(value)) {
|
|
1574
|
+
const serializedArray = serializeArrayParam({
|
|
1575
|
+
allowReserved: options.allowReserved,
|
|
1576
|
+
explode: true,
|
|
1577
|
+
name,
|
|
1578
|
+
style: "form",
|
|
1579
|
+
value,
|
|
1580
|
+
...options.array
|
|
1581
|
+
});
|
|
1582
|
+
if (serializedArray) search.push(serializedArray);
|
|
1583
|
+
} else if (typeof value === "object") {
|
|
1584
|
+
const serializedObject = serializeObjectParam({
|
|
1585
|
+
allowReserved: options.allowReserved,
|
|
1586
|
+
explode: true,
|
|
1587
|
+
name,
|
|
1588
|
+
style: "deepObject",
|
|
1589
|
+
value,
|
|
1590
|
+
...options.object
|
|
1591
|
+
});
|
|
1592
|
+
if (serializedObject) search.push(serializedObject);
|
|
1593
|
+
} else {
|
|
1594
|
+
const serializedPrimitive = serializePrimitiveParam({
|
|
1595
|
+
allowReserved: options.allowReserved,
|
|
1596
|
+
name,
|
|
1597
|
+
value
|
|
1598
|
+
});
|
|
1599
|
+
if (serializedPrimitive) search.push(serializedPrimitive);
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
return search.join("&");
|
|
1604
|
+
}, "querySerializer");
|
|
1605
|
+
return querySerializer;
|
|
1606
|
+
}, "createQuerySerializer");
|
|
1607
|
+
var getParseAs = /* @__PURE__ */ __name((contentType) => {
|
|
1608
|
+
if (!contentType) {
|
|
1609
|
+
return "stream";
|
|
1610
|
+
}
|
|
1611
|
+
const cleanContent = contentType.split(";")[0]?.trim();
|
|
1612
|
+
if (!cleanContent) {
|
|
1613
|
+
return;
|
|
1614
|
+
}
|
|
1615
|
+
if (cleanContent.startsWith("application/json") || cleanContent.endsWith("+json")) {
|
|
1616
|
+
return "json";
|
|
1617
|
+
}
|
|
1618
|
+
if (cleanContent === "multipart/form-data") {
|
|
1619
|
+
return "formData";
|
|
1620
|
+
}
|
|
1621
|
+
if (["application/", "audio/", "image/", "video/"].some((type) => cleanContent.startsWith(type))) {
|
|
1622
|
+
return "blob";
|
|
1623
|
+
}
|
|
1624
|
+
if (cleanContent.startsWith("text/")) {
|
|
1625
|
+
return "text";
|
|
1626
|
+
}
|
|
1627
|
+
return;
|
|
1628
|
+
}, "getParseAs");
|
|
1629
|
+
var checkForExistence = /* @__PURE__ */ __name((options, name) => {
|
|
1630
|
+
if (!name) {
|
|
1631
|
+
return false;
|
|
1632
|
+
}
|
|
1633
|
+
if (options.headers.has(name) || options.query?.[name] || options.headers.get("Cookie")?.includes(`${name}=`)) {
|
|
1634
|
+
return true;
|
|
1635
|
+
}
|
|
1636
|
+
return false;
|
|
1637
|
+
}, "checkForExistence");
|
|
1638
|
+
async function setAuthParams(options) {
|
|
1639
|
+
for (const auth2 of options.security ?? []) {
|
|
1640
|
+
if (checkForExistence(options, auth2.name)) {
|
|
1641
|
+
continue;
|
|
1642
|
+
}
|
|
1643
|
+
const token = await getAuthToken(auth2, options.auth);
|
|
1644
|
+
if (!token) {
|
|
1645
|
+
continue;
|
|
1646
|
+
}
|
|
1647
|
+
const name = auth2.name ?? "Authorization";
|
|
1648
|
+
switch (auth2.in) {
|
|
1649
|
+
case "query":
|
|
1650
|
+
if (!options.query) {
|
|
1651
|
+
options.query = {};
|
|
1652
|
+
}
|
|
1653
|
+
options.query[name] = token;
|
|
1654
|
+
break;
|
|
1655
|
+
case "cookie":
|
|
1656
|
+
options.headers.append("Cookie", `${name}=${token}`);
|
|
1657
|
+
break;
|
|
1658
|
+
case "header":
|
|
1659
|
+
default:
|
|
1660
|
+
options.headers.set(name, token);
|
|
1661
|
+
break;
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
__name(setAuthParams, "setAuthParams");
|
|
1666
|
+
var buildUrl = /* @__PURE__ */ __name((options) => getUrl({
|
|
1667
|
+
baseUrl: options.baseUrl,
|
|
1668
|
+
path: options.path,
|
|
1669
|
+
query: options.query,
|
|
1670
|
+
querySerializer: typeof options.querySerializer === "function" ? options.querySerializer : createQuerySerializer(options.querySerializer),
|
|
1671
|
+
url: options.url
|
|
1672
|
+
}), "buildUrl");
|
|
1673
|
+
var mergeConfigs = /* @__PURE__ */ __name((a, b) => {
|
|
1674
|
+
const config = { ...a, ...b };
|
|
1675
|
+
if (config.baseUrl?.endsWith("/")) {
|
|
1676
|
+
config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1);
|
|
1677
|
+
}
|
|
1678
|
+
config.headers = mergeHeaders(a.headers, b.headers);
|
|
1679
|
+
return config;
|
|
1680
|
+
}, "mergeConfigs");
|
|
1681
|
+
var headersEntries = /* @__PURE__ */ __name((headers) => {
|
|
1682
|
+
const entries = [];
|
|
1683
|
+
headers.forEach((value, key) => {
|
|
1684
|
+
entries.push([key, value]);
|
|
1685
|
+
});
|
|
1686
|
+
return entries;
|
|
1687
|
+
}, "headersEntries");
|
|
1688
|
+
var mergeHeaders = /* @__PURE__ */ __name((...headers) => {
|
|
1689
|
+
const mergedHeaders = new Headers();
|
|
1690
|
+
for (const header of headers) {
|
|
1691
|
+
if (!header) {
|
|
1692
|
+
continue;
|
|
1693
|
+
}
|
|
1694
|
+
const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header);
|
|
1695
|
+
for (const [key, value] of iterator) {
|
|
1696
|
+
if (value === null) {
|
|
1697
|
+
mergedHeaders.delete(key);
|
|
1698
|
+
} else if (Array.isArray(value)) {
|
|
1699
|
+
for (const v of value) {
|
|
1700
|
+
mergedHeaders.append(key, v);
|
|
1701
|
+
}
|
|
1702
|
+
} else if (value !== void 0) {
|
|
1703
|
+
mergedHeaders.set(
|
|
1704
|
+
key,
|
|
1705
|
+
typeof value === "object" ? JSON.stringify(value) : value
|
|
1706
|
+
);
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
return mergedHeaders;
|
|
1711
|
+
}, "mergeHeaders");
|
|
1712
|
+
var Interceptors = class {
|
|
1713
|
+
static {
|
|
1714
|
+
__name(this, "Interceptors");
|
|
1715
|
+
}
|
|
1716
|
+
fns = [];
|
|
1717
|
+
clear() {
|
|
1718
|
+
this.fns = [];
|
|
1719
|
+
}
|
|
1720
|
+
eject(id) {
|
|
1721
|
+
const index = this.getInterceptorIndex(id);
|
|
1722
|
+
if (this.fns[index]) {
|
|
1723
|
+
this.fns[index] = null;
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1726
|
+
exists(id) {
|
|
1727
|
+
const index = this.getInterceptorIndex(id);
|
|
1728
|
+
return Boolean(this.fns[index]);
|
|
1729
|
+
}
|
|
1730
|
+
getInterceptorIndex(id) {
|
|
1731
|
+
if (typeof id === "number") {
|
|
1732
|
+
return this.fns[id] ? id : -1;
|
|
1733
|
+
}
|
|
1734
|
+
return this.fns.indexOf(id);
|
|
1735
|
+
}
|
|
1736
|
+
update(id, fn) {
|
|
1737
|
+
const index = this.getInterceptorIndex(id);
|
|
1738
|
+
if (this.fns[index]) {
|
|
1739
|
+
this.fns[index] = fn;
|
|
1740
|
+
return id;
|
|
1741
|
+
}
|
|
1742
|
+
return false;
|
|
1743
|
+
}
|
|
1744
|
+
use(fn) {
|
|
1745
|
+
this.fns.push(fn);
|
|
1746
|
+
return this.fns.length - 1;
|
|
1747
|
+
}
|
|
1748
|
+
};
|
|
1749
|
+
var createInterceptors = /* @__PURE__ */ __name(() => ({
|
|
1750
|
+
error: new Interceptors(),
|
|
1751
|
+
request: new Interceptors(),
|
|
1752
|
+
response: new Interceptors()
|
|
1753
|
+
}), "createInterceptors");
|
|
1754
|
+
var defaultQuerySerializer = createQuerySerializer({
|
|
1755
|
+
allowReserved: false,
|
|
1756
|
+
array: {
|
|
1757
|
+
explode: true,
|
|
1758
|
+
style: "form"
|
|
1759
|
+
},
|
|
1760
|
+
object: {
|
|
1761
|
+
explode: true,
|
|
1762
|
+
style: "deepObject"
|
|
1763
|
+
}
|
|
1764
|
+
});
|
|
1765
|
+
var defaultHeaders = {
|
|
1766
|
+
"Content-Type": "application/json"
|
|
1767
|
+
};
|
|
1768
|
+
var createConfig = /* @__PURE__ */ __name((override = {}) => ({
|
|
1769
|
+
...jsonBodySerializer,
|
|
1770
|
+
headers: defaultHeaders,
|
|
1771
|
+
parseAs: "auto",
|
|
1772
|
+
querySerializer: defaultQuerySerializer,
|
|
1773
|
+
...override
|
|
1774
|
+
}), "createConfig");
|
|
1775
|
+
|
|
1776
|
+
// src/_api/generated/client/client.gen.ts
|
|
1777
|
+
var createClient = /* @__PURE__ */ __name((config = {}) => {
|
|
1778
|
+
let _config = mergeConfigs(createConfig(), config);
|
|
1779
|
+
const getConfig = /* @__PURE__ */ __name(() => ({ ..._config }), "getConfig");
|
|
1780
|
+
const setConfig = /* @__PURE__ */ __name((config2) => {
|
|
1781
|
+
_config = mergeConfigs(_config, config2);
|
|
1782
|
+
return getConfig();
|
|
1783
|
+
}, "setConfig");
|
|
1784
|
+
const interceptors = createInterceptors();
|
|
1785
|
+
const beforeRequest = /* @__PURE__ */ __name(async (options) => {
|
|
1786
|
+
const opts = {
|
|
1787
|
+
..._config,
|
|
1788
|
+
...options,
|
|
1789
|
+
fetch: options.fetch ?? _config.fetch ?? globalThis.fetch,
|
|
1790
|
+
headers: mergeHeaders(_config.headers, options.headers),
|
|
1791
|
+
serializedBody: void 0
|
|
1792
|
+
};
|
|
1793
|
+
if (opts.security) {
|
|
1794
|
+
await setAuthParams(opts);
|
|
1795
|
+
}
|
|
1796
|
+
if (opts.requestValidator) {
|
|
1797
|
+
await opts.requestValidator(opts);
|
|
1798
|
+
}
|
|
1799
|
+
if (opts.body !== void 0 && opts.bodySerializer) {
|
|
1800
|
+
opts.serializedBody = opts.bodySerializer(opts.body);
|
|
1801
|
+
}
|
|
1802
|
+
if (opts.body === void 0 || opts.serializedBody === "") {
|
|
1803
|
+
opts.headers.delete("Content-Type");
|
|
1804
|
+
}
|
|
1805
|
+
const resolvedOpts = opts;
|
|
1806
|
+
const url = buildUrl(resolvedOpts);
|
|
1807
|
+
return { opts: resolvedOpts, url };
|
|
1808
|
+
}, "beforeRequest");
|
|
1809
|
+
const request = /* @__PURE__ */ __name(async (options) => {
|
|
1810
|
+
const throwOnError = options.throwOnError ?? _config.throwOnError;
|
|
1811
|
+
const responseStyle = options.responseStyle ?? _config.responseStyle;
|
|
1812
|
+
let request2;
|
|
1813
|
+
let response;
|
|
1814
|
+
try {
|
|
1815
|
+
const { opts, url } = await beforeRequest(options);
|
|
1816
|
+
const requestInit = {
|
|
1817
|
+
redirect: "follow",
|
|
1818
|
+
...opts,
|
|
1819
|
+
body: getValidRequestBody(opts)
|
|
1820
|
+
};
|
|
1821
|
+
request2 = new Request(url, requestInit);
|
|
1822
|
+
for (const fn of interceptors.request.fns) {
|
|
1823
|
+
if (fn) {
|
|
1824
|
+
request2 = await fn(request2, opts);
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1827
|
+
const _fetch = opts.fetch;
|
|
1828
|
+
response = await _fetch(request2);
|
|
1829
|
+
for (const fn of interceptors.response.fns) {
|
|
1830
|
+
if (fn) {
|
|
1831
|
+
response = await fn(response, request2, opts);
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
const result = {
|
|
1835
|
+
request: request2,
|
|
1836
|
+
response
|
|
1837
|
+
};
|
|
1838
|
+
if (response.ok) {
|
|
1839
|
+
const parseAs = (opts.parseAs === "auto" ? getParseAs(response.headers.get("Content-Type")) : opts.parseAs) ?? "json";
|
|
1840
|
+
if (response.status === 204 || response.headers.get("Content-Length") === "0") {
|
|
1841
|
+
let emptyData;
|
|
1842
|
+
switch (parseAs) {
|
|
1843
|
+
case "arrayBuffer":
|
|
1844
|
+
case "blob":
|
|
1845
|
+
case "text":
|
|
1846
|
+
emptyData = await response[parseAs]();
|
|
1847
|
+
break;
|
|
1848
|
+
case "formData":
|
|
1849
|
+
emptyData = new FormData();
|
|
1850
|
+
break;
|
|
1851
|
+
case "stream":
|
|
1852
|
+
emptyData = response.body;
|
|
1853
|
+
break;
|
|
1854
|
+
case "json":
|
|
1855
|
+
default:
|
|
1856
|
+
emptyData = {};
|
|
1857
|
+
break;
|
|
1858
|
+
}
|
|
1859
|
+
return opts.responseStyle === "data" ? emptyData : {
|
|
1860
|
+
data: emptyData,
|
|
1861
|
+
...result
|
|
1862
|
+
};
|
|
1863
|
+
}
|
|
1864
|
+
let data;
|
|
1865
|
+
switch (parseAs) {
|
|
1866
|
+
case "arrayBuffer":
|
|
1867
|
+
case "blob":
|
|
1868
|
+
case "formData":
|
|
1869
|
+
case "text":
|
|
1870
|
+
data = await response[parseAs]();
|
|
1871
|
+
break;
|
|
1872
|
+
case "json": {
|
|
1873
|
+
const text = await response.text();
|
|
1874
|
+
data = text ? JSON.parse(text) : {};
|
|
1875
|
+
break;
|
|
1876
|
+
}
|
|
1877
|
+
case "stream":
|
|
1878
|
+
return opts.responseStyle === "data" ? response.body : {
|
|
1879
|
+
data: response.body,
|
|
1880
|
+
...result
|
|
1881
|
+
};
|
|
1882
|
+
}
|
|
1883
|
+
if (parseAs === "json") {
|
|
1884
|
+
if (opts.responseValidator) {
|
|
1885
|
+
await opts.responseValidator(data);
|
|
1886
|
+
}
|
|
1887
|
+
if (opts.responseTransformer) {
|
|
1888
|
+
data = await opts.responseTransformer(data);
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
return opts.responseStyle === "data" ? data : {
|
|
1892
|
+
data,
|
|
1893
|
+
...result
|
|
1894
|
+
};
|
|
1895
|
+
}
|
|
1896
|
+
const textError = await response.text();
|
|
1897
|
+
let jsonError;
|
|
1898
|
+
try {
|
|
1899
|
+
jsonError = JSON.parse(textError);
|
|
1900
|
+
} catch {
|
|
1901
|
+
}
|
|
1902
|
+
throw jsonError ?? textError;
|
|
1903
|
+
} catch (error) {
|
|
1904
|
+
let finalError = error;
|
|
1905
|
+
for (const fn of interceptors.error.fns) {
|
|
1906
|
+
if (fn) {
|
|
1907
|
+
finalError = await fn(finalError, response, request2, options);
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
finalError = finalError || {};
|
|
1911
|
+
if (throwOnError) {
|
|
1912
|
+
throw finalError;
|
|
1913
|
+
}
|
|
1914
|
+
return responseStyle === "data" ? void 0 : {
|
|
1915
|
+
error: finalError,
|
|
1916
|
+
request: request2,
|
|
1917
|
+
response
|
|
1918
|
+
};
|
|
1919
|
+
}
|
|
1920
|
+
}, "request");
|
|
1921
|
+
const makeMethodFn = /* @__PURE__ */ __name((method) => (options) => request({ ...options, method }), "makeMethodFn");
|
|
1922
|
+
const makeSseFn = /* @__PURE__ */ __name((method) => async (options) => {
|
|
1923
|
+
const { opts, url } = await beforeRequest(options);
|
|
1924
|
+
return createSseClient({
|
|
1925
|
+
...opts,
|
|
1926
|
+
body: opts.body,
|
|
1927
|
+
method,
|
|
1928
|
+
onRequest: /* @__PURE__ */ __name(async (url2, init) => {
|
|
1929
|
+
let request2 = new Request(url2, init);
|
|
1930
|
+
for (const fn of interceptors.request.fns) {
|
|
1931
|
+
if (fn) {
|
|
1932
|
+
request2 = await fn(request2, opts);
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
return request2;
|
|
1936
|
+
}, "onRequest"),
|
|
1937
|
+
serializedBody: getValidRequestBody(opts),
|
|
1938
|
+
url
|
|
1939
|
+
});
|
|
1940
|
+
}, "makeSseFn");
|
|
1941
|
+
const _buildUrl = /* @__PURE__ */ __name((options) => buildUrl({ ..._config, ...options }), "_buildUrl");
|
|
1942
|
+
return {
|
|
1943
|
+
buildUrl: _buildUrl,
|
|
1944
|
+
connect: makeMethodFn("CONNECT"),
|
|
1945
|
+
delete: makeMethodFn("DELETE"),
|
|
1946
|
+
get: makeMethodFn("GET"),
|
|
1947
|
+
getConfig,
|
|
1948
|
+
head: makeMethodFn("HEAD"),
|
|
1949
|
+
interceptors,
|
|
1950
|
+
options: makeMethodFn("OPTIONS"),
|
|
1951
|
+
patch: makeMethodFn("PATCH"),
|
|
1952
|
+
post: makeMethodFn("POST"),
|
|
1953
|
+
put: makeMethodFn("PUT"),
|
|
1954
|
+
request,
|
|
1955
|
+
setConfig,
|
|
1956
|
+
sse: {
|
|
1957
|
+
connect: makeSseFn("CONNECT"),
|
|
1958
|
+
delete: makeSseFn("DELETE"),
|
|
1959
|
+
get: makeSseFn("GET"),
|
|
1960
|
+
head: makeSseFn("HEAD"),
|
|
1961
|
+
options: makeSseFn("OPTIONS"),
|
|
1962
|
+
patch: makeSseFn("PATCH"),
|
|
1963
|
+
post: makeSseFn("POST"),
|
|
1964
|
+
put: makeSseFn("PUT"),
|
|
1965
|
+
trace: makeSseFn("TRACE")
|
|
1966
|
+
},
|
|
1967
|
+
trace: makeMethodFn("TRACE")
|
|
1968
|
+
};
|
|
1969
|
+
}, "createClient");
|
|
1970
|
+
|
|
1971
|
+
// src/_api/generated/client.gen.ts
|
|
1972
|
+
var client = createClient(createConfig({ baseUrl: "http://localhost:8000" }));
|
|
1973
|
+
installAuthOnClient(client);
|
|
1974
|
+
|
|
1975
|
+
// src/_api/generated/sdk.gen.ts
|
|
1976
|
+
var CfgAccountsOauth = class {
|
|
1977
|
+
static {
|
|
1978
|
+
__name(this, "CfgAccountsOauth");
|
|
1979
|
+
}
|
|
1980
|
+
/**
|
|
1981
|
+
* List OAuth connections
|
|
1982
|
+
*
|
|
1983
|
+
* Get all OAuth connections for the current user.
|
|
1984
|
+
*/
|
|
1985
|
+
static cfgAccountsOauthConnectionsList(options) {
|
|
1986
|
+
return (options?.client ?? client).get({
|
|
1987
|
+
security: [
|
|
1988
|
+
{ name: "X-API-Key", type: "apiKey" },
|
|
1989
|
+
{ scheme: "bearer", type: "http" },
|
|
1990
|
+
{ name: "Authorization", type: "apiKey" }
|
|
1991
|
+
],
|
|
1992
|
+
url: "/cfg/accounts/oauth/connections/",
|
|
1993
|
+
...options
|
|
1994
|
+
});
|
|
1995
|
+
}
|
|
1996
|
+
/**
|
|
1997
|
+
* Disconnect OAuth provider
|
|
1998
|
+
*
|
|
1999
|
+
* Remove OAuth connection for the specified provider.
|
|
2000
|
+
*/
|
|
2001
|
+
static cfgAccountsOauthDisconnectCreate(options) {
|
|
2002
|
+
return (options.client ?? client).post({
|
|
2003
|
+
security: [
|
|
2004
|
+
{ name: "X-API-Key", type: "apiKey" },
|
|
2005
|
+
{ scheme: "bearer", type: "http" },
|
|
2006
|
+
{ name: "Authorization", type: "apiKey" }
|
|
2007
|
+
],
|
|
2008
|
+
url: "/cfg/accounts/oauth/disconnect/",
|
|
2009
|
+
...options,
|
|
2010
|
+
headers: {
|
|
2011
|
+
"Content-Type": "application/json",
|
|
2012
|
+
...options.headers
|
|
2013
|
+
}
|
|
2014
|
+
});
|
|
2015
|
+
}
|
|
2016
|
+
/**
|
|
2017
|
+
* Start GitHub OAuth
|
|
2018
|
+
*
|
|
2019
|
+
* Generate GitHub OAuth authorization URL. Redirect user to this URL to start authentication.
|
|
2020
|
+
*/
|
|
2021
|
+
static cfgAccountsOauthGithubAuthorizeCreate(options) {
|
|
2022
|
+
return (options?.client ?? client).post({
|
|
2023
|
+
url: "/cfg/accounts/oauth/github/authorize/",
|
|
2024
|
+
...options,
|
|
2025
|
+
headers: {
|
|
2026
|
+
"Content-Type": "application/json",
|
|
2027
|
+
...options?.headers
|
|
2028
|
+
}
|
|
2029
|
+
});
|
|
2030
|
+
}
|
|
2031
|
+
/**
|
|
2032
|
+
* Complete GitHub OAuth
|
|
2033
|
+
*
|
|
2034
|
+
* Exchange authorization code for JWT tokens. Call this after GitHub redirects back with code.
|
|
2035
|
+
*/
|
|
2036
|
+
static cfgAccountsOauthGithubCallbackCreate(options) {
|
|
2037
|
+
return (options.client ?? client).post({
|
|
2038
|
+
url: "/cfg/accounts/oauth/github/callback/",
|
|
2039
|
+
...options,
|
|
2040
|
+
headers: {
|
|
2041
|
+
"Content-Type": "application/json",
|
|
2042
|
+
...options.headers
|
|
2043
|
+
}
|
|
2044
|
+
});
|
|
2045
|
+
}
|
|
2046
|
+
/**
|
|
2047
|
+
* List OAuth providers
|
|
2048
|
+
*
|
|
2049
|
+
* Get list of available OAuth providers for authentication.
|
|
2050
|
+
*/
|
|
2051
|
+
static cfgAccountsOauthProvidersRetrieve(options) {
|
|
2052
|
+
return (options?.client ?? client).get({ url: "/cfg/accounts/oauth/providers/", ...options });
|
|
2053
|
+
}
|
|
2054
|
+
};
|
|
2055
|
+
var CfgAccounts = class {
|
|
2056
|
+
static {
|
|
2057
|
+
__name(this, "CfgAccounts");
|
|
2058
|
+
}
|
|
2059
|
+
/**
|
|
2060
|
+
* Request OTP code to email.
|
|
2061
|
+
*/
|
|
2062
|
+
static cfgAccountsOtpRequestCreate(options) {
|
|
2063
|
+
return (options.client ?? client).post({
|
|
2064
|
+
security: [
|
|
2065
|
+
{ name: "X-API-Key", type: "apiKey" },
|
|
2066
|
+
{ scheme: "bearer", type: "http" },
|
|
2067
|
+
{ name: "Authorization", type: "apiKey" }
|
|
2068
|
+
],
|
|
2069
|
+
url: "/cfg/accounts/otp/request/",
|
|
2070
|
+
...options,
|
|
2071
|
+
headers: {
|
|
2072
|
+
"Content-Type": "application/json",
|
|
2073
|
+
...options.headers
|
|
2074
|
+
}
|
|
2075
|
+
});
|
|
2076
|
+
}
|
|
2077
|
+
/**
|
|
2078
|
+
* Verify OTP code and return JWT tokens or 2FA session.
|
|
2079
|
+
*
|
|
2080
|
+
* If user has 2FA enabled:
|
|
2081
|
+
* - Returns requires_2fa=True with session_id
|
|
2082
|
+
* - Client must complete 2FA verification at /cfg/totp/verify/
|
|
2083
|
+
*
|
|
2084
|
+
* If user has no 2FA:
|
|
2085
|
+
* - Returns JWT tokens and user data directly
|
|
2086
|
+
*/
|
|
2087
|
+
static cfgAccountsOtpVerifyCreate(options) {
|
|
2088
|
+
return (options.client ?? client).post({
|
|
2089
|
+
security: [
|
|
2090
|
+
{ name: "X-API-Key", type: "apiKey" },
|
|
2091
|
+
{ scheme: "bearer", type: "http" },
|
|
2092
|
+
{ name: "Authorization", type: "apiKey" }
|
|
2093
|
+
],
|
|
2094
|
+
url: "/cfg/accounts/otp/verify/",
|
|
2095
|
+
...options,
|
|
2096
|
+
headers: {
|
|
2097
|
+
"Content-Type": "application/json",
|
|
2098
|
+
...options.headers
|
|
2099
|
+
}
|
|
2100
|
+
});
|
|
2101
|
+
}
|
|
2102
|
+
};
|
|
2103
|
+
var CfgAccountsProfile = class {
|
|
2104
|
+
static {
|
|
2105
|
+
__name(this, "CfgAccountsProfile");
|
|
2106
|
+
}
|
|
2107
|
+
/**
|
|
2108
|
+
* Get current user profile
|
|
2109
|
+
*
|
|
2110
|
+
* Retrieve the current authenticated user's profile information.
|
|
2111
|
+
*/
|
|
2112
|
+
static cfgAccountsProfileRetrieve(options) {
|
|
2113
|
+
return (options?.client ?? client).get({
|
|
2114
|
+
security: [{ scheme: "bearer", type: "http" }, {
|
|
2115
|
+
in: "cookie",
|
|
2116
|
+
name: "sessionid",
|
|
2117
|
+
type: "apiKey"
|
|
2118
|
+
}],
|
|
2119
|
+
url: "/cfg/accounts/profile/",
|
|
2120
|
+
...options
|
|
2121
|
+
});
|
|
2122
|
+
}
|
|
2123
|
+
/**
|
|
2124
|
+
* Upload user avatar
|
|
2125
|
+
*
|
|
2126
|
+
* Upload avatar image for the current authenticated user. Accepts multipart/form-data with 'avatar' field.
|
|
2127
|
+
*/
|
|
2128
|
+
static cfgAccountsProfileAvatarCreate(options) {
|
|
2129
|
+
return (options?.client ?? client).post({
|
|
2130
|
+
...formDataBodySerializer,
|
|
2131
|
+
security: [
|
|
2132
|
+
{ name: "X-API-Key", type: "apiKey" },
|
|
2133
|
+
{ scheme: "bearer", type: "http" },
|
|
2134
|
+
{ name: "Authorization", type: "apiKey" }
|
|
2135
|
+
],
|
|
2136
|
+
url: "/cfg/accounts/profile/avatar/",
|
|
2137
|
+
...options,
|
|
2138
|
+
headers: {
|
|
2139
|
+
"Content-Type": null,
|
|
2140
|
+
...options?.headers
|
|
2141
|
+
}
|
|
2142
|
+
});
|
|
2143
|
+
}
|
|
2144
|
+
/**
|
|
2145
|
+
* Delete user account
|
|
2146
|
+
*
|
|
2147
|
+
*
|
|
2148
|
+
* Permanently delete the current user's account.
|
|
2149
|
+
*
|
|
2150
|
+
* This operation:
|
|
2151
|
+
* - Deactivates the account (user cannot log in)
|
|
2152
|
+
* - Anonymizes personal data (GDPR compliance)
|
|
2153
|
+
* - Frees up the email address for re-registration
|
|
2154
|
+
* - Preserves audit trail
|
|
2155
|
+
*
|
|
2156
|
+
* The account can be restored by an administrator if needed.
|
|
2157
|
+
*
|
|
2158
|
+
*/
|
|
2159
|
+
static cfgAccountsProfileDeleteCreate(options) {
|
|
2160
|
+
return (options?.client ?? client).post({
|
|
2161
|
+
security: [{ scheme: "bearer", type: "http" }, {
|
|
2162
|
+
in: "cookie",
|
|
2163
|
+
name: "sessionid",
|
|
2164
|
+
type: "apiKey"
|
|
2165
|
+
}],
|
|
2166
|
+
url: "/cfg/accounts/profile/delete/",
|
|
2167
|
+
...options
|
|
2168
|
+
});
|
|
2169
|
+
}
|
|
2170
|
+
/**
|
|
2171
|
+
* Partial update user profile
|
|
2172
|
+
*
|
|
2173
|
+
* Partially update the current authenticated user's profile information. Supports avatar upload.
|
|
2174
|
+
*/
|
|
2175
|
+
static cfgAccountsProfilePartialPartialUpdate(options) {
|
|
2176
|
+
return (options?.client ?? client).patch({
|
|
2177
|
+
security: [{ scheme: "bearer", type: "http" }, {
|
|
2178
|
+
in: "cookie",
|
|
2179
|
+
name: "sessionid",
|
|
2180
|
+
type: "apiKey"
|
|
2181
|
+
}],
|
|
2182
|
+
url: "/cfg/accounts/profile/partial/",
|
|
2183
|
+
...options,
|
|
2184
|
+
headers: {
|
|
2185
|
+
"Content-Type": "application/json",
|
|
2186
|
+
...options?.headers
|
|
2187
|
+
}
|
|
2188
|
+
});
|
|
2189
|
+
}
|
|
2190
|
+
/**
|
|
2191
|
+
* Partial update user profile
|
|
2192
|
+
*
|
|
2193
|
+
* Partially update the current authenticated user's profile information. Supports avatar upload.
|
|
2194
|
+
*/
|
|
2195
|
+
static cfgAccountsProfilePartialUpdate(options) {
|
|
2196
|
+
return (options?.client ?? client).put({
|
|
2197
|
+
security: [{ scheme: "bearer", type: "http" }, {
|
|
2198
|
+
in: "cookie",
|
|
2199
|
+
name: "sessionid",
|
|
2200
|
+
type: "apiKey"
|
|
2201
|
+
}],
|
|
2202
|
+
url: "/cfg/accounts/profile/partial/",
|
|
2203
|
+
...options,
|
|
2204
|
+
headers: {
|
|
2205
|
+
"Content-Type": "application/json",
|
|
2206
|
+
...options?.headers
|
|
2207
|
+
}
|
|
2208
|
+
});
|
|
2209
|
+
}
|
|
2210
|
+
/**
|
|
2211
|
+
* Update user profile
|
|
2212
|
+
*
|
|
2213
|
+
* Update the current authenticated user's profile information.
|
|
2214
|
+
*/
|
|
2215
|
+
static cfgAccountsProfileUpdatePartialUpdate(options) {
|
|
2216
|
+
return (options?.client ?? client).patch({
|
|
2217
|
+
security: [{ scheme: "bearer", type: "http" }, {
|
|
2218
|
+
in: "cookie",
|
|
2219
|
+
name: "sessionid",
|
|
2220
|
+
type: "apiKey"
|
|
2221
|
+
}],
|
|
2222
|
+
url: "/cfg/accounts/profile/update/",
|
|
2223
|
+
...options,
|
|
2224
|
+
headers: {
|
|
2225
|
+
"Content-Type": "application/json",
|
|
2226
|
+
...options?.headers
|
|
2227
|
+
}
|
|
2228
|
+
});
|
|
2229
|
+
}
|
|
2230
|
+
/**
|
|
2231
|
+
* Update user profile
|
|
2232
|
+
*
|
|
2233
|
+
* Update the current authenticated user's profile information.
|
|
2234
|
+
*/
|
|
2235
|
+
static cfgAccountsProfileUpdateUpdate(options) {
|
|
2236
|
+
return (options?.client ?? client).put({
|
|
2237
|
+
security: [{ scheme: "bearer", type: "http" }, {
|
|
2238
|
+
in: "cookie",
|
|
2239
|
+
name: "sessionid",
|
|
2240
|
+
type: "apiKey"
|
|
2241
|
+
}],
|
|
2242
|
+
url: "/cfg/accounts/profile/update/",
|
|
2243
|
+
...options,
|
|
2244
|
+
headers: {
|
|
2245
|
+
"Content-Type": "application/json",
|
|
2246
|
+
...options?.headers
|
|
2247
|
+
}
|
|
2248
|
+
});
|
|
2249
|
+
}
|
|
2250
|
+
};
|
|
2251
|
+
var CfgAccountsAuth = class {
|
|
2252
|
+
static {
|
|
2253
|
+
__name(this, "CfgAccountsAuth");
|
|
2254
|
+
}
|
|
2255
|
+
/**
|
|
2256
|
+
* Revoke a refresh token (logout).
|
|
2257
|
+
*
|
|
2258
|
+
* Blacklists the posted refresh token so it can never mint another access
|
|
2259
|
+
* token. Called best-effort by the client's logout — without it, "logout"
|
|
2260
|
+
* is purely client-side and a stolen refresh token survives until expiry.
|
|
2261
|
+
*/
|
|
2262
|
+
static cfgAccountsTokenBlacklistCreate(options) {
|
|
2263
|
+
return (options.client ?? client).post({
|
|
2264
|
+
url: "/cfg/accounts/token/blacklist/",
|
|
2265
|
+
...options,
|
|
2266
|
+
headers: {
|
|
2267
|
+
"Content-Type": "application/json",
|
|
2268
|
+
...options.headers
|
|
2269
|
+
}
|
|
2270
|
+
});
|
|
2271
|
+
}
|
|
2272
|
+
/**
|
|
2273
|
+
* Refresh JWT token.
|
|
2274
|
+
*
|
|
2275
|
+
* DPoP-aware: when the incoming refresh token is key-bound (`cnf.jkt`), the
|
|
2276
|
+
* rotated access/refresh in the response are re-stamped with the same `cnf`
|
|
2277
|
+
* (stock SimpleJWT drops it from the derived access), and a matching DPoP
|
|
2278
|
+
* proof is required on the refresh request — so a stolen refresh token can't
|
|
2279
|
+
* be used to mint fresh tokens.
|
|
2280
|
+
*/
|
|
2281
|
+
static cfgAccountsTokenRefreshCreate(options) {
|
|
2282
|
+
return (options.client ?? client).post({
|
|
2283
|
+
url: "/cfg/accounts/token/refresh/",
|
|
2284
|
+
...options,
|
|
2285
|
+
headers: {
|
|
2286
|
+
"Content-Type": "application/json",
|
|
2287
|
+
...options.headers
|
|
2288
|
+
}
|
|
2289
|
+
});
|
|
2290
|
+
}
|
|
2291
|
+
};
|
|
2292
|
+
var CfgTotp = class {
|
|
2293
|
+
static {
|
|
2294
|
+
__name(this, "CfgTotp");
|
|
2295
|
+
}
|
|
2296
|
+
/**
|
|
2297
|
+
* List all TOTP devices for user.
|
|
2298
|
+
*/
|
|
2299
|
+
static cfgTotpDevicesRetrieve(options) {
|
|
2300
|
+
return (options?.client ?? client).get({
|
|
2301
|
+
security: [
|
|
2302
|
+
{ name: "X-API-Key", type: "apiKey" },
|
|
2303
|
+
{ scheme: "bearer", type: "http" },
|
|
2304
|
+
{ name: "Authorization", type: "apiKey" }
|
|
2305
|
+
],
|
|
2306
|
+
url: "/cfg/totp/devices/",
|
|
2307
|
+
...options
|
|
2308
|
+
});
|
|
2309
|
+
}
|
|
2310
|
+
/**
|
|
2311
|
+
* Delete a TOTP device.
|
|
2312
|
+
*
|
|
2313
|
+
* Requires verification code if removing the last/primary device.
|
|
2314
|
+
*/
|
|
2315
|
+
static cfgTotpDevicesDestroy(options) {
|
|
2316
|
+
return (options.client ?? client).delete({
|
|
2317
|
+
security: [
|
|
2318
|
+
{ name: "X-API-Key", type: "apiKey" },
|
|
2319
|
+
{ scheme: "bearer", type: "http" },
|
|
2320
|
+
{ name: "Authorization", type: "apiKey" }
|
|
2321
|
+
],
|
|
2322
|
+
url: "/cfg/totp/devices/{id}/",
|
|
2323
|
+
...options
|
|
2324
|
+
});
|
|
2325
|
+
}
|
|
2326
|
+
/**
|
|
2327
|
+
* Completely disable 2FA for account.
|
|
2328
|
+
*
|
|
2329
|
+
* Requires verification code.
|
|
2330
|
+
*/
|
|
2331
|
+
static cfgTotpDisableCreate(options) {
|
|
2332
|
+
return (options.client ?? client).post({
|
|
2333
|
+
security: [
|
|
2334
|
+
{ name: "X-API-Key", type: "apiKey" },
|
|
2335
|
+
{ scheme: "bearer", type: "http" },
|
|
2336
|
+
{ name: "Authorization", type: "apiKey" }
|
|
2337
|
+
],
|
|
2338
|
+
url: "/cfg/totp/disable/",
|
|
2339
|
+
...options,
|
|
2340
|
+
headers: {
|
|
2341
|
+
"Content-Type": "application/json",
|
|
2342
|
+
...options.headers
|
|
2343
|
+
}
|
|
2344
|
+
});
|
|
2345
|
+
}
|
|
2346
|
+
};
|
|
2347
|
+
var CfgTotpSetup = class {
|
|
2348
|
+
static {
|
|
2349
|
+
__name(this, "CfgTotpSetup");
|
|
2350
|
+
}
|
|
2351
|
+
/**
|
|
2352
|
+
* Start 2FA setup process.
|
|
2353
|
+
*
|
|
2354
|
+
* Creates a new TOTP device and returns QR code for scanning.
|
|
2355
|
+
*/
|
|
2356
|
+
static cfgTotpSetupCreate(options) {
|
|
2357
|
+
return (options?.client ?? client).post({
|
|
2358
|
+
security: [
|
|
2359
|
+
{ name: "X-API-Key", type: "apiKey" },
|
|
2360
|
+
{ scheme: "bearer", type: "http" },
|
|
2361
|
+
{ name: "Authorization", type: "apiKey" }
|
|
2362
|
+
],
|
|
2363
|
+
url: "/cfg/totp/setup/",
|
|
2364
|
+
...options,
|
|
2365
|
+
headers: {
|
|
2366
|
+
"Content-Type": "application/json",
|
|
2367
|
+
...options?.headers
|
|
2368
|
+
}
|
|
2369
|
+
});
|
|
2370
|
+
}
|
|
2371
|
+
/**
|
|
2372
|
+
* Confirm 2FA setup with first valid code.
|
|
2373
|
+
*
|
|
2374
|
+
* Activates the device and generates backup codes.
|
|
2375
|
+
*/
|
|
2376
|
+
static cfgTotpSetupConfirmCreate(options) {
|
|
2377
|
+
return (options.client ?? client).post({
|
|
2378
|
+
security: [
|
|
2379
|
+
{ name: "X-API-Key", type: "apiKey" },
|
|
2380
|
+
{ scheme: "bearer", type: "http" },
|
|
2381
|
+
{ name: "Authorization", type: "apiKey" }
|
|
2382
|
+
],
|
|
2383
|
+
url: "/cfg/totp/setup/confirm/",
|
|
2384
|
+
...options,
|
|
2385
|
+
headers: {
|
|
2386
|
+
"Content-Type": "application/json",
|
|
2387
|
+
...options.headers
|
|
2388
|
+
}
|
|
2389
|
+
});
|
|
2390
|
+
}
|
|
2391
|
+
};
|
|
2392
|
+
var CfgTotpVerify = class {
|
|
2393
|
+
static {
|
|
2394
|
+
__name(this, "CfgTotpVerify");
|
|
2395
|
+
}
|
|
2396
|
+
/**
|
|
2397
|
+
* Verify TOTP code for 2FA session.
|
|
2398
|
+
*
|
|
2399
|
+
* Completes authentication and returns JWT tokens on success.
|
|
2400
|
+
*/
|
|
2401
|
+
static cfgTotpVerifyCreate(options) {
|
|
2402
|
+
return (options.client ?? client).post({
|
|
2403
|
+
security: [
|
|
2404
|
+
{ name: "X-API-Key", type: "apiKey" },
|
|
2405
|
+
{ scheme: "bearer", type: "http" },
|
|
2406
|
+
{ name: "Authorization", type: "apiKey" }
|
|
2407
|
+
],
|
|
2408
|
+
url: "/cfg/totp/verify/",
|
|
2409
|
+
...options,
|
|
2410
|
+
headers: {
|
|
2411
|
+
"Content-Type": "application/json",
|
|
2412
|
+
...options.headers
|
|
2413
|
+
}
|
|
2414
|
+
});
|
|
2415
|
+
}
|
|
2416
|
+
/**
|
|
2417
|
+
* Verify backup recovery code for 2FA session.
|
|
2418
|
+
*
|
|
2419
|
+
* Alternative verification method when TOTP device unavailable.
|
|
2420
|
+
*/
|
|
2421
|
+
static cfgTotpVerifyBackupCreate(options) {
|
|
2422
|
+
return (options.client ?? client).post({
|
|
2423
|
+
security: [
|
|
2424
|
+
{ name: "X-API-Key", type: "apiKey" },
|
|
2425
|
+
{ scheme: "bearer", type: "http" },
|
|
2426
|
+
{ name: "Authorization", type: "apiKey" }
|
|
2427
|
+
],
|
|
2428
|
+
url: "/cfg/totp/verify/backup/",
|
|
2429
|
+
...options,
|
|
2430
|
+
headers: {
|
|
2431
|
+
"Content-Type": "application/json",
|
|
2432
|
+
...options.headers
|
|
2433
|
+
}
|
|
2434
|
+
});
|
|
2435
|
+
}
|
|
2436
|
+
};
|
|
2700
2437
|
|
|
2701
2438
|
// src/auth/utils/analytics.ts
|
|
2702
2439
|
var AnalyticsEvent = /* @__PURE__ */ ((AnalyticsEvent2) => {
|
|
@@ -2731,22 +2468,228 @@ var Analytics = {
|
|
|
2731
2468
|
if (isDev) {
|
|
2732
2469
|
console.log("[Analytics] Set user:", userId);
|
|
2733
2470
|
}
|
|
2734
|
-
}
|
|
2735
|
-
};
|
|
2471
|
+
}
|
|
2472
|
+
};
|
|
2473
|
+
|
|
2474
|
+
// src/auth/hooks/useSessionStorage.ts
|
|
2475
|
+
var import_react7 = require("react");
|
|
2476
|
+
function useSessionStorage(key, initialValue) {
|
|
2477
|
+
const [storedValue, setStoredValue] = (0, import_react7.useState)(() => {
|
|
2478
|
+
if (typeof window === "undefined") {
|
|
2479
|
+
return initialValue;
|
|
2480
|
+
}
|
|
2481
|
+
try {
|
|
2482
|
+
const item = window.sessionStorage.getItem(key);
|
|
2483
|
+
return item ? JSON.parse(item) : initialValue;
|
|
2484
|
+
} catch (error) {
|
|
2485
|
+
authLogger.error(`Error reading sessionStorage key "${key}":`, error);
|
|
2486
|
+
return initialValue;
|
|
2487
|
+
}
|
|
2488
|
+
});
|
|
2489
|
+
const checkDataSize = /* @__PURE__ */ __name((data) => {
|
|
2490
|
+
try {
|
|
2491
|
+
const jsonString = JSON.stringify(data);
|
|
2492
|
+
const sizeInBytes = new Blob([jsonString]).size;
|
|
2493
|
+
const sizeInKB = sizeInBytes / 1024;
|
|
2494
|
+
if (sizeInKB > 1024) {
|
|
2495
|
+
authLogger.warn(`Data size (${sizeInKB.toFixed(2)}KB) exceeds 1MB limit for key "${key}"`);
|
|
2496
|
+
return false;
|
|
2497
|
+
}
|
|
2498
|
+
return true;
|
|
2499
|
+
} catch (error) {
|
|
2500
|
+
authLogger.error(`Error checking data size for key "${key}":`, error);
|
|
2501
|
+
return false;
|
|
2502
|
+
}
|
|
2503
|
+
}, "checkDataSize");
|
|
2504
|
+
const clearOldData = /* @__PURE__ */ __name(() => {
|
|
2505
|
+
try {
|
|
2506
|
+
const keys = Object.keys(sessionStorage).filter((key2) => key2 && typeof key2 === "string");
|
|
2507
|
+
if (keys.length > 50) {
|
|
2508
|
+
const itemsToRemove = Math.ceil(keys.length * 0.2);
|
|
2509
|
+
for (let i = 0; i < itemsToRemove; i++) {
|
|
2510
|
+
try {
|
|
2511
|
+
const key2 = keys[i];
|
|
2512
|
+
if (key2) {
|
|
2513
|
+
sessionStorage.removeItem(key2);
|
|
2514
|
+
sessionStorage.removeItem(`${key2}_timestamp`);
|
|
2515
|
+
}
|
|
2516
|
+
} catch {
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2519
|
+
}
|
|
2520
|
+
} catch (error) {
|
|
2521
|
+
authLogger.error("Error clearing old sessionStorage data:", error);
|
|
2522
|
+
}
|
|
2523
|
+
}, "clearOldData");
|
|
2524
|
+
const forceClearAll = /* @__PURE__ */ __name(() => {
|
|
2525
|
+
try {
|
|
2526
|
+
const keys = Object.keys(sessionStorage);
|
|
2527
|
+
for (const key2 of keys) {
|
|
2528
|
+
try {
|
|
2529
|
+
sessionStorage.removeItem(key2);
|
|
2530
|
+
} catch {
|
|
2531
|
+
}
|
|
2532
|
+
}
|
|
2533
|
+
} catch (error) {
|
|
2534
|
+
authLogger.error("Error force clearing sessionStorage:", error);
|
|
2535
|
+
}
|
|
2536
|
+
}, "forceClearAll");
|
|
2537
|
+
const setValue = /* @__PURE__ */ __name((value) => {
|
|
2538
|
+
try {
|
|
2539
|
+
const valueToStore = value instanceof Function ? value(storedValue) : value;
|
|
2540
|
+
if (!checkDataSize(valueToStore)) {
|
|
2541
|
+
authLogger.warn(`Data size too large for key "${key}", removing key`);
|
|
2542
|
+
try {
|
|
2543
|
+
window.sessionStorage.removeItem(key);
|
|
2544
|
+
window.sessionStorage.removeItem(`${key}_timestamp`);
|
|
2545
|
+
} catch {
|
|
2546
|
+
}
|
|
2547
|
+
setStoredValue(valueToStore);
|
|
2548
|
+
return;
|
|
2549
|
+
}
|
|
2550
|
+
setStoredValue(valueToStore);
|
|
2551
|
+
if (typeof window !== "undefined") {
|
|
2552
|
+
try {
|
|
2553
|
+
window.sessionStorage.setItem(key, JSON.stringify(valueToStore));
|
|
2554
|
+
window.sessionStorage.setItem(`${key}_timestamp`, Date.now().toString());
|
|
2555
|
+
} catch (storageError) {
|
|
2556
|
+
if (storageError.name === "QuotaExceededError" || storageError.code === 22 || storageError.message?.includes("quota")) {
|
|
2557
|
+
authLogger.warn("sessionStorage quota exceeded, clearing old data...");
|
|
2558
|
+
clearOldData();
|
|
2559
|
+
try {
|
|
2560
|
+
window.sessionStorage.setItem(key, JSON.stringify(valueToStore));
|
|
2561
|
+
window.sessionStorage.setItem(`${key}_timestamp`, Date.now().toString());
|
|
2562
|
+
} catch (retryError) {
|
|
2563
|
+
authLogger.error(`Failed to set sessionStorage key "${key}" after clearing old data:`, retryError);
|
|
2564
|
+
try {
|
|
2565
|
+
forceClearAll();
|
|
2566
|
+
window.sessionStorage.setItem(key, JSON.stringify(valueToStore));
|
|
2567
|
+
window.sessionStorage.setItem(`${key}_timestamp`, Date.now().toString());
|
|
2568
|
+
} catch (finalError) {
|
|
2569
|
+
authLogger.error(`Failed to set sessionStorage key "${key}" after force clearing:`, finalError);
|
|
2570
|
+
setStoredValue(valueToStore);
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2573
|
+
} else {
|
|
2574
|
+
throw storageError;
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2577
|
+
}
|
|
2578
|
+
} catch (error) {
|
|
2579
|
+
authLogger.error(`Error setting sessionStorage key "${key}":`, error);
|
|
2580
|
+
const valueToStore = value instanceof Function ? value(storedValue) : value;
|
|
2581
|
+
setStoredValue(valueToStore);
|
|
2582
|
+
}
|
|
2583
|
+
}, "setValue");
|
|
2584
|
+
const removeValue = /* @__PURE__ */ __name(() => {
|
|
2585
|
+
try {
|
|
2586
|
+
setStoredValue(initialValue);
|
|
2587
|
+
if (typeof window !== "undefined") {
|
|
2588
|
+
try {
|
|
2589
|
+
window.sessionStorage.removeItem(key);
|
|
2590
|
+
window.sessionStorage.removeItem(`${key}_timestamp`);
|
|
2591
|
+
} catch (removeError) {
|
|
2592
|
+
if (removeError.name === "QuotaExceededError" || removeError.code === 22 || removeError.message?.includes("quota")) {
|
|
2593
|
+
authLogger.warn("sessionStorage quota exceeded during removal, clearing old data...");
|
|
2594
|
+
clearOldData();
|
|
2595
|
+
try {
|
|
2596
|
+
window.sessionStorage.removeItem(key);
|
|
2597
|
+
window.sessionStorage.removeItem(`${key}_timestamp`);
|
|
2598
|
+
} catch (retryError) {
|
|
2599
|
+
authLogger.error(`Failed to remove sessionStorage key "${key}" after clearing:`, retryError);
|
|
2600
|
+
forceClearAll();
|
|
2601
|
+
}
|
|
2602
|
+
} else {
|
|
2603
|
+
throw removeError;
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
} catch (error) {
|
|
2608
|
+
authLogger.error(`Error removing sessionStorage key "${key}":`, error);
|
|
2609
|
+
}
|
|
2610
|
+
}, "removeValue");
|
|
2611
|
+
return [storedValue, setValue, removeValue];
|
|
2612
|
+
}
|
|
2613
|
+
__name(useSessionStorage, "useSessionStorage");
|
|
2614
|
+
|
|
2615
|
+
// src/auth/hooks/useAuthRedirect.ts
|
|
2616
|
+
var AUTH_REDIRECT_KEY = "auth_redirect_url";
|
|
2617
|
+
var getRedirectFromStorage = /* @__PURE__ */ __name(() => {
|
|
2618
|
+
if (typeof window === "undefined") return "";
|
|
2619
|
+
try {
|
|
2620
|
+
const item = window.sessionStorage.getItem(AUTH_REDIRECT_KEY);
|
|
2621
|
+
return item ? JSON.parse(item) : "";
|
|
2622
|
+
} catch {
|
|
2623
|
+
return "";
|
|
2624
|
+
}
|
|
2625
|
+
}, "getRedirectFromStorage");
|
|
2626
|
+
var clearRedirectFromStorage = /* @__PURE__ */ __name(() => {
|
|
2627
|
+
if (typeof window === "undefined") return;
|
|
2628
|
+
try {
|
|
2629
|
+
window.sessionStorage.removeItem(AUTH_REDIRECT_KEY);
|
|
2630
|
+
window.sessionStorage.removeItem(`${AUTH_REDIRECT_KEY}_timestamp`);
|
|
2631
|
+
} catch {
|
|
2632
|
+
}
|
|
2633
|
+
}, "clearRedirectFromStorage");
|
|
2634
|
+
var peekSavedRedirect = /* @__PURE__ */ __name(() => getRedirectFromStorage() || null, "peekSavedRedirect");
|
|
2635
|
+
var consumeSavedRedirect = /* @__PURE__ */ __name(() => {
|
|
2636
|
+
const stored = getRedirectFromStorage();
|
|
2637
|
+
if (stored) clearRedirectFromStorage();
|
|
2638
|
+
return stored || null;
|
|
2639
|
+
}, "consumeSavedRedirect");
|
|
2640
|
+
var useAuthRedirectManager = /* @__PURE__ */ __name((options = {}) => {
|
|
2641
|
+
const { fallbackUrl = "/dashboard", clearOnUse = true } = options;
|
|
2642
|
+
const [redirectUrl, setRedirectUrl, removeRedirectUrl] = useSessionStorage(AUTH_REDIRECT_KEY, "");
|
|
2643
|
+
const setRedirect = /* @__PURE__ */ __name((url) => {
|
|
2644
|
+
setRedirectUrl(url);
|
|
2645
|
+
}, "setRedirect");
|
|
2646
|
+
const getRedirect = /* @__PURE__ */ __name(() => {
|
|
2647
|
+
return getRedirectFromStorage() || redirectUrl;
|
|
2648
|
+
}, "getRedirect");
|
|
2649
|
+
const clearRedirect = /* @__PURE__ */ __name(() => {
|
|
2650
|
+
removeRedirectUrl();
|
|
2651
|
+
clearRedirectFromStorage();
|
|
2652
|
+
}, "clearRedirect");
|
|
2653
|
+
const hasRedirect = /* @__PURE__ */ __name(() => {
|
|
2654
|
+
const stored = getRedirectFromStorage();
|
|
2655
|
+
return stored.length > 0 || redirectUrl.length > 0;
|
|
2656
|
+
}, "hasRedirect");
|
|
2657
|
+
const getFinalRedirectUrl = /* @__PURE__ */ __name(() => {
|
|
2658
|
+
const stored = getRedirectFromStorage();
|
|
2659
|
+
return stored || redirectUrl || fallbackUrl;
|
|
2660
|
+
}, "getFinalRedirectUrl");
|
|
2661
|
+
const useAndClearRedirect = /* @__PURE__ */ __name(() => {
|
|
2662
|
+
const stored = getRedirectFromStorage();
|
|
2663
|
+
const finalUrl = stored || redirectUrl || fallbackUrl;
|
|
2664
|
+
if (clearOnUse) {
|
|
2665
|
+
clearRedirect();
|
|
2666
|
+
}
|
|
2667
|
+
return finalUrl;
|
|
2668
|
+
}, "useAndClearRedirect");
|
|
2669
|
+
return {
|
|
2670
|
+
redirectUrl,
|
|
2671
|
+
setRedirect,
|
|
2672
|
+
getRedirect,
|
|
2673
|
+
clearRedirect,
|
|
2674
|
+
hasRedirect,
|
|
2675
|
+
getFinalRedirectUrl,
|
|
2676
|
+
useAndClearRedirect
|
|
2677
|
+
};
|
|
2678
|
+
}, "useAuthRedirectManager");
|
|
2736
2679
|
|
|
2737
2680
|
// src/auth/hooks/useTwoFactor.ts
|
|
2738
2681
|
var useTwoFactor = /* @__PURE__ */ __name((options = {}) => {
|
|
2739
2682
|
const { onSuccess, onError, redirectUrl, skipRedirect = false } = options;
|
|
2740
2683
|
const router = useCfgRouter();
|
|
2741
|
-
const [isLoading, setIsLoading] = (0,
|
|
2742
|
-
const [error, setError] = (0,
|
|
2743
|
-
const [warning, setWarning] = (0,
|
|
2744
|
-
const [remainingBackupCodes, setRemainingBackupCodes] = (0,
|
|
2745
|
-
const [attemptsRemaining, setAttemptsRemaining] = (0,
|
|
2746
|
-
const clearError = (0,
|
|
2684
|
+
const [isLoading, setIsLoading] = (0, import_react8.useState)(false);
|
|
2685
|
+
const [error, setError] = (0, import_react8.useState)(null);
|
|
2686
|
+
const [warning, setWarning] = (0, import_react8.useState)(null);
|
|
2687
|
+
const [remainingBackupCodes, setRemainingBackupCodes] = (0, import_react8.useState)(null);
|
|
2688
|
+
const [attemptsRemaining, setAttemptsRemaining] = (0, import_react8.useState)(null);
|
|
2689
|
+
const clearError = (0, import_react8.useCallback)(() => {
|
|
2747
2690
|
setError(null);
|
|
2748
2691
|
}, []);
|
|
2749
|
-
const handleSuccess = (0,
|
|
2692
|
+
const handleSuccess = (0, import_react8.useCallback)((response) => {
|
|
2750
2693
|
auth.setSession({ access: response.access_token, refresh: response.refresh_token });
|
|
2751
2694
|
if (response.warning) {
|
|
2752
2695
|
setWarning(response.warning);
|
|
@@ -2763,12 +2706,12 @@ var useTwoFactor = /* @__PURE__ */ __name((options = {}) => {
|
|
|
2763
2706
|
}
|
|
2764
2707
|
onSuccess?.(response.user);
|
|
2765
2708
|
if (!skipRedirect) {
|
|
2766
|
-
const finalRedirectUrl = redirectUrl || "/
|
|
2709
|
+
const finalRedirectUrl = consumeSavedRedirect() || redirectUrl || "/";
|
|
2767
2710
|
authLogger.info("2FA successful, redirecting to:", finalRedirectUrl);
|
|
2768
2711
|
router.hardPush(finalRedirectUrl);
|
|
2769
2712
|
}
|
|
2770
2713
|
}, [onSuccess, redirectUrl, router, skipRedirect]);
|
|
2771
|
-
const verifyTOTP = (0,
|
|
2714
|
+
const verifyTOTP = (0, import_react8.useCallback)(async (sessionId, code) => {
|
|
2772
2715
|
if (!sessionId) {
|
|
2773
2716
|
const msg = "Missing 2FA session ID";
|
|
2774
2717
|
setError(msg);
|
|
@@ -2812,7 +2755,7 @@ var useTwoFactor = /* @__PURE__ */ __name((options = {}) => {
|
|
|
2812
2755
|
setIsLoading(false);
|
|
2813
2756
|
}
|
|
2814
2757
|
}, [handleSuccess, onError]);
|
|
2815
|
-
const verifyBackupCode = (0,
|
|
2758
|
+
const verifyBackupCode = (0, import_react8.useCallback)(async (sessionId, backupCode) => {
|
|
2816
2759
|
if (!sessionId) {
|
|
2817
2760
|
const msg = "Missing 2FA session ID";
|
|
2818
2761
|
setError(msg);
|
|
@@ -2884,8 +2827,8 @@ var useAuthForm = /* @__PURE__ */ __name((options) => {
|
|
|
2884
2827
|
} = options;
|
|
2885
2828
|
const formState = useAuthFormState();
|
|
2886
2829
|
const validation = useAuthValidation();
|
|
2887
|
-
const isAutoSubmitFromUrlRef = (0,
|
|
2888
|
-
const processedOtpKeyRef = (0,
|
|
2830
|
+
const isAutoSubmitFromUrlRef = (0, import_react9.useRef)(false);
|
|
2831
|
+
const processedOtpKeyRef = (0, import_react9.useRef)(null);
|
|
2889
2832
|
const {
|
|
2890
2833
|
requestOTP,
|
|
2891
2834
|
verifyOTP,
|
|
@@ -2928,16 +2871,16 @@ var useAuthForm = /* @__PURE__ */ __name((options) => {
|
|
|
2928
2871
|
// We handle navigation via success step
|
|
2929
2872
|
});
|
|
2930
2873
|
const { validateIdentifier: validateIdentifier2 } = validation;
|
|
2931
|
-
const saveIdentifierToStorage = (0,
|
|
2874
|
+
const saveIdentifierToStorage = (0, import_react9.useCallback)((id) => {
|
|
2932
2875
|
saveEmail(id);
|
|
2933
2876
|
}, [saveEmail]);
|
|
2934
|
-
(0,
|
|
2877
|
+
(0, import_react9.useEffect)(() => {
|
|
2935
2878
|
const savedEmail = getSavedEmail();
|
|
2936
2879
|
if (savedEmail) {
|
|
2937
2880
|
setIdentifier(savedEmail);
|
|
2938
2881
|
}
|
|
2939
2882
|
}, []);
|
|
2940
|
-
const handleIdentifierSubmit = (0,
|
|
2883
|
+
const handleIdentifierSubmit = (0, import_react9.useCallback)(async (e) => {
|
|
2941
2884
|
e.preventDefault();
|
|
2942
2885
|
if (!identifier) {
|
|
2943
2886
|
const msg = "Please enter your email address";
|
|
@@ -2999,7 +2942,7 @@ var useAuthForm = /* @__PURE__ */ __name((options) => {
|
|
|
2999
2942
|
onError,
|
|
3000
2943
|
sourceUrl
|
|
3001
2944
|
]);
|
|
3002
|
-
const submitOTP = (0,
|
|
2945
|
+
const submitOTP = (0, import_react9.useCallback)(async (submitIdentifier, submitOtp) => {
|
|
3003
2946
|
if (!submitOtp || submitOtp.length < AUTH_CONSTANTS.EMAIL_OTP_LENGTH) {
|
|
3004
2947
|
const msg = `Please enter the ${AUTH_CONSTANTS.EMAIL_OTP_LENGTH}-digit verification code`;
|
|
3005
2948
|
setError(msg);
|
|
@@ -3038,11 +2981,11 @@ var useAuthForm = /* @__PURE__ */ __name((options) => {
|
|
|
3038
2981
|
setIsLoading(false);
|
|
3039
2982
|
}
|
|
3040
2983
|
}, [verifyOTP, saveIdentifierToStorage, setError, setIsLoading, clearError, onOTPSuccess, onError, sourceUrl, redirectUrl, setTwoFactorSessionId, setShouldPrompt2FA, setStep]);
|
|
3041
|
-
const handleOTPSubmit = (0,
|
|
2984
|
+
const handleOTPSubmit = (0, import_react9.useCallback)(async (e) => {
|
|
3042
2985
|
e.preventDefault();
|
|
3043
2986
|
await submitOTP(identifier, otp);
|
|
3044
2987
|
}, [identifier, otp, submitOTP]);
|
|
3045
|
-
const handleResendOTP = (0,
|
|
2988
|
+
const handleResendOTP = (0, import_react9.useCallback)(async () => {
|
|
3046
2989
|
setIsLoading(true);
|
|
3047
2990
|
clearError();
|
|
3048
2991
|
try {
|
|
@@ -3068,15 +3011,15 @@ var useAuthForm = /* @__PURE__ */ __name((options) => {
|
|
|
3068
3011
|
setIsLoading(false);
|
|
3069
3012
|
}
|
|
3070
3013
|
}, [identifier, requestOTP, saveIdentifierToStorage, setOtp, setError, setIsLoading, clearError, startRateLimitCountdown, setWebmail, onError, sourceUrl]);
|
|
3071
|
-
const handleBackToIdentifier = (0,
|
|
3014
|
+
const handleBackToIdentifier = (0, import_react9.useCallback)(() => {
|
|
3072
3015
|
setStep("identifier");
|
|
3073
3016
|
clearError();
|
|
3074
3017
|
}, [setStep, clearError]);
|
|
3075
|
-
const forceOTPStep = (0,
|
|
3018
|
+
const forceOTPStep = (0, import_react9.useCallback)(() => {
|
|
3076
3019
|
setStep("otp");
|
|
3077
3020
|
clearError();
|
|
3078
3021
|
}, [setStep, clearError]);
|
|
3079
|
-
const handle2FASubmit = (0,
|
|
3022
|
+
const handle2FASubmit = (0, import_react9.useCallback)(async (e) => {
|
|
3080
3023
|
e.preventDefault();
|
|
3081
3024
|
if (!twoFactorSessionId) {
|
|
3082
3025
|
const msg = "Missing 2FA session";
|
|
@@ -3090,17 +3033,17 @@ var useAuthForm = /* @__PURE__ */ __name((options) => {
|
|
|
3090
3033
|
await twoFactor.verifyTOTP(twoFactorSessionId, twoFactorCode);
|
|
3091
3034
|
}
|
|
3092
3035
|
}, [twoFactorSessionId, twoFactorCode, useBackupCode, twoFactor, setError, onError]);
|
|
3093
|
-
const handleUseBackupCode = (0,
|
|
3036
|
+
const handleUseBackupCode = (0, import_react9.useCallback)(() => {
|
|
3094
3037
|
setUseBackupCode(true);
|
|
3095
3038
|
setTwoFactorCode("");
|
|
3096
3039
|
clearError();
|
|
3097
3040
|
}, [setUseBackupCode, setTwoFactorCode, clearError]);
|
|
3098
|
-
const handleUseTOTP = (0,
|
|
3041
|
+
const handleUseTOTP = (0, import_react9.useCallback)(() => {
|
|
3099
3042
|
setUseBackupCode(false);
|
|
3100
3043
|
setTwoFactorCode("");
|
|
3101
3044
|
clearError();
|
|
3102
3045
|
}, [setUseBackupCode, setTwoFactorCode, clearError]);
|
|
3103
|
-
const handleOTPFromUrl = (0,
|
|
3046
|
+
const handleOTPFromUrl = (0, import_react9.useCallback)((detectedOtp, detectedEmail) => {
|
|
3104
3047
|
const autoIdentifier = detectedEmail || getSavedEmail() || "";
|
|
3105
3048
|
if (!autoIdentifier) {
|
|
3106
3049
|
authLogger.warn("No identifier found for auto-submit (no email in URL or storage)");
|
|
@@ -3153,15 +3096,13 @@ var useAuthForm = /* @__PURE__ */ __name((options) => {
|
|
|
3153
3096
|
}, "useAuthForm");
|
|
3154
3097
|
|
|
3155
3098
|
// src/auth/hooks/useGithubAuth.ts
|
|
3156
|
-
var
|
|
3157
|
-
init_auth();
|
|
3158
|
-
init_sdk_gen();
|
|
3099
|
+
var import_react10 = require("react");
|
|
3159
3100
|
var useGithubAuth = /* @__PURE__ */ __name((options = {}) => {
|
|
3160
3101
|
const { sourceUrl, onSuccess, onError, onRequires2FA, redirectUrl, skipRedirect = false } = options;
|
|
3161
3102
|
const router = useCfgRouter();
|
|
3162
|
-
const [isLoading, setIsLoading] = (0,
|
|
3163
|
-
const [error, setError] = (0,
|
|
3164
|
-
const startGithubAuth = (0,
|
|
3103
|
+
const [isLoading, setIsLoading] = (0, import_react10.useState)(false);
|
|
3104
|
+
const [error, setError] = (0, import_react10.useState)(null);
|
|
3105
|
+
const startGithubAuth = (0, import_react10.useCallback)(async () => {
|
|
3165
3106
|
setIsLoading(true);
|
|
3166
3107
|
setError(null);
|
|
3167
3108
|
try {
|
|
@@ -3199,7 +3140,7 @@ var useGithubAuth = /* @__PURE__ */ __name((options = {}) => {
|
|
|
3199
3140
|
setIsLoading(false);
|
|
3200
3141
|
}
|
|
3201
3142
|
}, [sourceUrl, onError]);
|
|
3202
|
-
const handleGithubCallback = (0,
|
|
3143
|
+
const handleGithubCallback = (0, import_react10.useCallback)(async (code, state) => {
|
|
3203
3144
|
setIsLoading(true);
|
|
3204
3145
|
setError(null);
|
|
3205
3146
|
try {
|
|
@@ -3265,27 +3206,26 @@ var useGithubAuth = /* @__PURE__ */ __name((options = {}) => {
|
|
|
3265
3206
|
}, "useGithubAuth");
|
|
3266
3207
|
|
|
3267
3208
|
// src/auth/hooks/useTwoFactorSetup.ts
|
|
3268
|
-
var
|
|
3269
|
-
init_sdk_gen();
|
|
3209
|
+
var import_react11 = require("react");
|
|
3270
3210
|
var useTwoFactorSetup = /* @__PURE__ */ __name((options = {}) => {
|
|
3271
3211
|
const { onComplete, onError } = options;
|
|
3272
|
-
const [isLoading, setIsLoading] = (0,
|
|
3273
|
-
const [error, setError] = (0,
|
|
3274
|
-
const [setupData, setSetupData] = (0,
|
|
3275
|
-
const [backupCodes, setBackupCodes] = (0,
|
|
3276
|
-
const [backupCodesWarning, setBackupCodesWarning] = (0,
|
|
3277
|
-
const [setupStep, setSetupStep] = (0,
|
|
3278
|
-
const clearError = (0,
|
|
3212
|
+
const [isLoading, setIsLoading] = (0, import_react11.useState)(false);
|
|
3213
|
+
const [error, setError] = (0, import_react11.useState)(null);
|
|
3214
|
+
const [setupData, setSetupData] = (0, import_react11.useState)(null);
|
|
3215
|
+
const [backupCodes, setBackupCodes] = (0, import_react11.useState)(null);
|
|
3216
|
+
const [backupCodesWarning, setBackupCodesWarning] = (0, import_react11.useState)(null);
|
|
3217
|
+
const [setupStep, setSetupStep] = (0, import_react11.useState)("idle");
|
|
3218
|
+
const clearError = (0, import_react11.useCallback)(() => {
|
|
3279
3219
|
setError(null);
|
|
3280
3220
|
}, []);
|
|
3281
|
-
const resetSetup = (0,
|
|
3221
|
+
const resetSetup = (0, import_react11.useCallback)(() => {
|
|
3282
3222
|
setSetupData(null);
|
|
3283
3223
|
setBackupCodes(null);
|
|
3284
3224
|
setBackupCodesWarning(null);
|
|
3285
3225
|
setSetupStep("idle");
|
|
3286
3226
|
setError(null);
|
|
3287
3227
|
}, []);
|
|
3288
|
-
const startSetup = (0,
|
|
3228
|
+
const startSetup = (0, import_react11.useCallback)(async (deviceName) => {
|
|
3289
3229
|
setIsLoading(true);
|
|
3290
3230
|
setError(null);
|
|
3291
3231
|
setSetupStep("scanning");
|
|
@@ -3317,7 +3257,7 @@ var useTwoFactorSetup = /* @__PURE__ */ __name((options = {}) => {
|
|
|
3317
3257
|
setIsLoading(false);
|
|
3318
3258
|
}
|
|
3319
3259
|
}, [onError]);
|
|
3320
|
-
const confirmSetup = (0,
|
|
3260
|
+
const confirmSetup = (0, import_react11.useCallback)(async (code) => {
|
|
3321
3261
|
if (!setupData) {
|
|
3322
3262
|
const msg = "Setup not started. Call startSetup() first.";
|
|
3323
3263
|
setError(msg);
|
|
@@ -3373,8 +3313,7 @@ var useTwoFactorSetup = /* @__PURE__ */ __name((options = {}) => {
|
|
|
3373
3313
|
}, "useTwoFactorSetup");
|
|
3374
3314
|
|
|
3375
3315
|
// src/auth/hooks/useTwoFactorStatus.ts
|
|
3376
|
-
var
|
|
3377
|
-
init_sdk_gen();
|
|
3316
|
+
var import_react12 = require("react");
|
|
3378
3317
|
function extractErrorMessage(err, fallback) {
|
|
3379
3318
|
if (err instanceof APIError) {
|
|
3380
3319
|
const body = err.response;
|
|
@@ -3387,14 +3326,14 @@ function extractErrorMessage(err, fallback) {
|
|
|
3387
3326
|
}
|
|
3388
3327
|
__name(extractErrorMessage, "extractErrorMessage");
|
|
3389
3328
|
var useTwoFactorStatus = /* @__PURE__ */ __name(() => {
|
|
3390
|
-
const [isLoading, setIsLoading] = (0,
|
|
3391
|
-
const [error, setError] = (0,
|
|
3392
|
-
const [has2FAEnabled, setHas2FAEnabled] = (0,
|
|
3393
|
-
const [devices, setDevices] = (0,
|
|
3394
|
-
const clearError = (0,
|
|
3329
|
+
const [isLoading, setIsLoading] = (0, import_react12.useState)(false);
|
|
3330
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
3331
|
+
const [has2FAEnabled, setHas2FAEnabled] = (0, import_react12.useState)(null);
|
|
3332
|
+
const [devices, setDevices] = (0, import_react12.useState)([]);
|
|
3333
|
+
const clearError = (0, import_react12.useCallback)(() => {
|
|
3395
3334
|
setError(null);
|
|
3396
3335
|
}, []);
|
|
3397
|
-
const fetchStatus = (0,
|
|
3336
|
+
const fetchStatus = (0, import_react12.useCallback)(async () => {
|
|
3398
3337
|
setIsLoading(true);
|
|
3399
3338
|
setError(null);
|
|
3400
3339
|
try {
|
|
@@ -3419,7 +3358,7 @@ var useTwoFactorStatus = /* @__PURE__ */ __name(() => {
|
|
|
3419
3358
|
setIsLoading(false);
|
|
3420
3359
|
}
|
|
3421
3360
|
}, []);
|
|
3422
|
-
const disable2FA = (0,
|
|
3361
|
+
const disable2FA = (0, import_react12.useCallback)(async (code) => {
|
|
3423
3362
|
if (!code || code.length !== 6) {
|
|
3424
3363
|
setError("Please enter a 6-digit code");
|
|
3425
3364
|
return false;
|
|
@@ -3453,206 +3392,6 @@ var useTwoFactorStatus = /* @__PURE__ */ __name(() => {
|
|
|
3453
3392
|
};
|
|
3454
3393
|
}, "useTwoFactorStatus");
|
|
3455
3394
|
|
|
3456
|
-
// src/auth/hooks/useSessionStorage.ts
|
|
3457
|
-
var import_react12 = require("react");
|
|
3458
|
-
function useSessionStorage(key, initialValue) {
|
|
3459
|
-
const [storedValue, setStoredValue] = (0, import_react12.useState)(() => {
|
|
3460
|
-
if (typeof window === "undefined") {
|
|
3461
|
-
return initialValue;
|
|
3462
|
-
}
|
|
3463
|
-
try {
|
|
3464
|
-
const item = window.sessionStorage.getItem(key);
|
|
3465
|
-
return item ? JSON.parse(item) : initialValue;
|
|
3466
|
-
} catch (error) {
|
|
3467
|
-
authLogger.error(`Error reading sessionStorage key "${key}":`, error);
|
|
3468
|
-
return initialValue;
|
|
3469
|
-
}
|
|
3470
|
-
});
|
|
3471
|
-
const checkDataSize = /* @__PURE__ */ __name((data) => {
|
|
3472
|
-
try {
|
|
3473
|
-
const jsonString = JSON.stringify(data);
|
|
3474
|
-
const sizeInBytes = new Blob([jsonString]).size;
|
|
3475
|
-
const sizeInKB = sizeInBytes / 1024;
|
|
3476
|
-
if (sizeInKB > 1024) {
|
|
3477
|
-
authLogger.warn(`Data size (${sizeInKB.toFixed(2)}KB) exceeds 1MB limit for key "${key}"`);
|
|
3478
|
-
return false;
|
|
3479
|
-
}
|
|
3480
|
-
return true;
|
|
3481
|
-
} catch (error) {
|
|
3482
|
-
authLogger.error(`Error checking data size for key "${key}":`, error);
|
|
3483
|
-
return false;
|
|
3484
|
-
}
|
|
3485
|
-
}, "checkDataSize");
|
|
3486
|
-
const clearOldData = /* @__PURE__ */ __name(() => {
|
|
3487
|
-
try {
|
|
3488
|
-
const keys = Object.keys(sessionStorage).filter((key2) => key2 && typeof key2 === "string");
|
|
3489
|
-
if (keys.length > 50) {
|
|
3490
|
-
const itemsToRemove = Math.ceil(keys.length * 0.2);
|
|
3491
|
-
for (let i = 0; i < itemsToRemove; i++) {
|
|
3492
|
-
try {
|
|
3493
|
-
const key2 = keys[i];
|
|
3494
|
-
if (key2) {
|
|
3495
|
-
sessionStorage.removeItem(key2);
|
|
3496
|
-
sessionStorage.removeItem(`${key2}_timestamp`);
|
|
3497
|
-
}
|
|
3498
|
-
} catch {
|
|
3499
|
-
}
|
|
3500
|
-
}
|
|
3501
|
-
}
|
|
3502
|
-
} catch (error) {
|
|
3503
|
-
authLogger.error("Error clearing old sessionStorage data:", error);
|
|
3504
|
-
}
|
|
3505
|
-
}, "clearOldData");
|
|
3506
|
-
const forceClearAll = /* @__PURE__ */ __name(() => {
|
|
3507
|
-
try {
|
|
3508
|
-
const keys = Object.keys(sessionStorage);
|
|
3509
|
-
for (const key2 of keys) {
|
|
3510
|
-
try {
|
|
3511
|
-
sessionStorage.removeItem(key2);
|
|
3512
|
-
} catch {
|
|
3513
|
-
}
|
|
3514
|
-
}
|
|
3515
|
-
} catch (error) {
|
|
3516
|
-
authLogger.error("Error force clearing sessionStorage:", error);
|
|
3517
|
-
}
|
|
3518
|
-
}, "forceClearAll");
|
|
3519
|
-
const setValue = /* @__PURE__ */ __name((value) => {
|
|
3520
|
-
try {
|
|
3521
|
-
const valueToStore = value instanceof Function ? value(storedValue) : value;
|
|
3522
|
-
if (!checkDataSize(valueToStore)) {
|
|
3523
|
-
authLogger.warn(`Data size too large for key "${key}", removing key`);
|
|
3524
|
-
try {
|
|
3525
|
-
window.sessionStorage.removeItem(key);
|
|
3526
|
-
window.sessionStorage.removeItem(`${key}_timestamp`);
|
|
3527
|
-
} catch {
|
|
3528
|
-
}
|
|
3529
|
-
setStoredValue(valueToStore);
|
|
3530
|
-
return;
|
|
3531
|
-
}
|
|
3532
|
-
setStoredValue(valueToStore);
|
|
3533
|
-
if (typeof window !== "undefined") {
|
|
3534
|
-
try {
|
|
3535
|
-
window.sessionStorage.setItem(key, JSON.stringify(valueToStore));
|
|
3536
|
-
window.sessionStorage.setItem(`${key}_timestamp`, Date.now().toString());
|
|
3537
|
-
} catch (storageError) {
|
|
3538
|
-
if (storageError.name === "QuotaExceededError" || storageError.code === 22 || storageError.message?.includes("quota")) {
|
|
3539
|
-
authLogger.warn("sessionStorage quota exceeded, clearing old data...");
|
|
3540
|
-
clearOldData();
|
|
3541
|
-
try {
|
|
3542
|
-
window.sessionStorage.setItem(key, JSON.stringify(valueToStore));
|
|
3543
|
-
window.sessionStorage.setItem(`${key}_timestamp`, Date.now().toString());
|
|
3544
|
-
} catch (retryError) {
|
|
3545
|
-
authLogger.error(`Failed to set sessionStorage key "${key}" after clearing old data:`, retryError);
|
|
3546
|
-
try {
|
|
3547
|
-
forceClearAll();
|
|
3548
|
-
window.sessionStorage.setItem(key, JSON.stringify(valueToStore));
|
|
3549
|
-
window.sessionStorage.setItem(`${key}_timestamp`, Date.now().toString());
|
|
3550
|
-
} catch (finalError) {
|
|
3551
|
-
authLogger.error(`Failed to set sessionStorage key "${key}" after force clearing:`, finalError);
|
|
3552
|
-
setStoredValue(valueToStore);
|
|
3553
|
-
}
|
|
3554
|
-
}
|
|
3555
|
-
} else {
|
|
3556
|
-
throw storageError;
|
|
3557
|
-
}
|
|
3558
|
-
}
|
|
3559
|
-
}
|
|
3560
|
-
} catch (error) {
|
|
3561
|
-
authLogger.error(`Error setting sessionStorage key "${key}":`, error);
|
|
3562
|
-
const valueToStore = value instanceof Function ? value(storedValue) : value;
|
|
3563
|
-
setStoredValue(valueToStore);
|
|
3564
|
-
}
|
|
3565
|
-
}, "setValue");
|
|
3566
|
-
const removeValue = /* @__PURE__ */ __name(() => {
|
|
3567
|
-
try {
|
|
3568
|
-
setStoredValue(initialValue);
|
|
3569
|
-
if (typeof window !== "undefined") {
|
|
3570
|
-
try {
|
|
3571
|
-
window.sessionStorage.removeItem(key);
|
|
3572
|
-
window.sessionStorage.removeItem(`${key}_timestamp`);
|
|
3573
|
-
} catch (removeError) {
|
|
3574
|
-
if (removeError.name === "QuotaExceededError" || removeError.code === 22 || removeError.message?.includes("quota")) {
|
|
3575
|
-
authLogger.warn("sessionStorage quota exceeded during removal, clearing old data...");
|
|
3576
|
-
clearOldData();
|
|
3577
|
-
try {
|
|
3578
|
-
window.sessionStorage.removeItem(key);
|
|
3579
|
-
window.sessionStorage.removeItem(`${key}_timestamp`);
|
|
3580
|
-
} catch (retryError) {
|
|
3581
|
-
authLogger.error(`Failed to remove sessionStorage key "${key}" after clearing:`, retryError);
|
|
3582
|
-
forceClearAll();
|
|
3583
|
-
}
|
|
3584
|
-
} else {
|
|
3585
|
-
throw removeError;
|
|
3586
|
-
}
|
|
3587
|
-
}
|
|
3588
|
-
}
|
|
3589
|
-
} catch (error) {
|
|
3590
|
-
authLogger.error(`Error removing sessionStorage key "${key}":`, error);
|
|
3591
|
-
}
|
|
3592
|
-
}, "removeValue");
|
|
3593
|
-
return [storedValue, setValue, removeValue];
|
|
3594
|
-
}
|
|
3595
|
-
__name(useSessionStorage, "useSessionStorage");
|
|
3596
|
-
|
|
3597
|
-
// src/auth/hooks/useAuthRedirect.ts
|
|
3598
|
-
var AUTH_REDIRECT_KEY = "auth_redirect_url";
|
|
3599
|
-
var getRedirectFromStorage = /* @__PURE__ */ __name(() => {
|
|
3600
|
-
if (typeof window === "undefined") return "";
|
|
3601
|
-
try {
|
|
3602
|
-
const item = window.sessionStorage.getItem(AUTH_REDIRECT_KEY);
|
|
3603
|
-
return item ? JSON.parse(item) : "";
|
|
3604
|
-
} catch {
|
|
3605
|
-
return "";
|
|
3606
|
-
}
|
|
3607
|
-
}, "getRedirectFromStorage");
|
|
3608
|
-
var clearRedirectFromStorage = /* @__PURE__ */ __name(() => {
|
|
3609
|
-
if (typeof window === "undefined") return;
|
|
3610
|
-
try {
|
|
3611
|
-
window.sessionStorage.removeItem(AUTH_REDIRECT_KEY);
|
|
3612
|
-
window.sessionStorage.removeItem(`${AUTH_REDIRECT_KEY}_timestamp`);
|
|
3613
|
-
} catch {
|
|
3614
|
-
}
|
|
3615
|
-
}, "clearRedirectFromStorage");
|
|
3616
|
-
var useAuthRedirectManager = /* @__PURE__ */ __name((options = {}) => {
|
|
3617
|
-
const { fallbackUrl = "/dashboard", clearOnUse = true } = options;
|
|
3618
|
-
const [redirectUrl, setRedirectUrl, removeRedirectUrl] = useSessionStorage(AUTH_REDIRECT_KEY, "");
|
|
3619
|
-
const setRedirect = /* @__PURE__ */ __name((url) => {
|
|
3620
|
-
setRedirectUrl(url);
|
|
3621
|
-
}, "setRedirect");
|
|
3622
|
-
const getRedirect = /* @__PURE__ */ __name(() => {
|
|
3623
|
-
return getRedirectFromStorage() || redirectUrl;
|
|
3624
|
-
}, "getRedirect");
|
|
3625
|
-
const clearRedirect = /* @__PURE__ */ __name(() => {
|
|
3626
|
-
removeRedirectUrl();
|
|
3627
|
-
clearRedirectFromStorage();
|
|
3628
|
-
}, "clearRedirect");
|
|
3629
|
-
const hasRedirect = /* @__PURE__ */ __name(() => {
|
|
3630
|
-
const stored = getRedirectFromStorage();
|
|
3631
|
-
return stored.length > 0 || redirectUrl.length > 0;
|
|
3632
|
-
}, "hasRedirect");
|
|
3633
|
-
const getFinalRedirectUrl = /* @__PURE__ */ __name(() => {
|
|
3634
|
-
const stored = getRedirectFromStorage();
|
|
3635
|
-
return stored || redirectUrl || fallbackUrl;
|
|
3636
|
-
}, "getFinalRedirectUrl");
|
|
3637
|
-
const useAndClearRedirect = /* @__PURE__ */ __name(() => {
|
|
3638
|
-
const stored = getRedirectFromStorage();
|
|
3639
|
-
const finalUrl = stored || redirectUrl || fallbackUrl;
|
|
3640
|
-
if (clearOnUse) {
|
|
3641
|
-
clearRedirect();
|
|
3642
|
-
}
|
|
3643
|
-
return finalUrl;
|
|
3644
|
-
}, "useAndClearRedirect");
|
|
3645
|
-
return {
|
|
3646
|
-
redirectUrl,
|
|
3647
|
-
setRedirect,
|
|
3648
|
-
getRedirect,
|
|
3649
|
-
clearRedirect,
|
|
3650
|
-
hasRedirect,
|
|
3651
|
-
getFinalRedirectUrl,
|
|
3652
|
-
useAndClearRedirect
|
|
3653
|
-
};
|
|
3654
|
-
}, "useAuthRedirectManager");
|
|
3655
|
-
|
|
3656
3395
|
// src/auth/hooks/useLocalStorage.ts
|
|
3657
3396
|
var import_react13 = require("react");
|
|
3658
3397
|
function useLocalStorage(key, initialValue) {
|
|
@@ -3953,7 +3692,6 @@ __name(getCacheMetadata, "getCacheMetadata");
|
|
|
3953
3692
|
|
|
3954
3693
|
// src/auth/hooks/useDeleteAccount.ts
|
|
3955
3694
|
var import_react14 = require("react");
|
|
3956
|
-
init_sdk_gen();
|
|
3957
3695
|
var useDeleteAccount = /* @__PURE__ */ __name(() => {
|
|
3958
3696
|
const [isLoading, setIsLoading] = (0, import_react14.useState)(false);
|
|
3959
3697
|
const [error, setError] = (0, import_react14.useState)(null);
|
|
@@ -3992,14 +3730,9 @@ var useDeleteAccount = /* @__PURE__ */ __name(() => {
|
|
|
3992
3730
|
|
|
3993
3731
|
// src/auth/context/AccountsContext.tsx
|
|
3994
3732
|
var import_react15 = require("react");
|
|
3995
|
-
init_auth();
|
|
3996
|
-
|
|
3997
|
-
// src/_api/generated/_cfg_accounts/sdk.gen.ts
|
|
3998
|
-
init_sdk_gen();
|
|
3999
3733
|
|
|
4000
3734
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsApiKeyRegenerateCreate.ts
|
|
4001
3735
|
var import_mutation = __toESM(require("swr/mutation"), 1);
|
|
4002
|
-
init_sdk_gen();
|
|
4003
3736
|
|
|
4004
3737
|
// src/_api/generated/_cfg_accounts/schemas/APIKeyRegenerate.ts
|
|
4005
3738
|
var import_zod = require("zod");
|
|
@@ -4010,7 +3743,6 @@ var APIKeyRegenerateSchema = import_zod.z.object({
|
|
|
4010
3743
|
|
|
4011
3744
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsApiKeyRetrieve.ts
|
|
4012
3745
|
var import_swr = __toESM(require("swr"), 1);
|
|
4013
|
-
init_sdk_gen();
|
|
4014
3746
|
|
|
4015
3747
|
// src/_api/generated/_cfg_accounts/schemas/APIKey.ts
|
|
4016
3748
|
var import_zod2 = require("zod");
|
|
@@ -4022,7 +3754,6 @@ var APIKeySchema = import_zod2.z.object({
|
|
|
4022
3754
|
|
|
4023
3755
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsApiKeyRevealCreate.ts
|
|
4024
3756
|
var import_mutation2 = __toESM(require("swr/mutation"), 1);
|
|
4025
|
-
init_sdk_gen();
|
|
4026
3757
|
|
|
4027
3758
|
// src/_api/generated/_cfg_accounts/schemas/APIKeyReveal.ts
|
|
4028
3759
|
var import_zod3 = require("zod");
|
|
@@ -4034,7 +3765,6 @@ var APIKeyRevealSchema = import_zod3.z.object({
|
|
|
4034
3765
|
|
|
4035
3766
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsApiKeyTestCreate.ts
|
|
4036
3767
|
var import_mutation3 = __toESM(require("swr/mutation"), 1);
|
|
4037
|
-
init_sdk_gen();
|
|
4038
3768
|
|
|
4039
3769
|
// src/_api/generated/_cfg_accounts/schemas/APIKeyTestResult.ts
|
|
4040
3770
|
var import_zod4 = require("zod");
|
|
@@ -4045,7 +3775,6 @@ var APIKeyTestResultSchema = import_zod4.z.object({
|
|
|
4045
3775
|
|
|
4046
3776
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsOauthConnectionsList.ts
|
|
4047
3777
|
var import_swr2 = __toESM(require("swr"), 1);
|
|
4048
|
-
init_sdk_gen();
|
|
4049
3778
|
|
|
4050
3779
|
// src/_api/generated/_cfg_accounts/schemas/cfg_accounts_oauth_connections_response_200_AutoRef.ts
|
|
4051
3780
|
var import_zod7 = require("zod");
|
|
@@ -4074,7 +3803,6 @@ var cfg_accounts_oauth_connections_response_200_AutoRefSchema = import_zod7.z.ar
|
|
|
4074
3803
|
|
|
4075
3804
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsOauthDisconnectCreate.ts
|
|
4076
3805
|
var import_mutation4 = __toESM(require("swr/mutation"), 1);
|
|
4077
|
-
init_sdk_gen();
|
|
4078
3806
|
|
|
4079
3807
|
// src/_api/generated/_cfg_accounts/schemas/cfg_accounts_oauth_disconnect_response_200_AutoRef.ts
|
|
4080
3808
|
var import_zod8 = require("zod");
|
|
@@ -4084,7 +3812,6 @@ var cfg_accounts_oauth_disconnect_response_200_AutoRefSchema = import_zod8.z.obj
|
|
|
4084
3812
|
|
|
4085
3813
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsOauthGithubAuthorizeCreate.ts
|
|
4086
3814
|
var import_mutation5 = __toESM(require("swr/mutation"), 1);
|
|
4087
|
-
init_sdk_gen();
|
|
4088
3815
|
|
|
4089
3816
|
// src/_api/generated/_cfg_accounts/schemas/OAuthAuthorizeResponse.ts
|
|
4090
3817
|
var import_zod9 = require("zod");
|
|
@@ -4095,7 +3822,6 @@ var OAuthAuthorizeResponseSchema = import_zod9.z.object({
|
|
|
4095
3822
|
|
|
4096
3823
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsOauthGithubCallbackCreate.ts
|
|
4097
3824
|
var import_mutation6 = __toESM(require("swr/mutation"), 1);
|
|
4098
|
-
init_sdk_gen();
|
|
4099
3825
|
|
|
4100
3826
|
// src/_api/generated/_cfg_accounts/schemas/OAuthTokenResponse.ts
|
|
4101
3827
|
var import_zod10 = require("zod");
|
|
@@ -4112,7 +3838,6 @@ var OAuthTokenResponseSchema = import_zod10.z.object({
|
|
|
4112
3838
|
|
|
4113
3839
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsOauthProvidersRetrieve.ts
|
|
4114
3840
|
var import_swr3 = __toESM(require("swr"), 1);
|
|
4115
|
-
init_sdk_gen();
|
|
4116
3841
|
|
|
4117
3842
|
// src/_api/generated/_cfg_accounts/schemas/OAuthProvidersResponse.ts
|
|
4118
3843
|
var import_zod11 = require("zod");
|
|
@@ -4122,7 +3847,6 @@ var OAuthProvidersResponseSchema = import_zod11.z.object({
|
|
|
4122
3847
|
|
|
4123
3848
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsOtpRequestCreate.ts
|
|
4124
3849
|
var import_mutation7 = __toESM(require("swr/mutation"), 1);
|
|
4125
|
-
init_sdk_gen();
|
|
4126
3850
|
|
|
4127
3851
|
// src/_api/generated/_cfg_accounts/schemas/OTPRequestResponse.ts
|
|
4128
3852
|
var import_zod14 = require("zod");
|
|
@@ -4197,7 +3921,6 @@ __name(useCfgAccountsOtpRequestCreate, "useCfgAccountsOtpRequestCreate");
|
|
|
4197
3921
|
|
|
4198
3922
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsOtpVerifyCreate.ts
|
|
4199
3923
|
var import_mutation8 = __toESM(require("swr/mutation"), 1);
|
|
4200
|
-
init_sdk_gen();
|
|
4201
3924
|
|
|
4202
3925
|
// src/_api/generated/_cfg_accounts/schemas/OTPVerifyResponse.ts
|
|
4203
3926
|
var import_zod17 = require("zod");
|
|
@@ -4297,7 +4020,6 @@ __name(useCfgAccountsOtpVerifyCreate, "useCfgAccountsOtpVerifyCreate");
|
|
|
4297
4020
|
|
|
4298
4021
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsProfileAvatarCreate.ts
|
|
4299
4022
|
var import_mutation9 = __toESM(require("swr/mutation"), 1);
|
|
4300
|
-
init_sdk_gen();
|
|
4301
4023
|
function useCfgAccountsProfileAvatarCreate(config) {
|
|
4302
4024
|
return (0, import_mutation9.default)(
|
|
4303
4025
|
["cfg_accounts_profile_avatar_create"],
|
|
@@ -4346,7 +4068,6 @@ __name(useCfgAccountsProfileAvatarCreate, "useCfgAccountsProfileAvatarCreate");
|
|
|
4346
4068
|
|
|
4347
4069
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsProfileDeleteCreate.ts
|
|
4348
4070
|
var import_mutation10 = __toESM(require("swr/mutation"), 1);
|
|
4349
|
-
init_sdk_gen();
|
|
4350
4071
|
|
|
4351
4072
|
// src/_api/generated/_cfg_accounts/schemas/AccountDeleteResponse.ts
|
|
4352
4073
|
var import_zod18 = require("zod");
|
|
@@ -4357,11 +4078,9 @@ var AccountDeleteResponseSchema = import_zod18.z.object({
|
|
|
4357
4078
|
|
|
4358
4079
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsProfilePartialPartialUpdate.ts
|
|
4359
4080
|
var import_mutation11 = __toESM(require("swr/mutation"), 1);
|
|
4360
|
-
init_sdk_gen();
|
|
4361
4081
|
|
|
4362
4082
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsProfilePartialUpdate.ts
|
|
4363
4083
|
var import_mutation12 = __toESM(require("swr/mutation"), 1);
|
|
4364
|
-
init_sdk_gen();
|
|
4365
4084
|
function useCfgAccountsProfilePartialUpdate(config) {
|
|
4366
4085
|
return (0, import_mutation12.default)(
|
|
4367
4086
|
["cfg_accounts_profile_partial_update"],
|
|
@@ -4410,15 +4129,12 @@ __name(useCfgAccountsProfilePartialUpdate, "useCfgAccountsProfilePartialUpdate")
|
|
|
4410
4129
|
|
|
4411
4130
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsProfileRetrieve.ts
|
|
4412
4131
|
var import_swr4 = __toESM(require("swr"), 1);
|
|
4413
|
-
init_sdk_gen();
|
|
4414
4132
|
|
|
4415
4133
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsProfileUpdatePartialUpdate.ts
|
|
4416
4134
|
var import_mutation13 = __toESM(require("swr/mutation"), 1);
|
|
4417
|
-
init_sdk_gen();
|
|
4418
4135
|
|
|
4419
4136
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsProfileUpdateUpdate.ts
|
|
4420
4137
|
var import_mutation14 = __toESM(require("swr/mutation"), 1);
|
|
4421
|
-
init_sdk_gen();
|
|
4422
4138
|
function useCfgAccountsProfileUpdateUpdate(config) {
|
|
4423
4139
|
return (0, import_mutation14.default)(
|
|
4424
4140
|
["cfg_accounts_profile_update_update"],
|
|
@@ -4467,11 +4183,9 @@ __name(useCfgAccountsProfileUpdateUpdate, "useCfgAccountsProfileUpdateUpdate");
|
|
|
4467
4183
|
|
|
4468
4184
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsTokenBlacklistCreate.ts
|
|
4469
4185
|
var import_mutation15 = __toESM(require("swr/mutation"), 1);
|
|
4470
|
-
init_sdk_gen();
|
|
4471
4186
|
|
|
4472
4187
|
// src/_api/generated/_cfg_accounts/hooks/useCfgAccountsTokenRefreshCreate.ts
|
|
4473
4188
|
var import_mutation16 = __toESM(require("swr/mutation"), 1);
|
|
4474
|
-
init_sdk_gen();
|
|
4475
4189
|
|
|
4476
4190
|
// src/_api/generated/_cfg_accounts/schemas/TokenRefresh.ts
|
|
4477
4191
|
var import_zod19 = require("zod");
|
|
@@ -4715,10 +4429,15 @@ __name(useAccountsContext, "useAccountsContext");
|
|
|
4715
4429
|
// src/auth/context/AuthContext.tsx
|
|
4716
4430
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
4717
4431
|
var defaultRoutes = {
|
|
4718
|
-
auth:
|
|
4719
|
-
defaultCallback:
|
|
4720
|
-
defaultAuthCallback:
|
|
4432
|
+
auth: "/auth",
|
|
4433
|
+
defaultCallback: "/",
|
|
4434
|
+
defaultAuthCallback: "/auth"
|
|
4721
4435
|
};
|
|
4436
|
+
var resolveAuthRoutes = /* @__PURE__ */ __name((routes) => ({
|
|
4437
|
+
auth: routes?.auth || defaultRoutes.auth,
|
|
4438
|
+
defaultCallback: routes?.defaultCallback || defaultRoutes.defaultCallback,
|
|
4439
|
+
defaultAuthCallback: routes?.defaultAuthCallback || routes?.auth || defaultRoutes.defaultAuthCallback
|
|
4440
|
+
}), "resolveAuthRoutes");
|
|
4722
4441
|
var EMAIL_STORAGE_KEY = "auth_email";
|
|
4723
4442
|
var AuthContext = (0, import_react16.createContext)(void 0);
|
|
4724
4443
|
var apiErrorMessage = /* @__PURE__ */ __name((error) => {
|
|
@@ -4736,8 +4455,13 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4736
4455
|
EMAIL_STORAGE_KEY,
|
|
4737
4456
|
null
|
|
4738
4457
|
);
|
|
4458
|
+
const routes = (0, import_react16.useMemo)(() => resolveAuthRoutes(config?.routes), [config?.routes]);
|
|
4459
|
+
const routesRef = (0, import_react16.useRef)(routes);
|
|
4460
|
+
(0, import_react16.useEffect)(() => {
|
|
4461
|
+
routesRef.current = routes;
|
|
4462
|
+
}, [routes]);
|
|
4739
4463
|
const redirectManager = useAuthRedirectManager({
|
|
4740
|
-
fallbackUrl:
|
|
4464
|
+
fallbackUrl: routes.defaultCallback,
|
|
4741
4465
|
clearOnUse: true
|
|
4742
4466
|
});
|
|
4743
4467
|
const configRef = (0, import_react16.useRef)(config);
|
|
@@ -4748,13 +4472,15 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4748
4472
|
(0, import_react16.useEffect)(() => {
|
|
4749
4473
|
accountsRef.current = accounts;
|
|
4750
4474
|
}, [accounts]);
|
|
4475
|
+
const pendingManualNavRef = (0, import_react16.useRef)(false);
|
|
4751
4476
|
const [profileSettled, setProfileSettled] = (0, import_react16.useState)(false);
|
|
4752
4477
|
const hasProfile = Boolean(accounts.profile);
|
|
4753
4478
|
const profileAttemptedRef = (0, import_react16.useRef)(false);
|
|
4754
4479
|
(0, import_react16.useEffect)(() => {
|
|
4755
4480
|
if (!isAuthenticated) {
|
|
4756
4481
|
profileAttemptedRef.current = false;
|
|
4757
|
-
|
|
4482
|
+
const hasTokens = Boolean(auth.getToken() || auth.getRefreshToken());
|
|
4483
|
+
if (hasTokens && !auth.isAuthenticated()) {
|
|
4758
4484
|
authLogger.warn("Dead session in storage \u2014 clearing");
|
|
4759
4485
|
auth.clearSession();
|
|
4760
4486
|
clearProfileCache();
|
|
@@ -4788,18 +4514,18 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4788
4514
|
Analytics.event("auth_session_expired" /* AUTH_SESSION_EXPIRED */, {
|
|
4789
4515
|
category: "auth" /* AUTH */
|
|
4790
4516
|
});
|
|
4791
|
-
|
|
4792
|
-
router.hardReplace(authCallbackUrl);
|
|
4517
|
+
router.hardReplace(routesRef.current.defaultAuthCallback);
|
|
4793
4518
|
});
|
|
4794
4519
|
return unsubscribe;
|
|
4795
4520
|
}, [router]);
|
|
4796
4521
|
(0, import_react16.useEffect)(() => {
|
|
4797
|
-
if (!isAuthenticated) return;
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4522
|
+
if (!isAuthenticated || pendingManualNavRef.current) return;
|
|
4523
|
+
if (pathname === routes.auth && !queryParams.get("flow")) {
|
|
4524
|
+
const saved = redirectManager.hasRedirect() ? redirectManager.getRedirect() : null;
|
|
4525
|
+
if (saved) redirectManager.clearRedirect();
|
|
4526
|
+
router.push(saved || routes.defaultCallback);
|
|
4801
4527
|
}
|
|
4802
|
-
}, [isAuthenticated, pathname, queryParams,
|
|
4528
|
+
}, [isAuthenticated, pathname, queryParams, routes, router, redirectManager]);
|
|
4803
4529
|
const loadCurrentProfile = (0, import_react16.useCallback)(async (callerId) => {
|
|
4804
4530
|
if (!auth.isAuthenticated()) {
|
|
4805
4531
|
throw new Error("No valid authentication token");
|
|
@@ -4809,16 +4535,15 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4809
4535
|
});
|
|
4810
4536
|
}, []);
|
|
4811
4537
|
const checkAuthAndRedirect = (0, import_react16.useCallback)(async () => {
|
|
4812
|
-
const routes = configRef.current?.routes;
|
|
4813
4538
|
if (auth.isAuthenticated()) {
|
|
4814
4539
|
try {
|
|
4815
4540
|
await loadCurrentProfile("checkAuthAndRedirect");
|
|
4816
4541
|
} catch (error) {
|
|
4817
4542
|
authLogger.warn("checkAuthAndRedirect: profile load failed", error);
|
|
4818
4543
|
}
|
|
4819
|
-
router.push(
|
|
4544
|
+
router.push(routesRef.current.defaultCallback);
|
|
4820
4545
|
} else {
|
|
4821
|
-
router.push(
|
|
4546
|
+
router.push(routesRef.current.defaultAuthCallback);
|
|
4822
4547
|
}
|
|
4823
4548
|
}, [loadCurrentProfile, router]);
|
|
4824
4549
|
const requestOTP = (0, import_react16.useCallback)(
|
|
@@ -4858,6 +4583,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4858
4583
|
const verifyOTP = (0, import_react16.useCallback)(
|
|
4859
4584
|
async (identifier, otpCode, sourceUrl, redirectUrl, skipRedirect) => {
|
|
4860
4585
|
try {
|
|
4586
|
+
pendingManualNavRef.current = Boolean(skipRedirect);
|
|
4861
4587
|
const result = await accountsRef.current.verifyOTP({
|
|
4862
4588
|
identifier,
|
|
4863
4589
|
otp: otpCode,
|
|
@@ -4888,8 +4614,9 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4888
4614
|
Analytics.setUser(String(result.user.id));
|
|
4889
4615
|
}
|
|
4890
4616
|
if (!skipRedirect) {
|
|
4891
|
-
const
|
|
4892
|
-
|
|
4617
|
+
const saved = redirectManager.hasRedirect() ? redirectManager.getRedirect() : null;
|
|
4618
|
+
if (saved) redirectManager.clearRedirect();
|
|
4619
|
+
const finalRedirectUrl = saved || redirectUrl || routesRef.current.defaultCallback;
|
|
4893
4620
|
authLogger.info("Redirecting after auth to:", finalRedirectUrl);
|
|
4894
4621
|
router.hardPush(finalRedirectUrl);
|
|
4895
4622
|
}
|
|
@@ -4931,8 +4658,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4931
4658
|
category: "auth" /* AUTH */
|
|
4932
4659
|
});
|
|
4933
4660
|
accountsRef.current.logout();
|
|
4934
|
-
|
|
4935
|
-
router.hardReplace(authCallbackUrl);
|
|
4661
|
+
router.hardReplace(routesRef.current.defaultAuthCallback);
|
|
4936
4662
|
}, [router]);
|
|
4937
4663
|
const user = accounts.profile ?? null;
|
|
4938
4664
|
const isAdminUser = Boolean(user?.is_staff || user?.is_superuser);
|
|
@@ -4958,6 +4684,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4958
4684
|
// expiry timer, cross-tab/cross-store sync) — no ticks, no polling.
|
|
4959
4685
|
isAuthenticated,
|
|
4960
4686
|
isAdminUser,
|
|
4687
|
+
routes,
|
|
4961
4688
|
loadCurrentProfile,
|
|
4962
4689
|
checkAuthAndRedirect,
|
|
4963
4690
|
getToken: /* @__PURE__ */ __name(() => auth.getToken(), "getToken"),
|
|
@@ -4981,6 +4708,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4981
4708
|
isLoading,
|
|
4982
4709
|
isAuthenticated,
|
|
4983
4710
|
isAdminUser,
|
|
4711
|
+
routes,
|
|
4984
4712
|
loadCurrentProfile,
|
|
4985
4713
|
checkAuthAndRedirect,
|
|
4986
4714
|
storedEmail,
|
|
@@ -5008,6 +4736,7 @@ var defaultAuthState = {
|
|
|
5008
4736
|
isLoading: false,
|
|
5009
4737
|
isAuthenticated: false,
|
|
5010
4738
|
isAdminUser: false,
|
|
4739
|
+
routes: resolveAuthRoutes(),
|
|
5011
4740
|
loadCurrentProfile: /* @__PURE__ */ __name(async () => {
|
|
5012
4741
|
authLogger.warn("useAuth: loadCurrentProfile called outside AuthProvider");
|
|
5013
4742
|
}, "loadCurrentProfile"),
|