@aurabase/core 0.4.1 → 0.5.0
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/README.md +10 -5
- package/dist/index.cjs +183 -92
- package/dist/index.d.cts +609 -72
- package/dist/index.d.ts +609 -72
- package/dist/index.js +182 -93
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -113,7 +113,7 @@ class WidgetsService extends BaseService {
|
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
private get prefix(): string {
|
|
116
|
-
return
|
|
116
|
+
return '/v1/widgets'
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
async list(): Promise<AuraResponse<Widget[]>> {
|
|
@@ -132,16 +132,21 @@ class WidgetsService extends BaseService {
|
|
|
132
132
|
|
|
133
133
|
`BaseAuthStore` est en mémoire (event-emitter `onChange`, stockage clé/valeur générique pour le PKCE `code_verifier`). `LocalAuthStore` l'étend avec persistance `localStorage` et des helpers cookie pour le rendu serveur.
|
|
134
134
|
|
|
135
|
+
Son argument `key` est **obligatoire** et doit être SCOPÉ par projet : deux clients pointant sur deux projets dans la même page partagent un seul `localStorage` (celui de la page), et une clé constante les ferait s'écraser. Le nom canonique est `aura-${clientScope(baseUrl)}-auth` — celui que posent déjà `AuraClient` et `createServerClient`.
|
|
136
|
+
|
|
135
137
|
```ts
|
|
136
|
-
import { LocalAuthStore } from '@aurabase/core'
|
|
138
|
+
import { LocalAuthStore, clientScope } from '@aurabase/core'
|
|
139
|
+
|
|
140
|
+
const PROJET = 'https://mon-projet.aurabase.cloud'
|
|
141
|
+
const CLE = `aura-${clientScope(PROJET)}-auth`
|
|
137
142
|
|
|
138
143
|
function hydrateFromCookieHeader(cookieHeader: string) {
|
|
139
|
-
const store = new LocalAuthStore(
|
|
144
|
+
const store = new LocalAuthStore(CLE)
|
|
140
145
|
store.loadFromCookie(cookieHeader) // hydrate depuis l'en-tête Cookie de la requête entrante
|
|
141
146
|
return store
|
|
142
147
|
}
|
|
143
148
|
|
|
144
|
-
const store = hydrateFromCookieHeader(
|
|
149
|
+
const store = hydrateFromCookieHeader(`${CLE}=%7B%22token%22%3Anull%7D`)
|
|
145
150
|
|
|
146
151
|
// Après une mutation de session, sérialiser l'état courant en Set-Cookie.
|
|
147
152
|
const setCookieValue = store.exportToCookie({ path: '/', secure: true, sameSite: 'Lax', httpOnly: true })
|
|
@@ -163,7 +168,7 @@ Cette couche (`fetchWithAuth`, `refreshOnce`) est exportée mais reste un détai
|
|
|
163
168
|
|
|
164
169
|
- Package d'infrastructure : pas d'API « produit ». Pour construire une application, utilisez le méta-package [`aurabase`](../aurabase), qui assemble tous les services derrière un seul client.
|
|
165
170
|
- `BaseAuthStore` est en mémoire — l'état est perdu au reload ; `LocalAuthStore` nécessite un `localStorage` disponible (sinon retombe silencieusement sur le comportement en mémoire, sauf via les helpers cookie explicites).
|
|
166
|
-
- `AuraClientLike` est un contrat minimal (`baseUrl`, `
|
|
171
|
+
- `AuraClientLike` est un contrat minimal (`baseUrl`, `apiKey`, `fetchFn`, `authStore`, `auth.refreshSession`, `retryConfig?`, `requestTimeoutMs?`) : un client maison doit l'implémenter intégralement pour rester compatible avec `BaseService`.
|
|
167
172
|
- La couche fetch bas niveau (`fetchWithAuth`/`refreshOnce`) est un détail d'implémentation interne, pas une API publique stabilisée.
|
|
168
173
|
|
|
169
174
|
## Documentation
|
package/dist/index.cjs
CHANGED
|
@@ -33,6 +33,70 @@ function isAuraError(error) {
|
|
|
33
33
|
return error instanceof AuraError || typeof error === "object" && error !== null && error.__isAuraError === true;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
// src/retry.ts
|
|
37
|
+
var RETRYABLE_STATUS = /* @__PURE__ */ new Set([408, 429, 502, 503, 504]);
|
|
38
|
+
var RETRYABLE_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD"]);
|
|
39
|
+
var DEFAULT_MAX_RETRIES = 3;
|
|
40
|
+
var BASE_MS = 500;
|
|
41
|
+
var CAP_MS = 1e4;
|
|
42
|
+
function isRetryableStatus(status) {
|
|
43
|
+
return RETRYABLE_STATUS.has(status);
|
|
44
|
+
}
|
|
45
|
+
function isRetryableMethod(method) {
|
|
46
|
+
return RETRYABLE_METHODS.has(method.toUpperCase());
|
|
47
|
+
}
|
|
48
|
+
function computeBackoff(attempt, rand = Math.random) {
|
|
49
|
+
const bound = Math.min(BASE_MS * 2 ** attempt, CAP_MS);
|
|
50
|
+
return Math.floor(rand() * bound);
|
|
51
|
+
}
|
|
52
|
+
function parseRetryAfter(header, now = Date.now()) {
|
|
53
|
+
if (header === null) return null;
|
|
54
|
+
const trimmed = header.trim();
|
|
55
|
+
if (/^\d+$/.test(trimmed)) return parseInt(trimmed, 10) * 1e3;
|
|
56
|
+
const dateMs = Date.parse(trimmed);
|
|
57
|
+
if (Number.isNaN(dateMs)) return null;
|
|
58
|
+
return Math.max(0, dateMs - now);
|
|
59
|
+
}
|
|
60
|
+
function abortableSleep(ms, signal) {
|
|
61
|
+
return new Promise((resolve) => {
|
|
62
|
+
if (signal?.aborted) {
|
|
63
|
+
resolve();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const onAbort = () => {
|
|
67
|
+
clearTimeout(timer);
|
|
68
|
+
resolve();
|
|
69
|
+
};
|
|
70
|
+
const timer = setTimeout(() => {
|
|
71
|
+
signal?.removeEventListener("abort", onAbort);
|
|
72
|
+
resolve();
|
|
73
|
+
}, ms);
|
|
74
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function isAbortError(err) {
|
|
78
|
+
return typeof err === "object" && err !== null && err.name === "AbortError";
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// src/scope.ts
|
|
82
|
+
function clientScope(baseUrl) {
|
|
83
|
+
let host;
|
|
84
|
+
try {
|
|
85
|
+
host = new URL(baseUrl).host;
|
|
86
|
+
} catch {
|
|
87
|
+
host = baseUrl;
|
|
88
|
+
}
|
|
89
|
+
return host.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "default";
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// src/serialize.ts
|
|
93
|
+
function serializeBody(body) {
|
|
94
|
+
return JSON.stringify(
|
|
95
|
+
body,
|
|
96
|
+
(_key, value) => typeof value === "bigint" ? value.toString() : value
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
36
100
|
// src/types.ts
|
|
37
101
|
function redactUrl(u) {
|
|
38
102
|
const cut = u.search(/[?#]/);
|
|
@@ -52,6 +116,60 @@ function emitAuraEvent(onEvent, debug, event) {
|
|
|
52
116
|
} catch {
|
|
53
117
|
}
|
|
54
118
|
}
|
|
119
|
+
var AUTH_SETTINGS_WRITABLE_FIELDS = [
|
|
120
|
+
"allow_signup",
|
|
121
|
+
"email_confirmation_required",
|
|
122
|
+
"password_min_length",
|
|
123
|
+
"mfa_enabled",
|
|
124
|
+
"allow_anonymous_users",
|
|
125
|
+
"jwt_expiry_seconds",
|
|
126
|
+
"refresh_token_expiry_days",
|
|
127
|
+
"site_url",
|
|
128
|
+
"oauth_providers",
|
|
129
|
+
"new_device_alerts_enabled",
|
|
130
|
+
"webhook_url",
|
|
131
|
+
"webhook_secret",
|
|
132
|
+
"smtp_host",
|
|
133
|
+
"smtp_port",
|
|
134
|
+
"smtp_username",
|
|
135
|
+
"smtp_password",
|
|
136
|
+
"smtp_from_email",
|
|
137
|
+
"smtp_from_name",
|
|
138
|
+
"smtp_clear",
|
|
139
|
+
"oauth_credentials",
|
|
140
|
+
"oauth_credentials_clear",
|
|
141
|
+
"captcha_enabled",
|
|
142
|
+
"captcha_provider",
|
|
143
|
+
"captcha_site_key",
|
|
144
|
+
"captcha_secret_key",
|
|
145
|
+
"password_check_hibp",
|
|
146
|
+
"sms_provider",
|
|
147
|
+
"sms_api_key",
|
|
148
|
+
"sms_api_secret",
|
|
149
|
+
"sms_from_number",
|
|
150
|
+
"sms_clear",
|
|
151
|
+
"redirect_urls",
|
|
152
|
+
"session_inactivity_timeout_seconds",
|
|
153
|
+
"hook_send_sms_url",
|
|
154
|
+
"hook_send_email_url",
|
|
155
|
+
"hook_mfa_verification_url",
|
|
156
|
+
"hook_password_verification_url",
|
|
157
|
+
"auto_link_by_email",
|
|
158
|
+
"rate_limit_login_per_hour",
|
|
159
|
+
"rate_limit_emails_per_hour",
|
|
160
|
+
"rate_limit_signup_per_hour",
|
|
161
|
+
"revoke_on_new_device",
|
|
162
|
+
"enforce_ip_binding",
|
|
163
|
+
"allowed_email_domains",
|
|
164
|
+
"blocked_email_domains",
|
|
165
|
+
"password_require_uppercase",
|
|
166
|
+
"password_require_number",
|
|
167
|
+
"password_require_special",
|
|
168
|
+
"hook_before_signup_url",
|
|
169
|
+
"hook_after_signup_url",
|
|
170
|
+
"hook_custom_access_token_url",
|
|
171
|
+
"hook_secret"
|
|
172
|
+
];
|
|
55
173
|
|
|
56
174
|
// src/stores/BaseAuthStore.ts
|
|
57
175
|
function decodeJwtPayload(token) {
|
|
@@ -172,59 +290,6 @@ var BaseAuthStore = class {
|
|
|
172
290
|
}
|
|
173
291
|
};
|
|
174
292
|
|
|
175
|
-
// src/retry.ts
|
|
176
|
-
var RETRYABLE_STATUS = /* @__PURE__ */ new Set([408, 429, 502, 503, 504]);
|
|
177
|
-
var RETRYABLE_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD"]);
|
|
178
|
-
var DEFAULT_MAX_RETRIES = 3;
|
|
179
|
-
var BASE_MS = 500;
|
|
180
|
-
var CAP_MS = 1e4;
|
|
181
|
-
function isRetryableStatus(status) {
|
|
182
|
-
return RETRYABLE_STATUS.has(status);
|
|
183
|
-
}
|
|
184
|
-
function isRetryableMethod(method) {
|
|
185
|
-
return RETRYABLE_METHODS.has(method.toUpperCase());
|
|
186
|
-
}
|
|
187
|
-
function computeBackoff(attempt, rand = Math.random) {
|
|
188
|
-
const bound = Math.min(BASE_MS * 2 ** attempt, CAP_MS);
|
|
189
|
-
return Math.floor(rand() * bound);
|
|
190
|
-
}
|
|
191
|
-
function parseRetryAfter(header, now = Date.now()) {
|
|
192
|
-
if (header === null) return null;
|
|
193
|
-
const trimmed = header.trim();
|
|
194
|
-
if (/^\d+$/.test(trimmed)) return parseInt(trimmed, 10) * 1e3;
|
|
195
|
-
const dateMs = Date.parse(trimmed);
|
|
196
|
-
if (Number.isNaN(dateMs)) return null;
|
|
197
|
-
return Math.max(0, dateMs - now);
|
|
198
|
-
}
|
|
199
|
-
function abortableSleep(ms, signal) {
|
|
200
|
-
return new Promise((resolve) => {
|
|
201
|
-
if (signal?.aborted) {
|
|
202
|
-
resolve();
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
const onAbort = () => {
|
|
206
|
-
clearTimeout(timer);
|
|
207
|
-
resolve();
|
|
208
|
-
};
|
|
209
|
-
const timer = setTimeout(() => {
|
|
210
|
-
signal?.removeEventListener("abort", onAbort);
|
|
211
|
-
resolve();
|
|
212
|
-
}, ms);
|
|
213
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
function isAbortError(err) {
|
|
217
|
-
return typeof err === "object" && err !== null && err.name === "AbortError";
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// src/serialize.ts
|
|
221
|
-
function serializeBody(body) {
|
|
222
|
-
return JSON.stringify(
|
|
223
|
-
body,
|
|
224
|
-
(_key, value) => typeof value === "bigint" ? value.toString() : value
|
|
225
|
-
);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
293
|
// src/fetch.ts
|
|
229
294
|
var REFRESH_MARGIN_SEC = 30;
|
|
230
295
|
var RETRY_AFTER_CAP_MS = 6e4;
|
|
@@ -292,7 +357,9 @@ async function doRefresh(client) {
|
|
|
292
357
|
if (!rt) {
|
|
293
358
|
return {
|
|
294
359
|
data: null,
|
|
295
|
-
error: new AuraError(0, {
|
|
360
|
+
error: new AuraError(0, {
|
|
361
|
+
error: { code: "no_session", message: "No refresh token available" }
|
|
362
|
+
})
|
|
296
363
|
};
|
|
297
364
|
}
|
|
298
365
|
const epoch = store.removalEpoch;
|
|
@@ -319,7 +386,7 @@ async function doRefresh(client) {
|
|
|
319
386
|
};
|
|
320
387
|
let res;
|
|
321
388
|
try {
|
|
322
|
-
res = await client.fetchFn(`${client.baseUrl}/v1/auth
|
|
389
|
+
res = await client.fetchFn(`${client.baseUrl}/v1/auth/refresh`, {
|
|
323
390
|
method: "POST",
|
|
324
391
|
headers,
|
|
325
392
|
body: serializeBody({ refresh_token: rt }),
|
|
@@ -330,13 +397,16 @@ async function doRefresh(client) {
|
|
|
330
397
|
if (timedOut) {
|
|
331
398
|
emitAuraEvent(client.onEvent, client.debug, {
|
|
332
399
|
kind: "timeout",
|
|
333
|
-
url: `${client.baseUrl}/v1/auth
|
|
400
|
+
url: `${client.baseUrl}/v1/auth/refresh`
|
|
334
401
|
});
|
|
335
402
|
}
|
|
336
403
|
return {
|
|
337
404
|
data: null,
|
|
338
405
|
error: new AuraError(0, {
|
|
339
|
-
error: timedOut ? { code: "timeout", message: `Refresh timed out after ${timeoutMs}ms` } : {
|
|
406
|
+
error: timedOut ? { code: "timeout", message: `Refresh timed out after ${timeoutMs}ms` } : {
|
|
407
|
+
code: "network_error",
|
|
408
|
+
message: err instanceof Error ? err.message : "Network request failed"
|
|
409
|
+
}
|
|
340
410
|
})
|
|
341
411
|
};
|
|
342
412
|
}
|
|
@@ -365,7 +435,7 @@ async function doRefresh(client) {
|
|
|
365
435
|
if (okRead.timedOut) {
|
|
366
436
|
emitAuraEvent(client.onEvent, client.debug, {
|
|
367
437
|
kind: "timeout",
|
|
368
|
-
url: `${client.baseUrl}/v1/auth
|
|
438
|
+
url: `${client.baseUrl}/v1/auth/refresh`
|
|
369
439
|
});
|
|
370
440
|
}
|
|
371
441
|
return {
|
|
@@ -380,7 +450,9 @@ async function doRefresh(client) {
|
|
|
380
450
|
} catch {
|
|
381
451
|
return {
|
|
382
452
|
data: null,
|
|
383
|
-
error: new AuraError(0, {
|
|
453
|
+
error: new AuraError(0, {
|
|
454
|
+
error: { code: "invalid_response", message: "Invalid refresh response (non-JSON body)" }
|
|
455
|
+
})
|
|
384
456
|
};
|
|
385
457
|
}
|
|
386
458
|
const data = unwrapEnvelope(body);
|
|
@@ -392,7 +464,9 @@ async function doRefresh(client) {
|
|
|
392
464
|
});
|
|
393
465
|
return {
|
|
394
466
|
data: null,
|
|
395
|
-
error: new AuraError(409, {
|
|
467
|
+
error: new AuraError(409, {
|
|
468
|
+
error: { code: "refresh_discarded", message: "Session changed during refresh" }
|
|
469
|
+
})
|
|
396
470
|
};
|
|
397
471
|
}
|
|
398
472
|
store.save(data.access_token, data.refresh_token, data.user);
|
|
@@ -401,7 +475,9 @@ async function doRefresh(client) {
|
|
|
401
475
|
}
|
|
402
476
|
return {
|
|
403
477
|
data: null,
|
|
404
|
-
error: new AuraError(0, {
|
|
478
|
+
error: new AuraError(0, {
|
|
479
|
+
error: { code: "invalid_response", message: "Invalid refresh response" }
|
|
480
|
+
})
|
|
405
481
|
};
|
|
406
482
|
}
|
|
407
483
|
function withRefreshLock(client, fn) {
|
|
@@ -412,7 +488,7 @@ function withRefreshLock(client, fn) {
|
|
|
412
488
|
return fn();
|
|
413
489
|
}
|
|
414
490
|
const request = locks.request;
|
|
415
|
-
const lockName = `aura-refresh-${client.
|
|
491
|
+
const lockName = `aura-refresh-${clientScope(client.baseUrl)}`;
|
|
416
492
|
const timeoutMs = (client.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS) || DEFAULT_REQUEST_TIMEOUT_MS;
|
|
417
493
|
let timer;
|
|
418
494
|
const options = {};
|
|
@@ -528,7 +604,10 @@ async function fetchWithAuth(url, init, client) {
|
|
|
528
604
|
return {
|
|
529
605
|
data: null,
|
|
530
606
|
error: new AuraError(0, {
|
|
531
|
-
error: timedOut ? { code: "timeout", message: `Request timed out after ${timeoutMs}ms` } : {
|
|
607
|
+
error: timedOut ? { code: "timeout", message: `Request timed out after ${timeoutMs}ms` } : {
|
|
608
|
+
code: "network_error",
|
|
609
|
+
message: err instanceof Error ? err.message : "Network request failed"
|
|
610
|
+
}
|
|
532
611
|
})
|
|
533
612
|
};
|
|
534
613
|
}
|
|
@@ -541,7 +620,12 @@ async function fetchWithAuth(url, init, client) {
|
|
|
541
620
|
await res.body?.cancel().catch(() => {
|
|
542
621
|
});
|
|
543
622
|
const nextAttempt = attempt + 1;
|
|
544
|
-
emitAuraEvent(client.onEvent, client.debug, {
|
|
623
|
+
emitAuraEvent(client.onEvent, client.debug, {
|
|
624
|
+
kind: "retry",
|
|
625
|
+
attempt: nextAttempt,
|
|
626
|
+
status: res.status,
|
|
627
|
+
url
|
|
628
|
+
});
|
|
545
629
|
await abortableSleep(delay, init.signal);
|
|
546
630
|
attempt = nextAttempt;
|
|
547
631
|
continue;
|
|
@@ -647,12 +731,40 @@ var BaseService = class {
|
|
|
647
731
|
}
|
|
648
732
|
};
|
|
649
733
|
|
|
734
|
+
// src/cookie-utils.ts
|
|
735
|
+
function parseCookieHeader(header) {
|
|
736
|
+
const result = {};
|
|
737
|
+
if (!header) return result;
|
|
738
|
+
for (const pair of header.split(";")) {
|
|
739
|
+
const idx = pair.indexOf("=");
|
|
740
|
+
if (idx === -1) continue;
|
|
741
|
+
const key = pair.slice(0, idx).trim();
|
|
742
|
+
const value = pair.slice(idx + 1).trim();
|
|
743
|
+
if (key) result[key] = decodeURIComponent(value);
|
|
744
|
+
}
|
|
745
|
+
return result;
|
|
746
|
+
}
|
|
747
|
+
function serializeCookieHeader(name, value, options = {}) {
|
|
748
|
+
const parts = [`${name}=${encodeURIComponent(value)}`];
|
|
749
|
+
if (options.path) parts.push(`Path=${options.path}`);
|
|
750
|
+
if (options.domain) parts.push(`Domain=${options.domain}`);
|
|
751
|
+
if (options.maxAge !== void 0) parts.push(`Max-Age=${options.maxAge}`);
|
|
752
|
+
if (options.secure) parts.push("Secure");
|
|
753
|
+
if (options.sameSite) parts.push(`SameSite=${options.sameSite}`);
|
|
754
|
+
if (options.httpOnly) parts.push("HttpOnly");
|
|
755
|
+
return parts.join("; ");
|
|
756
|
+
}
|
|
757
|
+
|
|
650
758
|
// src/stores/LocalAuthStore.ts
|
|
651
759
|
var LocalAuthStore = class extends BaseAuthStore {
|
|
652
760
|
/** Persiste en localStorage → survit au redirect pleine page (cf. PKCE). */
|
|
653
761
|
persistent = true;
|
|
654
762
|
key;
|
|
655
|
-
|
|
763
|
+
/**
|
|
764
|
+
* @param key Nom de l'entrée `localStorage` (et du cookie SSR). Scopez-le par projet :
|
|
765
|
+
* `aura-${clientScope(baseUrl)}-auth`.
|
|
766
|
+
*/
|
|
767
|
+
constructor(key) {
|
|
656
768
|
super();
|
|
657
769
|
this.key = key;
|
|
658
770
|
this._loadFromStorage();
|
|
@@ -669,11 +781,12 @@ var LocalAuthStore = class extends BaseAuthStore {
|
|
|
669
781
|
}
|
|
670
782
|
/**
|
|
671
783
|
* Supprime de localStorage tous les artefacts d'auth éphémères sur disque :
|
|
672
|
-
* - `code_verifier` PKCE (`aura-<
|
|
673
|
-
* - marqueur d'initiation OAuth implicit (`aura-<
|
|
784
|
+
* - `code_verifier` PKCE (`aura-<portée>-pkce-code-verifier`),
|
|
785
|
+
* - marqueur d'initiation OAuth implicit (`aura-<portée>-oauth-implicit-initiated`,
|
|
674
786
|
* SEC-F3). Un `signOut`/`clear()` ne doit laisser aucun résidu réutilisable (parité
|
|
675
787
|
* `@supabase/ssr` : ces artefacts sont éphémères). On itère les clés préfixées pour
|
|
676
|
-
* couvrir un store partagé entre plusieurs projets, sans dépendre
|
|
788
|
+
* couvrir un store partagé entre plusieurs projets, sans dépendre de la portée courante
|
|
789
|
+
* (`clientScope`, dérivée de l'URL du projet).
|
|
677
790
|
*/
|
|
678
791
|
_removePkceVerifiers() {
|
|
679
792
|
if (typeof localStorage === "undefined") return;
|
|
@@ -794,30 +907,7 @@ var LocalAuthStore = class extends BaseAuthStore {
|
|
|
794
907
|
}
|
|
795
908
|
};
|
|
796
909
|
|
|
797
|
-
|
|
798
|
-
function parseCookieHeader(header) {
|
|
799
|
-
const result = {};
|
|
800
|
-
if (!header) return result;
|
|
801
|
-
for (const pair of header.split(";")) {
|
|
802
|
-
const idx = pair.indexOf("=");
|
|
803
|
-
if (idx === -1) continue;
|
|
804
|
-
const key = pair.slice(0, idx).trim();
|
|
805
|
-
const value = pair.slice(idx + 1).trim();
|
|
806
|
-
if (key) result[key] = decodeURIComponent(value);
|
|
807
|
-
}
|
|
808
|
-
return result;
|
|
809
|
-
}
|
|
810
|
-
function serializeCookieHeader(name, value, options = {}) {
|
|
811
|
-
const parts = [`${name}=${encodeURIComponent(value)}`];
|
|
812
|
-
if (options.path) parts.push(`Path=${options.path}`);
|
|
813
|
-
if (options.domain) parts.push(`Domain=${options.domain}`);
|
|
814
|
-
if (options.maxAge !== void 0) parts.push(`Max-Age=${options.maxAge}`);
|
|
815
|
-
if (options.secure) parts.push("Secure");
|
|
816
|
-
if (options.sameSite) parts.push(`SameSite=${options.sameSite}`);
|
|
817
|
-
if (options.httpOnly) parts.push("HttpOnly");
|
|
818
|
-
return parts.join("; ");
|
|
819
|
-
}
|
|
820
|
-
|
|
910
|
+
exports.AUTH_SETTINGS_WRITABLE_FIELDS = AUTH_SETTINGS_WRITABLE_FIELDS;
|
|
821
911
|
exports.AuraError = AuraError;
|
|
822
912
|
exports.BaseAuthStore = BaseAuthStore;
|
|
823
913
|
exports.BaseService = BaseService;
|
|
@@ -827,6 +917,7 @@ exports.LocalAuthStore = LocalAuthStore;
|
|
|
827
917
|
exports.RETRYABLE_METHODS = RETRYABLE_METHODS;
|
|
828
918
|
exports.RETRYABLE_STATUS = RETRYABLE_STATUS;
|
|
829
919
|
exports.abortableSleep = abortableSleep;
|
|
920
|
+
exports.clientScope = clientScope;
|
|
830
921
|
exports.computeBackoff = computeBackoff;
|
|
831
922
|
exports.emitAuraEvent = emitAuraEvent;
|
|
832
923
|
exports.fetchWithAuth = fetchWithAuth;
|