@foir/sdk 0.30.0 → 0.31.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.
@@ -3,8 +3,8 @@
3
3
  * lifecycle, and guards.
4
4
  *
5
5
  * Session I/O is injected via {@link SessionAdapter} (no Hydrogen/React-Router
6
- * coupling). Pre-login flows authenticate with the project `x-api-key`;
7
- * post-login reads add the user's bearer. Anything project-specific about the
6
+ * coupling). Flows before sign-in authenticate with the project `x-api-key`;
7
+ * signed-in reads add the user's bearer. Anything project-specific about the
8
8
  * user (a profile record, say) is resolved by a consumer-supplied
9
9
  * `resolveUser`: the SDK never hardcodes a per-project profile shape.
10
10
  *
@@ -17,7 +17,8 @@
17
17
  */
18
18
  import { type FoirEnv } from '../graphql/foir-request';
19
19
  import { type AuthOpName, type AuthOpOptions } from './ops';
20
- import { type AuthConfig, type AuthProviderPublic, type CurrentUser, type AuthResult, type DefaultAuthProvider, type AuthorizedApp, type DeleteAccountResult, type MyOrganization, type MyOrganizationChoices, type MyProfile, type MyProfileChange, type MySession, type MyAddress, type MyDataExport, type MyFactor, type StepUp, type FactorEnrollment, type MySignInMethod, type NewPersonalAccessToken, type ProviderCallbackInput, type ProviderLoginInput, type ProviderLoginResult, type ProviderOTPVerifyInput, type ProviderToken, type SignupContext } from './operations';
20
+ import { type FoirAccountStep, type FoirSignInStep } from './steps';
21
+ import { type AuthConfig, type AuthProviderPublic, type CurrentUser, type AuthResult, type DefaultAuthProvider, type AuthorizedApp, type DeleteAccountResult, type MyOrganization, type MyOrganizationChoices, type MyProfile, type MyProfileChange, type MySession, type MyAddress, type MyDataExport, type MyFactor, type StepUp, type FactorEnrollment, type MySignInMethod, type NewPersonalAccessToken, type ProviderCallbackInput, type ProviderSignInInput, type ProviderSignInResult, type ProviderToken, type SignupContext } from './operations';
21
22
  import type { TypedDocumentNode } from '@graphql-typed-document-node/core';
22
23
  /** An access token + its rotating refresh token. */
23
24
  export interface FoirAuthTokens {
@@ -38,39 +39,27 @@ export interface SessionAdapter {
38
39
  set(key: string, value: string): void | Promise<void>;
39
40
  unset(key: string): void | Promise<void>;
40
41
  }
41
- /** Login with email + password. Requires the project to have passwords enabled. */
42
- export declare function login(env: FoirEnv, vars: {
43
- email: string;
44
- password: string;
45
- }): Promise<AuthResult>;
46
42
  /**
47
- * Start an account with email + password. The address is mailed a code, and
48
- * signing in with it ({@link loginWithOTP}) proves the address and finishes
49
- * the account. Answered the same whether or not the address has an account
50
- * already, or the project takes nobody new: its holder is told by email.
43
+ * Email the user a one-time code to sign in with. Answers the step the code
44
+ * is brought back to with {@link signInWithOTP}, for every address alike.
51
45
  */
52
- export declare function register(env: FoirEnv, vars: {
53
- email: string;
54
- password: string;
55
- }): Promise<boolean>;
56
- /** Request a one-time password be emailed to the user. */
57
- export declare function requestOTP(env: FoirEnv, email: string): Promise<boolean>;
58
- /** Complete an OTP login. */
59
- export declare function loginWithOTP(env: FoirEnv, vars: {
60
- email: string;
61
- otp: string;
62
- }): Promise<AuthResult>;
63
- /** Rotate an access token using a refresh token. */
64
- export declare function refreshTokens(env: FoirEnv, refreshToken: string): Promise<AuthResult>;
46
+ export declare function requestOTP(env: FoirEnv, email: string): Promise<FoirSignInStep>;
47
+ /**
48
+ * Start a provider (OAuth/OIDC) sign-in. Answers the provider's address to send
49
+ * the user to, and keeps the step its finish is brought back to in the session
50
+ * store, across the redirect, for {@link finishProviderSignIn}.
51
+ */
52
+ export declare function signInWithProvider(adapter: SessionAdapter, env: FoirEnv, input: ProviderSignInInput): Promise<ProviderSignInResult>;
65
53
  /**
66
- * Initiate provider (OAuth/OIDC) login — returns a `redirectUrl` to send the
67
- * user to, or an inline `token` for non-redirect providers.
54
+ * Finish a provider sign-in on your callback: bring the provider's `code` and
55
+ * `state` back to the step {@link signInWithProvider} kept, and persist the
56
+ * session. The route is built from your configured API address.
57
+ *
58
+ * When the sign-in named an address somebody already holds and a code was sent
59
+ * to it ({@link providerSignInRefusalOf} says `link_code_sent`),
60
+ * {@link confirmProviderLink} brings the code back to the same step.
68
61
  */
69
- export declare function loginWithProvider(env: FoirEnv, input: ProviderLoginInput): Promise<ProviderLoginResult>;
70
- /** Complete a provider login from the OAuth callback (`code`/`state`). */
71
- export declare function providerCallback(env: FoirEnv, input: ProviderCallbackInput): Promise<AuthResult>;
72
- /** Verify an OTP issued by an external provider. */
73
- export declare function providerVerifyOTP(env: FoirEnv, input: ProviderOTPVerifyInput): Promise<AuthResult>;
62
+ export declare function finishProviderSignIn(adapter: SessionAdapter, env: FoirEnv, input: ProviderCallbackInput): Promise<FoirUser>;
74
63
  /**
75
64
  * Why a provider sign-in did not finish, as the platform said it: a stable code
76
65
  * your app shows its own words for (`signup_closed`, `provider_named_no_address`,
@@ -87,41 +76,42 @@ export declare function providerSignInRefusalOf(error: unknown): {
87
76
  /**
88
77
  * Why a sign-in your app's own form sent was refused, as the platform said it:
89
78
  * a stable code your app shows its own words for. `password_sign_in_off` from
90
- * {@link login} or {@link register} where the project, or the app the sign-in
91
- * came through, takes no password; `code_sign_in_off` from {@link requestOTP}
92
- * or {@link loginWithOTP} where it takes no code. Null for any other failure.
79
+ * {@link signInWithPassword} or {@link signUpWithPassword} where the project,
80
+ * or the app the sign-in came through, takes no password; `code_sign_in_off`
81
+ * from {@link requestOTP} or {@link signInWithOTP} where it takes no code.
82
+ * Null for any other failure.
93
83
  */
94
84
  export declare function signInRefusalOf(error: unknown): {
95
85
  code: string;
96
86
  } | null;
97
87
  /**
98
88
  * Finish a provider sign-in that is waiting for the code sent to its address,
99
- * connecting the provider to the account that holds the address. See
100
- * {@link providerSignInRefusalOf}.
89
+ * connecting the provider to the account that holds the address, and persist
90
+ * the session. See {@link providerSignInRefusalOf}.
101
91
  */
102
- export declare function confirmProviderLink(env: FoirEnv, input: {
92
+ export declare function confirmProviderLink(adapter: SessionAdapter, env: FoirEnv, input: {
103
93
  pending: string;
104
94
  code: string;
105
- }): Promise<AuthResult>;
95
+ }): Promise<FoirUser>;
106
96
  /**
107
97
  * Send a new code for a provider sign-in that is waiting for one. The new code
108
98
  * replaces the one before, and the answer names the new wait.
109
99
  */
110
- export declare function resendProviderLinkCode(env: FoirEnv, input: {
100
+ export declare function resendProviderLinkCode(adapter: SessionAdapter, env: FoirEnv, input: {
111
101
  pending: string;
112
102
  }): Promise<{
113
103
  pending: string;
114
104
  }>;
115
- /** List the project's configured auth providers (for a login UI). */
105
+ /** List the project's configured auth providers (for a sign-in UI). */
116
106
  export declare function getAuthProviders(env: FoirEnv): Promise<AuthProviderPublic[]>;
117
107
  /**
118
108
  * Read the project's public auth configuration — which built-in methods are
119
- * enabled and which external providers to offer. This is what a login screen
109
+ * enabled and which external providers to offer. This is what a sign-in screen
120
110
  * renders itself from, before any user token exists.
121
111
  */
122
112
  export declare function getAuthConfig(env: FoirEnv): Promise<AuthConfig>;
123
113
  /**
124
- * The provider a login screen should default to, or `null` when the project has
114
+ * The provider a sign-in screen should default to, or `null` when the project has
125
115
  * configured none.
126
116
  */
127
117
  export declare function getDefaultAuthProvider(env: FoirEnv): Promise<DefaultAuthProvider | null>;
@@ -150,15 +140,6 @@ export declare function joinWaitlist(env: FoirEnv, email: string): Promise<boole
150
140
  export declare function requestPasswordReset(env: FoirEnv, email: string, options?: {
151
141
  clientId?: string;
152
142
  }): Promise<boolean>;
153
- /**
154
- * Redeem an emailed reset token and set a new password. Returns a fresh session
155
- * (resetting a password signs the user in), so pair it with
156
- * {@link saveSession}, or use {@link resetPasswordAndSignIn} which does both.
157
- */
158
- export declare function resetPassword(env: FoirEnv, vars: {
159
- token: string;
160
- newPassword: string;
161
- }): Promise<AuthResult>;
162
143
  /**
163
144
  * Change the calling user's password. Requires the current password as well
164
145
  * as the bearer, so a stolen token alone cannot take the account over.
@@ -188,12 +169,6 @@ export declare function currentUser(env: FoirEnv, options?: AuthOpOptions): Prom
188
169
  export declare function myProviderToken(env: FoirEnv, providerKey: string, options?: AuthOpOptions & {
189
170
  forceRefresh?: boolean;
190
171
  }): Promise<ProviderToken | null>;
191
- /**
192
- * End the sign-in's provider tokens server-side: this device's, and no other
193
- * device's. This does NOT clear local session state — {@link signOut} is the
194
- * pairing that does both.
195
- */
196
- export declare function logout(env: FoirEnv, options?: AuthOpOptions): Promise<boolean>;
197
172
  /**
198
173
  * Delete the calling user's account and their owned records and files.
199
174
  * Irreversible. `password` is required for an account that holds one. An
@@ -260,23 +235,27 @@ export declare function createPersonalAccessToken(env: FoirEnv, vars: {
260
235
  export declare function myAddresses(env: FoirEnv, options?: AuthOpOptions): Promise<MyAddress[]>;
261
236
  /**
262
237
  * Send a code to an address the calling user is adding to their account, and
263
- * answer when it stops working (ISO-8601, ten minutes on). The address is kept
264
- * by {@link proveMyAddress}. `password` is their current one; an account with
265
- * none needs a sign-in in the last ten minutes instead. At most five codes an
238
+ * answer the step the code is brought back to with {@link proveMyAddress},
239
+ * within ten minutes. `password` is their current one; an account with none
240
+ * needs a sign-in in the last ten minutes instead. At most five codes an
266
241
  * hour.
267
242
  */
268
243
  export declare function addMyAddress(env: FoirEnv, vars: {
269
244
  email: string;
270
245
  password?: string;
271
- }, options?: AuthOpOptions): Promise<string>;
246
+ }, options?: AuthOpOptions): Promise<FoirAccountStep>;
272
247
  /**
273
- * Keep the address a code was sent to, as proven. Refused where another
274
- * account in the project holds the address: nobody's address is taken.
248
+ * Keep the address a step's code was sent to, as proven: bring the code back
249
+ * to the step {@link addMyAddress} answered, with that step's token. The route
250
+ * is built from your configured API address, and the post carries no key and
251
+ * no session: the step's token says whose account it is. Refused once the
252
+ * session that began the step has ended, and where another account in the
253
+ * project holds the address: nobody's address is taken.
275
254
  */
276
255
  export declare function proveMyAddress(env: FoirEnv, vars: {
277
- email: string;
256
+ step: FoirAccountStep;
278
257
  code: string;
279
- }, options?: AuthOpOptions): Promise<MyAddress>;
258
+ }): Promise<MyAddress>;
280
259
  /** Make one of the calling user's proven addresses the one their account uses. */
281
260
  export declare function makeMyAddressPrimary(env: FoirEnv, email: string, options?: AuthOpOptions): Promise<MyAddress>;
282
261
  /**
@@ -307,47 +286,39 @@ export declare function disconnectSignInMethod(env: FoirEnv, provider: string, o
307
286
  /** The second factors, passkeys and recovery codes the calling user holds. */
308
287
  export declare function myFactors(env: FoirEnv, options?: AuthOpOptions): Promise<MyFactor[]>;
309
288
  /**
310
- * Begin proving a second factor with the calling user's password.
311
- * {@link completeStepUp} finishes it; for a user who holds none, the answer's
312
- * `elevatedHandle` is already the proof.
289
+ * Begin proving the calling user's session again, on Fóir's hosted step-up
290
+ * page: their password, and their second factor where they hold one. Send the
291
+ * user to the answer's `url`, with `return_to` added to its query to have them
292
+ * sent back (it is admitted only under your app's own origins). The proof pays
293
+ * for one change to their factors in the next ten minutes, and a second factor
294
+ * also lifts the session to two factors. A factor change refused for want of a
295
+ * proof names the same page: see `stepUpRequired`.
313
296
  */
314
- export declare function beginStepUp(env: FoirEnv, password: string, options?: AuthOpOptions): Promise<StepUp>;
315
- /**
316
- * Prove a second factor with exactly one of a passkey's or security key's
317
- * assertion, an authenticator app's code or a recovery code, which is then
318
- * spent. The session making the request counts as two factors from here, and
319
- * the answer is an elevated handle for one change to the user's factors in
320
- * the next ten minutes.
321
- */
322
- export declare function completeStepUp(env: FoirEnv, vars: {
323
- handle: string;
324
- webauthnAssertionJson?: string;
325
- totpCode?: string;
326
- recoveryCode?: string;
327
- }, options?: AuthOpOptions): Promise<string>;
297
+ export declare function stepUp(env: FoirEnv, options?: AuthOpOptions): Promise<StepUp>;
328
298
  /**
329
299
  * Begin adding `totp` (an authenticator app), `webauthn` (a security key held
330
300
  * as a second factor) or `passkey` (a passkey that signs the user in on its
331
- * own), with the `elevatedHandle` {@link beginStepUp} or
332
- * {@link completeStepUp} answered.
301
+ * own), spending the session's {@link stepUp} proof.
333
302
  */
334
303
  export declare function beginFactorEnrollment(env: FoirEnv, vars: {
335
304
  method: 'webauthn' | 'totp' | 'passkey';
336
- elevatedHandle: string;
337
305
  }, options?: AuthOpOptions): Promise<FactorEnrollment>;
338
306
  /**
339
- * Finish adding a second factor, with the `navigator.credentials.create`
340
- * result or the authenticator app's code.
307
+ * Finish adding a second factor: bring the `navigator.credentials.create`
308
+ * result or the authenticator app's code back to the step
309
+ * {@link beginFactorEnrollment} answered, with that step's token. The route is
310
+ * built from your configured API address, and the post carries no key and no
311
+ * session: the step's token says whose account it is. Refused once the session
312
+ * that began the step has ended.
341
313
  */
342
314
  export declare function completeFactorEnrollment(env: FoirEnv, vars: {
343
- handle: string;
315
+ step: FoirAccountStep;
344
316
  webauthnAttestationJson?: string;
345
317
  totpCode?: string;
346
318
  name?: string;
347
- }, options?: AuthOpOptions): Promise<boolean>;
348
- /** Remove one of the calling user's factors, with an elevated handle from {@link completeStepUp}. */
319
+ }): Promise<boolean>;
320
+ /** Remove one of the calling user's factors, spending the session's {@link stepUp} proof. */
349
321
  export declare function removeFactor(env: FoirEnv, vars: {
350
- elevatedHandle: string;
351
322
  kind: string;
352
323
  id: string;
353
324
  }, options?: AuthOpOptions): Promise<boolean>;
@@ -361,10 +332,10 @@ export declare function renameFactor(env: FoirEnv, vars: {
361
332
  name: string;
362
333
  }, options?: AuthOpOptions): Promise<MyFactor>;
363
334
  /**
364
- * Make the calling user new recovery codes, with an elevated handle from
365
- * {@link completeStepUp}. They replace any held and are answered here once.
335
+ * Make the calling user new recovery codes, spending the session's
336
+ * {@link stepUp} proof. They replace any held and are answered here once.
366
337
  */
367
- export declare function makeRecoveryCodes(env: FoirEnv, elevatedHandle: string, options?: AuthOpOptions): Promise<string[]>;
338
+ export declare function makeRecoveryCodes(env: FoirEnv, options?: AuthOpOptions): Promise<string[]>;
368
339
  /**
369
340
  * The organizations this user may stand in.
370
341
  *
@@ -448,23 +419,31 @@ export declare function clearSession(adapter: SessionAdapter): Promise<void>;
448
419
  export declare function getSessionToken(adapter: SessionAdapter): Promise<string | null>;
449
420
  /** Read the stored user (null when signed out). */
450
421
  export declare function getSessionUser(adapter: SessionAdapter): Promise<FoirUser | null>;
451
- /** Login with email + password and persist the session. */
422
+ /**
423
+ * Sign in with email + password and persist the session. Requires the project
424
+ * to have passwords on.
425
+ */
452
426
  export declare function signInWithPassword(adapter: SessionAdapter, env: FoirEnv, vars: {
453
427
  email: string;
454
428
  password: string;
455
429
  }): Promise<FoirUser>;
456
430
  /**
457
431
  * Start a sign-up with email + password: the address is mailed a code, and
458
- * {@link signInWithOTP} with it finishes the account and persists the
459
- * session. Nobody is signed in until then.
432
+ * {@link signInWithOTP} with it and the step this answers proves the address,
433
+ * finishes the account and persists the session. Nobody is signed in until
434
+ * then. Answered the same whether or not the address has an account already,
435
+ * or the project takes nobody new: its holder is told by email.
460
436
  */
461
437
  export declare function signUpWithPassword(env: FoirEnv, vars: {
462
438
  email: string;
463
439
  password: string;
464
- }): Promise<void>;
465
- /** Complete an OTP login and persist the session. */
440
+ }): Promise<FoirSignInStep>;
441
+ /**
442
+ * Complete a code sign-in and persist the session: bring the code back to the
443
+ * step {@link requestOTP} or {@link signUpWithPassword} answered.
444
+ */
466
445
  export declare function signInWithOTP(adapter: SessionAdapter, env: FoirEnv, vars: {
467
- email: string;
446
+ step: FoirSignInStep;
468
447
  otp: string;
469
448
  }): Promise<FoirUser>;
470
449
  /**
@@ -12,14 +12,14 @@
12
12
  * Every URL/cookie/path is CONFIG, not a constant, so a domain restructure
13
13
  * is a config change, not a code change.
14
14
  */
15
- export interface HostedLoginConfig {
15
+ export interface HostedSignInConfig {
16
16
  /** White-label front-door origin, e.g. `https://login.example.com`. */
17
17
  loginOrigin: string;
18
18
  /** Session cookie name set on the registrable domain. Default `foir_session`. */
19
19
  cookieName?: string;
20
20
  /** Session-exchange path on the front door. Default `/session/token`. */
21
21
  sessionPath?: string;
22
- /** RP-initiated logout path on the front door. Default `/session/end-session`. */
22
+ /** RP-initiated sign-out path on the front door. Default `/session/end-session`. */
23
23
  endSessionPath?: string;
24
24
  /**
25
25
  * The app the bearer is for, when it is not the app the login domain fronts.
@@ -28,7 +28,7 @@ export interface HostedLoginConfig {
28
28
  clientId?: string;
29
29
  }
30
30
  /** What a sign-in started at the hosted front door is for. */
31
- export interface HostedLoginOptions {
31
+ export interface HostedSignInOptions {
32
32
  /**
33
33
  * The organization the person signs in to, when one auth client serves an
34
34
  * address per organization. It decides the branding, the pool, and which
@@ -50,27 +50,27 @@ export interface HostedLoginOptions {
50
50
  * Build the redirect URL to the hosted front door, forwarding an absolute
51
51
  * `returnTo` and, where the app names one, the organization the sign-in is for.
52
52
  */
53
- export declare function hostedLoginUrl(config: HostedLoginConfig, returnTo?: string, options?: HostedLoginOptions): string;
53
+ export declare function hostedSignInUrl(config: HostedSignInConfig, returnTo?: string, options?: HostedSignInOptions): string;
54
54
  /**
55
55
  * Build the redirect URL that ENDS the hosted session — the mirror of
56
- * `hostedLoginUrl`, and the only thing that actually signs a user out on
56
+ * `hostedSignInUrl`, and the only thing that actually signs a user out on
57
57
  * this flow.
58
58
  *
59
59
  * The cookie is the durable credential. Disposing of a bearer, clearing a
60
- * local session, or calling the `logout` mutation (which clears
60
+ * local session, or calling the `signOut` mutation (which clears
61
61
  * upstream provider tokens and nothing else) all leave it in place, and the
62
62
  * next request re-establishes the user from it. This URL points at the
63
63
  * front door's end-session endpoint, which revokes the session row and clears
64
64
  * the cookie before returning the browser to `returnTo`.
65
65
  *
66
66
  * A URL builder, deliberately: no transport, no CORS surface, no CSRF header,
67
- * and no JavaScript required at the consumer. Server-side logout is
68
- * `return redirect(hostedLogoutUrl(config, clientId, returnTo))`.
67
+ * and no JavaScript required at the consumer. Signing out server-side is
68
+ * `return redirect(hostedSignOutUrl(config, clientId, returnTo))`.
69
69
  *
70
70
  * `returnTo` must be an absolute URL on an origin registered for `clientId`;
71
71
  * the platform refuses anything else. Omit it for a bare 204 with no redirect.
72
72
  */
73
- export declare function hostedLogoutUrl(config: HostedLoginConfig, clientId: string, returnTo?: string): string;
73
+ export declare function hostedSignOutUrl(config: HostedSignInConfig, clientId: string, returnTo?: string): string;
74
74
  /** The identity + bearer returned by a successful hosted-session exchange. */
75
75
  export interface HostedSession {
76
76
  token: string;
@@ -115,7 +115,7 @@ export type HostedSessionResult =
115
115
  }
116
116
  /**
117
117
  * The user is signed out. Act on it: clear any local session and send
118
- * them to `hostedLoginUrl`.
118
+ * them to `hostedSignInUrl`.
119
119
  *
120
120
  * `no-cookie` — nothing to exchange. `rejected` — the front door refused the
121
121
  * cookie (401) and has already cleared it itself.
@@ -143,14 +143,14 @@ export type HostedSessionResult =
143
143
  cause?: unknown;
144
144
  };
145
145
  /**
146
- * Exchange the hosted-login cookie on an incoming request for a user
146
+ * Exchange the hosted sign-in cookie on an incoming request for a user
147
147
  * bearer + identity (server-to-server: forwards the cookie to the front door's
148
148
  * session endpoint with the CSRF header).
149
149
  *
150
150
  * See `HostedSessionResult` for why this reports an outcome rather than
151
151
  * returning `null` for everything that is not a success.
152
152
  */
153
- export declare function fetchHostedSession(request: Request, config: HostedLoginConfig): Promise<HostedSessionResult>;
153
+ export declare function fetchHostedSession(request: Request, config: HostedSignInConfig): Promise<HostedSessionResult>;
154
154
  /**
155
155
  * What hosted sign-in said beside the code when it sent someone back to your
156
156
  * app. A sign-in it refused carries a stable code (`foir_error`); one that
@@ -1,26 +1,30 @@
1
1
  /**
2
2
  * `@foir/sdk/auth`: framework-agnostic sign-in for your app's users.
3
3
  *
4
- * The whole sign-in surface (login, register, OTP, external providers,
4
+ * The whole sign-in surface (password, sign-up, code, external providers,
5
5
  * refresh, password management, email verification and account deletion) over
6
- * the server's generated `auth` namespace, plus token lifecycle with an
7
- * injected `SessionAdapter`, guards, and the optional hosted-login bridge.
6
+ * the server's generated `auth` namespace. Each sign-in flow keeps its session
7
+ * in an injected `SessionAdapter`; there are guards, and the optional hosted
8
+ * sign-in bridge.
8
9
  *
9
10
  * There are no operation documents here any more. The flows address root fields
10
11
  * the caller's own manifest advertises, through the same op transport
11
12
  * `@foir/sdk/data` uses, so `graphql` is not on this module's path at all.
12
13
  */
13
- export { login, register, requestOTP, loginWithOTP, refreshTokens, loginWithProvider, providerCallback, providerVerifyOTP, providerSignInRefusalOf, signInRefusalOf, confirmProviderLink, resendProviderLinkCode, getAuthProviders, getAuthConfig, getDefaultAuthProvider, signupContext, joinWaitlist, requestPasswordReset, resetPassword, updatePassword, currentUser, myProviderToken, logout, deleteMyAccount, deleteMyAccountAndSignOut, leaveMembership, updateMyProfile, myAuthorizedApps, revokeAuthorizedApp, mySessions, endMySession, myAddresses, addMyAddress, proveMyAddress, makeMyAddressPrimary, removeMyAddress, exportMyData, signOutEverywhere, createPersonalAccessToken, mySignInMethods, connectSignInMethod, disconnectSignInMethod, myFactors, beginStepUp, completeStepUp, beginFactorEnrollment, completeFactorEnrollment, removeFactor, renameFactor, makeRecoveryCodes, myOrganizations, myOrganizationChoices, registerOrganization, saveSession, clearSession, getSessionToken, getSessionUser, signInWithPassword, signUpWithPassword, signInWithOTP, resetPasswordAndSignIn, refreshSession, refreshSessionOnce, signOut, authedRequest, authedOp, requireAuth, } from './auth';
14
+ export { requestOTP, signInWithProvider, finishProviderSignIn, providerSignInRefusalOf, signInRefusalOf, confirmProviderLink, resendProviderLinkCode, getAuthProviders, getAuthConfig, getDefaultAuthProvider, signupContext, joinWaitlist, requestPasswordReset, updatePassword, currentUser, myProviderToken, deleteMyAccount, deleteMyAccountAndSignOut, leaveMembership, updateMyProfile, myAuthorizedApps, revokeAuthorizedApp, mySessions, endMySession, myAddresses, addMyAddress, proveMyAddress, makeMyAddressPrimary, removeMyAddress, exportMyData, signOutEverywhere, createPersonalAccessToken, mySignInMethods, connectSignInMethod, disconnectSignInMethod, myFactors, stepUp, beginFactorEnrollment, completeFactorEnrollment, removeFactor, renameFactor, makeRecoveryCodes, myOrganizations, myOrganizationChoices, registerOrganization, saveSession, clearSession, getSessionToken, getSessionUser, signInWithPassword, signUpWithPassword, signInWithOTP, resetPasswordAndSignIn, refreshSession, refreshSessionOnce, signOut, authedRequest, authedOp, requireAuth, } from './auth';
14
15
  export type { FoirAuthTokens, FoirUser, SessionAdapter, RequireAuthOptions, } from './auth';
15
16
  export { userAccess, getSessionAccess, hasRole, hasScope, requireRole, requireScope, FoirAccessDeniedError, } from './access';
16
17
  export type { FoirAccess, FoirAccessDenial } from './access';
17
18
  export { FoirAuthDowngradedError, FoirSessionExpiredError } from '../graphql/foir-request';
19
+ export { stepUpRequired } from '../transport/foir-http';
20
+ export type { FoirStepUp, FoirStepUpAsk } from '../transport/foir-http';
18
21
  export { AUTH_OPS } from './ops';
19
22
  export type { AuthOpName, AuthOpOptions } from './ops';
20
- export { hostedLoginUrl, hostedLogoutUrl, fetchHostedSession, hostedSignInNoticeOf } from './hosted';
23
+ export type { FoirAccountStep, FoirSignInStep } from './steps';
24
+ export { hostedSignInUrl, hostedSignOutUrl, fetchHostedSession, hostedSignInNoticeOf } from './hosted';
21
25
  export { beginSignIn, completeSignIn, CodeFlowError } from './code-flow';
22
26
  export type { CodeFlowConfig, BeginSignInOptions, PendingSignIn, CodeFlowTokens } from './code-flow';
23
- export type { HostedLoginConfig, HostedLoginOptions, HostedSession, HostedSessionResult, HostedSignInNotice } from './hosted';
27
+ export type { HostedSignInConfig, HostedSignInOptions, HostedSession, HostedSessionResult, HostedSignInNotice } from './hosted';
24
28
  export { createFoirSessionClient } from './session-client';
25
29
  export type { FoirSessionClient, FoirSessionConfig, FoirSessionUser, } from './session-client';
26
- export type { AuthResult, ProviderLoginResult, AuthProviderPublic, ProviderLoginInput, ProviderCallbackInput, ProviderOTPVerifyInput, SignupContext, SignupMode, AuthConfig, AuthConfigProvider, DefaultAuthProvider, CurrentUser, ProviderToken, ProviderTokenRefresh, DeleteAccountResult, MyOrganization, MyOrganizationChoice, MyOrganizationChoices, MyProfile, MyProfileChange, AuthorizedApp, MySession, MyAddress, MyDataExport, NewPersonalAccessToken, MySignInMethod, MyFactor, StepUp, FactorEnrollment, } from './operations';
30
+ export type { AuthResult, ProviderSignInResult, AuthProviderPublic, ProviderSignInInput, ProviderCallbackInput, SignupContext, SignupMode, AuthConfig, AuthConfigProvider, DefaultAuthProvider, CurrentUser, ProviderToken, ProviderTokenRefresh, DeleteAccountResult, MyOrganization, MyOrganizationChoice, MyOrganizationChoices, MyProfile, MyProfileChange, AuthorizedApp, MySession, MyAddress, MyDataExport, NewPersonalAccessToken, MySignInMethod, MyFactor, StepUp, FactorEnrollment, } from './operations';
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Foir sign-in result and input types.
3
3
  *
4
- * These are PLATFORM-STABLE primitives — login / register / refresh / OTP /
5
- * provider login / password management / account lifecycle are fixed-shape
4
+ * These are PLATFORM-STABLE primitives: sign-in, register, refresh, OTP,
5
+ * provider sign-in, password management and account lifecycle are fixed-shape
6
6
  * operations served by api-public for every project (gated per-project by the
7
7
  * password / OTP / provider flags, but identical in shape when present). Unlike
8
8
  * per-project model types they do not vary by configured models, so the SDK
@@ -29,19 +29,18 @@
29
29
  * here: that shape varies per project, so it stays consumer-injected (see
30
30
  * `requireAuth`'s `resolveUser`).
31
31
  */
32
- /** The common auth result every login/register/refresh mutation returns. */
32
+ import type { FoirAccountStep } from './steps';
33
+ /** The tokens and user a sign-in or refresh answers, which `saveSession` keeps. */
33
34
  export interface AuthResult {
34
35
  token: string;
35
36
  refreshToken: string;
36
37
  userId: string;
37
38
  email: string;
38
39
  }
39
- /** Result of initiating a provider login — a redirect URL or an inline token. */
40
- export interface ProviderLoginResult {
41
- /** OAuth/OIDC authorization URL to redirect the user to (redirect flows). */
40
+ /** A provider sign-in started: where to send the user. */
41
+ export interface ProviderSignInResult {
42
+ /** The provider's authorization address to send the user to. */
42
43
  redirectUrl: string | null;
43
- /** Inline access token (non-redirect provider flows). */
44
- token: string | null;
45
44
  }
46
45
  /** A configured auth provider, as exposed to unauthenticated callers. */
47
46
  export interface AuthProviderPublic {
@@ -51,9 +50,8 @@ export interface AuthProviderPublic {
51
50
  type: string;
52
51
  isDefault: boolean | null;
53
52
  }
54
- export interface ProviderLoginInput {
53
+ export interface ProviderSignInInput {
55
54
  providerKey: string;
56
- email?: string;
57
55
  returnTo?: string;
58
56
  /** Override the provider's default redirect_uri (must be allow-listed). */
59
57
  redirectUri?: string;
@@ -62,13 +60,6 @@ export interface ProviderCallbackInput {
62
60
  providerKey: string;
63
61
  code?: string;
64
62
  state?: string;
65
- email?: string;
66
- idToken?: string;
67
- }
68
- export interface ProviderOTPVerifyInput {
69
- providerKey: string;
70
- email: string;
71
- otp: string;
72
63
  }
73
64
  /** The project's signup mode. */
74
65
  export type SignupMode = 'PUBLIC' | 'RESTRICTED' | 'WAITLIST' | 'CLOSED';
@@ -85,8 +76,8 @@ export interface AuthConfigProvider {
85
76
  }
86
77
  /**
87
78
  * The project's public auth configuration: which built-in methods are on, and
88
- * which external providers a login screen should offer. Readable before any
89
- * user token exists: it is what a login screen renders itself from.
79
+ * which external providers a sign-in screen should offer. Readable before any
80
+ * user token exists: it is what a sign-in screen renders itself from.
90
81
  */
91
82
  export interface AuthConfig {
92
83
  passwordEnabled: boolean;
@@ -94,7 +85,7 @@ export interface AuthConfig {
94
85
  providers: AuthConfigProvider[] | null;
95
86
  }
96
87
  /**
97
- * The provider a login screen should default to, or `null` when the project has
88
+ * The provider a sign-in screen should default to, or `null` when the project has
98
89
  * configured none.
99
90
  */
100
91
  export interface DefaultAuthProvider {
@@ -289,21 +280,15 @@ export interface MyFactor {
289
280
  * factor, or, for a user who holds none, already proven by the password.
290
281
  */
291
282
  export interface StepUp {
292
- /** What {@link completeStepUp} takes, for a user who holds a second factor. */
293
- handle: string | null;
294
- /** For a user who holds no second factor: the proof their password is, for one change to their factors. */
295
- elevatedHandle: string | null;
296
- /** Whether a security key or passkey can prove it. */
297
- webauthn: boolean;
298
- /** Whether an authenticator app's code can prove it. */
299
- totp: boolean;
300
- /** The publicKey options for `navigator.credentials.get`, as JSON. */
301
- webauthnOptionsJson: string | null;
283
+ /** Fóir's hosted step-up page. Its token is in the fragment; add `return_to` to its query. */
284
+ url: string;
285
+ /** When the page stops working (RFC 3339). */
286
+ expiresAt: string;
302
287
  }
303
288
  /** A second factor being added, waiting for the browser or the authenticator app. */
304
289
  export interface FactorEnrollment {
305
- /** What {@link completeFactorEnrollment} takes. */
306
- handle: string;
290
+ /** The step what the authenticator makes is brought back to, with {@link completeFactorEnrollment}. */
291
+ step: FoirAccountStep;
307
292
  /** For a security key or passkey: the publicKey options for `navigator.credentials.create`, as JSON. */
308
293
  webauthnOptionsJson: string | null;
309
294
  /** For an authenticator app: the key to enter by hand. */
@@ -45,15 +45,13 @@ export declare const AUTH_OPS: {
45
45
  readonly currentUser: "currentUser";
46
46
  readonly myProviderToken: "myProviderToken";
47
47
  readonly whoami: "whoami";
48
- readonly login: "login";
48
+ readonly signIn: "signIn";
49
49
  readonly register: "register";
50
50
  readonly requestOTP: "requestOTP";
51
- readonly loginWithOTP: "loginWithOTP";
52
51
  readonly refreshToken: "refreshToken";
53
- readonly logout: "logout";
52
+ readonly signOut: "signOut";
54
53
  readonly joinWaitlist: "joinWaitlist";
55
54
  readonly requestPasswordReset: "requestPasswordReset";
56
- readonly resetPassword: "resetPassword";
57
55
  readonly updatePassword: "updatePassword";
58
56
  readonly deleteMyAccount: "deleteMyAccount";
59
57
  readonly leaveMembership: "leaveMembership";
@@ -65,7 +63,6 @@ export declare const AUTH_OPS: {
65
63
  readonly signOutEverywhere: "signOutEverywhere";
66
64
  readonly myAddresses: "myAddresses";
67
65
  readonly addMyAddress: "addMyAddress";
68
- readonly proveMyAddress: "proveMyAddress";
69
66
  readonly makeMyAddressPrimary: "makeMyAddressPrimary";
70
67
  readonly removeMyAddress: "removeMyAddress";
71
68
  readonly exportMyData: "exportMyData";
@@ -74,21 +71,15 @@ export declare const AUTH_OPS: {
74
71
  readonly connectSignInMethod: "connectSignInMethod";
75
72
  readonly disconnectSignInMethod: "disconnectSignInMethod";
76
73
  readonly myFactors: "myFactors";
77
- readonly beginStepUp: "beginStepUp";
78
- readonly completeStepUp: "completeStepUp";
74
+ readonly stepUp: "stepUp";
79
75
  readonly beginFactorEnrollment: "beginFactorEnrollment";
80
- readonly completeFactorEnrollment: "completeFactorEnrollment";
81
76
  readonly removeFactor: "removeFactor";
82
77
  readonly renameFactor: "renameFactor";
83
78
  readonly makeRecoveryCodes: "makeRecoveryCodes";
84
79
  readonly myOrganizations: "myOrganizations";
85
80
  readonly myOrganizationChoices: "myOrganizationChoices";
86
81
  readonly registerOrganization: "registerOrganization";
87
- readonly loginWithProvider: "loginWithProvider";
88
- readonly providerCallback: "providerCallback";
89
- readonly providerVerifyOTP: "providerVerifyOTP";
90
- readonly confirmProviderLink: "confirmProviderLink";
91
- readonly resendProviderLinkCode: "resendProviderLinkCode";
82
+ readonly signInWithProvider: "signInWithProvider";
92
83
  };
93
84
  /** One of the auth namespace's root field names. */
94
85
  export type AuthOpName = (typeof AUTH_OPS)[keyof typeof AUTH_OPS];
@@ -27,7 +27,7 @@
27
27
  * api.foir.dev but a browser cannot reach them there — the cookie would be
28
28
  * cross-site, and that CORS surface deliberately refuses credentials.
29
29
  */
30
- import type { HostedLoginOptions } from './hosted';
30
+ import type { HostedSignInOptions } from './hosted';
31
31
  export interface FoirSessionConfig {
32
32
  /**
33
33
  * Your verified custom login domain, e.g. `https://login.acme.com`. Must share
@@ -36,8 +36,8 @@ export interface FoirSessionConfig {
36
36
  loginOrigin: string;
37
37
  /** Session-exchange path. Default `/session/token`. */
38
38
  sessionPath?: string;
39
- /** Logout path. Default `/session/logout`. */
40
- logoutPath?: string;
39
+ /** Sign-out path. Default `/session/logout`. */
40
+ signOutPath?: string;
41
41
  /**
42
42
  * The app the bearer is for, when it is not the app the login domain fronts.
43
43
  * Default: the domain's own app.
@@ -72,7 +72,7 @@ export interface FoirSessionClient {
72
72
  * for with `options.org` when one auth client serves an address per
73
73
  * organization.
74
74
  */
75
- signInUrl(returnTo?: string, options?: HostedLoginOptions): string;
75
+ signInUrl(returnTo?: string, options?: HostedSignInOptions): string;
76
76
  /** Observe session changes. Returns an unsubscribe function. */
77
77
  subscribe(listener: (user: FoirSessionUser | null) => void): () => void;
78
78
  /** Cancel the refresh timer. Call on unmount. */