@foir/sdk 0.30.1 → 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.
- package/CHANGELOG.md +14 -0
- package/README.md +1 -1
- package/dist/ai/index.d.ts +8 -9
- package/dist/ai.js +162 -7
- package/dist/app/client.d.ts +9 -5
- package/dist/app.js +12 -13
- package/dist/auth/auth.d.ts +80 -101
- package/dist/auth/hosted.d.ts +12 -12
- package/dist/auth/index.d.ts +11 -7
- package/dist/auth/operations.d.ts +17 -32
- package/dist/auth/ops.d.ts +4 -13
- package/dist/auth/session-client.d.ts +4 -4
- package/dist/auth/steps.d.ts +50 -0
- package/dist/auth-session.js +3 -3
- package/dist/auth.js +157 -75
- package/dist/content/content-renderer.d.ts +2 -2
- package/dist/content/richtext.d.ts +2 -2
- package/dist/content.js +7 -7
- package/dist/data/builtins.d.ts +64 -33
- package/dist/data/index.d.ts +2 -2
- package/dist/data/manifest.d.ts +1 -1
- package/dist/data/schema.d.ts +1 -1
- package/dist/data/selection.d.ts +3 -3
- package/dist/data.js +5 -2
- package/dist/next/index.d.ts +1 -1
- package/dist/next/session.d.ts +27 -11
- package/dist/next.js +98 -40
- package/dist/push.js +9 -19
- package/dist/react/FoirProvider.d.ts +18 -16
- package/dist/react/feedback-notes.d.ts +1 -2
- package/dist/react.js +167 -84
- package/dist/runs/step-reply.d.ts +81 -0
- package/dist/server/callback-client.d.ts +11 -16
- package/dist/server/index.d.ts +2 -0
- package/dist/server/operation-types.d.ts +6 -13
- package/dist/server.js +76 -107
- package/dist/transport/foir-http.d.ts +20 -6
- package/package.json +1 -1
package/dist/auth/auth.d.ts
CHANGED
|
@@ -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).
|
|
7
|
-
*
|
|
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
|
|
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
|
-
*
|
|
48
|
-
*
|
|
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
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
*
|
|
67
|
-
*
|
|
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
|
|
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
|
|
91
|
-
* came through, takes no password; `code_sign_in_off`
|
|
92
|
-
* or {@link
|
|
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
|
|
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<
|
|
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
|
|
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
|
|
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
|
|
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
|
|
264
|
-
*
|
|
265
|
-
*
|
|
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<
|
|
246
|
+
}, options?: AuthOpOptions): Promise<FoirAccountStep>;
|
|
272
247
|
/**
|
|
273
|
-
* Keep the address a code was sent to, as proven
|
|
274
|
-
*
|
|
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
|
-
|
|
256
|
+
step: FoirAccountStep;
|
|
278
257
|
code: string;
|
|
279
|
-
}
|
|
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
|
|
311
|
-
*
|
|
312
|
-
* `
|
|
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
|
|
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),
|
|
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
|
|
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
|
-
|
|
315
|
+
step: FoirAccountStep;
|
|
344
316
|
webauthnAttestationJson?: string;
|
|
345
317
|
totpCode?: string;
|
|
346
318
|
name?: string;
|
|
347
|
-
}
|
|
348
|
-
/** Remove one of the calling user's factors,
|
|
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,
|
|
365
|
-
* {@link
|
|
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,
|
|
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
|
-
/**
|
|
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
|
|
459
|
-
* session. Nobody is signed in until
|
|
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<
|
|
465
|
-
/**
|
|
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
|
-
|
|
446
|
+
step: FoirSignInStep;
|
|
468
447
|
otp: string;
|
|
469
448
|
}): Promise<FoirUser>;
|
|
470
449
|
/**
|
package/dist/auth/hosted.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
* `
|
|
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 `
|
|
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.
|
|
68
|
-
* `return redirect(
|
|
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
|
|
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 `
|
|
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-
|
|
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:
|
|
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
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -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 (
|
|
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
|
|
7
|
-
* injected `SessionAdapter
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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,
|
|
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
|
|
5
|
-
* provider
|
|
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
|
-
|
|
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
|
-
/**
|
|
40
|
-
export interface
|
|
41
|
-
/**
|
|
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
|
|
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
|
|
89
|
-
* user token exists: it is what a
|
|
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
|
|
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
|
-
/**
|
|
293
|
-
|
|
294
|
-
/**
|
|
295
|
-
|
|
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
|
-
/**
|
|
306
|
-
|
|
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. */
|
package/dist/auth/ops.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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 {
|
|
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
|
-
/**
|
|
40
|
-
|
|
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?:
|
|
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. */
|