@zuzjs/flare 0.2.11 → 0.2.13

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.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { AuthToken, AuthGuard, ProviderId } from '@zuzjs/auth';
1
+ import { AuthToken } from '@zuzjs/auth';
2
2
  export { Anonymous, Apple, AuthGuard, AuthToken, CreateUserWithEmailAndPasswordInput, Credentials, Dropbox, Facebook, GitHub, Google, NormalizedProfile, OAuthProvider, ProviderId, Providers, SignInAnonymouslyInput, SignInWithEmailAndPasswordInput, Twitter, setupProvider } from '@zuzjs/auth';
3
3
 
4
4
  /**
@@ -29,6 +29,12 @@ interface FlareConfig {
29
29
  * Defaults to OAuth-compatible form encoding.
30
30
  */
31
31
  authRequestContentType?: "application/x-www-form-urlencoded" | "application/json";
32
+ /**
33
+ * Controls how onAuthStateChanged initializes auth in browser runtime.
34
+ * - `refresh` (default): attempt /auth/refresh once in httpBase mode.
35
+ * - `none`: skip automatic refresh bootstrap; listeners receive current in-memory state only.
36
+ */
37
+ authBootstrapMode?: "refresh" | "none";
32
38
  /** Public key for the application. */
33
39
  publicKey?: string;
34
40
  /** Whether to automatically reconnect on connection loss. */
@@ -97,6 +103,23 @@ interface FlareAuthUser {
97
103
  email_verified: string;
98
104
  [x: string]: any;
99
105
  }
106
+ interface FlareAuthHydrationInput {
107
+ uid?: string | null;
108
+ id?: string | null;
109
+ accessToken?: string | null;
110
+ refreshToken?: string | null;
111
+ ticket?: string | null;
112
+ provider?: string;
113
+ email?: string | null;
114
+ emailVerified?: boolean;
115
+ email_verified?: boolean;
116
+ profile?: Partial<FlareAuthUser> | null;
117
+ }
118
+ interface FlareAuthHydrationOptions {
119
+ source?: string;
120
+ markBootstrapAttempted?: boolean;
121
+ syncSocket?: boolean;
122
+ }
100
123
  interface RegisterPushTokenInput {
101
124
  token: string;
102
125
  platform?: string;
@@ -979,62 +1002,42 @@ declare class FlareBase<TPresetMap extends QueryPresetMap = {}> {
979
1002
  protected handleIncoming(msg: any): void;
980
1003
  }
981
1004
 
982
- /**
983
- * FlareAuth extends FlareBase with all authentication and CSRF logic.
984
- *
985
- * CSRF strategy
986
- * ─────────────
987
- * The server sets an HttpOnly cookie on /auth/config responses. The raw
988
- * cookie value is NOT readable by JS (HttpOnly), but the server also echoes
989
- * the token in the `x-flare-csrf` response header so the client can send
990
- * it back as `x-flare-csrf` on every mutating request.
991
- *
992
- * Two environments are supported:
993
- * 1. Browser – header is read from the /auth/config fetch; stored in
994
- * `this.csrfToken` (in-memory only, never written to a
995
- * readable cookie by the client).
996
- * 2. Next.js SSR – use the standalone `createCsrfProxy()` handler
997
- * (see Client/proxy.ts) which captures the Set-Cookie header
998
- * from Flare server and sets it on the client domain too, so
999
- * the browser owns two HttpOnly cookies: one from the Flare
1000
- * domain and one from the Next.js domain.
1001
- */
1002
1005
  declare class FlareAuth<TPresetMap extends QueryPresetMap = {}> extends FlareBase<TPresetMap> {
1003
1006
  static AUTH_TRACE_STORAGE_KEY: string;
1004
- protected authToken?: string;
1007
+ protected pushServiceWorkerInitPromise?: Promise<ServiceWorkerRegistration | null>;
1008
+ /** Current authentication configuration */
1005
1009
  protected userId?: string;
1006
- protected authGuard?: AuthGuard;
1010
+ protected authToken?: string;
1011
+ protected authTicket?: string;
1007
1012
  protected authConfig?: FlareAuthConfig;
1008
- /** In-memory CSRF token extracted from the `x-flare-csrf` response header */
1009
- protected csrfToken?: string;
1010
- protected csrfInitPromise?: Promise<void>;
1011
- protected csrfBootstrapAttempted: boolean;
1012
- protected socketAuthSyncPromise?: Promise<void>;
1013
- protected pushServiceWorkerInitPromise?: Promise<ServiceWorkerRegistration | null>;
1014
- protected authSession: FlareAuthSession | null;
1015
- protected authBootstrapPromise?: Promise<void>;
1016
- protected authBootstrapAttempted: boolean;
1017
1013
  protected authStateListeners: AuthStateListener[];
1018
1014
  protected authConfigListeners: AuthConfigListener[];
1015
+ protected authSession: FlareAuthSession | null;
1019
1016
  protected currentProfile: FlareAuthUser | undefined;
1017
+ protected authBootstrapAttempted: boolean;
1018
+ protected authBootstrapPromise?: Promise<void>;
1019
+ protected socketAuthSyncPromise?: Promise<void>;
1020
+ /** In-memory CSRF token extracted from the `x-flare-csrf` response header */
1021
+ protected csrfToken?: string;
1022
+ protected csrfBootstrapAttempted: boolean;
1023
+ protected csrfInitPromise?: Promise<void>;
1020
1024
  protected isAuthTraceEnabled(): boolean;
1021
- setAuthTrace(enabled: boolean, persist?: boolean): void;
1022
1025
  protected traceAuth(event: string, details?: Record<string, unknown>): void;
1023
- private getAuthRequestContentType;
1024
- private buildAuthRequestBody;
1026
+ setAuthTrace(enabled: boolean, persist?: boolean): void;
1027
+ protected fetchAuthMe(token?: string): Promise<{
1028
+ id?: string;
1029
+ email?: string | null;
1030
+ email_verified?: boolean;
1031
+ }>;
1032
+ isBootstrapAttempted(): boolean;
1033
+ hydrateAuthState(input: FlareAuthHydrationInput | null, options?: FlareAuthHydrationOptions): Promise<void>;
1034
+ loadAuthConfig(): Promise<FlareAuthConfig>;
1035
+ onAuthConfigLoaded(listener: AuthConfigListener): () => void;
1036
+ onAuthStateChanged(listener: AuthStateListener): () => void;
1037
+ getCurrentUser(): FlareAuthUser | undefined;
1038
+ getAuthTicket(): string | undefined;
1039
+ consumeAuthTicket(): string | undefined;
1025
1040
  private getDefaultCsrfCookieName;
1026
- getCsrfCookieName(): string;
1027
- /**
1028
- * Read the CSRF token from a browser-readable cookie (set by the server as
1029
- * a non-HttpOnly fallback) or fall back to the in-memory value captured
1030
- * from the response header.
1031
- *
1032
- * Priority:
1033
- * 1. Non-HttpOnly cookie on the current domain (browser only)
1034
- * 2. In-memory value from `x-flare-csrf` response header
1035
- */
1036
- getCsrfToken(): string | null;
1037
- private getCookieValue;
1038
1041
  /**
1039
1042
  * Extract CSRF token from a server response.
1040
1043
  * The server now sends it ONLY as the `x-flare-csrf` response header
@@ -1047,35 +1050,71 @@ declare class FlareAuth<TPresetMap extends QueryPresetMap = {}> extends FlareBas
1047
1050
  };
1048
1051
  }): string | undefined;
1049
1052
  getCsrfHeaders(): Record<string, string>;
1053
+ getCsrfCookieName(): string;
1050
1054
  /**
1051
- * Inject CSRF token directly (used by SSR middleware).
1052
- * This allows the server to bootstrap CSRF once and inject it into the client,
1053
- * preventing redundant /auth/config calls.
1055
+ * Read the CSRF token from a browser-readable cookie (set by the server as
1056
+ * a non-HttpOnly fallback) or fall back to the in-memory value captured
1057
+ * from the response header.
1054
1058
  *
1055
- * @example
1056
- * // In Next.js middleware
1057
- * const csrf = extractCsrfFromRequest(request, appId);
1058
- * if (csrf) {
1059
- * flareClient.setCsrfToken(csrf);
1060
- * }
1059
+ * Priority:
1060
+ * 1. Non-HttpOnly cookie on the current domain (browser only)
1061
+ * 2. In-memory value from `x-flare-csrf` response header
1061
1062
  */
1062
- setCsrfToken(token: string): void;
1063
+ getCsrfToken(): string | null;
1063
1064
  ensureCsrfProtection(): Promise<void>;
1064
- loadAuthConfig(): Promise<FlareAuthConfig>;
1065
- protected fetchAuthConfig(): Promise<FlareAuthConfig>;
1066
- onAuthConfigLoaded(listener: AuthConfigListener): () => void;
1067
- protected setProfile(profile: FlareAuthUser): void;
1068
1065
  protected setAuthSession(session: FlareAuthSession | null, source?: string): void;
1069
- onAuthStateChanged(listener: AuthStateListener): () => void;
1070
- onAuthStateChange(listener: AuthStateListener): () => void;
1071
- get currentUser(): FlareAuthUser | undefined;
1072
- getCurrentUser(): FlareAuthUser | undefined;
1073
- protected syncSocketAuth(accessToken?: string | null): Promise<void>;
1066
+ protected emitAuthState(): void;
1067
+ protected setProfile(profile: FlareAuthUser): void;
1068
+ protected ensureSessionForSocketAuth(reason: string): Promise<boolean>;
1069
+ refreshAuthSession(refresh_token?: string): Promise<FlareAuthSession | null>;
1074
1070
  protected updateSocketIdentity(uid?: string, forceReplay?: boolean): Promise<void>;
1071
+ protected waitUntilConnected(): Promise<void>;
1072
+ protected syncSocketAuth(accessToken?: string | null): Promise<void>;
1075
1073
  protected beforeActivateSubscription(_entry: any): Promise<void>;
1074
+ /**
1075
+ * Fetch a fresh one-time WebSocket ticket from the server.
1076
+ * Called on reconnect when neither an access token nor a cached ticket exists.
1077
+ * Requires `config.ticketRefreshUrl` to be configured.
1078
+ */
1079
+ protected fetchFreshTicket(): Promise<string | null>;
1076
1080
  protected onConnected(): void;
1077
- protected handleIncoming(msg: any): void;
1081
+ private toUint8ArrayFromBase64Url;
1082
+ private encodePushTokenFromSubscription;
1083
+ private fetchPushSetupConfig;
1084
+ setupPushServiceWorker(): Promise<ServiceWorkerRegistration | null>;
1085
+ requestPushPermission(): Promise<NotificationPermission>;
1086
+ acquireBrowserPushToken(options?: BrowserPushTokenOptions): Promise<{
1087
+ token: string;
1088
+ subscription: PushSubscription;
1089
+ }>;
1090
+ enableBrowserPush(options?: BrowserPushRegistrationOptions): Promise<{
1091
+ registered: boolean;
1092
+ appId: string;
1093
+ uid: string;
1094
+ token: string;
1095
+ platform?: string;
1096
+ subscription: PushSubscription;
1097
+ }>;
1098
+ registerPushToken(input: RegisterPushTokenInput): Promise<{
1099
+ registered: boolean;
1100
+ appId: string;
1101
+ uid: string;
1102
+ token: string;
1103
+ platform?: string;
1104
+ }>;
1105
+ unregisterPushToken(token: string, authAppId?: string): Promise<{
1106
+ unregistered: boolean;
1107
+ appId: string;
1108
+ token: string;
1109
+ removed: boolean;
1110
+ }>;
1111
+ sendPushNotification(input: SendPushNotificationInput): Promise<PushSendResult>;
1078
1112
  auth(token: string): Promise<AuthResult>;
1113
+ private getAuthRequestContentType;
1114
+ private buildAuthRequestBody;
1115
+ protected requestEmailPasswordToken(email: string, password: string, scope?: string[]): Promise<AuthToken & {
1116
+ kind: string;
1117
+ }>;
1079
1118
  signInWithEmailAndPassword(email: string, password: string, options?: {
1080
1119
  scope?: string[];
1081
1120
  createIfMissing?: boolean;
@@ -1241,96 +1280,12 @@ declare class FlareAuth<TPresetMap extends QueryPresetMap = {}> extends FlareBas
1241
1280
  email: string;
1242
1281
  sessionsRevoked?: number;
1243
1282
  }>;
1244
- private toUint8ArrayFromBase64Url;
1245
- private encodePushTokenFromSubscription;
1246
- private fetchPushSetupConfig;
1247
- setupPushServiceWorker(): Promise<ServiceWorkerRegistration | null>;
1248
- requestPushPermission(): Promise<NotificationPermission>;
1249
- acquireBrowserPushToken(options?: BrowserPushTokenOptions): Promise<{
1250
- token: string;
1251
- subscription: PushSubscription;
1252
- }>;
1253
- enableBrowserPush(options?: BrowserPushRegistrationOptions): Promise<{
1254
- registered: boolean;
1255
- appId: string;
1256
- uid: string;
1257
- token: string;
1258
- platform?: string;
1259
- subscription: PushSubscription;
1260
- }>;
1261
- registerPushToken(input: RegisterPushTokenInput): Promise<{
1262
- registered: boolean;
1263
- appId: string;
1264
- uid: string;
1265
- token: string;
1266
- platform?: string;
1267
- }>;
1268
- unregisterPushToken(token: string, authAppId?: string): Promise<{
1269
- unregistered: boolean;
1270
- appId: string;
1271
- token: string;
1272
- removed: boolean;
1273
- }>;
1274
- sendPushNotification(input: SendPushNotificationInput): Promise<PushSendResult>;
1275
- sendEmail(input: SendEmailInput): Promise<EmailSendResult>;
1276
- verifyEmailLink(input: VerifyEmailLinkInput): Promise<EmailLinkVerifyResult>;
1277
- signIn(providerId: ProviderId, options?: {
1278
- returnTo?: string;
1279
- metaTag?: string;
1280
- }): Promise<any>;
1281
- signIn(authGuard: Pick<AuthGuard, 'signIn'>, providerId: ProviderId, options?: {
1282
- returnTo?: string;
1283
- metaTag?: string;
1284
- }): Promise<any>;
1285
- signInWithGoogle(options?: {
1286
- returnTo?: string;
1287
- metaTag?: string;
1288
- }): Promise<any>;
1289
- signInWithGitHub(options?: {
1290
- returnTo?: string;
1291
- metaTag?: string;
1292
- }): Promise<any>;
1293
- signInWithFacebook(options?: {
1294
- returnTo?: string;
1295
- metaTag?: string;
1296
- }): Promise<any>;
1297
- signInWithDropbox(options?: {
1298
- returnTo?: string;
1299
- metaTag?: string;
1300
- }): Promise<any>;
1301
- handleSignInRedirect(autoRedirect?: boolean): Promise<(AuthResult & {
1302
- authToken: AuthToken;
1303
- provider?: ProviderId;
1304
- }) | null>;
1305
- handleSignInRedirect(authGuard: Pick<AuthGuard, 'handleRedirect'>, autoRedirect?: boolean): Promise<(AuthResult & {
1306
- authToken: AuthToken;
1307
- provider?: ProviderId;
1308
- }) | null>;
1309
- private exchangeProviderToken;
1310
- protected getAuthGuard(): Promise<AuthGuard>;
1311
- refreshAuthSession(refresh_token?: string): Promise<FlareAuthSession | null>;
1312
- issueSsrToken(ttlSeconds?: number): Promise<{
1313
- token: string;
1314
- token_type: string;
1315
- expires_in: number;
1316
- uid: string;
1317
- role: string;
1318
- email?: string;
1319
- }>;
1320
1283
  signOut(): Promise<void>;
1321
1284
  protected registerWithEmail(email: string, password: string, options?: {
1322
1285
  scope?: string[];
1323
1286
  additionalParams?: Record<string, string>;
1324
1287
  signInIfAllowed?: boolean;
1325
1288
  }): Promise<Record<string, any>>;
1326
- protected requestEmailPasswordToken(email: string, password: string, scope?: string[]): Promise<AuthToken & {
1327
- kind: string;
1328
- }>;
1329
- protected fetchAuthMe(token?: string): Promise<{
1330
- id?: string;
1331
- email?: string | null;
1332
- email_verified?: boolean;
1333
- }>;
1334
1289
  }
1335
1290
 
1336
1291
  /**
@@ -1553,4 +1508,4 @@ declare const getFlare: () => FlareClient | null;
1553
1508
  */
1554
1509
  declare const disconnectFlare: () => void;
1555
1510
 
1556
- export { type AggregateFunction, type AggregateSpec, type AndFilter, type AnyFilter, type AuthConfigListener, type AuthConfigResponse, type AuthResult, type AuthStateListener, type AuthWithPendingVerificationResult, type AuthWithTokenResult, type BaseMessage, type BrowserPushRegistrationOptions, type BrowserPushTokenOptions, type ChangeEvent, type ChangeOperation, type CollectionExternalStore, type CollectionPresetMethods, type CollectionQuery, CollectionReference, type CollectionStream, type CollectionStreamListener, type CollectionStreamMeta, type CollectionStreamOptions, type ConnectionState, type CsrfProxyConfig, type CursorValue, type DataMapperFn, type DataMapperRegistry, type DocAddedCallback, type DocChangedCallback, type DocDeletedCallback, type DocUpdatedCallback, DocumentQueryBuilder, DocumentReference, type DocumentSnapshot, type EmailLinkVerifyResult, type EmailSendResult, FlareAction, type FlareAuthConfig, type FlareAuthProviderId, type FlareAuthProviderPublicConfig, type FlareAuthSession, type FlareAuthUser, FlareClient, type FlareConfig, FlareError, FlareErrors, FlareEvent, FlareResponseCodes, type FlareRule, type GroupByClause, type HavingClause, type JoinClause, type JoinQueryPattern, type NestedJoinClause, type OfflineOperation, type OrFilter, type OrderByClause, type PresenceCallback, type PresenceJoinCallback, type PresenceLeaveCallback, type PresenceMember, type PushSendResult, type QueryConfig, type QueryOperator, type QueryPresetMap, type QueryPresetParams, type QueryPresetRow, type QueryPresetSpec, type QuerySnapshot, type RegisterPushTokenInput, type RulePermission, type SecurityRuleEntry, type SecurityRulesMap, type SendEmailInput, type SendPushNotificationInput, type SnapshotEvent, type StreamFlushReason, type StructuredJoinClause, type StructuredQuery, type SubscribeMessage, type SubscribeOptions, type SubscriptionCallback, type SubscriptionData, type SubscriptionError, type SubscriptionErrorCallback, type SubscriptionHandle, type VectorFieldConfig, type VectorSearchClause, type VerifyEmailLinkInput, type WhereCondition, buildFlareHeaders, connectApp, createCsrfProxy, createCsrfProxyHandler, disconnectFlare, extractCsrfFromRequest, flareRulesToSecurityMap, getFlare, parseValue, parseWhereCondition, securityMapToFlareRules };
1511
+ export { type AggregateFunction, type AggregateSpec, type AndFilter, type AnyFilter, type AuthConfigListener, type AuthConfigResponse, type AuthResult, type AuthStateListener, type AuthWithPendingVerificationResult, type AuthWithTokenResult, type BaseMessage, type BrowserPushRegistrationOptions, type BrowserPushTokenOptions, type ChangeEvent, type ChangeOperation, type CollectionExternalStore, type CollectionPresetMethods, type CollectionQuery, CollectionReference, type CollectionStream, type CollectionStreamListener, type CollectionStreamMeta, type CollectionStreamOptions, type ConnectionState, type CsrfProxyConfig, type CursorValue, type DataMapperFn, type DataMapperRegistry, type DocAddedCallback, type DocChangedCallback, type DocDeletedCallback, type DocUpdatedCallback, DocumentQueryBuilder, DocumentReference, type DocumentSnapshot, type EmailLinkVerifyResult, type EmailSendResult, FlareAction, type FlareAuthConfig, type FlareAuthHydrationInput, type FlareAuthHydrationOptions, type FlareAuthProviderId, type FlareAuthProviderPublicConfig, type FlareAuthSession, type FlareAuthUser, FlareClient, type FlareConfig, FlareError, FlareErrors, FlareEvent, FlareResponseCodes, type FlareRule, type GroupByClause, type HavingClause, type JoinClause, type JoinQueryPattern, type NestedJoinClause, type OfflineOperation, type OrFilter, type OrderByClause, type PresenceCallback, type PresenceJoinCallback, type PresenceLeaveCallback, type PresenceMember, type PushSendResult, type QueryConfig, type QueryOperator, type QueryPresetMap, type QueryPresetParams, type QueryPresetRow, type QueryPresetSpec, type QuerySnapshot, type RegisterPushTokenInput, type RulePermission, type SecurityRuleEntry, type SecurityRulesMap, type SendEmailInput, type SendPushNotificationInput, type SnapshotEvent, type StreamFlushReason, type StructuredJoinClause, type StructuredQuery, type SubscribeMessage, type SubscribeOptions, type SubscriptionCallback, type SubscriptionData, type SubscriptionError, type SubscriptionErrorCallback, type SubscriptionHandle, type VectorFieldConfig, type VectorSearchClause, type VerifyEmailLinkInput, type WhereCondition, buildFlareHeaders, connectApp, createCsrfProxy, createCsrfProxyHandler, disconnectFlare, extractCsrfFromRequest, flareRulesToSecurityMap, getFlare, parseValue, parseWhereCondition, securityMapToFlareRules };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AuthToken, AuthGuard, ProviderId } from '@zuzjs/auth';
1
+ import { AuthToken } from '@zuzjs/auth';
2
2
  export { Anonymous, Apple, AuthGuard, AuthToken, CreateUserWithEmailAndPasswordInput, Credentials, Dropbox, Facebook, GitHub, Google, NormalizedProfile, OAuthProvider, ProviderId, Providers, SignInAnonymouslyInput, SignInWithEmailAndPasswordInput, Twitter, setupProvider } from '@zuzjs/auth';
3
3
 
4
4
  /**
@@ -29,6 +29,12 @@ interface FlareConfig {
29
29
  * Defaults to OAuth-compatible form encoding.
30
30
  */
31
31
  authRequestContentType?: "application/x-www-form-urlencoded" | "application/json";
32
+ /**
33
+ * Controls how onAuthStateChanged initializes auth in browser runtime.
34
+ * - `refresh` (default): attempt /auth/refresh once in httpBase mode.
35
+ * - `none`: skip automatic refresh bootstrap; listeners receive current in-memory state only.
36
+ */
37
+ authBootstrapMode?: "refresh" | "none";
32
38
  /** Public key for the application. */
33
39
  publicKey?: string;
34
40
  /** Whether to automatically reconnect on connection loss. */
@@ -97,6 +103,23 @@ interface FlareAuthUser {
97
103
  email_verified: string;
98
104
  [x: string]: any;
99
105
  }
106
+ interface FlareAuthHydrationInput {
107
+ uid?: string | null;
108
+ id?: string | null;
109
+ accessToken?: string | null;
110
+ refreshToken?: string | null;
111
+ ticket?: string | null;
112
+ provider?: string;
113
+ email?: string | null;
114
+ emailVerified?: boolean;
115
+ email_verified?: boolean;
116
+ profile?: Partial<FlareAuthUser> | null;
117
+ }
118
+ interface FlareAuthHydrationOptions {
119
+ source?: string;
120
+ markBootstrapAttempted?: boolean;
121
+ syncSocket?: boolean;
122
+ }
100
123
  interface RegisterPushTokenInput {
101
124
  token: string;
102
125
  platform?: string;
@@ -979,62 +1002,42 @@ declare class FlareBase<TPresetMap extends QueryPresetMap = {}> {
979
1002
  protected handleIncoming(msg: any): void;
980
1003
  }
981
1004
 
982
- /**
983
- * FlareAuth extends FlareBase with all authentication and CSRF logic.
984
- *
985
- * CSRF strategy
986
- * ─────────────
987
- * The server sets an HttpOnly cookie on /auth/config responses. The raw
988
- * cookie value is NOT readable by JS (HttpOnly), but the server also echoes
989
- * the token in the `x-flare-csrf` response header so the client can send
990
- * it back as `x-flare-csrf` on every mutating request.
991
- *
992
- * Two environments are supported:
993
- * 1. Browser – header is read from the /auth/config fetch; stored in
994
- * `this.csrfToken` (in-memory only, never written to a
995
- * readable cookie by the client).
996
- * 2. Next.js SSR – use the standalone `createCsrfProxy()` handler
997
- * (see Client/proxy.ts) which captures the Set-Cookie header
998
- * from Flare server and sets it on the client domain too, so
999
- * the browser owns two HttpOnly cookies: one from the Flare
1000
- * domain and one from the Next.js domain.
1001
- */
1002
1005
  declare class FlareAuth<TPresetMap extends QueryPresetMap = {}> extends FlareBase<TPresetMap> {
1003
1006
  static AUTH_TRACE_STORAGE_KEY: string;
1004
- protected authToken?: string;
1007
+ protected pushServiceWorkerInitPromise?: Promise<ServiceWorkerRegistration | null>;
1008
+ /** Current authentication configuration */
1005
1009
  protected userId?: string;
1006
- protected authGuard?: AuthGuard;
1010
+ protected authToken?: string;
1011
+ protected authTicket?: string;
1007
1012
  protected authConfig?: FlareAuthConfig;
1008
- /** In-memory CSRF token extracted from the `x-flare-csrf` response header */
1009
- protected csrfToken?: string;
1010
- protected csrfInitPromise?: Promise<void>;
1011
- protected csrfBootstrapAttempted: boolean;
1012
- protected socketAuthSyncPromise?: Promise<void>;
1013
- protected pushServiceWorkerInitPromise?: Promise<ServiceWorkerRegistration | null>;
1014
- protected authSession: FlareAuthSession | null;
1015
- protected authBootstrapPromise?: Promise<void>;
1016
- protected authBootstrapAttempted: boolean;
1017
1013
  protected authStateListeners: AuthStateListener[];
1018
1014
  protected authConfigListeners: AuthConfigListener[];
1015
+ protected authSession: FlareAuthSession | null;
1019
1016
  protected currentProfile: FlareAuthUser | undefined;
1017
+ protected authBootstrapAttempted: boolean;
1018
+ protected authBootstrapPromise?: Promise<void>;
1019
+ protected socketAuthSyncPromise?: Promise<void>;
1020
+ /** In-memory CSRF token extracted from the `x-flare-csrf` response header */
1021
+ protected csrfToken?: string;
1022
+ protected csrfBootstrapAttempted: boolean;
1023
+ protected csrfInitPromise?: Promise<void>;
1020
1024
  protected isAuthTraceEnabled(): boolean;
1021
- setAuthTrace(enabled: boolean, persist?: boolean): void;
1022
1025
  protected traceAuth(event: string, details?: Record<string, unknown>): void;
1023
- private getAuthRequestContentType;
1024
- private buildAuthRequestBody;
1026
+ setAuthTrace(enabled: boolean, persist?: boolean): void;
1027
+ protected fetchAuthMe(token?: string): Promise<{
1028
+ id?: string;
1029
+ email?: string | null;
1030
+ email_verified?: boolean;
1031
+ }>;
1032
+ isBootstrapAttempted(): boolean;
1033
+ hydrateAuthState(input: FlareAuthHydrationInput | null, options?: FlareAuthHydrationOptions): Promise<void>;
1034
+ loadAuthConfig(): Promise<FlareAuthConfig>;
1035
+ onAuthConfigLoaded(listener: AuthConfigListener): () => void;
1036
+ onAuthStateChanged(listener: AuthStateListener): () => void;
1037
+ getCurrentUser(): FlareAuthUser | undefined;
1038
+ getAuthTicket(): string | undefined;
1039
+ consumeAuthTicket(): string | undefined;
1025
1040
  private getDefaultCsrfCookieName;
1026
- getCsrfCookieName(): string;
1027
- /**
1028
- * Read the CSRF token from a browser-readable cookie (set by the server as
1029
- * a non-HttpOnly fallback) or fall back to the in-memory value captured
1030
- * from the response header.
1031
- *
1032
- * Priority:
1033
- * 1. Non-HttpOnly cookie on the current domain (browser only)
1034
- * 2. In-memory value from `x-flare-csrf` response header
1035
- */
1036
- getCsrfToken(): string | null;
1037
- private getCookieValue;
1038
1041
  /**
1039
1042
  * Extract CSRF token from a server response.
1040
1043
  * The server now sends it ONLY as the `x-flare-csrf` response header
@@ -1047,35 +1050,71 @@ declare class FlareAuth<TPresetMap extends QueryPresetMap = {}> extends FlareBas
1047
1050
  };
1048
1051
  }): string | undefined;
1049
1052
  getCsrfHeaders(): Record<string, string>;
1053
+ getCsrfCookieName(): string;
1050
1054
  /**
1051
- * Inject CSRF token directly (used by SSR middleware).
1052
- * This allows the server to bootstrap CSRF once and inject it into the client,
1053
- * preventing redundant /auth/config calls.
1055
+ * Read the CSRF token from a browser-readable cookie (set by the server as
1056
+ * a non-HttpOnly fallback) or fall back to the in-memory value captured
1057
+ * from the response header.
1054
1058
  *
1055
- * @example
1056
- * // In Next.js middleware
1057
- * const csrf = extractCsrfFromRequest(request, appId);
1058
- * if (csrf) {
1059
- * flareClient.setCsrfToken(csrf);
1060
- * }
1059
+ * Priority:
1060
+ * 1. Non-HttpOnly cookie on the current domain (browser only)
1061
+ * 2. In-memory value from `x-flare-csrf` response header
1061
1062
  */
1062
- setCsrfToken(token: string): void;
1063
+ getCsrfToken(): string | null;
1063
1064
  ensureCsrfProtection(): Promise<void>;
1064
- loadAuthConfig(): Promise<FlareAuthConfig>;
1065
- protected fetchAuthConfig(): Promise<FlareAuthConfig>;
1066
- onAuthConfigLoaded(listener: AuthConfigListener): () => void;
1067
- protected setProfile(profile: FlareAuthUser): void;
1068
1065
  protected setAuthSession(session: FlareAuthSession | null, source?: string): void;
1069
- onAuthStateChanged(listener: AuthStateListener): () => void;
1070
- onAuthStateChange(listener: AuthStateListener): () => void;
1071
- get currentUser(): FlareAuthUser | undefined;
1072
- getCurrentUser(): FlareAuthUser | undefined;
1073
- protected syncSocketAuth(accessToken?: string | null): Promise<void>;
1066
+ protected emitAuthState(): void;
1067
+ protected setProfile(profile: FlareAuthUser): void;
1068
+ protected ensureSessionForSocketAuth(reason: string): Promise<boolean>;
1069
+ refreshAuthSession(refresh_token?: string): Promise<FlareAuthSession | null>;
1074
1070
  protected updateSocketIdentity(uid?: string, forceReplay?: boolean): Promise<void>;
1071
+ protected waitUntilConnected(): Promise<void>;
1072
+ protected syncSocketAuth(accessToken?: string | null): Promise<void>;
1075
1073
  protected beforeActivateSubscription(_entry: any): Promise<void>;
1074
+ /**
1075
+ * Fetch a fresh one-time WebSocket ticket from the server.
1076
+ * Called on reconnect when neither an access token nor a cached ticket exists.
1077
+ * Requires `config.ticketRefreshUrl` to be configured.
1078
+ */
1079
+ protected fetchFreshTicket(): Promise<string | null>;
1076
1080
  protected onConnected(): void;
1077
- protected handleIncoming(msg: any): void;
1081
+ private toUint8ArrayFromBase64Url;
1082
+ private encodePushTokenFromSubscription;
1083
+ private fetchPushSetupConfig;
1084
+ setupPushServiceWorker(): Promise<ServiceWorkerRegistration | null>;
1085
+ requestPushPermission(): Promise<NotificationPermission>;
1086
+ acquireBrowserPushToken(options?: BrowserPushTokenOptions): Promise<{
1087
+ token: string;
1088
+ subscription: PushSubscription;
1089
+ }>;
1090
+ enableBrowserPush(options?: BrowserPushRegistrationOptions): Promise<{
1091
+ registered: boolean;
1092
+ appId: string;
1093
+ uid: string;
1094
+ token: string;
1095
+ platform?: string;
1096
+ subscription: PushSubscription;
1097
+ }>;
1098
+ registerPushToken(input: RegisterPushTokenInput): Promise<{
1099
+ registered: boolean;
1100
+ appId: string;
1101
+ uid: string;
1102
+ token: string;
1103
+ platform?: string;
1104
+ }>;
1105
+ unregisterPushToken(token: string, authAppId?: string): Promise<{
1106
+ unregistered: boolean;
1107
+ appId: string;
1108
+ token: string;
1109
+ removed: boolean;
1110
+ }>;
1111
+ sendPushNotification(input: SendPushNotificationInput): Promise<PushSendResult>;
1078
1112
  auth(token: string): Promise<AuthResult>;
1113
+ private getAuthRequestContentType;
1114
+ private buildAuthRequestBody;
1115
+ protected requestEmailPasswordToken(email: string, password: string, scope?: string[]): Promise<AuthToken & {
1116
+ kind: string;
1117
+ }>;
1079
1118
  signInWithEmailAndPassword(email: string, password: string, options?: {
1080
1119
  scope?: string[];
1081
1120
  createIfMissing?: boolean;
@@ -1241,96 +1280,12 @@ declare class FlareAuth<TPresetMap extends QueryPresetMap = {}> extends FlareBas
1241
1280
  email: string;
1242
1281
  sessionsRevoked?: number;
1243
1282
  }>;
1244
- private toUint8ArrayFromBase64Url;
1245
- private encodePushTokenFromSubscription;
1246
- private fetchPushSetupConfig;
1247
- setupPushServiceWorker(): Promise<ServiceWorkerRegistration | null>;
1248
- requestPushPermission(): Promise<NotificationPermission>;
1249
- acquireBrowserPushToken(options?: BrowserPushTokenOptions): Promise<{
1250
- token: string;
1251
- subscription: PushSubscription;
1252
- }>;
1253
- enableBrowserPush(options?: BrowserPushRegistrationOptions): Promise<{
1254
- registered: boolean;
1255
- appId: string;
1256
- uid: string;
1257
- token: string;
1258
- platform?: string;
1259
- subscription: PushSubscription;
1260
- }>;
1261
- registerPushToken(input: RegisterPushTokenInput): Promise<{
1262
- registered: boolean;
1263
- appId: string;
1264
- uid: string;
1265
- token: string;
1266
- platform?: string;
1267
- }>;
1268
- unregisterPushToken(token: string, authAppId?: string): Promise<{
1269
- unregistered: boolean;
1270
- appId: string;
1271
- token: string;
1272
- removed: boolean;
1273
- }>;
1274
- sendPushNotification(input: SendPushNotificationInput): Promise<PushSendResult>;
1275
- sendEmail(input: SendEmailInput): Promise<EmailSendResult>;
1276
- verifyEmailLink(input: VerifyEmailLinkInput): Promise<EmailLinkVerifyResult>;
1277
- signIn(providerId: ProviderId, options?: {
1278
- returnTo?: string;
1279
- metaTag?: string;
1280
- }): Promise<any>;
1281
- signIn(authGuard: Pick<AuthGuard, 'signIn'>, providerId: ProviderId, options?: {
1282
- returnTo?: string;
1283
- metaTag?: string;
1284
- }): Promise<any>;
1285
- signInWithGoogle(options?: {
1286
- returnTo?: string;
1287
- metaTag?: string;
1288
- }): Promise<any>;
1289
- signInWithGitHub(options?: {
1290
- returnTo?: string;
1291
- metaTag?: string;
1292
- }): Promise<any>;
1293
- signInWithFacebook(options?: {
1294
- returnTo?: string;
1295
- metaTag?: string;
1296
- }): Promise<any>;
1297
- signInWithDropbox(options?: {
1298
- returnTo?: string;
1299
- metaTag?: string;
1300
- }): Promise<any>;
1301
- handleSignInRedirect(autoRedirect?: boolean): Promise<(AuthResult & {
1302
- authToken: AuthToken;
1303
- provider?: ProviderId;
1304
- }) | null>;
1305
- handleSignInRedirect(authGuard: Pick<AuthGuard, 'handleRedirect'>, autoRedirect?: boolean): Promise<(AuthResult & {
1306
- authToken: AuthToken;
1307
- provider?: ProviderId;
1308
- }) | null>;
1309
- private exchangeProviderToken;
1310
- protected getAuthGuard(): Promise<AuthGuard>;
1311
- refreshAuthSession(refresh_token?: string): Promise<FlareAuthSession | null>;
1312
- issueSsrToken(ttlSeconds?: number): Promise<{
1313
- token: string;
1314
- token_type: string;
1315
- expires_in: number;
1316
- uid: string;
1317
- role: string;
1318
- email?: string;
1319
- }>;
1320
1283
  signOut(): Promise<void>;
1321
1284
  protected registerWithEmail(email: string, password: string, options?: {
1322
1285
  scope?: string[];
1323
1286
  additionalParams?: Record<string, string>;
1324
1287
  signInIfAllowed?: boolean;
1325
1288
  }): Promise<Record<string, any>>;
1326
- protected requestEmailPasswordToken(email: string, password: string, scope?: string[]): Promise<AuthToken & {
1327
- kind: string;
1328
- }>;
1329
- protected fetchAuthMe(token?: string): Promise<{
1330
- id?: string;
1331
- email?: string | null;
1332
- email_verified?: boolean;
1333
- }>;
1334
1289
  }
1335
1290
 
1336
1291
  /**
@@ -1553,4 +1508,4 @@ declare const getFlare: () => FlareClient | null;
1553
1508
  */
1554
1509
  declare const disconnectFlare: () => void;
1555
1510
 
1556
- export { type AggregateFunction, type AggregateSpec, type AndFilter, type AnyFilter, type AuthConfigListener, type AuthConfigResponse, type AuthResult, type AuthStateListener, type AuthWithPendingVerificationResult, type AuthWithTokenResult, type BaseMessage, type BrowserPushRegistrationOptions, type BrowserPushTokenOptions, type ChangeEvent, type ChangeOperation, type CollectionExternalStore, type CollectionPresetMethods, type CollectionQuery, CollectionReference, type CollectionStream, type CollectionStreamListener, type CollectionStreamMeta, type CollectionStreamOptions, type ConnectionState, type CsrfProxyConfig, type CursorValue, type DataMapperFn, type DataMapperRegistry, type DocAddedCallback, type DocChangedCallback, type DocDeletedCallback, type DocUpdatedCallback, DocumentQueryBuilder, DocumentReference, type DocumentSnapshot, type EmailLinkVerifyResult, type EmailSendResult, FlareAction, type FlareAuthConfig, type FlareAuthProviderId, type FlareAuthProviderPublicConfig, type FlareAuthSession, type FlareAuthUser, FlareClient, type FlareConfig, FlareError, FlareErrors, FlareEvent, FlareResponseCodes, type FlareRule, type GroupByClause, type HavingClause, type JoinClause, type JoinQueryPattern, type NestedJoinClause, type OfflineOperation, type OrFilter, type OrderByClause, type PresenceCallback, type PresenceJoinCallback, type PresenceLeaveCallback, type PresenceMember, type PushSendResult, type QueryConfig, type QueryOperator, type QueryPresetMap, type QueryPresetParams, type QueryPresetRow, type QueryPresetSpec, type QuerySnapshot, type RegisterPushTokenInput, type RulePermission, type SecurityRuleEntry, type SecurityRulesMap, type SendEmailInput, type SendPushNotificationInput, type SnapshotEvent, type StreamFlushReason, type StructuredJoinClause, type StructuredQuery, type SubscribeMessage, type SubscribeOptions, type SubscriptionCallback, type SubscriptionData, type SubscriptionError, type SubscriptionErrorCallback, type SubscriptionHandle, type VectorFieldConfig, type VectorSearchClause, type VerifyEmailLinkInput, type WhereCondition, buildFlareHeaders, connectApp, createCsrfProxy, createCsrfProxyHandler, disconnectFlare, extractCsrfFromRequest, flareRulesToSecurityMap, getFlare, parseValue, parseWhereCondition, securityMapToFlareRules };
1511
+ export { type AggregateFunction, type AggregateSpec, type AndFilter, type AnyFilter, type AuthConfigListener, type AuthConfigResponse, type AuthResult, type AuthStateListener, type AuthWithPendingVerificationResult, type AuthWithTokenResult, type BaseMessage, type BrowserPushRegistrationOptions, type BrowserPushTokenOptions, type ChangeEvent, type ChangeOperation, type CollectionExternalStore, type CollectionPresetMethods, type CollectionQuery, CollectionReference, type CollectionStream, type CollectionStreamListener, type CollectionStreamMeta, type CollectionStreamOptions, type ConnectionState, type CsrfProxyConfig, type CursorValue, type DataMapperFn, type DataMapperRegistry, type DocAddedCallback, type DocChangedCallback, type DocDeletedCallback, type DocUpdatedCallback, DocumentQueryBuilder, DocumentReference, type DocumentSnapshot, type EmailLinkVerifyResult, type EmailSendResult, FlareAction, type FlareAuthConfig, type FlareAuthHydrationInput, type FlareAuthHydrationOptions, type FlareAuthProviderId, type FlareAuthProviderPublicConfig, type FlareAuthSession, type FlareAuthUser, FlareClient, type FlareConfig, FlareError, FlareErrors, FlareEvent, FlareResponseCodes, type FlareRule, type GroupByClause, type HavingClause, type JoinClause, type JoinQueryPattern, type NestedJoinClause, type OfflineOperation, type OrFilter, type OrderByClause, type PresenceCallback, type PresenceJoinCallback, type PresenceLeaveCallback, type PresenceMember, type PushSendResult, type QueryConfig, type QueryOperator, type QueryPresetMap, type QueryPresetParams, type QueryPresetRow, type QueryPresetSpec, type QuerySnapshot, type RegisterPushTokenInput, type RulePermission, type SecurityRuleEntry, type SecurityRulesMap, type SendEmailInput, type SendPushNotificationInput, type SnapshotEvent, type StreamFlushReason, type StructuredJoinClause, type StructuredQuery, type SubscribeMessage, type SubscribeOptions, type SubscriptionCallback, type SubscriptionData, type SubscriptionError, type SubscriptionErrorCallback, type SubscriptionHandle, type VectorFieldConfig, type VectorSearchClause, type VerifyEmailLinkInput, type WhereCondition, buildFlareHeaders, connectApp, createCsrfProxy, createCsrfProxyHandler, disconnectFlare, extractCsrfFromRequest, flareRulesToSecurityMap, getFlare, parseValue, parseWhereCondition, securityMapToFlareRules };