@nxgt/janus 0.16.0 → 0.17.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 +99 -11
- package/dist/auth/config/index.d.ts +1 -1
- package/dist/auth/config/index.d.ts.map +1 -1
- package/dist/auth/config/janus-config.d.ts +24 -3
- package/dist/auth/config/janus-config.d.ts.map +1 -1
- package/dist/auth/config/resolve-config.d.ts.map +1 -1
- package/dist/auth/config/resolve-devices.d.ts +5 -0
- package/dist/auth/config/resolve-devices.d.ts.map +1 -0
- package/dist/auth/config/resolved-config.d.ts +4 -0
- package/dist/auth/config/resolved-config.d.ts.map +1 -1
- package/dist/auth/devices/hint.d.ts +30 -0
- package/dist/auth/devices/hint.d.ts.map +1 -0
- package/dist/auth/devices/index.d.ts +10 -0
- package/dist/auth/devices/index.d.ts.map +1 -0
- package/dist/auth/devices/report.d.ts +11 -0
- package/dist/auth/devices/report.d.ts.map +1 -0
- package/dist/auth/devices/token.d.ts +13 -0
- package/dist/auth/devices/token.d.ts.map +1 -0
- package/dist/auth/email-sign-in.d.ts +4 -2
- package/dist/auth/email-sign-in.d.ts.map +1 -1
- package/dist/auth/events.d.ts +18 -5
- package/dist/auth/events.d.ts.map +1 -1
- package/dist/auth/index.d.ts +2 -2
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/magic-link.d.ts.map +1 -1
- package/dist/auth/second-factor/challenge.d.ts +2 -2
- package/dist/auth/second-factor/challenge.d.ts.map +1 -1
- package/dist/auth/second-factor/flows.d.ts +6 -4
- package/dist/auth/second-factor/flows.d.ts.map +1 -1
- package/dist/auth/second-factor/recovery.d.ts +6 -2
- package/dist/auth/second-factor/recovery.d.ts.map +1 -1
- package/dist/auth/sessions/open-session.d.ts +7 -1
- package/dist/auth/sessions/open-session.d.ts.map +1 -1
- package/dist/auth/sign-in-code.d.ts.map +1 -1
- package/dist/auth/types/email-flows.d.ts +2 -2
- package/dist/auth/types/email-flows.d.ts.map +1 -1
- package/dist/auth/types/index.d.ts +1 -1
- package/dist/auth/types/index.d.ts.map +1 -1
- package/dist/auth/types/magic-link.d.ts +2 -2
- package/dist/auth/types/magic-link.d.ts.map +1 -1
- package/dist/auth/types/password.d.ts +10 -3
- package/dist/auth/types/password.d.ts.map +1 -1
- package/dist/auth/types/second-factor.d.ts +6 -3
- package/dist/auth/types/second-factor.d.ts.map +1 -1
- package/dist/auth/types/sign-in.d.ts +32 -0
- package/dist/auth/types/sign-in.d.ts.map +1 -1
- package/dist/auth/users/flow-types.d.ts +2 -1
- package/dist/auth/users/flow-types.d.ts.map +1 -1
- package/dist/auth/users/password-flows.d.ts.map +1 -1
- package/dist/auth/users/sign-in.d.ts +5 -1
- package/dist/auth/users/sign-in.d.ts.map +1 -1
- package/dist/index.js +172 -73
- package/dist/index.js.map +19 -15
- package/docs/README.md +2 -1
- package/docs/guide/devices.md +428 -0
- package/docs/guide/events.md +53 -8
- package/docs/guide/magic-link.md +25 -3
- package/docs/guide/second-factor.md +30 -5
- package/docs/guide/sessions.md +8 -0
- package/docs/guide/sign-in-code.md +22 -3
- package/docs/guide/step-up.md +33 -0
- package/docs/guide/users.md +3 -2
- package/docs/guide/vocabulary.md +4 -3
- package/docs/roadmap.md +12 -8
- package/docs/troubleshooting.md +210 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -732,6 +732,53 @@ session should not do alone.
|
|
|
732
732
|
[The step-up guide](docs/guide/step-up.md) has the two requests, every
|
|
733
733
|
error, and the codes an app confirms.
|
|
734
734
|
|
|
735
|
+
### Devices — `devices`
|
|
736
|
+
|
|
737
|
+
```ts
|
|
738
|
+
import { z } from 'zod';
|
|
739
|
+
import { createMemoryStores, janus, scryptHasher } from '@nxgt/janus';
|
|
740
|
+
|
|
741
|
+
const auth = janus({
|
|
742
|
+
user: z.object({ email: z.email() }),
|
|
743
|
+
password: { login: 'email' },
|
|
744
|
+
store: createMemoryStores(),
|
|
745
|
+
hasher: scryptHasher(),
|
|
746
|
+
devices: { keys: [{ id: '2026-09', key: process.env.DEVICES_KEY ?? '' }] }, // openssl rand -base64 32
|
|
747
|
+
});
|
|
748
|
+
|
|
749
|
+
// `cookie`: the device cookie the request carries — string | undefined
|
|
750
|
+
const signedIn = await auth.signIn({ email, password }, { device: cookie ?? null });
|
|
751
|
+
// { status: 'signedIn', user, session, token, newDevice, deviceToken }
|
|
752
|
+
// keep signedIn.deviceToken in a long-lived HttpOnly cookie; newDevice: true sent user.newDeviceSignedIn
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
A sign-in from a device the user had not signed in from is told apart, so
|
|
756
|
+
you can tell the user. **Nothing is stored**: the client keeps a device
|
|
757
|
+
token janus signs, and presents it at its next sign-in.
|
|
758
|
+
|
|
759
|
+
- **`{ device }` is the last argument** of `signUp`, `signIn`,
|
|
760
|
+
`secondFactor.confirm`, `secondFactor.recover`, `signInCode.confirm` and
|
|
761
|
+
`magicLink.confirm` — a `SignInOptions`: the token the client holds, or
|
|
762
|
+
`null` when it holds none. **Absent, the call is not tracked**:
|
|
763
|
+
`newDevice: false`, `deviceToken: null`, no event.
|
|
764
|
+
- **Every answer that opens a session carries `newDevice` and
|
|
765
|
+
`deviceToken`.** `signUp` mints the first token and is never new. A
|
|
766
|
+
malformed, forged or another user's token is a new device, never an error.
|
|
767
|
+
- **`user.newDeviceSignedIn`** is sent for a new device, once the sign-in is
|
|
768
|
+
complete, with the new session's `sessionId`.
|
|
769
|
+
- **`devices: { keys }`** — a `DevicesConfig` — wires it; the keys take
|
|
770
|
+
`secondFactor.keys`' format. The first signs,
|
|
771
|
+
every one checks: a token signed by an older key is known, and handed back
|
|
772
|
+
signed with the first. **Removing a key is the only way to forget devices,
|
|
773
|
+
and it forgets every device that key signed.**
|
|
774
|
+
|
|
775
|
+
[`@nxgt/janus-mail`](https://www.npmjs.com/package/@nxgt/janus-mail)'s
|
|
776
|
+
`newSignIn` sends the notice, and
|
|
777
|
+
[`@nxgt/janus-hono`](https://www.npmjs.com/package/@nxgt/janus-hono)'s
|
|
778
|
+
`deviceOf` and `sendSession` keep the cookie.
|
|
779
|
+
[The devices guide](docs/guide/devices.md) has the cookie, the second
|
|
780
|
+
factor, the e-mail, key rotation, every error and a test.
|
|
781
|
+
|
|
735
782
|
### User events — `events`
|
|
736
783
|
|
|
737
784
|
```ts
|
|
@@ -765,28 +812,31 @@ await auth.signUp({ email, password }); // the listener has the event before thi
|
|
|
765
812
|
| `user.secondFactorDisabled` | `secondFactor.disable`, when it removed an active factor; `signInCode.confirm` and `magicLink.confirm` when their first proof of the e-mail removed one, after `user.emailVerified` and any `user.passwordChanged` — never for a user who had none, or one still waiting |
|
|
766
813
|
| `user.recoveryCodesRegenerated` | `secondFactor.regenerateRecoveryCodes` — not `activate`, whose codes come with `user.secondFactorEnabled` |
|
|
767
814
|
| `user.recoveryCodeUsed` | `secondFactor.recover`, once the recovery code is spent: a sign-in without the user's phone |
|
|
815
|
+
| `user.newDeviceSignedIn` | `signIn`, `secondFactor.confirm`, `secondFactor.recover`, `signInCode.confirm` and `magicLink.confirm`, given a `device` its token did not prove, once the sign-in is complete — carrying `sessionId`, the new session's. Never `signUp`, nor a call given no device |
|
|
768
816
|
| `user.deleted` | `delete`, once — a replay that deletes nobody sends nothing |
|
|
769
817
|
|
|
770
818
|
- **The user is named by id, and nothing else**: no login, no field, no
|
|
771
819
|
password, no token. Whoever receives the event reads the rest from where it
|
|
772
|
-
is kept, if they may.
|
|
820
|
+
is kept, if they may. Two exceptions: `user.emailChanged` carries
|
|
773
821
|
`formerEmail`, which nothing keeps once the write landed, so a notice can
|
|
774
|
-
reach the inbox the account just left
|
|
775
|
-
|
|
822
|
+
reach the inbox the account just left; and `user.newDeviceSignedIn`
|
|
823
|
+
carries `sessionId`, the session the new device holds.
|
|
824
|
+
`@nxgt/janus-webhooks` posts neither.
|
|
776
825
|
- **Each event has an `id` of its own**, a UUIDv7: the key to deliver it once.
|
|
777
826
|
- **The listener runs after the write, and is awaited** before the
|
|
778
827
|
flow answers, so a durable queue has the event by then. `occurredAt` is the
|
|
779
828
|
write's own time. A refused flow sends nothing.
|
|
780
829
|
- **Typed**: `events` is a `UserEventListener`; `UserEventType` is the closed
|
|
781
|
-
union of the
|
|
782
|
-
a new type, like the two recovery-code ones in 0.10
|
|
783
|
-
in 0.14, breaks it until handled.
|
|
830
|
+
union of the eleven types, so a `switch` on `event.type` is exhaustive —
|
|
831
|
+
and a new type, like the two recovery-code ones in 0.10, the two change
|
|
832
|
+
ones in 0.14 or `user.newDeviceSignedIn` in 0.17, breaks it until handled.
|
|
784
833
|
- **A listener that throws fails no flow** — the write happened. It is a
|
|
785
834
|
`JANUS_EVENT_FAILED` warning naming the event's type, its id and the user's
|
|
786
835
|
id, never the failure's message.
|
|
787
836
|
|
|
788
837
|
To tell the user their password or e-mail changed, their second factor was
|
|
789
|
-
turned on or off,
|
|
838
|
+
turned on or off, that a recovery code was used, or that a new device signed
|
|
839
|
+
in, send
|
|
790
840
|
[`@nxgt/janus-mail`](https://www.npmjs.com/package/@nxgt/janus-mail)'s notice
|
|
791
841
|
from the listener — or from a queue it feeds:
|
|
792
842
|
|
|
@@ -816,7 +866,7 @@ async events(event) {
|
|
|
816
866
|
|
|
817
867
|
To post them as signed webhooks:
|
|
818
868
|
[`@nxgt/janus-webhooks`](https://www.npmjs.com/package/@nxgt/janus-webhooks).
|
|
819
|
-
[The user events guide](docs/guide/events.md) has the listener, the
|
|
869
|
+
[The user events guide](docs/guide/events.md) has the listener, the eleven
|
|
820
870
|
types, mail for a recovery code used or a password or e-mail changed, what a failure costs, and a test.
|
|
821
871
|
|
|
822
872
|
### Permissions — `@nxgt/janus/permissions`
|
|
@@ -1102,6 +1152,43 @@ in again". Two *different* codes typed on one challenge at once are another
|
|
|
1102
1152
|
matter: the later one can still be removed from the user before it finds the
|
|
1103
1153
|
challenge spent, so two codes go for the one session the challenge opens.
|
|
1104
1154
|
|
|
1155
|
+
**A sign-in given no `device` tracks nothing.** Absent, `newDevice` is
|
|
1156
|
+
`false`, `deviceToken` is `null` and no event is sent — not "a new device".
|
|
1157
|
+
Pass `{ device: null }` for a client that holds no token yet, or it is never
|
|
1158
|
+
given one.
|
|
1159
|
+
|
|
1160
|
+
**`undefined` is not `null`.** A cookie read as `string | undefined` and
|
|
1161
|
+
passed as `device` is untracked whenever the cookie is missing — a compile
|
|
1162
|
+
error under `exactOptionalPropertyTypes`, silent without it. Write
|
|
1163
|
+
`{ device: cookie ?? null }`.
|
|
1164
|
+
|
|
1165
|
+
**Give the device again to `secondFactor.confirm` and `recover`.** The
|
|
1166
|
+
challenge `signIn`, `signInCode.confirm` or `magicLink.confirm` answers
|
|
1167
|
+
carries no device, so a confirmation called without `{ device }` is
|
|
1168
|
+
untracked, whatever the sign-in was given:
|
|
1169
|
+
`auth.secondFactor.confirm(challenge, code, { device: cookie ?? null })`.
|
|
1170
|
+
|
|
1171
|
+
**Every `janus()` that signs users in needs the same `devices`.** An instance
|
|
1172
|
+
without `devices` throws a `TypeError` for any `device`, and one whose keys
|
|
1173
|
+
differ reports every other instance's devices as new.
|
|
1174
|
+
|
|
1175
|
+
**One device cookie holds one user's token.** Two people sharing a browser
|
|
1176
|
+
who take turns signing in each present the other's token, which proves
|
|
1177
|
+
nothing for them: each gets a new token, and a notice, at every turn.
|
|
1178
|
+
|
|
1179
|
+
**Removing a device key forgets every device it signed.** Each is reported
|
|
1180
|
+
new once, at its next sign-in. It is the only way to forget devices — there
|
|
1181
|
+
is no per-device forget — so rotate by putting a new key first and keeping
|
|
1182
|
+
the old one.
|
|
1183
|
+
|
|
1184
|
+
**A device token is not a credential.** It proves only that this user signed
|
|
1185
|
+
in on this device before. Never authenticate a request with it, and never
|
|
1186
|
+
let it skip a password or a second factor.
|
|
1187
|
+
|
|
1188
|
+
**A `SignedIn` built by hand needs `newDevice` and `deviceToken`** (since
|
|
1189
|
+
0.17): a test double that answers `{ status, user, session, token }` no
|
|
1190
|
+
longer compiles — add `newDevice: false, deviceToken: null`.
|
|
1191
|
+
|
|
1105
1192
|
**On a user type, only `setOf` makes a set.** A user passed as it is — or
|
|
1106
1193
|
`{ type: 'staff', id, relation: 'managers' }` written out — is that one user,
|
|
1107
1194
|
even with a field named `relation`. The compiler refuses the written-out set
|
|
@@ -1234,12 +1321,13 @@ that sends one, since it is awaited: queue the event and return.
|
|
|
1234
1321
|
## Documentation
|
|
1235
1322
|
|
|
1236
1323
|
- [Guides](docs/README.md) — one page per area, every option with an example
|
|
1324
|
+
- [Devices](docs/guide/devices.md) — a sign-in from a new device: the token, the cookie, the notice
|
|
1237
1325
|
- [Troubleshooting](docs/troubleshooting.md) — by the error message you see
|
|
1238
1326
|
- [Roadmap](docs/roadmap.md) — what is next, and what is not planned
|
|
1239
1327
|
|
|
1240
1328
|
## Type safety, counted
|
|
1241
1329
|
|
|
1242
|
-
**One hundred and forty-
|
|
1330
|
+
**One hundred and forty-seven plausible mistakes, one hundred and forty-seven refused at compile time — and
|
|
1243
1331
|
two gaps, named.**
|
|
1244
1332
|
|
|
1245
1333
|
The lists are typechecked and never run, with one `@ts-expect-error` per
|
|
@@ -1247,10 +1335,10 @@ mistake beside the shapes that must keep compiling. One is a single file:
|
|
|
1247
1335
|
`test/types/refusals.ts` (fifteen, on the shared vocabulary). The other three
|
|
1248
1336
|
are folders with one file per behaviour: `test/types/port/` (twenty-four, on
|
|
1249
1337
|
the identity stores' port, from the point of view of the person implementing
|
|
1250
|
-
it), `test/types/auth/` (
|
|
1338
|
+
it), `test/types/auth/` (sixty, on `janus()`, from the point of view of
|
|
1251
1339
|
the application — twelve of them on the second factor, three on sign-in codes,
|
|
1252
1340
|
five on user events, four on step-ups, six on the sign-in throttle, four on
|
|
1253
|
-
sign-in links) and `test/types/permissions/` (forty-eight, on the
|
|
1341
|
+
sign-in links, six on devices) and `test/types/permissions/` (forty-eight, on the
|
|
1254
1342
|
permission model and the questions asked of it). The rule comes from
|
|
1255
1343
|
`nxgt-data`, and so does the reason to distrust the claim without the files:
|
|
1256
1344
|
when it was last measured on `@nxgt/mongo`, *seven of twelve plausible
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* Gathered here from the files beside this one.
|
|
10
10
|
*/
|
|
11
11
|
export type { PasswordHasher } from './hasher';
|
|
12
|
-
export type { CookieConfig, JanusConfig, MultiTypeConfig, SecondFactorConfig, SignInConfig, SignInThrottleConfig, SingleTypeConfig, } from './janus-config';
|
|
12
|
+
export type { CookieConfig, DevicesConfig, JanusConfig, MultiTypeConfig, SecondFactorConfig, SignInConfig, SignInThrottleConfig, SingleTypeConfig, } from './janus-config';
|
|
13
13
|
export { type Normalize, normalizeEmail } from './normalize';
|
|
14
14
|
export type { PasswordConfig } from './password-config';
|
|
15
15
|
export { RESERVED_FIELDS, RESERVED_TYPES, SINGLE_TYPE } from './reserved';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/config/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/C,YAAY,EACX,YAAY,EACZ,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7D,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtE,YAAY,EACX,UAAU,EACV,aAAa,EACb,UAAU,EACV,cAAc,GACd,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/config/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/C,YAAY,EACX,YAAY,EACZ,aAAa,EACb,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7D,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtE,YAAY,EACX,UAAU,EACV,aAAa,EACb,UAAU,EACV,cAAc,GACd,MAAM,aAAa,CAAC"}
|
|
@@ -65,11 +65,18 @@ interface SharedConfig {
|
|
|
65
65
|
* `secondFactor` flows exist and `signIn` answers a session directly.
|
|
66
66
|
*/
|
|
67
67
|
readonly secondFactor?: SecondFactorConfig;
|
|
68
|
+
/**
|
|
69
|
+
* Device tokens, for a notice when a user signs in from a device they had
|
|
70
|
+
* not signed in from. Absent, no sign-in may be given a `device`, and every
|
|
71
|
+
* answer's `newDevice` is `false`.
|
|
72
|
+
*/
|
|
73
|
+
readonly devices?: DevicesConfig;
|
|
68
74
|
/**
|
|
69
75
|
* Called with every user event — `user.created`, `user.emailVerified`,
|
|
70
|
-
* `user.passwordReset`, `user.
|
|
71
|
-
* `user.
|
|
72
|
-
* `user.
|
|
76
|
+
* `user.passwordReset`, `user.passwordChanged`, `user.emailChanged`,
|
|
77
|
+
* `user.secondFactorEnabled`, `user.secondFactorDisabled`,
|
|
78
|
+
* `user.recoveryCodesRegenerated`, `user.recoveryCodeUsed`,
|
|
79
|
+
* `user.newDeviceSignedIn`, `user.deleted` — once the write landed,
|
|
73
80
|
* and awaited before the flow answers. Any function will do;
|
|
74
81
|
* `webhooks({ … })` from `@nxgt/janus-webhooks` signs and delivers them.
|
|
75
82
|
*/
|
|
@@ -104,6 +111,20 @@ export interface SecondFactorConfig {
|
|
|
104
111
|
/** How long `signIn`'s challenge waits for a code. `'5m'` when absent. */
|
|
105
112
|
readonly challenge?: Duration;
|
|
106
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* The keys device tokens are signed with. **Nothing is stored**: a device
|
|
116
|
+
* token is the device's id and a keyed hash binding it to the user, kept by
|
|
117
|
+
* the application in a long-lived cookie.
|
|
118
|
+
*/
|
|
119
|
+
export interface DevicesConfig {
|
|
120
|
+
/**
|
|
121
|
+
* **The first signs, every one checks**: a token signed with an older key
|
|
122
|
+
* is known, and answered signed again with the first. A token whose key
|
|
123
|
+
* is gone is a new device — so **removing a key is the only way to forget
|
|
124
|
+
* devices**, and it forgets every device it signed.
|
|
125
|
+
*/
|
|
126
|
+
readonly keys: readonly [SealingKey, ...SealingKey[]];
|
|
127
|
+
}
|
|
107
128
|
/** An application with one user type: `user` is its schema. */
|
|
108
129
|
export interface SingleTypeConfig extends SharedConfig, Omit<UserTypeConfig, 'schema'> {
|
|
109
130
|
readonly user: UserSchema;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"janus-config.d.ts","sourceRoot":"","sources":["../../../src/auth/config/janus-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE9D,2DAA2D;AAC3D,MAAM,WAAW,YAAY;IAC5B,oFAAoF;IACpF,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,yBAAyB;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,2BAA2B;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC9C,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,UAAU,YAAY;IACrB,iEAAiE;IACjE,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC;IACjC,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAC/C,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE;QACjB,2BAA2B;QAC3B,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC;QAChC,0BAA0B;QAC1B,QAAQ,CAAC,aAAa,CAAC,EAAE,QAAQ,CAAC;QAClC,oEAAoE;QACpE,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC;QAC/B,oEAAoE;QACpE,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC;QAC9B,kFAAkF;QAClF,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC;KAC3B,CAAC;IACF;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;IAC/B;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAC3C
|
|
1
|
+
{"version":3,"file":"janus-config.d.ts","sourceRoot":"","sources":["../../../src/auth/config/janus-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-config.d.ts","sourceRoot":"","sources":["../../../src/auth/config/resolve-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EACX,WAAW,EAGX,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"resolve-config.d.ts","sourceRoot":"","sources":["../../../src/auth/config/resolve-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EACX,WAAW,EAGX,MAAM,gBAAgB,CAAC;AAQxB,OAAO,KAAK,EAAE,cAAc,EAAgB,MAAM,mBAAmB,CAAC;AAGtE,qFAAqF;AACrF,wBAAgB,aAAa,CAC5B,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,MAAM,GACX,cAAc,CAyBhB"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Resolves the device tokens' keys: the sealer that signs and checks them. */
|
|
2
|
+
import type { DevicesConfig } from './janus-config';
|
|
3
|
+
import type { ResolvedConfig } from './resolved-config';
|
|
4
|
+
export declare function resolveDevices(config: DevicesConfig | undefined, where: string): ResolvedConfig['devices'];
|
|
5
|
+
//# sourceMappingURL=resolve-devices.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-devices.d.ts","sourceRoot":"","sources":["../../../src/auth/config/resolve-devices.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAG/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,wBAAgB,cAAc,CAC7B,MAAM,EAAE,aAAa,GAAG,SAAS,EACjC,KAAK,EAAE,MAAM,GACX,cAAc,CAAC,SAAS,CAAC,CAI3B"}
|
|
@@ -38,6 +38,10 @@ export interface ResolvedConfig {
|
|
|
38
38
|
readonly sealer: Sealer;
|
|
39
39
|
readonly challengeTtlMs: number;
|
|
40
40
|
} | null;
|
|
41
|
+
/** `null` without `devices`: no sign-in may be given a device. */
|
|
42
|
+
readonly devices: {
|
|
43
|
+
readonly sealer: Sealer;
|
|
44
|
+
} | null;
|
|
41
45
|
readonly cookie: {
|
|
42
46
|
readonly name: string;
|
|
43
47
|
readonly domain: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolved-config.d.ts","sourceRoot":"","sources":["../../../src/auth/config/resolved-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,oFAAoF;AACpF,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE;QAClB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;QAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;KAC3B,GAAG,IAAI,CAAC;IACT,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAClD,QAAQ,CAAC,UAAU,EAAE;QACpB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,gDAAgD;IAChD,QAAQ,CAAC,cAAc,EAAE;QACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;KAC1B,GAAG,IAAI,CAAC;IACT,QAAQ,CAAC,YAAY,EAAE;QACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;KAChC,GAAG,IAAI,CAAC;IACT,QAAQ,CAAC,MAAM,EAAE;QAChB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;QAC7C,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;KACzB,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"resolved-config.d.ts","sourceRoot":"","sources":["../../../src/auth/config/resolved-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,oFAAoF;AACpF,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE;QAClB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;QAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;KAC3B,GAAG,IAAI,CAAC;IACT,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAClD,QAAQ,CAAC,UAAU,EAAE;QACpB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,gDAAgD;IAChD,QAAQ,CAAC,cAAc,EAAE;QACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;KAC1B,GAAG,IAAI,CAAC;IACT,QAAQ,CAAC,YAAY,EAAE;QACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;KAChC,GAAG,IAAI,CAAC;IACT,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACrD,QAAQ,CAAC,MAAM,EAAE;QAChB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;QAC7C,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;KACzB,CAAC;CACF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Context } from '../context';
|
|
2
|
+
import type { SignInOptions } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* What a sign-in was told of the device: `undefined` when nothing — devices
|
|
5
|
+
* are not tracked for that call — `null` for a device holding no token yet,
|
|
6
|
+
* or the token it presented.
|
|
7
|
+
*/
|
|
8
|
+
export type DeviceHint = string | null | undefined;
|
|
9
|
+
/** What a session-opening answer says of the device. */
|
|
10
|
+
export interface DeviceOutcome {
|
|
11
|
+
readonly newDevice: boolean;
|
|
12
|
+
readonly deviceToken: string | null;
|
|
13
|
+
}
|
|
14
|
+
/** No device given: nothing tracked, nothing minted. */
|
|
15
|
+
export declare const UNTRACKED: DeviceOutcome;
|
|
16
|
+
/**
|
|
17
|
+
* The device a sign-in's options name. A JavaScript caller's options that
|
|
18
|
+
* are not an object (the token itself), a `device` of another type, and a
|
|
19
|
+
* device given to a `janus()` wired without `devices`, are wiring
|
|
20
|
+
* mistakes — bare `TypeError`s. The value itself, whatever it holds, is the
|
|
21
|
+
* client's, and never refused.
|
|
22
|
+
*/
|
|
23
|
+
export declare function deviceHint(context: Context, options: SignInOptions | undefined, where: string): DeviceHint;
|
|
24
|
+
/**
|
|
25
|
+
* Whether a session opening for `userId` comes from a new device, and the
|
|
26
|
+
* token the client keeps from now on. A sign-up mints a token and is never
|
|
27
|
+
* new: the account has no device to be new against.
|
|
28
|
+
*/
|
|
29
|
+
export declare function deviceOutcome(context: Context, userId: string, hint: DeviceHint, signUp: boolean): DeviceOutcome;
|
|
30
|
+
//# sourceMappingURL=hint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hint.d.ts","sourceRoot":"","sources":["../../../src/auth/devices/hint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG9C;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;AAEnD,wDAAwD;AACxD,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,wDAAwD;AACxD,eAAO,MAAM,SAAS,EAAE,aAGtB,CAAC;AAEH;;;;;;GAMG;AACH,wBAAgB,UAAU,CACzB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,aAAa,GAAG,SAAS,EAClC,KAAK,EAAE,MAAM,GACX,UAAU,CAsBZ;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC5B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,OAAO,GACb,aAAa,CAWf"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Devices: the signed token a client keeps (`token.ts`), what a sign-in was
|
|
3
|
+
* told of the device and what it answers (`hint.ts`), and the event a new
|
|
4
|
+
* one sends (`report.ts`).
|
|
5
|
+
*
|
|
6
|
+
* Gathered here from the files beside this one.
|
|
7
|
+
*/
|
|
8
|
+
export { type DeviceHint, type DeviceOutcome, deviceHint, deviceOutcome, UNTRACKED, } from './hint';
|
|
9
|
+
export { reportNewDevice } from './report';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/devices/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACN,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,UAAU,EACV,aAAa,EACb,SAAS,GACT,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AnyUser, Context } from '../context';
|
|
2
|
+
import type { SignInResult } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Sends `user.newDeviceSignedIn` for a session a new device just opened —
|
|
5
|
+
* once the sign-in is complete, so a sign-in refused after its session
|
|
6
|
+
* opened (a password written meanwhile) reports nothing. A challenge, and a
|
|
7
|
+
* session from a known device or with no device given, report nothing
|
|
8
|
+
* either.
|
|
9
|
+
*/
|
|
10
|
+
export declare function reportNewDevice(context: Context, result: SignInResult<AnyUser>): Promise<void>;
|
|
11
|
+
//# sourceMappingURL=report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../../src/auth/devices/report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C;;;;;;GAMG;AACH,wBAAsB,eAAe,CACpC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,GAC3B,OAAO,CAAC,IAAI,CAAC,CASf"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Sealer } from '../sealing';
|
|
2
|
+
/** A token for a device never seen: a fresh device id, signed with the first key. */
|
|
3
|
+
export declare function mintDeviceToken(sealer: Sealer, userId: string): string;
|
|
4
|
+
/**
|
|
5
|
+
* The token to hand back when `presented` proves this user signed in on this
|
|
6
|
+
* device before — itself, or the same device signed again with the first key
|
|
7
|
+
* when an older key signed it — or `null` when it proves nothing: malformed,
|
|
8
|
+
* another user's, forged, or signed with a key no longer held.
|
|
9
|
+
*
|
|
10
|
+
* `presented` comes from a request, so nothing here throws.
|
|
11
|
+
*/
|
|
12
|
+
export declare function knownDeviceToken(sealer: Sealer, userId: string, presented: string): string | null;
|
|
13
|
+
//# sourceMappingURL=token.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../../src/auth/devices/token.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AA8BzC,qFAAqF;AACrF,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC/B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GACf,MAAM,GAAG,IAAI,CAgBf"}
|
|
@@ -7,10 +7,11 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { ResolvedType } from './config';
|
|
9
9
|
import { type AnyUser, type Context } from './context';
|
|
10
|
+
import { type DeviceHint } from './devices';
|
|
10
11
|
import type { TokenKind, TokenRecord, UserRecord } from './port/types';
|
|
11
12
|
import type { SignInResult } from './types';
|
|
12
13
|
/** What a sign-in answers once the user proved who they are: `secondFactor.finish`. */
|
|
13
|
-
export type Finish = (record: UserRecord, where: string) => Promise<SignInResult<AnyUser>>;
|
|
14
|
+
export type Finish = (record: UserRecord, where: string, device: DeviceHint) => Promise<SignInResult<AnyUser>>;
|
|
14
15
|
/**
|
|
15
16
|
* The user of this type holding `email`, when they may be sent a sign-in:
|
|
16
17
|
* `null` for nobody, and for an inactive user — the same answer, so the
|
|
@@ -26,7 +27,7 @@ export declare function keepOnlyLatest(context: Context, userId: string, kind: T
|
|
|
26
27
|
/**
|
|
27
28
|
* Ends a sign-in by e-mail whose token is spent: refuses an e-mail changed
|
|
28
29
|
* since it was sent and an inactive user, proves the e-mail — it reached the
|
|
29
|
-
* inbox — and finishes as a password would.
|
|
30
|
+
* inbox — and finishes as a password would, reporting a new device.
|
|
30
31
|
*
|
|
31
32
|
* **An e-mail proved for the first time drops the password and the second
|
|
32
33
|
* factor, and revokes every session** before the new one opens
|
|
@@ -41,5 +42,6 @@ export declare function finishEmailSignIn(context: Context, type: ResolvedType,
|
|
|
41
42
|
readonly token: TokenRecord;
|
|
42
43
|
readonly where: string;
|
|
43
44
|
readonly noun: 'token' | 'code';
|
|
45
|
+
readonly device: DeviceHint;
|
|
44
46
|
}): Promise<SignInResult<AnyUser>>;
|
|
45
47
|
//# sourceMappingURL=email-sign-in.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"email-sign-in.d.ts","sourceRoot":"","sources":["../../src/auth/email-sign-in.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,OAAO,EAAiB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"email-sign-in.d.ts","sourceRoot":"","sources":["../../src/auth/email-sign-in.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,OAAO,EAAiB,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,KAAK,UAAU,EAAmB,MAAM,WAAW,CAAC;AAG7D,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,uFAAuF;AACvF,MAAM,MAAM,MAAM,GAAG,CACpB,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,UAAU,KACd,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;AAEpC;;;;GAIG;AACH,wBAAsB,YAAY,CACjC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAG5B;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CACnC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CACtC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE;IACP,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;CAC5B,GACC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAiBhC"}
|
package/dist/auth/events.d.ts
CHANGED
|
@@ -28,14 +28,21 @@ import type { Context } from './context';
|
|
|
28
28
|
* come with `user.secondFactorEnabled`;
|
|
29
29
|
* - `user.recoveryCodeUsed` — by `secondFactor.recover`, once the code is
|
|
30
30
|
* spent: a sign-in without the user's phone;
|
|
31
|
+
* - `user.newDeviceSignedIn` — by a sign-in that opened a session from a
|
|
32
|
+
* device the user had not signed in from: `signIn`, `secondFactor.confirm`,
|
|
33
|
+
* `secondFactor.recover`, `signInCode.confirm` and `magicLink.confirm`, when
|
|
34
|
+
* given a `device` its token did not prove. Never by `signUp`, nor without
|
|
35
|
+
* a `device`. Carries `sessionId`;
|
|
31
36
|
* - `user.deleted` — by `delete`, once; a replay that finds nobody is none.
|
|
32
37
|
*/
|
|
33
|
-
export type UserEventType = 'user.created' | 'user.emailVerified' | 'user.passwordReset' | 'user.passwordChanged' | 'user.emailChanged' | 'user.secondFactorEnabled' | 'user.secondFactorDisabled' | 'user.recoveryCodesRegenerated' | 'user.recoveryCodeUsed' | 'user.deleted';
|
|
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';
|
|
34
39
|
/**
|
|
35
40
|
* A user event: **the user named by id, and nothing else** — no login, no
|
|
36
41
|
* field, no password, no token. Whoever receives it reads the rest from where
|
|
37
|
-
* it is kept, if they may.
|
|
38
|
-
* `user.emailChanged
|
|
42
|
+
* it is kept, if they may. Two exceptions: `formerEmail` on
|
|
43
|
+
* `user.emailChanged` — once the write landed, the old address is kept
|
|
44
|
+
* nowhere — and `sessionId` on `user.newDeviceSignedIn`, the session the new
|
|
45
|
+
* device holds.
|
|
39
46
|
*/
|
|
40
47
|
export interface UserEvent {
|
|
41
48
|
/** A UUIDv7 minted for this event: the key to deliver it once. */
|
|
@@ -55,9 +62,15 @@ export interface UserEvent {
|
|
|
55
62
|
* from every other type, and from an event a webhook delivered.
|
|
56
63
|
*/
|
|
57
64
|
readonly formerEmail?: string | null;
|
|
65
|
+
/**
|
|
66
|
+
* On `user.newDeviceSignedIn` only: the session the new device opened —
|
|
67
|
+
* to sign it out from a "this wasn't me" page. Absent from every other
|
|
68
|
+
* type, and from an event a webhook delivered.
|
|
69
|
+
*/
|
|
70
|
+
readonly sessionId?: string;
|
|
58
71
|
}
|
|
59
|
-
/** What an event carries beyond the user, on the
|
|
60
|
-
export type EventExtras = Pick<UserEvent, 'formerEmail'>;
|
|
72
|
+
/** What an event carries beyond the user, on the two types that do. */
|
|
73
|
+
export type EventExtras = Pick<UserEvent, 'formerEmail' | 'sessionId'>;
|
|
61
74
|
/**
|
|
62
75
|
* What `janus({ events })` takes: called once per event, **after** the write
|
|
63
76
|
* landed and before the flow answers — awaited, so a queue that stores the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/auth/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAU,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/auth/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAU,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,MAAM,aAAa,GACtB,cAAc,GACd,oBAAoB,GACpB,oBAAoB,GACpB,sBAAsB,GACtB,mBAAmB,GACnB,0BAA0B,GAC1B,2BAA2B,GAC3B,+BAA+B,GAC/B,uBAAuB,GACvB,wBAAwB,GACxB,cAAc,CAAC;AAElB;;;;;;;GAOG;AACH,MAAM,WAAW,SAAS;IACzB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC;IAChB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,uEAAuE;AACvE,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,aAAa,GAAG,WAAW,CAAC,CAAC;AAEvE;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE3E,oFAAoF;AACpF,wBAAgB,aAAa,CAC5B,MAAM,EAAE,OAAO,EACf,KAAK,EAAE,MAAM,GACX,iBAAiB,GAAG,IAAI,CAQ1B;AAED;;;;;;GAMG;AACH,wBAAsB,IAAI,CACzB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,aAAa,EACnB,IAAI,EAAE;IAAE,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAChD,UAAU,EAAE,IAAI,EAChB,MAAM,GAAE,WAAgB,GACtB,OAAO,CAAC,IAAI,CAAC,CAqBf"}
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { CookieConfig, FieldsJson, JanusConfig, MultiTypeConfig, Normalize, PasswordConfig, PasswordHasher, SecondFactorConfig, SessionConfig, SignInConfig, SignInThrottleConfig, SingleTypeConfig, UserSchema, UserTypeConfig, } from './config';
|
|
1
|
+
export type { CookieConfig, DevicesConfig, FieldsJson, JanusConfig, MultiTypeConfig, Normalize, PasswordConfig, PasswordHasher, SecondFactorConfig, SessionConfig, SignInConfig, SignInThrottleConfig, SingleTypeConfig, UserSchema, UserTypeConfig, } from './config';
|
|
2
2
|
export type { UserEvent, UserEventListener, UserEventType, } from './events';
|
|
3
3
|
export { bunHasher, scryptHasher } from './hashers';
|
|
4
4
|
export { janus } from './janus';
|
|
@@ -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, 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, 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,UAAU,EACV,WAAW,EACX,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,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,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 +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;
|
|
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;AAEzB,OAAO,KAAK,EAAe,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvE;;;;;;;;;;;;;;GAcG;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,CAY3D"}
|
|
@@ -2,7 +2,7 @@ import type { At } from '../at';
|
|
|
2
2
|
import type { ResolvedType } from '../config';
|
|
3
3
|
import type { AnyUser, Context } from '../context';
|
|
4
4
|
import type { UserRecord } from '../port/types';
|
|
5
|
-
import type { SecondFactorRequired, SignedIn } from '../types';
|
|
5
|
+
import type { SecondFactorRequired, SignedIn, SignInOptions } from '../types';
|
|
6
6
|
/**
|
|
7
7
|
* The challenge `signIn` answers instead of a session, and the code that
|
|
8
8
|
* redeems it. **Only the challenge's hash is stored**, like a session
|
|
@@ -10,6 +10,6 @@ import type { SecondFactorRequired, SignedIn } from '../types';
|
|
|
10
10
|
*/
|
|
11
11
|
export declare function challengeFlows(context: Context, type: ResolvedType, at: At): {
|
|
12
12
|
issue(record: UserRecord, where: string): Promise<SecondFactorRequired>;
|
|
13
|
-
confirm(challenge: string, code: string): Promise<SignedIn<AnyUser>>;
|
|
13
|
+
confirm(challenge: string, code: string, options?: SignInOptions): Promise<SignedIn<AnyUser>>;
|
|
14
14
|
};
|
|
15
15
|
//# sourceMappingURL=challenge.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"challenge.d.ts","sourceRoot":"","sources":["../../../src/auth/second-factor/challenge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"challenge.d.ts","sourceRoot":"","sources":["../../../src/auth/second-factor/challenge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,KAAK,EAAE,oBAAoB,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAI9E;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,EAAE;kBAGhE,UAAU,SACX,MAAM,GACX,OAAO,CAAC,oBAAoB,CAAC;uBAsBpB,MAAM,QACX,MAAM,YACF,aAAa,GACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;EAI9B"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { At } from '../at';
|
|
2
2
|
import type { ResolvedType } from '../config';
|
|
3
3
|
import type { AnyUser, Context } from '../context';
|
|
4
|
+
import type { DeviceHint } from '../devices';
|
|
4
5
|
import type { UserRecord } from '../port/types';
|
|
5
6
|
import type { SignInResult } from '../types';
|
|
6
7
|
/**
|
|
@@ -13,15 +14,16 @@ export declare function secondFactorFlows(context: Context, type: ResolvedType,
|
|
|
13
14
|
activate(user: import("..").UserRef, code: string, options?: import("..").WriteOptions): Promise<import("..").RecoveryCodesIssued<AnyUser>>;
|
|
14
15
|
regenerateRecoveryCodes(user: import("..").UserRef, code: string, options?: import("..").WriteOptions): Promise<import("..").RecoveryCodesIssued<AnyUser>>;
|
|
15
16
|
disable(user: import("..").UserRef, options?: import("..").WriteOptions): Promise<AnyUser>;
|
|
16
|
-
confirm(challenge: string, code: string): Promise<import("..").SignedIn<AnyUser>>;
|
|
17
|
-
recover(challenge: string, code: string): Promise<import("..").RecoveredSignIn<AnyUser>>;
|
|
17
|
+
confirm(challenge: string, code: string, options?: import("..").SignInOptions): Promise<import("..").SignedIn<AnyUser>>;
|
|
18
|
+
recover(challenge: string, code: string, options?: import("..").SignInOptions): Promise<import("..").RecoveredSignIn<AnyUser>>;
|
|
18
19
|
recoveryCodesLeft(user: import("..").UserRef): Promise<number | null>;
|
|
19
20
|
};
|
|
20
21
|
/**
|
|
21
22
|
* What a sign-in answers once the user proved who they are — by
|
|
22
23
|
* password or by an e-mail code: a session, or a challenge when their
|
|
23
|
-
* second factor is active. The first factor alone opens nothing then
|
|
24
|
+
* second factor is active. The first factor alone opens nothing then,
|
|
25
|
+
* and the device is not carried: its confirmation is given it again.
|
|
24
26
|
*/
|
|
25
|
-
finish: (record: UserRecord, where: string) => Promise<SignInResult<AnyUser>>;
|
|
27
|
+
finish: (record: UserRecord, where: string, device: DeviceHint) => Promise<SignInResult<AnyUser>>;
|
|
26
28
|
};
|
|
27
29
|
//# sourceMappingURL=flows.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flows.d.ts","sourceRoot":"","sources":["../../../src/auth/second-factor/flows.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,KAAK,EAAmB,YAAY,EAAE,MAAM,UAAU,CAAC;AAO9D;;;GAGG;AACH,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,YAAY,EAClB,EAAE,EAAE,EAAE;;;;;;;;;;IAmBL
|
|
1
|
+
{"version":3,"file":"flows.d.ts","sourceRoot":"","sources":["../../../src/auth/second-factor/flows.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,KAAK,EAAmB,YAAY,EAAE,MAAM,UAAU,CAAC;AAO9D;;;GAGG;AACH,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,YAAY,EAClB,EAAE,EAAE,EAAE;;;;;;;;;;IAmBL;;;;;OAKG;qBAEM,UAAU,SACX,MAAM,UACL,UAAU,KAChB,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;EAKlC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { At } from '../at';
|
|
2
2
|
import type { ResolvedType } from '../config';
|
|
3
3
|
import type { AnyUser, Context } from '../context';
|
|
4
|
-
import type { RecoveredSignIn } from '../types';
|
|
4
|
+
import type { RecoveredSignIn, SignInOptions } from '../types';
|
|
5
5
|
/**
|
|
6
6
|
* Redeems `signIn`'s challenge with a recovery code instead of an app's
|
|
7
7
|
* code: for a user whose phone is gone.
|
|
@@ -12,5 +12,9 @@ import type { RecoveredSignIn } from '../types';
|
|
|
12
12
|
* two sign-ins spending the same code at once, the second write is
|
|
13
13
|
* `VERSION_CONFLICT`, and that sign-in opens nothing.
|
|
14
14
|
*/
|
|
15
|
-
export declare function recoverWithCode(context: Context, type: ResolvedType,
|
|
15
|
+
export declare function recoverWithCode(context: Context, type: ResolvedType, given: {
|
|
16
|
+
readonly challenge: string;
|
|
17
|
+
readonly code: string;
|
|
18
|
+
readonly options: SignInOptions | undefined;
|
|
19
|
+
}, at: At): Promise<RecoveredSignIn<AnyUser>>;
|
|
16
20
|
//# sourceMappingURL=recovery.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recovery.d.ts","sourceRoot":"","sources":["../../../src/auth/second-factor/recovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"recovery.d.ts","sourceRoot":"","sources":["../../../src/auth/second-factor/recovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAKnD,OAAO,KAAK,EAAE,eAAe,EAAY,aAAa,EAAE,MAAM,UAAU,CAAC;AAIzE;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACpC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE;IACN,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,CAAC;CAC5C,EACD,EAAE,EAAE,EAAE,GACJ,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAwCnC"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { ResolvedType } from '../config';
|
|
6
6
|
import { type AnyUser, type Context } from '../context';
|
|
7
|
+
import { type DeviceHint } from '../devices';
|
|
7
8
|
import type { SessionRecord, UserRecord } from '../port/types';
|
|
8
9
|
import type { Session, SignedIn } from '../types';
|
|
9
10
|
/** A session as application code sees it: everything but the token's hash. */
|
|
@@ -11,6 +12,11 @@ export declare function toSession(record: SessionRecord): Session;
|
|
|
11
12
|
/**
|
|
12
13
|
* Opens a session for a user who just proved who they are. The token is in
|
|
13
14
|
* the answer and nowhere else: the store holds its hash.
|
|
15
|
+
*
|
|
16
|
+
* `device` is what the sign-in was told of the device, and the answer says
|
|
17
|
+
* whether it is new to the user; `signUp` mints a first token and is never
|
|
18
|
+
* new. Reporting a new device is the caller's, once its sign-in is complete
|
|
19
|
+
* (`reportNewDevice`).
|
|
14
20
|
*/
|
|
15
|
-
export declare function openSession(context: Context, type: ResolvedType, user: UserRecord): Promise<SignedIn<AnyUser>>;
|
|
21
|
+
export declare function openSession(context: Context, type: ResolvedType, user: UserRecord, device: DeviceHint, signUp?: boolean): Promise<SignedIn<AnyUser>>;
|
|
16
22
|
//# sourceMappingURL=open-session.d.ts.map
|