@nxgt/janus 0.19.0 → 0.20.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/README.md +117 -7
- package/dist/auth/email-flows/reset-password.d.ts.map +1 -1
- package/dist/auth/events.d.ts +3 -3
- package/dist/auth/index.d.ts +1 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/magic-link.d.ts +3 -0
- package/dist/auth/magic-link.d.ts.map +1 -1
- package/dist/auth/one-time/issue.d.ts +6 -0
- package/dist/auth/one-time/issue.d.ts.map +1 -1
- package/dist/auth/prepared.d.ts +21 -0
- package/dist/auth/prepared.d.ts.map +1 -0
- package/dist/auth/proven-sign-in.d.ts +22 -0
- package/dist/auth/proven-sign-in.d.ts.map +1 -0
- package/dist/auth/sign-in-code.d.ts +4 -0
- package/dist/auth/sign-in-code.d.ts.map +1 -1
- package/dist/auth/types/email-flows.d.ts +18 -0
- package/dist/auth/types/email-flows.d.ts.map +1 -1
- package/dist/auth/types/index.d.ts +2 -0
- package/dist/auth/types/index.d.ts.map +1 -1
- package/dist/auth/types/janus.d.ts +7 -5
- package/dist/auth/types/janus.d.ts.map +1 -1
- package/dist/auth/types/magic-link.d.ts +11 -0
- package/dist/auth/types/magic-link.d.ts.map +1 -1
- package/dist/auth/types/prepared.d.ts +41 -0
- package/dist/auth/types/prepared.d.ts.map +1 -0
- package/dist/auth/types/proven-sign-in.d.ts +43 -0
- package/dist/auth/types/proven-sign-in.d.ts.map +1 -0
- package/dist/auth/types/sign-in.d.ts +2 -2
- package/dist/auth/users/any-type-api.d.ts +2 -2
- package/dist/auth/users/any-type-api.d.ts.map +1 -1
- package/dist/auth/users/type-api.d.ts +2 -2
- package/dist/auth/users/type-api.d.ts.map +1 -1
- package/dist/index.js +92 -17
- package/dist/index.js.map +11 -9
- package/docs/README.md +1 -1
- package/docs/guide/devices.md +4 -0
- package/docs/guide/email-flows.md +105 -0
- package/docs/guide/errors.md +2 -2
- package/docs/guide/events.md +2 -2
- package/docs/guide/magic-link.md +49 -2
- package/docs/guide/passwords.md +5 -2
- package/docs/guide/second-factor.md +1 -1
- package/docs/guide/sessions.md +94 -1
- package/docs/guide/sign-in-code.md +54 -2
- package/docs/guide/users.md +1 -0
- package/docs/roadmap.md +17 -26
- package/docs/troubleshooting.md +81 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -327,6 +327,8 @@ await auth.signInCode.request(email); // { code, challenge, email,
|
|
|
327
327
|
await auth.signInCode.confirm(challenge, code); // { status: 'signedIn', user, session, token }
|
|
328
328
|
await auth.magicLink.request(email); // { token, email, expiresAt, user } | null
|
|
329
329
|
await auth.magicLink.confirm(token); // { status: 'signedIn', user, session, token }
|
|
330
|
+
await auth.magicLink.prepare(email); // counted, nobody looked up: { send() } — and signInCode, resetPassword
|
|
331
|
+
await auth.signInProven(user.id); // privileged: after a proof YOUR server verified — { status: 'signedIn', … }
|
|
330
332
|
await auth.stepUp.request(user); // { via: 'email', code, challenge, email, expiresAt, user }
|
|
331
333
|
await auth.stepUp.confirm(request, challenge, code); // the request's session, authenticatedAt: now
|
|
332
334
|
|
|
@@ -379,9 +381,9 @@ else reaches the store and is asynchronous.
|
|
|
379
381
|
back to `false`.
|
|
380
382
|
- **Per type**: `create`, `find` (or `null`), `findMany`, `get` (or
|
|
381
383
|
`NOT_FOUND`), `list`, `update(user, patch)` — merged over the stored fields,
|
|
382
|
-
then validated whole — `setActive` and `
|
|
383
|
-
`signIn`, `findByLogin`, `setPassword` and
|
|
384
|
-
`delete` takes an optional `ifVersion`.
|
|
384
|
+
then validated whole — `setActive`, `delete` and `signInProven` (below);
|
|
385
|
+
with a password, `signUp`, `signIn`, `findByLogin`, `setPassword` and
|
|
386
|
+
`changePassword`. Every write but `delete` takes an optional `ifVersion`.
|
|
385
387
|
- **`findMany(ids)`** answers the type's users **in the order the ids were
|
|
386
388
|
given**, each once — a repeated id at its first place. An id `find` answers
|
|
387
389
|
`null` for — malformed, unknown, another type's — is **left out**, so match
|
|
@@ -422,6 +424,8 @@ else reaches the store and is asynchronous.
|
|
|
422
424
|
`magicLink.request`, `signInCode.request` and `resetPassword.request` — an
|
|
423
425
|
address nobody holds is counted and refused alike — and per user for
|
|
424
426
|
`verifyEmail.send` and for `stepUp.request` when it e-mails a code.
|
|
427
|
+
`prepare` counts as `request` does, in the same window
|
|
428
|
+
([requests in two steps](#requests-in-two-steps--prepare)).
|
|
425
429
|
`mail: { throttle: { attempts, window } }` changes it, `mail: { throttle:
|
|
426
430
|
false }` turns it off; a store that cannot count throws `STORE_FAILED` and
|
|
427
431
|
nothing is issued
|
|
@@ -724,6 +728,91 @@ to type.
|
|
|
724
728
|
confirms from a `POST` so mail scanners spend nothing, every error, routes
|
|
725
729
|
and a test.
|
|
726
730
|
|
|
731
|
+
### Requests in two steps — `prepare`
|
|
732
|
+
|
|
733
|
+
```ts
|
|
734
|
+
// In the visitor's request: counted, nobody looked up — the same time for any address.
|
|
735
|
+
// Past the limit it throws MailThrottledError: answer 429 with retryAfter, which
|
|
736
|
+
// @nxgt/janus-hono's janusErrors() and @nxgt/janus-graphql do for you.
|
|
737
|
+
const pending = await auth.magicLink.prepare(email); // { send() }
|
|
738
|
+
|
|
739
|
+
// Off the visitor's request: looked up, issued, mailed — or nothing, for nobody.
|
|
740
|
+
void (async () => {
|
|
741
|
+
const issued = await pending.send(); // what request answers: { token, email, expiresAt, user } | null
|
|
742
|
+
if (issued !== null) {
|
|
743
|
+
await sendMail(issued.email, `Sign in: https://app.example/sign-in/link?token=${issued.token}`);
|
|
744
|
+
}
|
|
745
|
+
})().catch(reportError); // a STORE_FAILED here reaches nobody: log it
|
|
746
|
+
|
|
747
|
+
// the same page for everybody, whoever holds the address
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
`magicLink.prepare(email)`, `signInCode.prepare(email)` and
|
|
751
|
+
`resetPassword.prepare(email)` are `request(email)` cut in two at the mail
|
|
752
|
+
throttle's count, so `MAIL_THROTTLED` reaches the visitor while the e-mail
|
|
753
|
+
still goes out off their request.
|
|
754
|
+
|
|
755
|
+
- **`prepare(email)` validates, counts the address, and looks nobody up**:
|
|
756
|
+
the same store calls whoever holds the address, none with
|
|
757
|
+
`mail: { throttle: false }`. Past the limit it is `MailThrottledError`
|
|
758
|
+
with `retryAfter`, and nothing is issued. It shares its count with
|
|
759
|
+
`request`: one window per flow and address.
|
|
760
|
+
- **`send()` does the rest of `request`, once** — looks the address up,
|
|
761
|
+
issues, spends the earlier tokens — and answers what `request` answers,
|
|
762
|
+
`null` for nobody. It counts nothing: the count was `prepare`'s. A second
|
|
763
|
+
call is a `TypeError`, and so is a call after one that failed: prepare
|
|
764
|
+
again, which counts again.
|
|
765
|
+
- **`signInCode.prepare` also answers the `challenge`**, minted before the
|
|
766
|
+
lookup, so the visitor's cookie is set now, whoever holds the address —
|
|
767
|
+
it replaces the decoy an unknown address needed; for nobody it confirms as
|
|
768
|
+
`TOKEN_UNKNOWN`. `send()` answers the code issued under it.
|
|
769
|
+
- Typed per flow: `PreparedRequest<IssuedToken & { user }>` for a link and
|
|
770
|
+
a reset, `PreparedCode<User>` for a code. `verifyEmail.send` and
|
|
771
|
+
`stepUp.request` have no `prepare`: they take a user the application
|
|
772
|
+
already holds, so their time tells nothing about who has an account.
|
|
773
|
+
|
|
774
|
+
[The e-mail flows guide](docs/guide/email-flows.md#requests-in-two-steps)
|
|
775
|
+
has a route for each flow, with Hono.
|
|
776
|
+
|
|
777
|
+
### Signing in on your own proof — `signInProven`
|
|
778
|
+
|
|
779
|
+
```ts
|
|
780
|
+
// Accepting an invitation: the proof is the invitation token YOUR server issued and verified.
|
|
781
|
+
const invitation = await invitations.redeem(body.invitationToken); // yours: one use, expiring, hashed at rest
|
|
782
|
+
if (invitation === null) return new Response(null, { status: 404 });
|
|
783
|
+
|
|
784
|
+
const result = await auth.signInProven(invitation.userId, { device: deviceCookie ?? null });
|
|
785
|
+
if (result.status === 'secondFactor') return askForCode(result.challenge); // switch on status, as after signIn
|
|
786
|
+
// result: { status: 'signedIn', user, session, token, newDevice, deviceToken }
|
|
787
|
+
```
|
|
788
|
+
|
|
789
|
+
Signs in a user **the application proved by its own means** — an invitation
|
|
790
|
+
token it issued and the person followed, a channel of its own it verified —
|
|
791
|
+
with no password, code or link. Every user type has it.
|
|
792
|
+
|
|
793
|
+
- **Privileged: janus checks no credential, your server carries the
|
|
794
|
+
proof.** Call it only after that proof was verified, and **never with an
|
|
795
|
+
id a request supplied**: whoever chooses the id signs in as anybody. No
|
|
796
|
+
route of `@nxgt/janus-hono` or `@nxgt/janus-graphql` exposes it.
|
|
797
|
+
- **It finishes as every sign-in does**: an active second factor answers a
|
|
798
|
+
challenge for `secondFactor.confirm` (`SignInResult`, the same union as
|
|
799
|
+
`signIn`'s); `device` answers `newDevice` and `deviceToken` and sends
|
|
800
|
+
`user.newDeviceSignedIn` for a new one; an inactive user is
|
|
801
|
+
`USER_INACTIVE`.
|
|
802
|
+
- **Takes the user, or their id** (`UserRef`). A malformed id, an unknown
|
|
803
|
+
one, a deleted user or one of another type is `NOT_FOUND`, as for `get`:
|
|
804
|
+
a sign-in that found nobody throws rather than answer something to read
|
|
805
|
+
past.
|
|
806
|
+
- **Sends nothing, counts nothing, spends nothing**: no e-mail, no token,
|
|
807
|
+
no mail-throttle or sign-in-throttle count — so a loop of anonymous
|
|
808
|
+
`magicLink.request` on the invitee's address cannot make it answer 429 —
|
|
809
|
+
and links or codes already in the person's inbox still work. It proves
|
|
810
|
+
no e-mail either: `emailVerified` stays as it was, and nothing is dropped
|
|
811
|
+
as on a first proof by link.
|
|
812
|
+
|
|
813
|
+
[Sessions](docs/guide/sessions.md#signing-in-on-your-own-proof--signinproven)
|
|
814
|
+
has the invitation route in full, and what to verify before the call.
|
|
815
|
+
|
|
727
816
|
### Step-up — `stepUp` and `assertFresh`
|
|
728
817
|
|
|
729
818
|
```ts
|
|
@@ -1086,7 +1175,7 @@ runner-less layer.
|
|
|
1086
1175
|
## Traps
|
|
1087
1176
|
|
|
1088
1177
|
**Once `secondFactor` is configured, switch on `signIn`'s `status`** — and
|
|
1089
|
-
on `signInCode.confirm`'s
|
|
1178
|
+
on `signInCode.confirm`'s, `magicLink.confirm`'s and `signInProven`'s. A user whose factor is active gets
|
|
1090
1179
|
`{ status: 'secondFactor', challenge, expiresAt, userId }`, with no `token`
|
|
1091
1180
|
and no `session`: an e-mailed code or link proves the e-mail, not the factor.
|
|
1092
1181
|
`userId` is for your logs and rate limits — answer the visitor the
|
|
@@ -1126,6 +1215,16 @@ user — a new `request` spends the one before — so the throttle bounds how
|
|
|
1126
1215
|
often anyone who knows an address can fill its inbox or cancel its owner's
|
|
1127
1216
|
code; it does not stop it.
|
|
1128
1217
|
|
|
1218
|
+
**`signInProven` trusts the id you give it — give it only one your server
|
|
1219
|
+
proved.** It checks no credential: an id read off a request body, a query
|
|
1220
|
+
string or a cookie the client wrote signs in whoever sent it, as that user.
|
|
1221
|
+
Call it right after verifying a proof you issued — an invitation token
|
|
1222
|
+
(single use, expiring, stored hashed), a channel of your own — and take the
|
|
1223
|
+
id from that proof's record. For an invitation, it replaces
|
|
1224
|
+
`magicLink.request` + `confirm`, which counts against the mail throttle:
|
|
1225
|
+
five anonymous requests for the invitee's address would make the
|
|
1226
|
+
acceptance answer 429.
|
|
1227
|
+
|
|
1129
1228
|
**Confirm a sign-in link from a `POST`, never from its `GET`.** Mail
|
|
1130
1229
|
scanners open every link in an e-mail before the user does: a route that
|
|
1131
1230
|
calls `magicLink.confirm` on the link's `GET` spends it for the scanner, and
|
|
@@ -1263,6 +1362,17 @@ dummy hash when nobody holds the login, so the hashing time does not tell.
|
|
|
1263
1362
|
denied. `resetPassword.request` answers `null` for an unknown e-mail for the
|
|
1264
1363
|
same reason: answer the visitor the same page either way.
|
|
1265
1364
|
|
|
1365
|
+
**`request` sent off the visitor's request swallows `MAIL_THROTTLED`.** A
|
|
1366
|
+
`request` for an address with an account looks it up and writes tokens; one
|
|
1367
|
+
for an address nobody holds stops at the lookup — so an application that
|
|
1368
|
+
must not tell the two apart by time runs `request` in the background, where
|
|
1369
|
+
its refusal reaches nobody. Call `prepare(email)` in the visitor's request
|
|
1370
|
+
instead — counted, nobody looked up, the same time for any address — and
|
|
1371
|
+
answer its `MAIL_THROTTLED`; run `send()` in the background. **Never await
|
|
1372
|
+
`send()` in the visitor's request**: its time is `request`'s. And it runs
|
|
1373
|
+
once — a second `send()`, or one after a failed one, is a `TypeError`:
|
|
1374
|
+
`prepare` again.
|
|
1375
|
+
|
|
1266
1376
|
**`resetPassword.confirm` signs the user out everywhere, and opens no session.**
|
|
1267
1377
|
Whoever had the old password loses their sessions, and a sign-in they left
|
|
1268
1378
|
waiting on its second factor is spent with them — as it is by `setPassword`
|
|
@@ -1407,7 +1517,7 @@ that sends one, since it is awaited: queue the event and return.
|
|
|
1407
1517
|
|
|
1408
1518
|
## Type safety, counted
|
|
1409
1519
|
|
|
1410
|
-
**One hundred and
|
|
1520
|
+
**One hundred and sixty-three plausible mistakes, one hundred and sixty-three refused at compile time — and
|
|
1411
1521
|
two gaps, named.**
|
|
1412
1522
|
|
|
1413
1523
|
The lists are typechecked and never run, with one `@ts-expect-error` per
|
|
@@ -1415,10 +1525,10 @@ mistake beside the shapes that must keep compiling. One is a single file:
|
|
|
1415
1525
|
`test/types/refusals.ts` (fifteen, on the shared vocabulary). The other three
|
|
1416
1526
|
are folders with one file per behaviour: `test/types/port/` (twenty-five, on
|
|
1417
1527
|
the identity stores' port, from the point of view of the person implementing
|
|
1418
|
-
it), `test/types/auth/` (
|
|
1528
|
+
it), `test/types/auth/` (seventy-five, on `janus()`, from the point of view of
|
|
1419
1529
|
the application — twelve of them on the second factor, three on sign-in codes,
|
|
1420
1530
|
five on user events, four on step-ups, six on the sign-in throttle, five on the mail throttle, four on
|
|
1421
|
-
sign-in links, six on devices, two on `findMany
|
|
1531
|
+
sign-in links, six on devices, two on `findMany`, five on requests in two steps, three on signing in on the application's proof) and `test/types/permissions/` (forty-eight, on the
|
|
1422
1532
|
permission model and the questions asked of it). The rule comes from
|
|
1423
1533
|
`nxgt-data`, and so does the reason to distrust the claim without the files:
|
|
1424
1534
|
when it was last measured on `@nxgt/mongo`, *seven of twelve plausible
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reset-password.d.ts","sourceRoot":"","sources":["../../../src/auth/email-flows/reset-password.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EACN,KAAK,OAAO,EACZ,KAAK,OAAO,EAOZ,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"reset-password.d.ts","sourceRoot":"","sources":["../../../src/auth/email-flows/reset-password.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EACN,KAAK,OAAO,EACZ,KAAK,OAAO,EAOZ,MAAM,YAAY,CAAC;AAOpB,OAAO,KAAK,EAAgC,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAG/E,KAAK,aAAa,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC,eAAe,CAAC,CAAC;AAGhE;;;GAGG;AACH,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,YAAY,EAClB,EAAE,EAAE,EAAE,GACJ,aAAa,CAsBf"}
|
package/dist/auth/events.d.ts
CHANGED
|
@@ -30,9 +30,9 @@ import type { Context } from './context';
|
|
|
30
30
|
* spent: a sign-in without the user's phone;
|
|
31
31
|
* - `user.newDeviceSignedIn` — by a sign-in that opened a session from a
|
|
32
32
|
* device the user had not signed in from: `signIn`, `secondFactor.confirm`,
|
|
33
|
-
* `secondFactor.recover`, `signInCode.confirm
|
|
34
|
-
* given a `device` its token did not prove. Never by
|
|
35
|
-
* a `device`. Carries `sessionId`;
|
|
33
|
+
* `secondFactor.recover`, `signInCode.confirm`, `magicLink.confirm` and
|
|
34
|
+
* `signInProven`, when given a `device` its token did not prove. Never by
|
|
35
|
+
* `signUp`, nor without a `device`. Carries `sessionId`;
|
|
36
36
|
* - `user.deleted` — by `delete`, once; a replay that finds nobody is none.
|
|
37
37
|
*/
|
|
38
38
|
export type UserEventType = 'user.created' | 'user.emailVerified' | 'user.passwordReset' | 'user.passwordChanged' | 'user.emailChanged' | 'user.secondFactorEnabled' | 'user.secondFactorDisabled' | 'user.recoveryCodesRegenerated' | 'user.recoveryCodeUsed' | 'user.newDeviceSignedIn' | 'user.deleted';
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -8,5 +8,5 @@ export type { JanusStores, Json, JsonObject, PasswordRecord, SecondFactorRecord,
|
|
|
8
8
|
export type { SealingKey } from './sealing';
|
|
9
9
|
export { assertFresh } from './sessions/fresh';
|
|
10
10
|
export type { StandardSchemaV1 } from './standard-schema';
|
|
11
|
-
export type { Authenticated, Checked, EmailOf, HeaderRecord, IssuedCode, IssuedToken, Janus, LoginOf, MagicLinkApi, PasswordApi, RecoveredSignIn, RecoveryCodesIssued, RequestLike, RequiredStringKeys, ResetPasswordApi, SecondFactorApi, SecondFactorEnrolment, SecondFactorRequired, Session, SharedApi, SignedIn, SignInCodeApi, SignInOptions, SignInResult, StepUpApi, StepUpByApp, StepUpByEmail, TypeApi, TypesOf, User, UserBase, UserOf, UserRef, UserTypeApi, VerifyEmailApi, WriteOptions, } from './types';
|
|
11
|
+
export type { Authenticated, Checked, EmailOf, HeaderRecord, IssuedCode, IssuedToken, Janus, LoginOf, MagicLinkApi, PasswordApi, PreparedCode, PreparedRequest, ProvenSignInApi, RecoveredSignIn, RecoveryCodesIssued, RequestLike, RequiredStringKeys, ResetPasswordApi, SecondFactorApi, SecondFactorEnrolment, SecondFactorRequired, Session, SharedApi, SignedIn, SignInCodeApi, SignInOptions, SignInResult, StepUpApi, StepUpByApp, StepUpByEmail, TypeApi, TypesOf, User, UserBase, UserOf, UserRef, UserTypeApi, VerifyEmailApi, WriteOptions, } from './types';
|
|
12
12
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/auth/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,YAAY,EACZ,aAAa,EACb,UAAU,EACV,WAAW,EACX,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,SAAS,EACT,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,cAAc,GACd,MAAM,UAAU,CAAC;AAClB,YAAY,EACX,SAAS,EACT,iBAAiB,EACjB,aAAa,GACb,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,YAAY,EACX,WAAW,EACX,IAAI,EACJ,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,SAAS,EACT,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,SAAS,EACT,WAAW,EACX,UAAU,EACV,eAAe,EACf,SAAS,EACT,UAAU,EACV,SAAS,GACT,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,YAAY,EACX,aAAa,EACb,OAAO,EACP,OAAO,EACP,YAAY,EACZ,UAAU,EACV,WAAW,EACX,KAAK,EACL,OAAO,EACP,YAAY,EACZ,WAAW,EACX,eAAe,EACf,mBAAmB,EACnB,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,oBAAoB,EACpB,OAAO,EACP,SAAS,EACT,QAAQ,EACR,aAAa,EACb,aAAa,EACb,YAAY,EACZ,SAAS,EACT,WAAW,EACX,aAAa,EACb,OAAO,EACP,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,OAAO,EACP,WAAW,EACX,cAAc,EACd,YAAY,GACZ,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,YAAY,EACZ,aAAa,EACb,UAAU,EACV,WAAW,EACX,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,SAAS,EACT,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,cAAc,GACd,MAAM,UAAU,CAAC;AAClB,YAAY,EACX,SAAS,EACT,iBAAiB,EACjB,aAAa,GACb,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,YAAY,EACX,WAAW,EACX,IAAI,EACJ,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,SAAS,EACT,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,SAAS,EACT,WAAW,EACX,UAAU,EACV,eAAe,EACf,SAAS,EACT,UAAU,EACV,SAAS,GACT,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,YAAY,EACX,aAAa,EACb,OAAO,EACP,OAAO,EACP,YAAY,EACZ,UAAU,EACV,WAAW,EACX,KAAK,EACL,OAAO,EACP,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,eAAe,EACf,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,oBAAoB,EACpB,OAAO,EACP,SAAS,EACT,QAAQ,EACR,aAAa,EACb,aAAa,EACb,YAAY,EACZ,SAAS,EACT,WAAW,EACX,aAAa,EACb,OAAO,EACP,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,OAAO,EACP,WAAW,EACX,cAAc,EACd,YAAY,GACZ,MAAM,SAAS,CAAC"}
|
|
@@ -17,6 +17,9 @@ import type { MagicLinkApi, SignInResult } from './types';
|
|
|
17
17
|
* Whoever opens the link signs in, in the browser that opened it: the
|
|
18
18
|
* application confirms it from a `POST`, never from the `GET` of the link,
|
|
19
19
|
* which a mail scanner follows too.
|
|
20
|
+
*
|
|
21
|
+
* `request` is `prepare`, then `send`: counted, then looked up and issued
|
|
22
|
+
* (`prepared.ts`).
|
|
20
23
|
*/
|
|
21
24
|
export declare function magicLinkFlows(context: Context, type: ResolvedType, at: At, finish: Finish): MagicLinkApi<AnyUser, SignInResult<AnyUser>>['magicLink'];
|
|
22
25
|
//# sourceMappingURL=magic-link.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"magic-link.d.ts","sourceRoot":"","sources":["../../src/auth/magic-link.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,WAAW,CAAC;AAG/D,OAAO,EACN,KAAK,MAAM,EAIX,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"magic-link.d.ts","sourceRoot":"","sources":["../../src/auth/magic-link.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,WAAW,CAAC;AAG/D,OAAO,EACN,KAAK,MAAM,EAIX,MAAM,iBAAiB,CAAC;AAIzB,OAAO,KAAK,EAEX,YAAY,EAEZ,YAAY,EACZ,MAAM,SAAS,CAAC;AAIjB;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAC7B,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,YAAY,EAClB,EAAE,EAAE,EAAE,EACN,MAAM,EAAE,MAAM,GACZ,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAkB3D"}
|
|
@@ -9,6 +9,12 @@ interface OneTimeRequest {
|
|
|
9
9
|
readonly userId: string;
|
|
10
10
|
readonly address: string;
|
|
11
11
|
readonly ttlMs: number;
|
|
12
|
+
/**
|
|
13
|
+
* The secret to issue under, minted beforehand — a sign-in code's
|
|
14
|
+
* challenge, handed to the visitor by `prepare` before the lookup. A
|
|
15
|
+
* fresh one by default.
|
|
16
|
+
*/
|
|
17
|
+
readonly secret?: string;
|
|
12
18
|
}
|
|
13
19
|
/**
|
|
14
20
|
* Issues a one-time token: 32 random bytes, given back once, and only their
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issue.d.ts","sourceRoot":"","sources":["../../../src/auth/one-time/issue.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAI/C,UAAU,cAAc;IACvB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"issue.d.ts","sourceRoot":"","sources":["../../../src/auth/one-time/issue.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAI/C,UAAU,cAAc;IACvB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAsB,YAAY,CACjC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,cAAc,GACnB,OAAO,CAAC;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAA;CAAE,CAAC,CAEhE;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAC9B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,cAAc,GACnB,OAAO,CAAC;IACV,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB,CAAC,CAGD"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A request for an e-mail made in two steps — `prepare` counts it, `send`
|
|
3
|
+
* issues — so the mail throttle answers in the visitor's own request, while
|
|
4
|
+
* the lookup and the writes, whose time depends on whether the address has
|
|
5
|
+
* an account, run off it.
|
|
6
|
+
*
|
|
7
|
+
* `prepare` looks nobody up: it validates, counts the address
|
|
8
|
+
* (`mail-requests.ts`) and refuses past the limit, the same store calls for
|
|
9
|
+
* any address. `send` is what `request` does after the count, **once**: the
|
|
10
|
+
* count `prepare` made pays for one issue, so a second call is a `TypeError`
|
|
11
|
+
* — a bug of the caller's, never a value from a request — and nothing a
|
|
12
|
+
* caller can pass skips the count.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* `send` for a prepared request: `issue` on the first call, a `TypeError`
|
|
16
|
+
* on every other — marked spent before `issue` starts, so two calls at once
|
|
17
|
+
* cannot both issue, and spent even when `issue` fails: prepare again then,
|
|
18
|
+
* which counts again.
|
|
19
|
+
*/
|
|
20
|
+
export declare function sendOnce<T>(where: string, issue: () => Promise<T>): () => Promise<T>;
|
|
21
|
+
//# sourceMappingURL=prepared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prepared.d.ts","sourceRoot":"","sources":["../../src/auth/prepared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EACzB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACrB,MAAM,OAAO,CAAC,CAAC,CAAC,CAWlB"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Signing in a user the application proved by its own means — an
|
|
3
|
+
* invitation token it issued, a channel of its own: no credential checked
|
|
4
|
+
* here, so nothing to count, nothing to send and nothing to spend.
|
|
5
|
+
*/
|
|
6
|
+
import type { At } from './at';
|
|
7
|
+
import type { ResolvedType } from './config';
|
|
8
|
+
import { type AnyUser, type Context } from './context';
|
|
9
|
+
import type { Finish } from './email-sign-in';
|
|
10
|
+
import type { ProvenSignInApi, SignInResult } from './types';
|
|
11
|
+
/**
|
|
12
|
+
* `signInProven` for one user type: the user read by id — `NOT_FOUND` for
|
|
13
|
+
* nobody, as `get` — refused when inactive, then finished as every sign-in
|
|
14
|
+
* is, by `secondFactor.finish`: a session, or a challenge for an active
|
|
15
|
+
* factor.
|
|
16
|
+
*
|
|
17
|
+
* No throttle is counted and no count restarted, no token issued or spent,
|
|
18
|
+
* no e-mail proved: the proof is the application's, and links and codes
|
|
19
|
+
* already sent keep working.
|
|
20
|
+
*/
|
|
21
|
+
export declare function provenSignInFlows(context: Context, type: ResolvedType, at: At, finish: Finish): ProvenSignInApi<AnyUser, SignInResult<AnyUser>>;
|
|
22
|
+
//# sourceMappingURL=proven-sign-in.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proven-sign-in.d.ts","sourceRoot":"","sources":["../../src/auth/proven-sign-in.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,OAAO,EAAa,MAAM,WAAW,CAAC;AAElE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAW,MAAM,SAAS,CAAC;AAEtE;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,YAAY,EAClB,EAAE,EAAE,EAAE,EACN,MAAM,EAAE,MAAM,GACZ,eAAe,CAAC,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAiBjD"}
|
|
@@ -17,6 +17,10 @@ import type { SignInCodeApi, SignInResult } from './types';
|
|
|
17
17
|
* address (`mail-requests.ts`), and the application rate-limits it per
|
|
18
18
|
* client. The code's hash is keyed by the challenge, so the
|
|
19
19
|
* tokens alone do not reveal it.
|
|
20
|
+
*
|
|
21
|
+
* `request` is `prepare`, then `send` (`prepared.ts`): counted, the
|
|
22
|
+
* challenge minted — before anybody is looked up, so the visitor gets one
|
|
23
|
+
* whoever holds the address — then looked up and issued under it.
|
|
20
24
|
*/
|
|
21
25
|
export declare function signInCodeFlows(context: Context, type: ResolvedType, at: At, finish: Finish): SignInCodeApi<AnyUser, SignInResult<AnyUser>>['signInCode'];
|
|
22
26
|
//# sourceMappingURL=sign-in-code.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sign-in-code.d.ts","sourceRoot":"","sources":["../../src/auth/sign-in-code.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,OAAO,EAAsB,MAAM,WAAW,CAAC;AAE3E,OAAO,EACN,KAAK,MAAM,EAIX,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"sign-in-code.d.ts","sourceRoot":"","sources":["../../src/auth/sign-in-code.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,OAAO,EAAsB,MAAM,WAAW,CAAC;AAE3E,OAAO,EACN,KAAK,MAAM,EAIX,MAAM,iBAAiB,CAAC;AAczB,OAAO,KAAK,EAGX,aAAa,EAEb,YAAY,EACZ,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAC9B,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,YAAY,EAClB,EAAE,EAAE,EAAE,EACN,MAAM,EAAE,MAAM,GACZ,aAAa,CAAC,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAsB7D"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Part of what `janus()` hands back; `./index` gathers it.
|
|
6
6
|
*/
|
|
7
|
+
import type { PreparedCode, PreparedRequest } from './prepared';
|
|
7
8
|
import type { SignedIn, SignInOptions } from './sign-in';
|
|
8
9
|
import type { UserRef } from './user';
|
|
9
10
|
/** A one-time token, given to the application once, to send by e-mail. */
|
|
@@ -51,6 +52,14 @@ export interface SignInCodeApi<U, Answer = SignedIn<U>> {
|
|
|
51
52
|
* `retryAfter`, and no code. Rate-limit it per client too.
|
|
52
53
|
*/
|
|
53
54
|
request(email: string): Promise<IssuedCode<U> | null>;
|
|
55
|
+
/**
|
|
56
|
+
* `request` in two steps, for an application that sends the code off
|
|
57
|
+
* the visitor's request: counts the address — `MAIL_THROTTLED` with
|
|
58
|
+
* `retryAfter` past the limit — looks nobody up, and mints the
|
|
59
|
+
* `challenge` to give the visitor now, whoever holds the address.
|
|
60
|
+
* `send()` on the answer does the rest, once.
|
|
61
|
+
*/
|
|
62
|
+
prepare(email: string): Promise<PreparedCode<U>>;
|
|
54
63
|
/**
|
|
55
64
|
* Checks the code against its challenge, marks the e-mail verified —
|
|
56
65
|
* the code reached the inbox — and signs the user in. **An e-mail
|
|
@@ -99,6 +108,15 @@ export interface ResetPasswordApi<U> {
|
|
|
99
108
|
request(email: string): Promise<(IssuedToken & {
|
|
100
109
|
readonly user: U;
|
|
101
110
|
}) | null>;
|
|
111
|
+
/**
|
|
112
|
+
* `request` in two steps, for an application that sends the link off
|
|
113
|
+
* the visitor's request: counts the address — `MAIL_THROTTLED` with
|
|
114
|
+
* `retryAfter` past the limit — and looks nobody up. `send()` on the
|
|
115
|
+
* answer does the rest, once.
|
|
116
|
+
*/
|
|
117
|
+
prepare(email: string): Promise<PreparedRequest<IssuedToken & {
|
|
118
|
+
readonly user: U;
|
|
119
|
+
}>>;
|
|
102
120
|
/**
|
|
103
121
|
* Redeems the token, sets the password, marks the e-mail verified — the
|
|
104
122
|
* link proved it — and **signs the user out everywhere**. Every other
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"email-flows.d.ts","sourceRoot":"","sources":["../../../src/auth/types/email-flows.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAgB,MAAM,WAAW,CAAC;AACvE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,0EAA0E;AAC1E,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,iCAAiC;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;CACzB;AAED,oFAAoF;AACpF,MAAM,WAAW,UAAU,CAAC,CAAC;IAC5B,mFAAmF;IACnF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,uCAAuC;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;CACjB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC;IACrD,QAAQ,CAAC,UAAU,EAAE;QACpB;;;;;;;;;;;;WAYG;QACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACtD;;;;;;;;;;;;WAYG;QACH,OAAO,CACN,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,CAAC,CAAC;KACnB,CAAC;CACF;AAED,uDAAuD;AACvD,MAAM,WAAW,cAAc,CAAC,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE;QACrB;;;;;WAKG;QACH,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;QAC1C;;;WAGG;QACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;KACnC,CAAC;CACF;AAED,sEAAsE;AACtE,MAAM,WAAW,gBAAgB,CAAC,CAAC;IAClC,QAAQ,CAAC,aAAa,EAAE;QACvB;;;;;;;;WAQG;QACH,OAAO,CACN,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,CAAC,WAAW,GAAG;YAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;SAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QACxD;;;;;;WAMG;QACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;KACrD,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"email-flows.d.ts","sourceRoot":"","sources":["../../../src/auth/types/email-flows.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAgB,MAAM,WAAW,CAAC;AACvE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,0EAA0E;AAC1E,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,iCAAiC;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;CACzB;AAED,oFAAoF;AACpF,MAAM,WAAW,UAAU,CAAC,CAAC;IAC5B,mFAAmF;IACnF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,uCAAuC;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;CACjB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC;IACrD,QAAQ,CAAC,UAAU,EAAE;QACpB;;;;;;;;;;;;WAYG;QACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACtD;;;;;;WAMG;QACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QACjD;;;;;;;;;;;;WAYG;QACH,OAAO,CACN,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,CAAC,CAAC;KACnB,CAAC;CACF;AAED,uDAAuD;AACvD,MAAM,WAAW,cAAc,CAAC,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE;QACrB;;;;;WAKG;QACH,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;QAC1C;;;WAGG;QACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;KACnC,CAAC;CACF;AAED,sEAAsE;AACtE,MAAM,WAAW,gBAAgB,CAAC,CAAC;IAClC,QAAQ,CAAC,aAAa,EAAE;QACvB;;;;;;;;WAQG;QACH,OAAO,CACN,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,CAAC,WAAW,GAAG;YAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;SAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QACxD;;;;;WAKG;QACH,OAAO,CACN,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,eAAe,CAAC,WAAW,GAAG;YAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;SAAE,CAAC,CAAC,CAAC;QAChE;;;;;;WAMG;QACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;KACrD,CAAC;CACF"}
|
|
@@ -13,6 +13,8 @@ export type { EmailOf, LoginOf, RequiredStringKeys, TypesOf, UserOf, } from './i
|
|
|
13
13
|
export type { Janus, SharedApi, TypeApi } from './janus';
|
|
14
14
|
export type { MagicLinkApi } from './magic-link';
|
|
15
15
|
export type { PasswordApi } from './password';
|
|
16
|
+
export type { PreparedCode, PreparedRequest } from './prepared';
|
|
17
|
+
export type { ProvenSignInApi } from './proven-sign-in';
|
|
16
18
|
export type { RecoveredSignIn, RecoveryCodesIssued, SecondFactorApi, SecondFactorEnrolment, } from './second-factor';
|
|
17
19
|
export type { Authenticated, HeaderRecord, RequestLike, Session, } from './session';
|
|
18
20
|
export type { SecondFactorRequired, SignedIn, SignInOptions, SignInResult, } from './sign-in';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/types/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,YAAY,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACxC,YAAY,EACX,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,cAAc,GACd,MAAM,eAAe,CAAC;AACvB,YAAY,EACX,OAAO,EACP,OAAO,EACP,kBAAkB,EAClB,OAAO,EACP,MAAM,GACN,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACzD,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,YAAY,EACX,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,qBAAqB,GACrB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACX,aAAa,EACb,YAAY,EACZ,WAAW,EACX,OAAO,GACP,MAAM,WAAW,CAAC;AACnB,YAAY,EACX,oBAAoB,EACpB,QAAQ,EACR,aAAa,EACb,YAAY,GACZ,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACvE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACpE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/types/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,YAAY,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACxC,YAAY,EACX,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,cAAc,GACd,MAAM,eAAe,CAAC;AACvB,YAAY,EACX,OAAO,EACP,OAAO,EACP,kBAAkB,EAClB,OAAO,EACP,MAAM,GACN,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACzD,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAChE,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,YAAY,EACX,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,qBAAqB,GACrB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACX,aAAa,EACb,YAAY,EACZ,WAAW,EACX,OAAO,GACP,MAAM,WAAW,CAAC;AACnB,YAAY,EACX,oBAAoB,EACpB,QAAQ,EACR,aAAa,EACb,YAAY,GACZ,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACvE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACpE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -9,6 +9,7 @@ import type { ResetPasswordApi, SignInCodeApi, VerifyEmailApi } from './email-fl
|
|
|
9
9
|
import type { EmailOf, FieldsInput, LoginOf, SingleAsType, UserOf, UserOfType } from './inference';
|
|
10
10
|
import type { MagicLinkApi } from './magic-link';
|
|
11
11
|
import type { PasswordApi } from './password';
|
|
12
|
+
import type { ProvenSignInApi } from './proven-sign-in';
|
|
12
13
|
import type { SecondFactorApi } from './second-factor';
|
|
13
14
|
import type { Authenticated, RequestLike, Session } from './session';
|
|
14
15
|
import type { SignedIn, SignInResult } from './sign-in';
|
|
@@ -16,16 +17,17 @@ import type { StepUpApi, StepUpByApp, StepUpByEmail } from './step-up';
|
|
|
16
17
|
import type { UserRef } from './user';
|
|
17
18
|
import type { UserTypeApi } from './user-type';
|
|
18
19
|
/**
|
|
19
|
-
* What a sign-in
|
|
20
|
-
*
|
|
21
|
-
*
|
|
20
|
+
* What a sign-in other than the password's answers — a code, a link, or
|
|
21
|
+
* the application's own proof: a session, or a challenge when the type has
|
|
22
|
+
* a password in an instance given a `secondFactor`, since none of them
|
|
23
|
+
* proves the factor.
|
|
22
24
|
*/
|
|
23
|
-
type
|
|
25
|
+
type SignInAnswer<Name extends string, Def, TwoFactor extends boolean> = TwoFactor extends true ? [LoginOf<Def>] extends [never] ? SignedIn<UserOfType<Name, Def>> : SignInResult<UserOfType<Name, Def>> : SignedIn<UserOfType<Name, Def>>;
|
|
24
26
|
/**
|
|
25
27
|
* The whole surface of one user type, with only the flows its configuration
|
|
26
28
|
* allows. `TwoFactor` is whether `janus()` was given a `secondFactor`.
|
|
27
29
|
*/
|
|
28
|
-
export type TypeApi<Name extends string, Def, TwoFactor extends boolean = false> = UserTypeApi<UserOfType<Name, Def>, FieldsInput<Def>> & ([LoginOf<Def>] extends [never] ? unknown : TwoFactor extends true ? PasswordApi<UserOfType<Name, Def>, FieldsInput<Def>, LoginOf<Def>, SignInResult<UserOfType<Name, Def>>> & SecondFactorApi<UserOfType<Name, Def>> : PasswordApi<UserOfType<Name, Def>, FieldsInput<Def>, LoginOf<Def>>) & ([EmailOf<Def>] extends [never] ? unknown : VerifyEmailApi<UserOfType<Name, Def>> & SignInCodeApi<UserOfType<Name, Def>,
|
|
30
|
+
export type TypeApi<Name extends string, Def, TwoFactor extends boolean = false> = UserTypeApi<UserOfType<Name, Def>, FieldsInput<Def>> & ProvenSignInApi<UserOfType<Name, Def>, SignInAnswer<Name, Def, TwoFactor>> & ([LoginOf<Def>] extends [never] ? unknown : TwoFactor extends true ? PasswordApi<UserOfType<Name, Def>, FieldsInput<Def>, LoginOf<Def>, SignInResult<UserOfType<Name, Def>>> & SecondFactorApi<UserOfType<Name, Def>> : PasswordApi<UserOfType<Name, Def>, FieldsInput<Def>, LoginOf<Def>>) & ([EmailOf<Def>] extends [never] ? unknown : VerifyEmailApi<UserOfType<Name, Def>> & SignInCodeApi<UserOfType<Name, Def>, SignInAnswer<Name, Def, TwoFactor>> & MagicLinkApi<UserOfType<Name, Def>, SignInAnswer<Name, Def, TwoFactor>> & StepUpApi<UserOfType<Name, Def>, TwoFactor extends true ? [LoginOf<Def>] extends [never] ? StepUpByEmail<UserOfType<Name, Def>> : StepUpByEmail<UserOfType<Name, Def>> | StepUpByApp<UserOfType<Name, Def>> : StepUpByEmail<UserOfType<Name, Def>>>) & ([LoginOf<Def>] extends [never] ? unknown : [EmailOf<Def>] extends [never] ? unknown : ResetPasswordApi<UserOfType<Name, Def>>);
|
|
29
31
|
/** What every configuration answers, whatever its user types. */
|
|
30
32
|
export interface SharedApi<U extends {
|
|
31
33
|
readonly type: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"janus.d.ts","sourceRoot":"","sources":["../../../src/auth/types/janus.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAChF,OAAO,KAAK,EACX,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EACX,OAAO,EACP,WAAW,EACX,OAAO,EACP,YAAY,EACZ,MAAM,EACN,UAAU,EACV,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C
|
|
1
|
+
{"version":3,"file":"janus.d.ts","sourceRoot":"","sources":["../../../src/auth/types/janus.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Part of what `janus()` hands back; `./index` gathers it.
|
|
6
6
|
*/
|
|
7
7
|
import type { IssuedToken } from './email-flows';
|
|
8
|
+
import type { PreparedRequest } from './prepared';
|
|
8
9
|
import type { SignedIn, SignInOptions } from './sign-in';
|
|
9
10
|
/**
|
|
10
11
|
* Signing in with a link sent to the user's e-mail, no password needed —
|
|
@@ -31,6 +32,16 @@ export interface MagicLinkApi<U, Answer = SignedIn<U>> {
|
|
|
31
32
|
request(email: string): Promise<(IssuedToken & {
|
|
32
33
|
readonly user: U;
|
|
33
34
|
}) | null>;
|
|
35
|
+
/**
|
|
36
|
+
* `request` in two steps, for an application that sends the link off
|
|
37
|
+
* the visitor's request: counts the address — `MAIL_THROTTLED` with
|
|
38
|
+
* `retryAfter` past the limit, to show the visitor now — and looks
|
|
39
|
+
* nobody up, so it takes the same time for any address. `send()` on
|
|
40
|
+
* the answer does the rest, once, and answers what `request` does.
|
|
41
|
+
*/
|
|
42
|
+
prepare(email: string): Promise<PreparedRequest<IssuedToken & {
|
|
43
|
+
readonly user: U;
|
|
44
|
+
}>>;
|
|
34
45
|
/**
|
|
35
46
|
* Spends the link's token, marks the e-mail verified — the link reached
|
|
36
47
|
* the inbox — and signs the user in. **An e-mail proved for the first
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"magic-link.d.ts","sourceRoot":"","sources":["../../../src/auth/types/magic-link.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAEzD;;;;;;GAMG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC;IACpD,QAAQ,CAAC,SAAS,EAAE;QACnB;;;;;;;;;;;;WAYG;QACH,OAAO,CACN,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,CAAC,WAAW,GAAG;YAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;SAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QACxD;;;;;;;;;;;;;;WAcG;QACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;KACjE,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"magic-link.d.ts","sourceRoot":"","sources":["../../../src/auth/types/magic-link.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAEzD;;;;;;GAMG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC;IACpD,QAAQ,CAAC,SAAS,EAAE;QACnB;;;;;;;;;;;;WAYG;QACH,OAAO,CACN,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,CAAC,WAAW,GAAG;YAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;SAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QACxD;;;;;;WAMG;QACH,OAAO,CACN,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,eAAe,CAAC,WAAW,GAAG;YAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;SAAE,CAAC,CAAC,CAAC;QAChE;;;;;;;;;;;;;;WAcG;QACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;KACjE,CAAC;CACF"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What `prepare` answers — `magicLink.prepare`, `signInCode.prepare`,
|
|
3
|
+
* `resetPassword.prepare`: a request for an e-mail, counted, not yet looked
|
|
4
|
+
* up.
|
|
5
|
+
*
|
|
6
|
+
* Part of what `janus()` hands back; `./index` gathers it.
|
|
7
|
+
*/
|
|
8
|
+
import type { IssuedCode } from './email-flows';
|
|
9
|
+
/**
|
|
10
|
+
* A request counted by the mail throttle and not yet looked up: `send()`
|
|
11
|
+
* does the rest of what `request` does — looks the address up, issues, and
|
|
12
|
+
* spends the earlier tokens — and answers what `request` answers, `null`
|
|
13
|
+
* for an address nobody (active) holds.
|
|
14
|
+
*
|
|
15
|
+
* **`send()` runs once.** A second call is a `TypeError`, and so is a call
|
|
16
|
+
* after a first one failed: `prepare` again, which counts again.
|
|
17
|
+
*/
|
|
18
|
+
export interface PreparedRequest<Issued> {
|
|
19
|
+
/**
|
|
20
|
+
* Looks the address up and issues, without counting again — the count
|
|
21
|
+
* was `prepare`'s. Send it off the visitor's request: its time tells
|
|
22
|
+
* whether the address has an account.
|
|
23
|
+
*/
|
|
24
|
+
send(): Promise<Issued | null>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* A sign-in code's prepared request: the `challenge` is minted before
|
|
28
|
+
* anybody is looked up, so it goes to the visitor now, whoever holds the
|
|
29
|
+
* address — and replaces the decoy an unknown address needs. For an address
|
|
30
|
+
* nobody holds, `send()` answers `null` and the challenge is
|
|
31
|
+
* `TOKEN_UNKNOWN`; otherwise it is the `challenge` of what `send()` issues.
|
|
32
|
+
*/
|
|
33
|
+
export interface PreparedCode<U> extends PreparedRequest<IssuedCode<U>> {
|
|
34
|
+
/**
|
|
35
|
+
* The secret the code will be checked against. **Keep it with the
|
|
36
|
+
* visitor** — a short-lived cookie, or the code form's body — never in
|
|
37
|
+
* the e-mail, a URL or a log.
|
|
38
|
+
*/
|
|
39
|
+
readonly challenge: string;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=prepared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prepared.d.ts","sourceRoot":"","sources":["../../../src/auth/types/prepared.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe,CAAC,MAAM;IACtC;;;;OAIG;IACH,IAAI,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC,CAAE,SAAQ,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IACtE;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC3B"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What every user type answers besides: signing in a user the application
|
|
3
|
+
* proved by its own means, with no credential janus checks.
|
|
4
|
+
*
|
|
5
|
+
* Part of what `janus()` hands back; `./index` gathers it.
|
|
6
|
+
*/
|
|
7
|
+
import type { SignedIn, SignInOptions } from './sign-in';
|
|
8
|
+
import type { UserRef } from './user';
|
|
9
|
+
/**
|
|
10
|
+
* Signing in a user **the application has already proved** — by an
|
|
11
|
+
* invitation token it issued and the person followed, or a channel of its
|
|
12
|
+
* own it verified — without a password, a code or a link.
|
|
13
|
+
*
|
|
14
|
+
* `Answer` is `SignInResult` when the type may have a second factor: the
|
|
15
|
+
* application's proof is a first factor, and an active factor is still asked
|
|
16
|
+
* for.
|
|
17
|
+
*/
|
|
18
|
+
export interface ProvenSignInApi<U, Answer = SignedIn<U>> {
|
|
19
|
+
/**
|
|
20
|
+
* Signs in the user of this type with this id, and answers what every
|
|
21
|
+
* other sign-in answers: a session, or a second-factor challenge when
|
|
22
|
+
* their factor is active — switch on `status`.
|
|
23
|
+
*
|
|
24
|
+
* **Privileged: janus checks no credential here, the application carries
|
|
25
|
+
* the proof.** Call it only after your server verified one — an
|
|
26
|
+
* invitation token it issued, a channel of its own — and never with an
|
|
27
|
+
* id a request supplied: whoever can choose the id signs in as anybody.
|
|
28
|
+
*
|
|
29
|
+
* Sends no e-mail, issues no token, counts nothing in the mail or the
|
|
30
|
+
* sign-in throttle, and **spends nothing**: links and codes already sent
|
|
31
|
+
* still work. Proves no e-mail either: `emailVerified` stays as it was.
|
|
32
|
+
*
|
|
33
|
+
* An inactive user is `USER_INACTIVE`, as for every sign-in. A malformed
|
|
34
|
+
* id, an unknown one or one of another type is `NOT_FOUND`, as for `get`:
|
|
35
|
+
* a sign-in that found nobody is never an answer to read past.
|
|
36
|
+
*
|
|
37
|
+
* Given a `device`, answers `newDevice` and `deviceToken`, and sends
|
|
38
|
+
* `user.newDeviceSignedIn` for a device new to the user. A challenge
|
|
39
|
+
* carries no device: give it again to `secondFactor.confirm`.
|
|
40
|
+
*/
|
|
41
|
+
signInProven(user: UserRef, options?: SignInOptions): Promise<Answer>;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=proven-sign-in.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proven-sign-in.d.ts","sourceRoot":"","sources":["../../../src/auth/types/proven-sign-in.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC;IACvD;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACtE"}
|
|
@@ -33,8 +33,8 @@ export interface SignedIn<U> {
|
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
35
|
* What a sign-in takes besides its credentials: `signUp`, `signIn`,
|
|
36
|
-
* `secondFactor.confirm`, `secondFactor.recover`, `signInCode.confirm
|
|
37
|
-
* `magicLink.confirm`.
|
|
36
|
+
* `secondFactor.confirm`, `secondFactor.recover`, `signInCode.confirm`,
|
|
37
|
+
* `magicLink.confirm` and `signInProven`.
|
|
38
38
|
*/
|
|
39
39
|
export interface SignInOptions {
|
|
40
40
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AnyUser } from '../context';
|
|
2
|
-
import type { MagicLinkApi, PasswordApi, ResetPasswordApi, SecondFactorApi, SignInCodeApi, SignInResult, StepUpApi, StepUpByApp, StepUpByEmail, UserTypeApi, VerifyEmailApi } from '../types';
|
|
2
|
+
import type { MagicLinkApi, PasswordApi, ProvenSignInApi, ResetPasswordApi, SecondFactorApi, SignInCodeApi, SignInResult, StepUpApi, StepUpByApp, StepUpByEmail, UserTypeApi, VerifyEmailApi } from '../types';
|
|
3
3
|
import type { Input } from './flow-types';
|
|
4
4
|
/** Everything one user type answers. Which flows it has is decided by its types; all are built. */
|
|
5
|
-
export type AnyTypeApi = UserTypeApi<AnyUser, Input> & PasswordApi<AnyUser, Input, string, SignInResult<AnyUser>> & SecondFactorApi<AnyUser> & SignInCodeApi<AnyUser, SignInResult<AnyUser>> & MagicLinkApi<AnyUser, SignInResult<AnyUser>> & StepUpApi<AnyUser, StepUpByEmail<AnyUser> | StepUpByApp<AnyUser>> & VerifyEmailApi<AnyUser> & ResetPasswordApi<AnyUser>;
|
|
5
|
+
export type AnyTypeApi = UserTypeApi<AnyUser, Input> & PasswordApi<AnyUser, Input, string, SignInResult<AnyUser>> & SecondFactorApi<AnyUser> & ProvenSignInApi<AnyUser, SignInResult<AnyUser>> & SignInCodeApi<AnyUser, SignInResult<AnyUser>> & MagicLinkApi<AnyUser, SignInResult<AnyUser>> & StepUpApi<AnyUser, StepUpByEmail<AnyUser> | StepUpByApp<AnyUser>> & VerifyEmailApi<AnyUser> & ResetPasswordApi<AnyUser>;
|
|
6
6
|
//# sourceMappingURL=any-type-api.d.ts.map
|