@aurabase/core 0.7.0 → 0.7.1
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/index.cjs +74 -31
- package/dist/index.d.cts +43 -13
- package/dist/index.d.ts +43 -13
- package/dist/index.js +74 -31
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -96,8 +96,12 @@ var AuraError = class _AuraError extends Error {
|
|
|
96
96
|
this.code = "SESSION_REVOKED";
|
|
97
97
|
} else if (status === 401 && lowerMsg.includes("expired")) {
|
|
98
98
|
this.code = "SESSION_EXPIRED";
|
|
99
|
-
} else if (status === 400 && lowerMsg.includes("password")) {
|
|
99
|
+
} else if (status === 400 && (lowerMsg.includes("current password") || lowerMsg.includes("old password") || lowerMsg.includes("password") && lowerMsg.includes("required"))) {
|
|
100
|
+
this.code = lowerMsg.includes("incorrect") || lowerMsg.includes("invalid") ? "INVALID_CURRENT_PASSWORD" : "CURRENT_PASSWORD_REQUIRED";
|
|
101
|
+
} else if (status === 400 && lowerMsg.includes("password") && (lowerMsg.includes("weak") || lowerMsg.includes("length") || lowerMsg.includes("strength") || lowerMsg.includes("character") || lowerMsg.includes("digit") || lowerMsg.includes("pwned") || lowerMsg.includes("too short") || lowerMsg.includes("too common"))) {
|
|
100
102
|
this.code = "WEAK_PASSWORD";
|
|
103
|
+
} else if (status === 400 && lowerMsg.includes("password")) {
|
|
104
|
+
this.code = "INVALID_PASSWORD";
|
|
101
105
|
} else if (status === 409 && (lowerMsg.includes("already exists") || lowerMsg.includes("already in use") || lowerMsg.includes("email"))) {
|
|
102
106
|
this.code = "EMAIL_ALREADY_IN_USE";
|
|
103
107
|
} else if (status === 404 && lowerMsg.includes("user not found")) {
|
|
@@ -279,6 +283,33 @@ var AUTH_SETTINGS_WRITABLE_FIELDS = [
|
|
|
279
283
|
"hook_secret"
|
|
280
284
|
];
|
|
281
285
|
|
|
286
|
+
// src/cookie-utils.ts
|
|
287
|
+
function parseCookieHeader(header) {
|
|
288
|
+
const result = {};
|
|
289
|
+
if (!header) return result;
|
|
290
|
+
for (const pair of header.split(";")) {
|
|
291
|
+
const idx = pair.indexOf("=");
|
|
292
|
+
if (idx === -1) continue;
|
|
293
|
+
const key = pair.slice(0, idx).trim();
|
|
294
|
+
const value = pair.slice(idx + 1).trim();
|
|
295
|
+
if (key) result[key] = decodeURIComponent(value);
|
|
296
|
+
}
|
|
297
|
+
return result;
|
|
298
|
+
}
|
|
299
|
+
function sameSiteAttribute(v) {
|
|
300
|
+
return v.charAt(0).toUpperCase() + v.slice(1);
|
|
301
|
+
}
|
|
302
|
+
function serializeCookieHeader(name, value, options = {}) {
|
|
303
|
+
const parts = [`${name}=${encodeURIComponent(value)}`];
|
|
304
|
+
if (options.path) parts.push(`Path=${options.path}`);
|
|
305
|
+
if (options.domain) parts.push(`Domain=${options.domain}`);
|
|
306
|
+
if (options.maxAge !== void 0) parts.push(`Max-Age=${options.maxAge}`);
|
|
307
|
+
if (options.secure) parts.push("Secure");
|
|
308
|
+
if (options.sameSite) parts.push(`SameSite=${sameSiteAttribute(options.sameSite)}`);
|
|
309
|
+
if (options.httpOnly) parts.push("HttpOnly");
|
|
310
|
+
return parts.join("; ");
|
|
311
|
+
}
|
|
312
|
+
|
|
282
313
|
// src/stores/BaseAuthStore.ts
|
|
283
314
|
function decodeJwtPayload(token) {
|
|
284
315
|
try {
|
|
@@ -323,6 +354,7 @@ var BaseAuthStore = class {
|
|
|
323
354
|
* le flux PKCE : le `code_verifier` doit survivre au redirect OAuth.
|
|
324
355
|
*/
|
|
325
356
|
persistent = false;
|
|
357
|
+
key;
|
|
326
358
|
_token = null;
|
|
327
359
|
_refreshToken = null;
|
|
328
360
|
_user = null;
|
|
@@ -333,6 +365,9 @@ var BaseAuthStore = class {
|
|
|
333
365
|
/** Hook d'observabilité (LOT 3) — câblé par `AuraClient` via `setObservabilityHook`. */
|
|
334
366
|
_onEvent;
|
|
335
367
|
_debug = false;
|
|
368
|
+
constructor(key = "aura-auth") {
|
|
369
|
+
this.key = key;
|
|
370
|
+
}
|
|
336
371
|
// -- Getters ----------------------------------------------------------------
|
|
337
372
|
/** Compteur incrémenté à chaque `clear()` — sert au commit-guard anti-race du refresh. */
|
|
338
373
|
get removalEpoch() {
|
|
@@ -394,6 +429,43 @@ var BaseAuthStore = class {
|
|
|
394
429
|
_emitStorageBlocked(op) {
|
|
395
430
|
emitAuraEvent(this._onEvent, this._debug, { kind: "storage-blocked", op });
|
|
396
431
|
}
|
|
432
|
+
/**
|
|
433
|
+
* Populate the store from a raw `Cookie` header string (server-side).
|
|
434
|
+
* Looks for the key matching `this.key`.
|
|
435
|
+
*/
|
|
436
|
+
loadFromCookie(cookieString) {
|
|
437
|
+
const prefix = `${this.key}=`;
|
|
438
|
+
const entry = cookieString.split(";").map((c) => c.trim()).find((c) => c.startsWith(prefix));
|
|
439
|
+
if (!entry) return;
|
|
440
|
+
try {
|
|
441
|
+
const raw = decodeURIComponent(entry.slice(prefix.length));
|
|
442
|
+
const parsed = JSON.parse(raw);
|
|
443
|
+
const user = parsed.token ? userFromAccessToken(parsed.token) : null;
|
|
444
|
+
if (parsed.token && parsed.refreshToken && user) {
|
|
445
|
+
this.save(parsed.token, parsed.refreshToken, user);
|
|
446
|
+
}
|
|
447
|
+
} catch {
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Serialize the session tokens into a `Set-Cookie` value. The `user` object is NOT included: its
|
|
452
|
+
* `user_metadata` is already inside the access token.
|
|
453
|
+
*/
|
|
454
|
+
exportToCookie(options = {}) {
|
|
455
|
+
const data = {
|
|
456
|
+
token: this.token,
|
|
457
|
+
refreshToken: this.refreshToken
|
|
458
|
+
};
|
|
459
|
+
const encoded = encodeURIComponent(JSON.stringify(data));
|
|
460
|
+
const parts = [`${this.key}=${encoded}`];
|
|
461
|
+
if (options.path) parts.push(`Path=${options.path}`);
|
|
462
|
+
if (options.domain) parts.push(`Domain=${options.domain}`);
|
|
463
|
+
if (options.maxAge !== void 0) parts.push(`Max-Age=${options.maxAge}`);
|
|
464
|
+
if (options.secure) parts.push("Secure");
|
|
465
|
+
if (options.sameSite) parts.push(`SameSite=${sameSiteAttribute(options.sameSite)}`);
|
|
466
|
+
if (options.httpOnly) parts.push("HttpOnly");
|
|
467
|
+
return parts.join("; ");
|
|
468
|
+
}
|
|
397
469
|
// -- Event emitter ----------------------------------------------------------
|
|
398
470
|
/**
|
|
399
471
|
* Register a callback that fires whenever the auth state changes.
|
|
@@ -888,45 +960,16 @@ var BaseService = class {
|
|
|
888
960
|
}
|
|
889
961
|
};
|
|
890
962
|
|
|
891
|
-
// src/cookie-utils.ts
|
|
892
|
-
function parseCookieHeader(header) {
|
|
893
|
-
const result = {};
|
|
894
|
-
if (!header) return result;
|
|
895
|
-
for (const pair of header.split(";")) {
|
|
896
|
-
const idx = pair.indexOf("=");
|
|
897
|
-
if (idx === -1) continue;
|
|
898
|
-
const key = pair.slice(0, idx).trim();
|
|
899
|
-
const value = pair.slice(idx + 1).trim();
|
|
900
|
-
if (key) result[key] = decodeURIComponent(value);
|
|
901
|
-
}
|
|
902
|
-
return result;
|
|
903
|
-
}
|
|
904
|
-
function sameSiteAttribute(v) {
|
|
905
|
-
return v.charAt(0).toUpperCase() + v.slice(1);
|
|
906
|
-
}
|
|
907
|
-
function serializeCookieHeader(name, value, options = {}) {
|
|
908
|
-
const parts = [`${name}=${encodeURIComponent(value)}`];
|
|
909
|
-
if (options.path) parts.push(`Path=${options.path}`);
|
|
910
|
-
if (options.domain) parts.push(`Domain=${options.domain}`);
|
|
911
|
-
if (options.maxAge !== void 0) parts.push(`Max-Age=${options.maxAge}`);
|
|
912
|
-
if (options.secure) parts.push("Secure");
|
|
913
|
-
if (options.sameSite) parts.push(`SameSite=${sameSiteAttribute(options.sameSite)}`);
|
|
914
|
-
if (options.httpOnly) parts.push("HttpOnly");
|
|
915
|
-
return parts.join("; ");
|
|
916
|
-
}
|
|
917
|
-
|
|
918
963
|
// src/stores/LocalAuthStore.ts
|
|
919
964
|
var LocalAuthStore = class extends BaseAuthStore {
|
|
920
965
|
/** Persiste en localStorage → survit au redirect pleine page (cf. PKCE). */
|
|
921
966
|
persistent = true;
|
|
922
|
-
key;
|
|
923
967
|
/**
|
|
924
968
|
* @param key Nom de l'entrée `localStorage` (et du cookie SSR). Scopez-le par projet :
|
|
925
969
|
* `aura-${clientScope(baseUrl)}-auth`.
|
|
926
970
|
*/
|
|
927
971
|
constructor(key) {
|
|
928
|
-
super();
|
|
929
|
-
this.key = key;
|
|
972
|
+
super(key);
|
|
930
973
|
this._loadFromStorage();
|
|
931
974
|
}
|
|
932
975
|
// -- Overrides --------------------------------------------------------------
|
package/dist/index.d.cts
CHANGED
|
@@ -203,6 +203,8 @@ interface User {
|
|
|
203
203
|
last_sign_in_at?: string | null;
|
|
204
204
|
}
|
|
205
205
|
interface Session {
|
|
206
|
+
/** Identifiant unique de la session (UUID ou 'sess_...'), dérivé du claim `session_id` du JWT. */
|
|
207
|
+
id?: string;
|
|
206
208
|
access_token: string;
|
|
207
209
|
refresh_token: string;
|
|
208
210
|
token_type: string;
|
|
@@ -267,6 +269,7 @@ interface SignUpRequest {
|
|
|
267
269
|
options?: {
|
|
268
270
|
emailRedirectTo?: string;
|
|
269
271
|
data?: Record<string, unknown>;
|
|
272
|
+
preventEmailEnumeration?: boolean;
|
|
270
273
|
};
|
|
271
274
|
}
|
|
272
275
|
interface SignInRequest {
|
|
@@ -369,14 +372,25 @@ interface MfaEnrollResponse {
|
|
|
369
372
|
* Pour une passkey, utilisez `auth.mfa.webauthn.verify`.
|
|
370
373
|
*/
|
|
371
374
|
type MfaVerifyRequest = {
|
|
372
|
-
mfa_token
|
|
375
|
+
mfa_token?: string;
|
|
376
|
+
mfaToken?: string;
|
|
377
|
+
challenge_id?: string;
|
|
378
|
+
challengeId?: string;
|
|
373
379
|
code: string;
|
|
374
380
|
} | {
|
|
375
|
-
mfa_token
|
|
381
|
+
mfa_token?: string;
|
|
382
|
+
mfaToken?: string;
|
|
383
|
+
challenge_id?: string;
|
|
384
|
+
challengeId?: string;
|
|
376
385
|
recovery_code: string;
|
|
386
|
+
recoveryCode?: string;
|
|
377
387
|
} | {
|
|
378
|
-
mfa_token
|
|
388
|
+
mfa_token?: string;
|
|
389
|
+
mfaToken?: string;
|
|
390
|
+
challenge_id?: string;
|
|
391
|
+
challengeId?: string;
|
|
379
392
|
sms_code: string;
|
|
393
|
+
smsCode?: string;
|
|
380
394
|
};
|
|
381
395
|
/** Facteur MFA utilisable pour relever un défi (`auth.mfa.factors`). */
|
|
382
396
|
type MfaFactorType = 'totp' | 'webauthn' | 'sms';
|
|
@@ -1839,6 +1853,19 @@ type AuthChangeCallback = (token: string | null, user: User | null) => void;
|
|
|
1839
1853
|
* Check whether a JWT has expired (or will expire within `marginSec` seconds).
|
|
1840
1854
|
*/
|
|
1841
1855
|
declare function isTokenExpired(token: string, marginSec?: number): boolean;
|
|
1856
|
+
interface CookieOptions {
|
|
1857
|
+
path?: string;
|
|
1858
|
+
domain?: string;
|
|
1859
|
+
maxAge?: number;
|
|
1860
|
+
secure?: boolean;
|
|
1861
|
+
sameSite?: 'strict' | 'lax' | 'none';
|
|
1862
|
+
httpOnly?: boolean;
|
|
1863
|
+
}
|
|
1864
|
+
interface StoredAuth {
|
|
1865
|
+
token: string | null;
|
|
1866
|
+
refreshToken: string | null;
|
|
1867
|
+
user: User | null;
|
|
1868
|
+
}
|
|
1842
1869
|
/**
|
|
1843
1870
|
* In-memory auth store with an event-emitter pattern.
|
|
1844
1871
|
* Can be extended (see LocalAuthStore) for persistence.
|
|
@@ -1850,6 +1877,7 @@ declare class BaseAuthStore {
|
|
|
1850
1877
|
* le flux PKCE : le `code_verifier` doit survivre au redirect OAuth.
|
|
1851
1878
|
*/
|
|
1852
1879
|
readonly persistent: boolean;
|
|
1880
|
+
protected readonly key: string;
|
|
1853
1881
|
private _token;
|
|
1854
1882
|
private _refreshToken;
|
|
1855
1883
|
private _user;
|
|
@@ -1860,6 +1888,7 @@ declare class BaseAuthStore {
|
|
|
1860
1888
|
/** Hook d'observabilité (LOT 3) — câblé par `AuraClient` via `setObservabilityHook`. */
|
|
1861
1889
|
private _onEvent?;
|
|
1862
1890
|
private _debug;
|
|
1891
|
+
constructor(key?: string);
|
|
1863
1892
|
/** Compteur incrémenté à chaque `clear()` — sert au commit-guard anti-race du refresh. */
|
|
1864
1893
|
get removalEpoch(): number;
|
|
1865
1894
|
get token(): string | null;
|
|
@@ -1881,6 +1910,16 @@ declare class BaseAuthStore {
|
|
|
1881
1910
|
setObservabilityHook(onEvent: ((event: AuraObservabilityEvent) => void) | undefined, debug: boolean | undefined): void;
|
|
1882
1911
|
/** Émet `{kind:'storage-blocked', op}` — ne throw jamais (voir `emitAuraEvent`). */
|
|
1883
1912
|
protected _emitStorageBlocked(op: string): void;
|
|
1913
|
+
/**
|
|
1914
|
+
* Populate the store from a raw `Cookie` header string (server-side).
|
|
1915
|
+
* Looks for the key matching `this.key`.
|
|
1916
|
+
*/
|
|
1917
|
+
loadFromCookie(cookieString: string): void;
|
|
1918
|
+
/**
|
|
1919
|
+
* Serialize the session tokens into a `Set-Cookie` value. The `user` object is NOT included: its
|
|
1920
|
+
* `user_metadata` is already inside the access token.
|
|
1921
|
+
*/
|
|
1922
|
+
exportToCookie(options?: CookieOptions): string;
|
|
1884
1923
|
/**
|
|
1885
1924
|
* Register a callback that fires whenever the auth state changes.
|
|
1886
1925
|
* Returns an unsubscribe function.
|
|
@@ -2038,14 +2077,6 @@ declare function clientScope(baseUrl: string): string;
|
|
|
2038
2077
|
/** JSON.stringify avec support des bigint (sérialisés en string). */
|
|
2039
2078
|
declare function serializeBody(body: unknown): string;
|
|
2040
2079
|
|
|
2041
|
-
interface CookieOptions {
|
|
2042
|
-
path?: string;
|
|
2043
|
-
domain?: string;
|
|
2044
|
-
maxAge?: number;
|
|
2045
|
-
secure?: boolean;
|
|
2046
|
-
sameSite?: 'strict' | 'lax' | 'none';
|
|
2047
|
-
httpOnly?: boolean;
|
|
2048
|
-
}
|
|
2049
2080
|
/**
|
|
2050
2081
|
* Auth store backed by `localStorage` (browser) with cookie helpers for SSR.
|
|
2051
2082
|
*
|
|
@@ -2062,7 +2093,6 @@ interface CookieOptions {
|
|
|
2062
2093
|
declare class LocalAuthStore extends BaseAuthStore {
|
|
2063
2094
|
/** Persiste en localStorage → survit au redirect pleine page (cf. PKCE). */
|
|
2064
2095
|
readonly persistent = true;
|
|
2065
|
-
private readonly key;
|
|
2066
2096
|
/**
|
|
2067
2097
|
* @param key Nom de l'entrée `localStorage` (et du cookie SSR). Scopez-le par projet :
|
|
2068
2098
|
* `aura-${clientScope(baseUrl)}-auth`.
|
|
@@ -2103,4 +2133,4 @@ declare class LocalAuthStore extends BaseAuthStore {
|
|
|
2103
2133
|
private _removeStorage;
|
|
2104
2134
|
}
|
|
2105
2135
|
|
|
2106
|
-
export { AUTH_SETTINGS_WRITABLE_FIELDS, type AdminCreateUserRequest, type AdminSessionInfo, type AdminUpdateUserRequest, type AdminUser, type ApnsPublicSettings, type ApnsSettingsPatch, type AuditLogEntry, type AuraClientLike, type AuraClientOptions, AuraError, type AuraErrorCode, type AuraFailure, type AuraNoContent, type AuraObservabilityEvent, type AuraResponse, type AuraSuccess, type AuthChangePayload, type AuthEvent, type AuthSettings, type AuthSettingsUpdate, BaseAuthStore, BaseService, type BatchSendItemResult, type BatchSendResponse, type BroadcastAckMessage, type BroadcastFilter, type BroadcastPayload, type BroadcastSendStatus, type CdcPayload, type ChannelConfig, type ChatMessage, type ChatResponse, type CountMode, type CreateNotificationRuleRequest, type CreatePgFunctionRequest, type CreatePgTriggerRequest, type CronJob, DEFAULT_MAX_RETRIES, DEFAULT_REQUEST_TIMEOUT_MS, type EmailTemplateUpdate, type EmbedRequest, type EmbedResponse, type FcmPublicSettings, type FcmSettingsPatch, type FetchInit, type FileEntry, type FilterOp, type FunctionDef, type FunctionPermissions, type GenerateLinkResult, type GenerateLinkType, type GetClaimsResult, type IdentityInfo, type ImageTransform, type Job, type JwtClaims, LocalAuthStore, type LoginResponse, type MagicLinkRequest, type Meta, type MfaChallenge, type MfaEnrollResponse, type MfaFactorType, type MfaVerifyRequest, type Notification, type NotificationAttempt, type NotificationAttemptStatus, type NotificationChannel, type NotificationChannelStats, type NotificationDeadLetter, type NotificationEvent, type NotificationProviderLog, type NotificationQueueStats, type NotificationRule, type NotificationSettings, type NotificationSettingsPatch, type NotificationSettingsPublic, type NotificationStats, type NotificationStatsWindow, type NotificationStatus, type NotificationTemplate, type NotificationTemplatePreview, type OAuthProviderSetting, type OAuthSignInObjectOptions, type OAuthSignInOptions, type ObjectMeta, type PasskeyInfo, type PasskeyRegisterResult, type PasswordResetRequest, type PgExecutableRole, type PgFunctionInfo, type PgTriggerInfo, type PostgresChangesFilter, type PresenceFilter, type PresenceInfo, type PresenceState, type QueryFilter, type QueryOptions, type QuotaPublicSettings, type QuotaSettingsPatch, RETRYABLE_METHODS, RETRYABLE_STATUS, type RagIngestRequest, type RagIngestResponse, type RagRequest, type RagResponse, type RealtimeBroadcastEvent, type RealtimeEvent, type RealtimeListenType, type RealtimePostgresChangesBasePayload, type RealtimePostgresChangesPayload, type RealtimePostgresDeletePayload, type RealtimePostgresInsertPayload, type RealtimePostgresUpdatePayload, type RealtimeSubscribeStatus, type SchemaColumn, type SchemaEnum, type SchemaFunction, type SchemaFunctionArg, type SchemaIndex, type SchemaTable, type SemanticSearchResult, type SendNotificationItem, type SendNotificationOptions, type SendNotificationRequest, type SerializeCookieOptions, type ServerChannelRecoveredMsg, type ServerErrorMsg, type ServerEventMsg, type ServerMessage, type ServerPongMsg, type ServerPresenceStateMsg, type ServerSubscribedMsg, type ServerTokenRefreshedMsg, type Session, type SessionInfo, type SettingsSource, type SignInRequest, type SignUpRequest, type SmtpPublicSettings, type SmtpSettingsPatch, type StorageBucket, type SubscribeCallback, type TokenPair, type TwilioPublicSettings, type TwilioSettingsPatch, type UpdateNotificationRuleRequest, type UpdateUserRequest, type UploadResult, type User, type UserStats, type WebhookPublicSettings, type WebhookSettingsPatch, abortableSleep, clientScope, computeBackoff, emitAuraEvent, fetchWithAuth, isAbortError, isAuraError, isRetryableMethod, isRetryableStatus, isTokenExpired, parseCookieHeader, parseRetryAfter, refreshOnce, serializeBody, serializeCookieHeader };
|
|
2136
|
+
export { AUTH_SETTINGS_WRITABLE_FIELDS, type AdminCreateUserRequest, type AdminSessionInfo, type AdminUpdateUserRequest, type AdminUser, type ApnsPublicSettings, type ApnsSettingsPatch, type AuditLogEntry, type AuraClientLike, type AuraClientOptions, AuraError, type AuraErrorCode, type AuraFailure, type AuraNoContent, type AuraObservabilityEvent, type AuraResponse, type AuraSuccess, type AuthChangePayload, type AuthEvent, type AuthSettings, type AuthSettingsUpdate, BaseAuthStore, BaseService, type BatchSendItemResult, type BatchSendResponse, type BroadcastAckMessage, type BroadcastFilter, type BroadcastPayload, type BroadcastSendStatus, type CdcPayload, type ChannelConfig, type ChatMessage, type ChatResponse, type CookieOptions, type CountMode, type CreateNotificationRuleRequest, type CreatePgFunctionRequest, type CreatePgTriggerRequest, type CronJob, DEFAULT_MAX_RETRIES, DEFAULT_REQUEST_TIMEOUT_MS, type EmailTemplateUpdate, type EmbedRequest, type EmbedResponse, type FcmPublicSettings, type FcmSettingsPatch, type FetchInit, type FileEntry, type FilterOp, type FunctionDef, type FunctionPermissions, type GenerateLinkResult, type GenerateLinkType, type GetClaimsResult, type IdentityInfo, type ImageTransform, type Job, type JwtClaims, LocalAuthStore, type LoginResponse, type MagicLinkRequest, type Meta, type MfaChallenge, type MfaEnrollResponse, type MfaFactorType, type MfaVerifyRequest, type Notification, type NotificationAttempt, type NotificationAttemptStatus, type NotificationChannel, type NotificationChannelStats, type NotificationDeadLetter, type NotificationEvent, type NotificationProviderLog, type NotificationQueueStats, type NotificationRule, type NotificationSettings, type NotificationSettingsPatch, type NotificationSettingsPublic, type NotificationStats, type NotificationStatsWindow, type NotificationStatus, type NotificationTemplate, type NotificationTemplatePreview, type OAuthProviderSetting, type OAuthSignInObjectOptions, type OAuthSignInOptions, type ObjectMeta, type PasskeyInfo, type PasskeyRegisterResult, type PasswordResetRequest, type PgExecutableRole, type PgFunctionInfo, type PgTriggerInfo, type PostgresChangesFilter, type PresenceFilter, type PresenceInfo, type PresenceState, type QueryFilter, type QueryOptions, type QuotaPublicSettings, type QuotaSettingsPatch, RETRYABLE_METHODS, RETRYABLE_STATUS, type RagIngestRequest, type RagIngestResponse, type RagRequest, type RagResponse, type RealtimeBroadcastEvent, type RealtimeEvent, type RealtimeListenType, type RealtimePostgresChangesBasePayload, type RealtimePostgresChangesPayload, type RealtimePostgresDeletePayload, type RealtimePostgresInsertPayload, type RealtimePostgresUpdatePayload, type RealtimeSubscribeStatus, type SchemaColumn, type SchemaEnum, type SchemaFunction, type SchemaFunctionArg, type SchemaIndex, type SchemaTable, type SemanticSearchResult, type SendNotificationItem, type SendNotificationOptions, type SendNotificationRequest, type SerializeCookieOptions, type ServerChannelRecoveredMsg, type ServerErrorMsg, type ServerEventMsg, type ServerMessage, type ServerPongMsg, type ServerPresenceStateMsg, type ServerSubscribedMsg, type ServerTokenRefreshedMsg, type Session, type SessionInfo, type SettingsSource, type SignInRequest, type SignUpRequest, type SmtpPublicSettings, type SmtpSettingsPatch, type StorageBucket, type StoredAuth, type SubscribeCallback, type TokenPair, type TwilioPublicSettings, type TwilioSettingsPatch, type UpdateNotificationRuleRequest, type UpdateUserRequest, type UploadResult, type User, type UserStats, type WebhookPublicSettings, type WebhookSettingsPatch, abortableSleep, clientScope, computeBackoff, emitAuraEvent, fetchWithAuth, isAbortError, isAuraError, isRetryableMethod, isRetryableStatus, isTokenExpired, parseCookieHeader, parseRetryAfter, refreshOnce, serializeBody, serializeCookieHeader };
|
package/dist/index.d.ts
CHANGED
|
@@ -203,6 +203,8 @@ interface User {
|
|
|
203
203
|
last_sign_in_at?: string | null;
|
|
204
204
|
}
|
|
205
205
|
interface Session {
|
|
206
|
+
/** Identifiant unique de la session (UUID ou 'sess_...'), dérivé du claim `session_id` du JWT. */
|
|
207
|
+
id?: string;
|
|
206
208
|
access_token: string;
|
|
207
209
|
refresh_token: string;
|
|
208
210
|
token_type: string;
|
|
@@ -267,6 +269,7 @@ interface SignUpRequest {
|
|
|
267
269
|
options?: {
|
|
268
270
|
emailRedirectTo?: string;
|
|
269
271
|
data?: Record<string, unknown>;
|
|
272
|
+
preventEmailEnumeration?: boolean;
|
|
270
273
|
};
|
|
271
274
|
}
|
|
272
275
|
interface SignInRequest {
|
|
@@ -369,14 +372,25 @@ interface MfaEnrollResponse {
|
|
|
369
372
|
* Pour une passkey, utilisez `auth.mfa.webauthn.verify`.
|
|
370
373
|
*/
|
|
371
374
|
type MfaVerifyRequest = {
|
|
372
|
-
mfa_token
|
|
375
|
+
mfa_token?: string;
|
|
376
|
+
mfaToken?: string;
|
|
377
|
+
challenge_id?: string;
|
|
378
|
+
challengeId?: string;
|
|
373
379
|
code: string;
|
|
374
380
|
} | {
|
|
375
|
-
mfa_token
|
|
381
|
+
mfa_token?: string;
|
|
382
|
+
mfaToken?: string;
|
|
383
|
+
challenge_id?: string;
|
|
384
|
+
challengeId?: string;
|
|
376
385
|
recovery_code: string;
|
|
386
|
+
recoveryCode?: string;
|
|
377
387
|
} | {
|
|
378
|
-
mfa_token
|
|
388
|
+
mfa_token?: string;
|
|
389
|
+
mfaToken?: string;
|
|
390
|
+
challenge_id?: string;
|
|
391
|
+
challengeId?: string;
|
|
379
392
|
sms_code: string;
|
|
393
|
+
smsCode?: string;
|
|
380
394
|
};
|
|
381
395
|
/** Facteur MFA utilisable pour relever un défi (`auth.mfa.factors`). */
|
|
382
396
|
type MfaFactorType = 'totp' | 'webauthn' | 'sms';
|
|
@@ -1839,6 +1853,19 @@ type AuthChangeCallback = (token: string | null, user: User | null) => void;
|
|
|
1839
1853
|
* Check whether a JWT has expired (or will expire within `marginSec` seconds).
|
|
1840
1854
|
*/
|
|
1841
1855
|
declare function isTokenExpired(token: string, marginSec?: number): boolean;
|
|
1856
|
+
interface CookieOptions {
|
|
1857
|
+
path?: string;
|
|
1858
|
+
domain?: string;
|
|
1859
|
+
maxAge?: number;
|
|
1860
|
+
secure?: boolean;
|
|
1861
|
+
sameSite?: 'strict' | 'lax' | 'none';
|
|
1862
|
+
httpOnly?: boolean;
|
|
1863
|
+
}
|
|
1864
|
+
interface StoredAuth {
|
|
1865
|
+
token: string | null;
|
|
1866
|
+
refreshToken: string | null;
|
|
1867
|
+
user: User | null;
|
|
1868
|
+
}
|
|
1842
1869
|
/**
|
|
1843
1870
|
* In-memory auth store with an event-emitter pattern.
|
|
1844
1871
|
* Can be extended (see LocalAuthStore) for persistence.
|
|
@@ -1850,6 +1877,7 @@ declare class BaseAuthStore {
|
|
|
1850
1877
|
* le flux PKCE : le `code_verifier` doit survivre au redirect OAuth.
|
|
1851
1878
|
*/
|
|
1852
1879
|
readonly persistent: boolean;
|
|
1880
|
+
protected readonly key: string;
|
|
1853
1881
|
private _token;
|
|
1854
1882
|
private _refreshToken;
|
|
1855
1883
|
private _user;
|
|
@@ -1860,6 +1888,7 @@ declare class BaseAuthStore {
|
|
|
1860
1888
|
/** Hook d'observabilité (LOT 3) — câblé par `AuraClient` via `setObservabilityHook`. */
|
|
1861
1889
|
private _onEvent?;
|
|
1862
1890
|
private _debug;
|
|
1891
|
+
constructor(key?: string);
|
|
1863
1892
|
/** Compteur incrémenté à chaque `clear()` — sert au commit-guard anti-race du refresh. */
|
|
1864
1893
|
get removalEpoch(): number;
|
|
1865
1894
|
get token(): string | null;
|
|
@@ -1881,6 +1910,16 @@ declare class BaseAuthStore {
|
|
|
1881
1910
|
setObservabilityHook(onEvent: ((event: AuraObservabilityEvent) => void) | undefined, debug: boolean | undefined): void;
|
|
1882
1911
|
/** Émet `{kind:'storage-blocked', op}` — ne throw jamais (voir `emitAuraEvent`). */
|
|
1883
1912
|
protected _emitStorageBlocked(op: string): void;
|
|
1913
|
+
/**
|
|
1914
|
+
* Populate the store from a raw `Cookie` header string (server-side).
|
|
1915
|
+
* Looks for the key matching `this.key`.
|
|
1916
|
+
*/
|
|
1917
|
+
loadFromCookie(cookieString: string): void;
|
|
1918
|
+
/**
|
|
1919
|
+
* Serialize the session tokens into a `Set-Cookie` value. The `user` object is NOT included: its
|
|
1920
|
+
* `user_metadata` is already inside the access token.
|
|
1921
|
+
*/
|
|
1922
|
+
exportToCookie(options?: CookieOptions): string;
|
|
1884
1923
|
/**
|
|
1885
1924
|
* Register a callback that fires whenever the auth state changes.
|
|
1886
1925
|
* Returns an unsubscribe function.
|
|
@@ -2038,14 +2077,6 @@ declare function clientScope(baseUrl: string): string;
|
|
|
2038
2077
|
/** JSON.stringify avec support des bigint (sérialisés en string). */
|
|
2039
2078
|
declare function serializeBody(body: unknown): string;
|
|
2040
2079
|
|
|
2041
|
-
interface CookieOptions {
|
|
2042
|
-
path?: string;
|
|
2043
|
-
domain?: string;
|
|
2044
|
-
maxAge?: number;
|
|
2045
|
-
secure?: boolean;
|
|
2046
|
-
sameSite?: 'strict' | 'lax' | 'none';
|
|
2047
|
-
httpOnly?: boolean;
|
|
2048
|
-
}
|
|
2049
2080
|
/**
|
|
2050
2081
|
* Auth store backed by `localStorage` (browser) with cookie helpers for SSR.
|
|
2051
2082
|
*
|
|
@@ -2062,7 +2093,6 @@ interface CookieOptions {
|
|
|
2062
2093
|
declare class LocalAuthStore extends BaseAuthStore {
|
|
2063
2094
|
/** Persiste en localStorage → survit au redirect pleine page (cf. PKCE). */
|
|
2064
2095
|
readonly persistent = true;
|
|
2065
|
-
private readonly key;
|
|
2066
2096
|
/**
|
|
2067
2097
|
* @param key Nom de l'entrée `localStorage` (et du cookie SSR). Scopez-le par projet :
|
|
2068
2098
|
* `aura-${clientScope(baseUrl)}-auth`.
|
|
@@ -2103,4 +2133,4 @@ declare class LocalAuthStore extends BaseAuthStore {
|
|
|
2103
2133
|
private _removeStorage;
|
|
2104
2134
|
}
|
|
2105
2135
|
|
|
2106
|
-
export { AUTH_SETTINGS_WRITABLE_FIELDS, type AdminCreateUserRequest, type AdminSessionInfo, type AdminUpdateUserRequest, type AdminUser, type ApnsPublicSettings, type ApnsSettingsPatch, type AuditLogEntry, type AuraClientLike, type AuraClientOptions, AuraError, type AuraErrorCode, type AuraFailure, type AuraNoContent, type AuraObservabilityEvent, type AuraResponse, type AuraSuccess, type AuthChangePayload, type AuthEvent, type AuthSettings, type AuthSettingsUpdate, BaseAuthStore, BaseService, type BatchSendItemResult, type BatchSendResponse, type BroadcastAckMessage, type BroadcastFilter, type BroadcastPayload, type BroadcastSendStatus, type CdcPayload, type ChannelConfig, type ChatMessage, type ChatResponse, type CountMode, type CreateNotificationRuleRequest, type CreatePgFunctionRequest, type CreatePgTriggerRequest, type CronJob, DEFAULT_MAX_RETRIES, DEFAULT_REQUEST_TIMEOUT_MS, type EmailTemplateUpdate, type EmbedRequest, type EmbedResponse, type FcmPublicSettings, type FcmSettingsPatch, type FetchInit, type FileEntry, type FilterOp, type FunctionDef, type FunctionPermissions, type GenerateLinkResult, type GenerateLinkType, type GetClaimsResult, type IdentityInfo, type ImageTransform, type Job, type JwtClaims, LocalAuthStore, type LoginResponse, type MagicLinkRequest, type Meta, type MfaChallenge, type MfaEnrollResponse, type MfaFactorType, type MfaVerifyRequest, type Notification, type NotificationAttempt, type NotificationAttemptStatus, type NotificationChannel, type NotificationChannelStats, type NotificationDeadLetter, type NotificationEvent, type NotificationProviderLog, type NotificationQueueStats, type NotificationRule, type NotificationSettings, type NotificationSettingsPatch, type NotificationSettingsPublic, type NotificationStats, type NotificationStatsWindow, type NotificationStatus, type NotificationTemplate, type NotificationTemplatePreview, type OAuthProviderSetting, type OAuthSignInObjectOptions, type OAuthSignInOptions, type ObjectMeta, type PasskeyInfo, type PasskeyRegisterResult, type PasswordResetRequest, type PgExecutableRole, type PgFunctionInfo, type PgTriggerInfo, type PostgresChangesFilter, type PresenceFilter, type PresenceInfo, type PresenceState, type QueryFilter, type QueryOptions, type QuotaPublicSettings, type QuotaSettingsPatch, RETRYABLE_METHODS, RETRYABLE_STATUS, type RagIngestRequest, type RagIngestResponse, type RagRequest, type RagResponse, type RealtimeBroadcastEvent, type RealtimeEvent, type RealtimeListenType, type RealtimePostgresChangesBasePayload, type RealtimePostgresChangesPayload, type RealtimePostgresDeletePayload, type RealtimePostgresInsertPayload, type RealtimePostgresUpdatePayload, type RealtimeSubscribeStatus, type SchemaColumn, type SchemaEnum, type SchemaFunction, type SchemaFunctionArg, type SchemaIndex, type SchemaTable, type SemanticSearchResult, type SendNotificationItem, type SendNotificationOptions, type SendNotificationRequest, type SerializeCookieOptions, type ServerChannelRecoveredMsg, type ServerErrorMsg, type ServerEventMsg, type ServerMessage, type ServerPongMsg, type ServerPresenceStateMsg, type ServerSubscribedMsg, type ServerTokenRefreshedMsg, type Session, type SessionInfo, type SettingsSource, type SignInRequest, type SignUpRequest, type SmtpPublicSettings, type SmtpSettingsPatch, type StorageBucket, type SubscribeCallback, type TokenPair, type TwilioPublicSettings, type TwilioSettingsPatch, type UpdateNotificationRuleRequest, type UpdateUserRequest, type UploadResult, type User, type UserStats, type WebhookPublicSettings, type WebhookSettingsPatch, abortableSleep, clientScope, computeBackoff, emitAuraEvent, fetchWithAuth, isAbortError, isAuraError, isRetryableMethod, isRetryableStatus, isTokenExpired, parseCookieHeader, parseRetryAfter, refreshOnce, serializeBody, serializeCookieHeader };
|
|
2136
|
+
export { AUTH_SETTINGS_WRITABLE_FIELDS, type AdminCreateUserRequest, type AdminSessionInfo, type AdminUpdateUserRequest, type AdminUser, type ApnsPublicSettings, type ApnsSettingsPatch, type AuditLogEntry, type AuraClientLike, type AuraClientOptions, AuraError, type AuraErrorCode, type AuraFailure, type AuraNoContent, type AuraObservabilityEvent, type AuraResponse, type AuraSuccess, type AuthChangePayload, type AuthEvent, type AuthSettings, type AuthSettingsUpdate, BaseAuthStore, BaseService, type BatchSendItemResult, type BatchSendResponse, type BroadcastAckMessage, type BroadcastFilter, type BroadcastPayload, type BroadcastSendStatus, type CdcPayload, type ChannelConfig, type ChatMessage, type ChatResponse, type CookieOptions, type CountMode, type CreateNotificationRuleRequest, type CreatePgFunctionRequest, type CreatePgTriggerRequest, type CronJob, DEFAULT_MAX_RETRIES, DEFAULT_REQUEST_TIMEOUT_MS, type EmailTemplateUpdate, type EmbedRequest, type EmbedResponse, type FcmPublicSettings, type FcmSettingsPatch, type FetchInit, type FileEntry, type FilterOp, type FunctionDef, type FunctionPermissions, type GenerateLinkResult, type GenerateLinkType, type GetClaimsResult, type IdentityInfo, type ImageTransform, type Job, type JwtClaims, LocalAuthStore, type LoginResponse, type MagicLinkRequest, type Meta, type MfaChallenge, type MfaEnrollResponse, type MfaFactorType, type MfaVerifyRequest, type Notification, type NotificationAttempt, type NotificationAttemptStatus, type NotificationChannel, type NotificationChannelStats, type NotificationDeadLetter, type NotificationEvent, type NotificationProviderLog, type NotificationQueueStats, type NotificationRule, type NotificationSettings, type NotificationSettingsPatch, type NotificationSettingsPublic, type NotificationStats, type NotificationStatsWindow, type NotificationStatus, type NotificationTemplate, type NotificationTemplatePreview, type OAuthProviderSetting, type OAuthSignInObjectOptions, type OAuthSignInOptions, type ObjectMeta, type PasskeyInfo, type PasskeyRegisterResult, type PasswordResetRequest, type PgExecutableRole, type PgFunctionInfo, type PgTriggerInfo, type PostgresChangesFilter, type PresenceFilter, type PresenceInfo, type PresenceState, type QueryFilter, type QueryOptions, type QuotaPublicSettings, type QuotaSettingsPatch, RETRYABLE_METHODS, RETRYABLE_STATUS, type RagIngestRequest, type RagIngestResponse, type RagRequest, type RagResponse, type RealtimeBroadcastEvent, type RealtimeEvent, type RealtimeListenType, type RealtimePostgresChangesBasePayload, type RealtimePostgresChangesPayload, type RealtimePostgresDeletePayload, type RealtimePostgresInsertPayload, type RealtimePostgresUpdatePayload, type RealtimeSubscribeStatus, type SchemaColumn, type SchemaEnum, type SchemaFunction, type SchemaFunctionArg, type SchemaIndex, type SchemaTable, type SemanticSearchResult, type SendNotificationItem, type SendNotificationOptions, type SendNotificationRequest, type SerializeCookieOptions, type ServerChannelRecoveredMsg, type ServerErrorMsg, type ServerEventMsg, type ServerMessage, type ServerPongMsg, type ServerPresenceStateMsg, type ServerSubscribedMsg, type ServerTokenRefreshedMsg, type Session, type SessionInfo, type SettingsSource, type SignInRequest, type SignUpRequest, type SmtpPublicSettings, type SmtpSettingsPatch, type StorageBucket, type StoredAuth, type SubscribeCallback, type TokenPair, type TwilioPublicSettings, type TwilioSettingsPatch, type UpdateNotificationRuleRequest, type UpdateUserRequest, type UploadResult, type User, type UserStats, type WebhookPublicSettings, type WebhookSettingsPatch, abortableSleep, clientScope, computeBackoff, emitAuraEvent, fetchWithAuth, isAbortError, isAuraError, isRetryableMethod, isRetryableStatus, isTokenExpired, parseCookieHeader, parseRetryAfter, refreshOnce, serializeBody, serializeCookieHeader };
|
package/dist/index.js
CHANGED
|
@@ -94,8 +94,12 @@ var AuraError = class _AuraError extends Error {
|
|
|
94
94
|
this.code = "SESSION_REVOKED";
|
|
95
95
|
} else if (status === 401 && lowerMsg.includes("expired")) {
|
|
96
96
|
this.code = "SESSION_EXPIRED";
|
|
97
|
-
} else if (status === 400 && lowerMsg.includes("password")) {
|
|
97
|
+
} else if (status === 400 && (lowerMsg.includes("current password") || lowerMsg.includes("old password") || lowerMsg.includes("password") && lowerMsg.includes("required"))) {
|
|
98
|
+
this.code = lowerMsg.includes("incorrect") || lowerMsg.includes("invalid") ? "INVALID_CURRENT_PASSWORD" : "CURRENT_PASSWORD_REQUIRED";
|
|
99
|
+
} else if (status === 400 && lowerMsg.includes("password") && (lowerMsg.includes("weak") || lowerMsg.includes("length") || lowerMsg.includes("strength") || lowerMsg.includes("character") || lowerMsg.includes("digit") || lowerMsg.includes("pwned") || lowerMsg.includes("too short") || lowerMsg.includes("too common"))) {
|
|
98
100
|
this.code = "WEAK_PASSWORD";
|
|
101
|
+
} else if (status === 400 && lowerMsg.includes("password")) {
|
|
102
|
+
this.code = "INVALID_PASSWORD";
|
|
99
103
|
} else if (status === 409 && (lowerMsg.includes("already exists") || lowerMsg.includes("already in use") || lowerMsg.includes("email"))) {
|
|
100
104
|
this.code = "EMAIL_ALREADY_IN_USE";
|
|
101
105
|
} else if (status === 404 && lowerMsg.includes("user not found")) {
|
|
@@ -277,6 +281,33 @@ var AUTH_SETTINGS_WRITABLE_FIELDS = [
|
|
|
277
281
|
"hook_secret"
|
|
278
282
|
];
|
|
279
283
|
|
|
284
|
+
// src/cookie-utils.ts
|
|
285
|
+
function parseCookieHeader(header) {
|
|
286
|
+
const result = {};
|
|
287
|
+
if (!header) return result;
|
|
288
|
+
for (const pair of header.split(";")) {
|
|
289
|
+
const idx = pair.indexOf("=");
|
|
290
|
+
if (idx === -1) continue;
|
|
291
|
+
const key = pair.slice(0, idx).trim();
|
|
292
|
+
const value = pair.slice(idx + 1).trim();
|
|
293
|
+
if (key) result[key] = decodeURIComponent(value);
|
|
294
|
+
}
|
|
295
|
+
return result;
|
|
296
|
+
}
|
|
297
|
+
function sameSiteAttribute(v) {
|
|
298
|
+
return v.charAt(0).toUpperCase() + v.slice(1);
|
|
299
|
+
}
|
|
300
|
+
function serializeCookieHeader(name, value, options = {}) {
|
|
301
|
+
const parts = [`${name}=${encodeURIComponent(value)}`];
|
|
302
|
+
if (options.path) parts.push(`Path=${options.path}`);
|
|
303
|
+
if (options.domain) parts.push(`Domain=${options.domain}`);
|
|
304
|
+
if (options.maxAge !== void 0) parts.push(`Max-Age=${options.maxAge}`);
|
|
305
|
+
if (options.secure) parts.push("Secure");
|
|
306
|
+
if (options.sameSite) parts.push(`SameSite=${sameSiteAttribute(options.sameSite)}`);
|
|
307
|
+
if (options.httpOnly) parts.push("HttpOnly");
|
|
308
|
+
return parts.join("; ");
|
|
309
|
+
}
|
|
310
|
+
|
|
280
311
|
// src/stores/BaseAuthStore.ts
|
|
281
312
|
function decodeJwtPayload(token) {
|
|
282
313
|
try {
|
|
@@ -321,6 +352,7 @@ var BaseAuthStore = class {
|
|
|
321
352
|
* le flux PKCE : le `code_verifier` doit survivre au redirect OAuth.
|
|
322
353
|
*/
|
|
323
354
|
persistent = false;
|
|
355
|
+
key;
|
|
324
356
|
_token = null;
|
|
325
357
|
_refreshToken = null;
|
|
326
358
|
_user = null;
|
|
@@ -331,6 +363,9 @@ var BaseAuthStore = class {
|
|
|
331
363
|
/** Hook d'observabilité (LOT 3) — câblé par `AuraClient` via `setObservabilityHook`. */
|
|
332
364
|
_onEvent;
|
|
333
365
|
_debug = false;
|
|
366
|
+
constructor(key = "aura-auth") {
|
|
367
|
+
this.key = key;
|
|
368
|
+
}
|
|
334
369
|
// -- Getters ----------------------------------------------------------------
|
|
335
370
|
/** Compteur incrémenté à chaque `clear()` — sert au commit-guard anti-race du refresh. */
|
|
336
371
|
get removalEpoch() {
|
|
@@ -392,6 +427,43 @@ var BaseAuthStore = class {
|
|
|
392
427
|
_emitStorageBlocked(op) {
|
|
393
428
|
emitAuraEvent(this._onEvent, this._debug, { kind: "storage-blocked", op });
|
|
394
429
|
}
|
|
430
|
+
/**
|
|
431
|
+
* Populate the store from a raw `Cookie` header string (server-side).
|
|
432
|
+
* Looks for the key matching `this.key`.
|
|
433
|
+
*/
|
|
434
|
+
loadFromCookie(cookieString) {
|
|
435
|
+
const prefix = `${this.key}=`;
|
|
436
|
+
const entry = cookieString.split(";").map((c) => c.trim()).find((c) => c.startsWith(prefix));
|
|
437
|
+
if (!entry) return;
|
|
438
|
+
try {
|
|
439
|
+
const raw = decodeURIComponent(entry.slice(prefix.length));
|
|
440
|
+
const parsed = JSON.parse(raw);
|
|
441
|
+
const user = parsed.token ? userFromAccessToken(parsed.token) : null;
|
|
442
|
+
if (parsed.token && parsed.refreshToken && user) {
|
|
443
|
+
this.save(parsed.token, parsed.refreshToken, user);
|
|
444
|
+
}
|
|
445
|
+
} catch {
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Serialize the session tokens into a `Set-Cookie` value. The `user` object is NOT included: its
|
|
450
|
+
* `user_metadata` is already inside the access token.
|
|
451
|
+
*/
|
|
452
|
+
exportToCookie(options = {}) {
|
|
453
|
+
const data = {
|
|
454
|
+
token: this.token,
|
|
455
|
+
refreshToken: this.refreshToken
|
|
456
|
+
};
|
|
457
|
+
const encoded = encodeURIComponent(JSON.stringify(data));
|
|
458
|
+
const parts = [`${this.key}=${encoded}`];
|
|
459
|
+
if (options.path) parts.push(`Path=${options.path}`);
|
|
460
|
+
if (options.domain) parts.push(`Domain=${options.domain}`);
|
|
461
|
+
if (options.maxAge !== void 0) parts.push(`Max-Age=${options.maxAge}`);
|
|
462
|
+
if (options.secure) parts.push("Secure");
|
|
463
|
+
if (options.sameSite) parts.push(`SameSite=${sameSiteAttribute(options.sameSite)}`);
|
|
464
|
+
if (options.httpOnly) parts.push("HttpOnly");
|
|
465
|
+
return parts.join("; ");
|
|
466
|
+
}
|
|
395
467
|
// -- Event emitter ----------------------------------------------------------
|
|
396
468
|
/**
|
|
397
469
|
* Register a callback that fires whenever the auth state changes.
|
|
@@ -886,45 +958,16 @@ var BaseService = class {
|
|
|
886
958
|
}
|
|
887
959
|
};
|
|
888
960
|
|
|
889
|
-
// src/cookie-utils.ts
|
|
890
|
-
function parseCookieHeader(header) {
|
|
891
|
-
const result = {};
|
|
892
|
-
if (!header) return result;
|
|
893
|
-
for (const pair of header.split(";")) {
|
|
894
|
-
const idx = pair.indexOf("=");
|
|
895
|
-
if (idx === -1) continue;
|
|
896
|
-
const key = pair.slice(0, idx).trim();
|
|
897
|
-
const value = pair.slice(idx + 1).trim();
|
|
898
|
-
if (key) result[key] = decodeURIComponent(value);
|
|
899
|
-
}
|
|
900
|
-
return result;
|
|
901
|
-
}
|
|
902
|
-
function sameSiteAttribute(v) {
|
|
903
|
-
return v.charAt(0).toUpperCase() + v.slice(1);
|
|
904
|
-
}
|
|
905
|
-
function serializeCookieHeader(name, value, options = {}) {
|
|
906
|
-
const parts = [`${name}=${encodeURIComponent(value)}`];
|
|
907
|
-
if (options.path) parts.push(`Path=${options.path}`);
|
|
908
|
-
if (options.domain) parts.push(`Domain=${options.domain}`);
|
|
909
|
-
if (options.maxAge !== void 0) parts.push(`Max-Age=${options.maxAge}`);
|
|
910
|
-
if (options.secure) parts.push("Secure");
|
|
911
|
-
if (options.sameSite) parts.push(`SameSite=${sameSiteAttribute(options.sameSite)}`);
|
|
912
|
-
if (options.httpOnly) parts.push("HttpOnly");
|
|
913
|
-
return parts.join("; ");
|
|
914
|
-
}
|
|
915
|
-
|
|
916
961
|
// src/stores/LocalAuthStore.ts
|
|
917
962
|
var LocalAuthStore = class extends BaseAuthStore {
|
|
918
963
|
/** Persiste en localStorage → survit au redirect pleine page (cf. PKCE). */
|
|
919
964
|
persistent = true;
|
|
920
|
-
key;
|
|
921
965
|
/**
|
|
922
966
|
* @param key Nom de l'entrée `localStorage` (et du cookie SSR). Scopez-le par projet :
|
|
923
967
|
* `aura-${clientScope(baseUrl)}-auth`.
|
|
924
968
|
*/
|
|
925
969
|
constructor(key) {
|
|
926
|
-
super();
|
|
927
|
-
this.key = key;
|
|
970
|
+
super(key);
|
|
928
971
|
this._loadFromStorage();
|
|
929
972
|
}
|
|
930
973
|
// -- Overrides --------------------------------------------------------------
|
package/package.json
CHANGED