@foir/sdk 0.20.0 → 0.22.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.
Files changed (65) hide show
  1. package/CHANGELOG.md +135 -1
  2. package/README.md +9 -9
  3. package/dist/app/client.d.ts +90 -84
  4. package/dist/app/contract/proto/apps/v1/apps_pb.d.ts +14 -13
  5. package/dist/app/dispatch.d.ts +5 -5
  6. package/dist/app/errors.d.ts +11 -11
  7. package/dist/app/index.d.ts +4 -4
  8. package/dist/app/naming.d.ts +1 -1
  9. package/dist/app/ticket.d.ts +2 -2
  10. package/dist/app/vocabulary.generated.d.ts +2 -2
  11. package/dist/app-contract.js +3 -3
  12. package/dist/app.js +92 -90
  13. package/dist/auth/access.d.ts +19 -19
  14. package/dist/auth/auth.d.ts +216 -114
  15. package/dist/auth/hosted.d.ts +14 -14
  16. package/dist/auth/index.d.ts +7 -7
  17. package/dist/auth/operations.d.ts +128 -32
  18. package/dist/auth/ops.d.ts +39 -21
  19. package/dist/auth/session-client.d.ts +3 -3
  20. package/dist/auth-session.js +3 -3
  21. package/dist/auth.js +291 -146
  22. package/dist/client/platform-client.d.ts +1 -1
  23. package/dist/client.js +32 -5
  24. package/dist/codegen/index.js +1 -1
  25. package/dist/data/builtins.d.ts +41 -82
  26. package/dist/data/client.d.ts +2 -2
  27. package/dist/data/decimal.d.ts +1 -1
  28. package/dist/data/document.d.ts +14 -0
  29. package/dist/data/index.d.ts +2 -2
  30. package/dist/data/manifest.d.ts +1 -1
  31. package/dist/data/schema.d.ts +1 -1
  32. package/dist/data/transport.d.ts +33 -26
  33. package/dist/data/ws-transport.d.ts +1 -1
  34. package/dist/data.js +97 -19
  35. package/dist/graphql/content-client.d.ts +13 -13
  36. package/dist/index.js +24 -0
  37. package/dist/live/drift.d.ts +1 -1
  38. package/dist/media/screen-capture.d.ts +1 -1
  39. package/dist/next/index.d.ts +2 -2
  40. package/dist/next/session.d.ts +10 -10
  41. package/dist/next.js +121 -61
  42. package/dist/placement/index.d.ts +15 -32
  43. package/dist/placement.js +18 -20
  44. package/dist/push.js +113 -46
  45. package/dist/react/FoirFeedback.d.ts +2 -2
  46. package/dist/react/FoirProvider.d.ts +23 -23
  47. package/dist/react/SignIn.d.ts +4 -4
  48. package/dist/react/UserButton.d.ts +1 -1
  49. package/dist/react/feedback-notes.d.ts +4 -4
  50. package/dist/react/index.d.ts +3 -3
  51. package/dist/react.js +168 -105
  52. package/dist/realtime/index.d.ts +1 -1
  53. package/dist/server/callback-client.d.ts +4 -4
  54. package/dist/server/events-client.d.ts +18 -18
  55. package/dist/server/operation-types.d.ts +8 -8
  56. package/dist/server/require-scoped-token.d.ts +3 -3
  57. package/dist/server/server-client.d.ts +1 -1
  58. package/dist/server/types.d.ts +1 -1
  59. package/dist/server/verify-scoped-token.d.ts +4 -28
  60. package/dist/server.js +67 -112
  61. package/dist/transport/foir-http.d.ts +57 -18
  62. package/dist/transport/key-kind.d.ts +40 -0
  63. package/dist/types/index.d.ts +2 -2
  64. package/package.json +3 -3
  65. package/dist/server/older-claims.generated.d.ts +0 -8
@@ -1,11 +1,12 @@
1
1
  /**
2
- * Foir customer auth — framework-agnostic flows, token lifecycle, and guards.
2
+ * Foir sign-in for your app's users: framework-agnostic flows, token
3
+ * lifecycle, and guards.
3
4
  *
4
5
  * Session I/O is injected via {@link SessionAdapter} (no Hydrogen/React-Router
5
6
  * coupling). Pre-login flows authenticate with the project `x-api-key`;
6
- * post-login reads add the customer bearer. The project-specific profile (e.g.
7
- * `isAdmin`) is resolved by a consumer-supplied `resolveUser` — the SDK never
8
- * hardcodes the per-project customer profile shape.
7
+ * post-login reads add the user's bearer. Anything project-specific about the
8
+ * user (a profile record, say) is resolved by a consumer-supplied
9
+ * `resolveUser`: the SDK never hardcodes a per-project profile shape.
9
10
  *
10
11
  * TRANSPORT. Every flow below addresses the server's generated `auth` namespace
11
12
  * through `./ops`, which is `@foir/sdk/data`'s op transport. This module holds
@@ -16,23 +17,17 @@
16
17
  */
17
18
  import { type FoirEnv } from '../graphql/foir-request';
18
19
  import { type AuthOpName, type AuthOpOptions } from './ops';
19
- import { type AuthConfig, type AuthProviderPublic, type CurrentUser, type CustomerAuthResult, type DefaultAuthProvider, type DeleteAccountResult, type MyOrganization, type SelectedOrganization, type ProviderCallbackInput, type ProviderLoginInput, type ProviderLoginResult, type ProviderOTPVerifyInput, type ProviderToken, type SignupContext, type WaitlistJoinResult } from './operations';
20
+ import { type AuthConfig, type AuthProviderPublic, type CurrentUser, type AuthResult, type DefaultAuthProvider, type AuthorizedApp, type DeleteAccountResult, type MyOrganization, type MyProfile, type MyProfileChange, type MySession, type MyFactor, type StepUp, type FactorEnrollment, type MySignInMethod, type NewPersonalAccessToken, type ProviderCallbackInput, type ProviderLoginInput, type ProviderLoginResult, type ProviderOTPVerifyInput, type ProviderToken, type SignupContext, type WaitlistJoinResult } from './operations';
20
21
  import type { TypedDocumentNode } from '@graphql-typed-document-node/core';
21
22
  /** An access token + its rotating refresh token. */
22
23
  export interface FoirAuthTokens {
23
24
  token: string;
24
25
  refreshToken: string;
25
26
  }
26
- /** The customer identity carried by an auth result. */
27
- export interface FoirCustomer {
28
- id: string;
29
- email: string;
30
- }
31
- /** The resolved customer for a guarded surface. */
27
+ /** The signed-in user an auth result and a session carry. */
32
28
  export interface FoirUser {
33
29
  id: string;
34
30
  email: string;
35
- isAdmin: boolean;
36
31
  }
37
32
  /**
38
33
  * Injected session store. Methods may be sync or async so consumers can plug
@@ -44,39 +39,70 @@ export interface SessionAdapter {
44
39
  unset(key: string): void | Promise<void>;
45
40
  }
46
41
  /** Login with email + password. Requires the project to have passwords enabled. */
47
- export declare function customerLogin(env: FoirEnv, vars: {
42
+ export declare function login(env: FoirEnv, vars: {
48
43
  email: string;
49
44
  password: string;
50
- }): Promise<CustomerAuthResult>;
51
- /** Register a new customer with email + password. */
52
- export declare function customerRegister(env: FoirEnv, vars: {
45
+ }): Promise<AuthResult>;
46
+ /** Register a new user with email + password. */
47
+ export declare function register(env: FoirEnv, vars: {
53
48
  email: string;
54
49
  password: string;
55
- }): Promise<CustomerAuthResult>;
56
- /** Request a one-time password be emailed to the customer. */
57
- export declare function customerRequestOTP(env: FoirEnv, email: string): Promise<boolean>;
50
+ }): Promise<AuthResult>;
51
+ /** Request a one-time password be emailed to the user. */
52
+ export declare function requestOTP(env: FoirEnv, email: string): Promise<boolean>;
58
53
  /** Complete an OTP login. */
59
- export declare function customerLoginOTP(env: FoirEnv, vars: {
54
+ export declare function loginWithOTP(env: FoirEnv, vars: {
60
55
  email: string;
61
56
  otp: string;
62
- }): Promise<CustomerAuthResult>;
57
+ }): Promise<AuthResult>;
63
58
  /** Rotate an access token using a refresh token. */
64
- export declare function customerRefreshToken(env: FoirEnv, refreshToken: string): Promise<CustomerAuthResult>;
59
+ export declare function refreshTokens(env: FoirEnv, refreshToken: string): Promise<AuthResult>;
65
60
  /**
66
61
  * Initiate provider (OAuth/OIDC) login — returns a `redirectUrl` to send the
67
62
  * user to, or an inline `token` for non-redirect providers.
68
63
  */
69
- export declare function customerLoginWithProvider(env: FoirEnv, input: ProviderLoginInput): Promise<ProviderLoginResult>;
64
+ export declare function loginWithProvider(env: FoirEnv, input: ProviderLoginInput): Promise<ProviderLoginResult>;
70
65
  /** Complete a provider login from the OAuth callback (`code`/`state`). */
71
- export declare function customerProviderCallback(env: FoirEnv, input: ProviderCallbackInput): Promise<CustomerAuthResult>;
66
+ export declare function providerCallback(env: FoirEnv, input: ProviderCallbackInput): Promise<AuthResult>;
72
67
  /** Verify an OTP issued by an external provider. */
73
- export declare function customerProviderVerifyOTP(env: FoirEnv, input: ProviderOTPVerifyInput): Promise<CustomerAuthResult>;
68
+ export declare function providerVerifyOTP(env: FoirEnv, input: ProviderOTPVerifyInput): Promise<AuthResult>;
69
+ /**
70
+ * Why a provider sign-in did not finish, as the platform said it: a stable code
71
+ * your app shows its own words for (`signup_closed`, `provider_named_no_address`,
72
+ * `account_unavailable`, ...). When the code is `link_code_sent`, the sign-in
73
+ * named an address somebody already holds, through a provider that does not
74
+ * prove the address is theirs, and a code was sent to it: `pending` names the
75
+ * wait, and {@link confirmProviderLink} finishes the sign-in with that code.
76
+ * Null for any other failure.
77
+ */
78
+ export declare function providerSignInRefusalOf(error: unknown): {
79
+ code: string;
80
+ pending?: string;
81
+ } | null;
82
+ /**
83
+ * Finish a provider sign-in that is waiting for the code sent to its address,
84
+ * connecting the provider to the account that holds the address. See
85
+ * {@link providerSignInRefusalOf}.
86
+ */
87
+ export declare function confirmProviderLink(env: FoirEnv, input: {
88
+ pending: string;
89
+ code: string;
90
+ }): Promise<AuthResult>;
91
+ /**
92
+ * Send a new code for a provider sign-in that is waiting for one. The new code
93
+ * replaces the one before, and the answer names the new wait.
94
+ */
95
+ export declare function resendProviderLinkCode(env: FoirEnv, input: {
96
+ pending: string;
97
+ }): Promise<{
98
+ pending: string;
99
+ }>;
74
100
  /** List the project's configured auth providers (for a login UI). */
75
101
  export declare function getAuthProviders(env: FoirEnv): Promise<AuthProviderPublic[]>;
76
102
  /**
77
103
  * Read the project's public auth configuration — which built-in methods are
78
104
  * enabled and which external providers to offer. This is what a login screen
79
- * renders itself from, before any customer token exists.
105
+ * renders itself from, before any user token exists.
80
106
  */
81
107
  export declare function getAuthConfig(env: FoirEnv): Promise<AuthConfig>;
82
108
  /**
@@ -85,55 +111,55 @@ export declare function getAuthConfig(env: FoirEnv): Promise<AuthConfig>;
85
111
  */
86
112
  export declare function getDefaultAuthProvider(env: FoirEnv): Promise<DefaultAuthProvider | null>;
87
113
  /**
88
- * Read the project's customer signup mode (public/restricted/waitlist/closed)
114
+ * Read the project's signup mode (public/restricted/waitlist/closed)
89
115
  * so a self-hosted frontend can render the right signup surface proactively.
90
116
  */
91
- export declare function customerSignupContext(env: FoirEnv): Promise<SignupContext>;
117
+ export declare function signupContext(env: FoirEnv): Promise<SignupContext>;
92
118
  /** Join the project's signup waitlist. The project must be in waitlist mode. */
93
- export declare function customerJoinWaitlist(env: FoirEnv, email: string): Promise<WaitlistJoinResult>;
119
+ export declare function joinWaitlist(env: FoirEnv, email: string): Promise<WaitlistJoinResult>;
94
120
  /**
95
121
  * Send a password-reset email. Resolves `true` whether or not the address has
96
122
  * an account: the server answers identically either way, on purpose, so this
97
123
  * endpoint cannot be used to test whether someone has signed up.
98
124
  */
99
- export declare function customerRequestPasswordReset(env: FoirEnv, email: string): Promise<boolean>;
125
+ export declare function requestPasswordReset(env: FoirEnv, email: string): Promise<boolean>;
100
126
  /**
101
127
  * Redeem an emailed reset token and set a new password. Returns a fresh session
102
- * — resetting a password signs the customer in — so pair it with
128
+ * (resetting a password signs the user in), so pair it with
103
129
  * {@link saveSession}, or use {@link resetPasswordAndSignIn} which does both.
104
130
  */
105
- export declare function customerResetPassword(env: FoirEnv, vars: {
131
+ export declare function resetPassword(env: FoirEnv, vars: {
106
132
  token: string;
107
133
  newPassword: string;
108
- }): Promise<CustomerAuthResult>;
134
+ }): Promise<AuthResult>;
109
135
  /** Redeem an emailed verification token. */
110
- export declare function customerVerifyEmail(env: FoirEnv, token: string): Promise<boolean>;
136
+ export declare function verifyEmail(env: FoirEnv, token: string): Promise<boolean>;
111
137
  /**
112
- * Change the calling customer's password. Requires the current password as well
138
+ * Change the calling user's password. Requires the current password as well
113
139
  * as the bearer, so a stolen token alone cannot take the account over.
114
140
  */
115
- export declare function customerUpdatePassword(env: FoirEnv, vars: {
141
+ export declare function updatePassword(env: FoirEnv, vars: {
116
142
  currentPassword: string;
117
143
  newPassword: string;
118
144
  }, options?: AuthOpOptions): Promise<boolean>;
119
145
  /**
120
- * The calling customer, or `null` when the request carried no customer token.
146
+ * The calling user, or `null` when the request carried no user token.
121
147
  * An absent session is an answer rather than a failure, so this does not throw.
122
148
  */
123
149
  export declare function currentUser(env: FoirEnv, options?: AuthOpOptions): Promise<CurrentUser | null>;
124
150
  /**
125
- * The stored upstream provider token for the calling customer, refreshed
151
+ * The stored upstream provider token for the calling user, refreshed
126
152
  * transparently by the server when it has expired. `null` when there is no
127
- * customer token on the request or none stored for that provider.
153
+ * user token on the request or none stored for that provider.
128
154
  */
129
155
  export declare function myProviderToken(env: FoirEnv, providerKey: string, options?: AuthOpOptions): Promise<ProviderToken | null>;
130
156
  /**
131
157
  * End the session server-side, revoking stored provider tokens. This does NOT
132
158
  * clear local session state — {@link signOut} is the pairing that does both.
133
159
  */
134
- export declare function customerLogout(env: FoirEnv, options?: AuthOpOptions): Promise<boolean>;
160
+ export declare function logout(env: FoirEnv, options?: AuthOpOptions): Promise<boolean>;
135
161
  /**
136
- * Delete the calling customer's account and their owned records and files.
162
+ * Delete the calling user's account and their owned records and files.
137
163
  * Irreversible. `password` is required for password accounts and omitted for
138
164
  * provider-only ones; the server enforces the actual re-auth gate and fails
139
165
  * closed, so omitting it is refused rather than allowed.
@@ -143,60 +169,140 @@ export declare function deleteMyAccount(env: FoirEnv, vars: {
143
169
  password?: string;
144
170
  }, options?: AuthOpOptions): Promise<DeleteAccountResult>;
145
171
  /**
146
- * The organizations this operator may stand in.
172
+ * Change the calling user's own name, picture or language. It asks no
173
+ * permission: these are theirs.
174
+ */
175
+ export declare function updateMyProfile(env: FoirEnv, change: MyProfileChange, options?: AuthOpOptions): Promise<MyProfile>;
176
+ /**
177
+ * The apps the calling user has agreed may act for them, and what each may
178
+ * carry: the list an account page shows with a way to take each one back.
179
+ */
180
+ export declare function myAuthorizedApps(env: FoirEnv, options?: AuthOpOptions): Promise<AuthorizedApp[]>;
181
+ /**
182
+ * Take back an app's authority to act for the calling user. Its tokens for
183
+ * them stop working at once, and it has to ask them again.
184
+ */
185
+ export declare function revokeAuthorizedApp(env: FoirEnv, id: string, options?: AuthOpOptions): Promise<boolean>;
186
+ /** Where the calling user is signed in, and the personal access tokens they hold. */
187
+ export declare function mySessions(env: FoirEnv, options?: AuthOpOptions): Promise<MySession[]>;
188
+ /** Sign the calling user out of one session, or revoke one of their tokens, by its id. */
189
+ export declare function endMySession(env: FoirEnv, id: string, options?: AuthOpOptions): Promise<boolean>;
190
+ /**
191
+ * Sign the calling user out of every session and every app, and answer how
192
+ * many sessions ended. Their personal access tokens stay. `keepThis` keeps the
193
+ * session making the request.
194
+ */
195
+ export declare function signOutEverywhere(env: FoirEnv, vars?: {
196
+ keepThis?: boolean;
197
+ }, options?: AuthOpOptions): Promise<number>;
198
+ /**
199
+ * Make a personal access token for the calling user: a standing credential
200
+ * they present beside the app's key, as `Authorization: Bearer`. Its value is
201
+ * answered here once.
202
+ */
203
+ export declare function createPersonalAccessToken(env: FoirEnv, vars: {
204
+ name: string;
205
+ expiresInDays: number;
206
+ }, options?: AuthOpOptions): Promise<NewPersonalAccessToken>;
207
+ /** The providers the calling user signs in with. */
208
+ export declare function mySignInMethods(env: FoirEnv, options?: AuthOpOptions): Promise<MySignInMethod[]>;
209
+ /**
210
+ * Start connecting one of the project's providers to the calling user's
211
+ * account, and answer the provider's address to send the browser to. It comes
212
+ * back to `returnTo` with `connected` or `connect_error` added.
213
+ */
214
+ export declare function connectSignInMethod(env: FoirEnv, vars: {
215
+ provider: string;
216
+ returnTo: string;
217
+ }, options?: AuthOpOptions): Promise<string>;
218
+ /** Disconnect a provider from the calling user's account. */
219
+ export declare function disconnectSignInMethod(env: FoirEnv, provider: string, options?: AuthOpOptions): Promise<boolean>;
220
+ /** The second factors, passkeys and recovery codes the calling user holds. */
221
+ export declare function myFactors(env: FoirEnv, options?: AuthOpOptions): Promise<MyFactor[]>;
222
+ /**
223
+ * Begin proving a second factor with the calling user's password.
224
+ * {@link completeStepUp} finishes it; for a user who holds none, the answer's
225
+ * `elevatedHandle` is already the proof.
226
+ */
227
+ export declare function beginStepUp(env: FoirEnv, password: string, options?: AuthOpOptions): Promise<StepUp>;
228
+ /**
229
+ * Prove a second factor with exactly one of a passkey's or security key's
230
+ * assertion, an authenticator app's code or a recovery code, which is then
231
+ * spent. The session making the request counts as two factors from here, and
232
+ * the answer is an elevated handle for one change to the user's factors in
233
+ * the next ten minutes.
234
+ */
235
+ export declare function completeStepUp(env: FoirEnv, vars: {
236
+ handle: string;
237
+ webauthnAssertionJson?: string;
238
+ totpCode?: string;
239
+ recoveryCode?: string;
240
+ }, options?: AuthOpOptions): Promise<string>;
241
+ /**
242
+ * Begin adding `totp` (an authenticator app), `webauthn` (a security key held
243
+ * as a second factor) or `passkey` (a passkey that signs the user in on its
244
+ * own), with the `elevatedHandle` {@link beginStepUp} or
245
+ * {@link completeStepUp} answered.
246
+ */
247
+ export declare function beginFactorEnrollment(env: FoirEnv, vars: {
248
+ method: 'webauthn' | 'totp' | 'passkey';
249
+ elevatedHandle: string;
250
+ }, options?: AuthOpOptions): Promise<FactorEnrollment>;
251
+ /**
252
+ * Finish adding a second factor, with the `navigator.credentials.create`
253
+ * result or the authenticator app's code.
254
+ */
255
+ export declare function completeFactorEnrollment(env: FoirEnv, vars: {
256
+ handle: string;
257
+ webauthnAttestationJson?: string;
258
+ totpCode?: string;
259
+ name?: string;
260
+ }, options?: AuthOpOptions): Promise<boolean>;
261
+ /** Remove one of the calling user's factors, with an elevated handle from {@link completeStepUp}. */
262
+ export declare function removeFactor(env: FoirEnv, vars: {
263
+ elevatedHandle: string;
264
+ kind: string;
265
+ id: string;
266
+ }, options?: AuthOpOptions): Promise<boolean>;
267
+ /**
268
+ * Make the calling user new recovery codes, with an elevated handle from
269
+ * {@link completeStepUp}. They replace any held and are answered here once.
270
+ */
271
+ export declare function makeRecoveryCodes(env: FoirEnv, elevatedHandle: string, options?: AuthOpOptions): Promise<string[]>;
272
+ /**
273
+ * The organizations this user may stand in.
147
274
  *
148
- * Answered from the CALLING customer's own memberships: each organization they
149
- * hold one in and every organization beneath it, so an operator is shown
150
- * exactly the set they can stand in, and a customer with no memberships sees
151
- * an empty list rather than a refusal. Requires the customer bearer; it is not
152
- * the project's inventory and cannot be used as one.
275
+ * Answered from the calling user's own memberships: each organization they
276
+ * hold one in and every organization beneath it, so the list is exactly the
277
+ * set a request of theirs may name, and a user with no memberships sees an
278
+ * empty list rather than a refusal. Requires the user's bearer; it is not the
279
+ * project's inventory and cannot be used as one.
280
+ *
281
+ * A MEMBERSHIP REACHES DOWNWARD. Someone who is a member of an organization may
282
+ * stand in any organization beneath it without holding a row of their own
283
+ * there. The reverse never works: a membership at a branch stands in no
284
+ * ancestor and in no sibling branch, and a request naming either is refused as
285
+ * not-found, the same answer an organization that does not exist gets.
286
+ * {@link MyOrganization.role} names ONE of the roles that apply where the
287
+ * person stands (the membership held in the organization itself, when there is
288
+ * one); their authority there is the union of every membership that reaches
289
+ * it, together with their own roles in the project.
153
290
  */
154
291
  export declare function myOrganizations(env: FoirEnv, vars?: {
155
292
  first?: number;
156
293
  after?: string;
157
294
  }, options?: AuthOpOptions): Promise<MyOrganization[]>;
158
- /**
159
- * Stand in one of them, for this customer, until they choose otherwise.
160
- *
161
- * Set once — not per call. The selection is stored against the customer and
162
- * resolved into the claim on every subsequent request, so nothing downstream
163
- * takes an org argument. Pass an empty `orgId` to clear it and return to the
164
- * project-shared view.
165
- *
166
- * The server authorises the choice against a live membership and refuses
167
- * otherwise, so a caller cannot select their way into an organization they do
168
- * not run.
169
- *
170
- * A MEMBERSHIP REACHES DOWNWARD, which is what "a live membership" means now
171
- * that organizations nest. Someone who is a member of an organization may stand in any
172
- * organization BENEATH it without holding a row of their own there, and
173
- * {@link myOrganizations} offers exactly that set — so any id it returned can
174
- * be passed here. The reverse never works: a membership at a branch stands in
175
- * no ancestor and in no sibling branch, and both are refused as not-found,
176
- * which is the same answer an organization that does not exist gets.
177
- *
178
- * WHAT STANDING THERE MEANS is every membership that reaches the organization
179
- * selected. Reach a client through a membership above it and the role shown is
180
- * that membership's; authority is the union of every membership that reaches
181
- * it, together with the customer's own roles in the project.
182
- * {@link MyOrganization.role} names ONE of those roles (the membership held in
183
- * the organization itself, when there is one), so it is part of what the next
184
- * request resolves and not the whole of it.
185
- */
186
- export declare function selectOrganization(env: FoirEnv, vars: {
187
- orgId: string;
188
- }, options?: AuthOpOptions): Promise<SelectedOrganization>;
189
295
  /**
190
296
  * Found an organization, as its first member.
191
297
  *
192
298
  * The caller decides the NAME and, optionally, where it hangs — and nothing
193
- * else. The founder is the customer behind the bearer, the id is minted
299
+ * else. The founder is the user behind the bearer, the id is minted
194
300
  * server-side the way a project's and a tenant's are, and the role they hold in
195
301
  * the new organization is the one the PROJECT named in its settings
196
- * (`operatorSignupRole`). The server creates the organization and that one
302
+ * (`organizationSignupRole`). The server creates the organization and that one
197
303
  * membership together.
198
304
  *
199
- * `parentId` FOUNDS A CHILD, which is what lets your own customer create its own
305
+ * `parentId` FOUNDS A CHILD, which is what lets the people you serve create their own
200
306
  * sub-tenants with no administrator in the loop — a reseller adding a client, a
201
307
  * franchise adding a branch. It is resolved against the caller's own
202
308
  * MEMBERSHIPS, not merely against the project: on this lane "an organization
@@ -204,59 +310,59 @@ export declare function selectOrganization(env: FoirEnv, vars: {
204
310
  * not-found. Omit it to found a root, which is what every registration did
205
311
  * before organizations nested.
206
312
  *
207
- * Exists on the wire only while the project's `operatorSignupEnabled` setting
313
+ * Exists on the wire only while the project's `organizationSignupEnabled` setting
208
314
  * is on; a project that never opted in has no such field, and this refuses
209
315
  * naming it. Returns the same entry `myOrganizations` would then list, role
210
- * included, so the application can go straight to {@link selectOrganization}.
316
+ * included, so the application can name it on its next request.
211
317
  */
212
318
  export declare function registerOrganization(env: FoirEnv, vars: {
213
319
  name: string;
214
320
  parentId?: string;
215
321
  }, options?: AuthOpOptions): Promise<MyOrganization>;
216
322
  /**
217
- * Persist an auth result to the session; returns the customer identity.
323
+ * Persist an auth result to the session; returns the signed-in user.
218
324
  *
219
- * A result that names no customer keeps the identity already stored. A refresh
325
+ * A result that names no user keeps the identity already stored. A refresh
220
326
  * rotates the tokens of a session that already knows who it belongs to, and a
221
- * platform that answers a refresh without the customer must not blank that:
327
+ * platform that answers a refresh without the user must not blank that:
222
328
  * {@link requireAuth} reads the stored identity, so a valid token beside an
223
329
  * empty identity reads as signed out.
224
330
  */
225
- export declare function saveSession(adapter: SessionAdapter, result: CustomerAuthResult): Promise<FoirCustomer>;
331
+ export declare function saveSession(adapter: SessionAdapter, result: AuthResult): Promise<FoirUser>;
226
332
  /** Clear all Foir auth keys from the session. */
227
333
  export declare function clearSession(adapter: SessionAdapter): Promise<void>;
228
334
  /** Read the stored access token (null when signed out). */
229
335
  export declare function getSessionToken(adapter: SessionAdapter): Promise<string | null>;
230
- /** Read the stored customer identity (null when signed out). */
231
- export declare function getSessionCustomer(adapter: SessionAdapter): Promise<FoirCustomer | null>;
336
+ /** Read the stored user (null when signed out). */
337
+ export declare function getSessionUser(adapter: SessionAdapter): Promise<FoirUser | null>;
232
338
  /** Login with email + password and persist the session. */
233
- export declare function loginWithPassword(adapter: SessionAdapter, env: FoirEnv, vars: {
339
+ export declare function signInWithPassword(adapter: SessionAdapter, env: FoirEnv, vars: {
234
340
  email: string;
235
341
  password: string;
236
- }): Promise<FoirCustomer>;
342
+ }): Promise<FoirUser>;
237
343
  /** Register with email + password and persist the session. */
238
- export declare function registerWithPassword(adapter: SessionAdapter, env: FoirEnv, vars: {
344
+ export declare function signUpWithPassword(adapter: SessionAdapter, env: FoirEnv, vars: {
239
345
  email: string;
240
346
  password: string;
241
- }): Promise<FoirCustomer>;
347
+ }): Promise<FoirUser>;
242
348
  /** Complete an OTP login and persist the session. */
243
- export declare function loginWithOTP(adapter: SessionAdapter, env: FoirEnv, vars: {
349
+ export declare function signInWithOTP(adapter: SessionAdapter, env: FoirEnv, vars: {
244
350
  email: string;
245
351
  otp: string;
246
- }): Promise<FoirCustomer>;
352
+ }): Promise<FoirUser>;
247
353
  /**
248
354
  * Complete a forgot-password flow: redeem the emailed token, set the new
249
355
  * password, and persist the session the server mints. The peer of
250
- * {@link loginWithPassword} for the branch where the customer cannot log in.
356
+ * {@link signInWithPassword} for the branch where the user cannot log in.
251
357
  */
252
358
  export declare function resetPasswordAndSignIn(adapter: SessionAdapter, env: FoirEnv, vars: {
253
359
  token: string;
254
360
  newPassword: string;
255
- }): Promise<FoirCustomer>;
361
+ }): Promise<FoirUser>;
256
362
  /**
257
363
  * End the session on both sides: revoke it server-side, then clear local state.
258
364
  *
259
- * The local clear happens even when the server call fails. A customer who
365
+ * The local clear happens even when the server call fails. Someone who
260
366
  * pressed sign-out and got a network error must not be left holding a session
261
367
  * on the device in front of them — the token expires on its own, and the
262
368
  * failure mode of clearing anyway (one orphaned provider token) is strictly
@@ -295,16 +401,18 @@ export declare function authedRequest<TData, TVariables>(adapter: SessionAdapter
295
401
  * management, which is the half a generated namespace does not give you.
296
402
  */
297
403
  export declare function authedOp<T>(adapter: SessionAdapter, env: FoirEnv, op: AuthOpName, args?: Record<string, unknown>): Promise<T>;
298
- export interface RequireAuthOptions {
404
+ export interface RequireAuthOptions<TUser = FoirUser> {
299
405
  /**
300
- * Resolve the full {@link FoirUser} (including the project-specific
301
- * `isAdmin`) from the session identity. Typically runs the project's
302
- * `myProfile` query via {@link authedRequest}. Defaults to `isAdmin: false`.
406
+ * Resolve what the guarded surface needs about the user from the session:
407
+ * typically the project's own profile record, read through
408
+ * {@link authedRequest}. Without it the guard answers the {@link FoirUser}
409
+ * the session holds. What the user may do is a role or a scope: guard on
410
+ * those with {@link requireRole} and {@link requireScope}.
303
411
  */
304
412
  resolveUser?: (ctx: {
305
413
  token: string;
306
- customer: FoirCustomer;
307
- }) => FoirUser | Promise<FoirUser>;
414
+ user: FoirUser;
415
+ }) => TUser | Promise<TUser>;
308
416
  /**
309
417
  * Called when there's no valid session — throw your framework's redirect
310
418
  * (e.g. `throw redirect(loginUrl)`). Must not return.
@@ -319,14 +427,8 @@ export interface RequireAuthOptions {
319
427
  env?: FoirEnv;
320
428
  }
321
429
  /**
322
- * Require a signed-in customer. Resolves the {@link FoirUser} via
323
- * `resolveUser` (or a minimal identity), or invokes `onUnauthenticated` when
324
- * there's no session.
430
+ * Require a signed-in user. Answers what `resolveUser` resolves (or the
431
+ * session's {@link FoirUser}), or invokes `onUnauthenticated` when there's no
432
+ * session.
325
433
  */
326
- export declare function requireAuth(adapter: SessionAdapter, options: RequireAuthOptions): Promise<FoirUser>;
327
- export interface RequireAdminOptions extends RequireAuthOptions {
328
- /** Called when the user is authenticated but not an admin. Must not return. */
329
- onForbidden: () => never | Promise<never>;
330
- }
331
- /** Require a signed-in customer who is also an admin. */
332
- export declare function requireAdmin(adapter: SessionAdapter, options: RequireAdminOptions): Promise<FoirUser>;
434
+ export declare function requireAuth<TUser = FoirUser>(adapter: SessionAdapter, options: RequireAuthOptions<TUser>): Promise<TUser>;
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * Hosted-login bridge — for storefronts that delegate sign-in to a Foir
3
- * white-label front door (the `customerLoginWithFoir` flow) instead of
3
+ * white-label front door (the `loginWithFoir` flow) instead of
4
4
  * rendering their own login UI.
5
5
  *
6
6
  * The front door sets a first-party session cookie on the registrable domain;
7
7
  * because that domain is shared, the cookie reaches the storefront, which
8
- * exchanges it server-side for a short-lived customer bearer + identity. The
8
+ * exchanges it server-side for a short-lived user bearer + identity. The
9
9
  * cookie is the durable credential (re-exchanged on bearer expiry) — there's
10
10
  * no separate refresh token in this flow.
11
11
  *
@@ -15,7 +15,7 @@
15
15
  export interface HostedLoginConfig {
16
16
  /** White-label front-door origin, e.g. `https://login.example.com`. */
17
17
  loginOrigin: string;
18
- /** Session cookie name set on the registrable domain. Default `foir_customer_session`. */
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;
@@ -29,13 +29,13 @@ export interface HostedLoginConfig {
29
29
  export declare function hostedLoginUrl(config: HostedLoginConfig, returnTo?: string): string;
30
30
  /**
31
31
  * Build the redirect URL that ENDS the hosted session — the mirror of
32
- * `hostedLoginUrl`, and the only thing that actually signs a customer out on
32
+ * `hostedLoginUrl`, and the only thing that actually signs a user out on
33
33
  * this flow.
34
34
  *
35
35
  * The cookie is the durable credential. Disposing of a bearer, clearing a
36
- * local session, or calling the `customerLogout` mutation (which clears
36
+ * local session, or calling the `logout` mutation (which clears
37
37
  * upstream provider tokens and nothing else) all leave it in place, and the
38
- * next request re-establishes the customer from it. This URL points at the
38
+ * next request re-establishes the user from it. This URL points at the
39
39
  * front door's end-session endpoint, which revokes the session row and clears
40
40
  * the cookie before returning the browser to `returnTo`.
41
41
  *
@@ -50,7 +50,7 @@ export declare function hostedLogoutUrl(config: HostedLoginConfig, clientId: str
50
50
  /** The identity + bearer returned by a successful hosted-session exchange. */
51
51
  export interface HostedSession {
52
52
  token: string;
53
- customerId: string;
53
+ userId: string;
54
54
  email: string;
55
55
  /**
56
56
  * Seconds until `token` lapses, from the endpoint's `expires_in`.
@@ -61,7 +61,7 @@ export interface HostedSession {
61
61
  * lifetime (coupling a storefront to a server constant it cannot see) or to
62
62
  * decode `exp` off the JWT. Both re-derive a number the response already
63
63
  * carried, and a consumer that does neither treats a 15-minute bearer as good
64
- * forever — which reads as a customer being signed out mid-session.
64
+ * forever — which reads as a user being signed out mid-session.
65
65
  *
66
66
  * Store the death date, not this number: it is seconds from when the exchange
67
67
  * ANSWERED, and a value held across requests is already stale.
@@ -76,9 +76,9 @@ export interface HostedSession {
76
76
  * reason says what happened.
77
77
  *
78
78
  * Collapsing all of this to `null` is what made a transient blip on
79
- * `/session/token` indistinguishable from a genuinely signed-out customer. The
79
+ * `/session/token` indistinguishable from a genuinely signed-out user. The
80
80
  * only safe-looking action on a bare `null` is to clear the session and send
81
- * the customer to the front door, so one 502 signed out a customer whose 30-day
81
+ * the user to the front door, so one 502 signed out a user whose 30-day
82
82
  * cookie was perfectly valid — and the route's rate limiter is deliberately
83
83
  * fail-open for exactly the opposite reason ("a Redis outage should degrade an
84
84
  * authenticated app, not log it out").
@@ -90,7 +90,7 @@ export type HostedSessionResult =
90
90
  session: HostedSession;
91
91
  }
92
92
  /**
93
- * The customer is signed out. Act on it: clear any local session and send
93
+ * The user is signed out. Act on it: clear any local session and send
94
94
  * them to `hostedLoginUrl`.
95
95
  *
96
96
  * `no-cookie` — nothing to exchange. `rejected` — the front door refused the
@@ -102,12 +102,12 @@ export type HostedSessionResult =
102
102
  }
103
103
  /**
104
104
  * The exchange could not be completed, and it says NOTHING about whether the
105
- * customer is signed in. KEEP the existing session, serve the request, try
105
+ * user is signed in. KEEP the existing session, serve the request, try
106
106
  * again on the next one.
107
107
  *
108
108
  * `forbidden` is the odd one: a 403 means the CSRF header did not arrive
109
109
  * (a proxy stripping it, most likely), which is a misconfiguration rather
110
- * than a blip. Retrying will not fix it — but signing the customer out would
110
+ * than a blip. Retrying will not fix it — but signing the user out would
111
111
  * be wrong, so the safe action is the same and it is grouped by that.
112
112
  */
113
113
  | {
@@ -119,7 +119,7 @@ export type HostedSessionResult =
119
119
  cause?: unknown;
120
120
  };
121
121
  /**
122
- * Exchange the hosted-login cookie on an incoming request for a customer
122
+ * Exchange the hosted-login cookie on an incoming request for a user
123
123
  * bearer + identity (server-to-server: forwards the cookie to the front door's
124
124
  * session endpoint with the CSRF header).
125
125
  *
@@ -1,8 +1,8 @@
1
1
  /**
2
- * `@foir/sdk/auth` — framework-agnostic Foir customer auth.
2
+ * `@foir/sdk/auth`: framework-agnostic sign-in for your app's users.
3
3
  *
4
- * The whole customer auth surface — login, register, OTP, external providers,
5
- * refresh, password management, email verification and account deletion — over
4
+ * The whole sign-in surface (login, register, OTP, external providers,
5
+ * refresh, password management, email verification and account deletion) over
6
6
  * the server's generated `auth` namespace, plus token lifecycle with an
7
7
  * injected `SessionAdapter`, guards, and the optional hosted-login bridge.
8
8
  *
@@ -10,9 +10,9 @@
10
10
  * the caller's own manifest advertises, through the same op transport
11
11
  * `@foir/sdk/data` uses, so `graphql` is not on this module's path at all.
12
12
  */
13
- export { customerLogin, customerRegister, customerRequestOTP, customerLoginOTP, customerRefreshToken, customerLoginWithProvider, customerProviderCallback, customerProviderVerifyOTP, getAuthProviders, getAuthConfig, getDefaultAuthProvider, customerSignupContext, customerJoinWaitlist, customerRequestPasswordReset, customerResetPassword, customerUpdatePassword, customerVerifyEmail, currentUser, myProviderToken, customerLogout, deleteMyAccount, myOrganizations, selectOrganization, registerOrganization, saveSession, clearSession, getSessionToken, getSessionCustomer, loginWithPassword, registerWithPassword, loginWithOTP, resetPasswordAndSignIn, refreshSession, refreshSessionOnce, signOut, authedRequest, authedOp, requireAuth, requireAdmin, } from './auth';
14
- export type { FoirAuthTokens, FoirCustomer, FoirUser, SessionAdapter, RequireAuthOptions, RequireAdminOptions, } from './auth';
15
- export { customerAccess, getSessionAccess, hasRole, hasScope, requireRole, requireScope, FoirAccessDeniedError, } from './access';
13
+ export { login, register, requestOTP, loginWithOTP, refreshTokens, loginWithProvider, providerCallback, providerVerifyOTP, providerSignInRefusalOf, confirmProviderLink, resendProviderLinkCode, getAuthProviders, getAuthConfig, getDefaultAuthProvider, signupContext, joinWaitlist, requestPasswordReset, resetPassword, updatePassword, verifyEmail, currentUser, myProviderToken, logout, deleteMyAccount, updateMyProfile, myAuthorizedApps, revokeAuthorizedApp, mySessions, endMySession, signOutEverywhere, createPersonalAccessToken, mySignInMethods, connectSignInMethod, disconnectSignInMethod, myFactors, beginStepUp, completeStepUp, beginFactorEnrollment, completeFactorEnrollment, removeFactor, makeRecoveryCodes, myOrganizations, registerOrganization, saveSession, clearSession, getSessionToken, getSessionUser, signInWithPassword, signUpWithPassword, signInWithOTP, resetPasswordAndSignIn, refreshSession, refreshSessionOnce, signOut, authedRequest, authedOp, requireAuth, } from './auth';
14
+ export type { FoirAuthTokens, FoirUser, SessionAdapter, RequireAuthOptions, } from './auth';
15
+ export { userAccess, getSessionAccess, hasRole, hasScope, requireRole, requireScope, FoirAccessDeniedError, } from './access';
16
16
  export type { FoirAccess, FoirAccessDenial } from './access';
17
17
  export { FoirAuthDowngradedError, FoirSessionExpiredError } from '../graphql/foir-request';
18
18
  export { AUTH_OPS } from './ops';
@@ -21,4 +21,4 @@ export { hostedLoginUrl, hostedLogoutUrl, fetchHostedSession } from './hosted';
21
21
  export type { HostedLoginConfig, HostedSession, HostedSessionResult } from './hosted';
22
22
  export { createFoirSessionClient } from './session-client';
23
23
  export type { FoirSessionClient, FoirSessionConfig, FoirSessionUser, } from './session-client';
24
- export type { CustomerAuthResult, ProviderLoginResult, AuthProviderPublic, ProviderLoginInput, ProviderCallbackInput, ProviderOTPVerifyInput, SignupContext, SignupMode, WaitlistJoinResult, AuthConfig, AuthConfigProvider, DefaultAuthProvider, CurrentUser, ProviderToken, DeleteAccountResult, MyOrganization, SelectedOrganization, } from './operations';
24
+ export type { AuthResult, ProviderLoginResult, AuthProviderPublic, ProviderLoginInput, ProviderCallbackInput, ProviderOTPVerifyInput, SignupContext, SignupMode, WaitlistJoinResult, AuthConfig, AuthConfigProvider, DefaultAuthProvider, CurrentUser, ProviderToken, DeleteAccountResult, MyOrganization, MyProfile, MyProfileChange, AuthorizedApp, MySession, NewPersonalAccessToken, MySignInMethod, MyFactor, StepUp, FactorEnrollment, } from './operations';