@nxgt/janus 0.18.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.
Files changed (74) hide show
  1. package/README.md +148 -12
  2. package/dist/auth/email-flows/reset-password.d.ts.map +1 -1
  3. package/dist/auth/events.d.ts +3 -3
  4. package/dist/auth/index.d.ts +1 -1
  5. package/dist/auth/index.d.ts.map +1 -1
  6. package/dist/auth/magic-link.d.ts +3 -0
  7. package/dist/auth/magic-link.d.ts.map +1 -1
  8. package/dist/auth/one-time/issue.d.ts +6 -0
  9. package/dist/auth/one-time/issue.d.ts.map +1 -1
  10. package/dist/auth/port/assert-stores.d.ts.map +1 -1
  11. package/dist/auth/port/memory/users.d.ts.map +1 -1
  12. package/dist/auth/port/types/stores.d.ts +5 -0
  13. package/dist/auth/port/types/stores.d.ts.map +1 -1
  14. package/dist/auth/port/types/users.d.ts +17 -0
  15. package/dist/auth/port/types/users.d.ts.map +1 -1
  16. package/dist/auth/prepared.d.ts +21 -0
  17. package/dist/auth/prepared.d.ts.map +1 -0
  18. package/dist/auth/proven-sign-in.d.ts +22 -0
  19. package/dist/auth/proven-sign-in.d.ts.map +1 -0
  20. package/dist/auth/sign-in-code.d.ts +4 -0
  21. package/dist/auth/sign-in-code.d.ts.map +1 -1
  22. package/dist/auth/types/email-flows.d.ts +18 -0
  23. package/dist/auth/types/email-flows.d.ts.map +1 -1
  24. package/dist/auth/types/index.d.ts +2 -0
  25. package/dist/auth/types/index.d.ts.map +1 -1
  26. package/dist/auth/types/janus.d.ts +7 -5
  27. package/dist/auth/types/janus.d.ts.map +1 -1
  28. package/dist/auth/types/magic-link.d.ts +11 -0
  29. package/dist/auth/types/magic-link.d.ts.map +1 -1
  30. package/dist/auth/types/prepared.d.ts +41 -0
  31. package/dist/auth/types/prepared.d.ts.map +1 -0
  32. package/dist/auth/types/proven-sign-in.d.ts +43 -0
  33. package/dist/auth/types/proven-sign-in.d.ts.map +1 -0
  34. package/dist/auth/types/sign-in.d.ts +2 -2
  35. package/dist/auth/types/user-type.d.ts +15 -0
  36. package/dist/auth/types/user-type.d.ts.map +1 -1
  37. package/dist/auth/users/any-type-api.d.ts +2 -2
  38. package/dist/auth/users/any-type-api.d.ts.map +1 -1
  39. package/dist/auth/users/find-many.d.ts +29 -0
  40. package/dist/auth/users/find-many.d.ts.map +1 -0
  41. package/dist/auth/users/record-flows.d.ts.map +1 -1
  42. package/dist/auth/users/type-api.d.ts +2 -2
  43. package/dist/auth/users/type-api.d.ts.map +1 -1
  44. package/dist/chunks/{index-kvjj5xkp.js → index-6bjfv4xv.js} +8 -2
  45. package/dist/chunks/{index-kvjj5xkp.js.map → index-6bjfv4xv.js.map} +3 -3
  46. package/dist/conformance/cases/outage.d.ts.map +1 -1
  47. package/dist/conformance/cases/users/batch.d.ts +8 -0
  48. package/dist/conformance/cases/users/batch.d.ts.map +1 -0
  49. package/dist/conformance/cases/users/index.d.ts.map +1 -1
  50. package/dist/conformance/describe.d.ts +2 -1
  51. package/dist/conformance/describe.d.ts.map +1 -1
  52. package/dist/conformance/index.d.ts +1 -1
  53. package/dist/conformance/index.d.ts.map +1 -1
  54. package/dist/conformance/index.js +104 -44
  55. package/dist/conformance/index.js.map +7 -6
  56. package/dist/conformance/types.d.ts +10 -2
  57. package/dist/conformance/types.d.ts.map +1 -1
  58. package/dist/index.js +150 -23
  59. package/dist/index.js.map +14 -11
  60. package/docs/README.md +1 -1
  61. package/docs/guide/adapters.md +44 -4
  62. package/docs/guide/devices.md +4 -0
  63. package/docs/guide/email-flows.md +105 -0
  64. package/docs/guide/errors.md +2 -2
  65. package/docs/guide/events.md +2 -2
  66. package/docs/guide/magic-link.md +49 -2
  67. package/docs/guide/passwords.md +5 -2
  68. package/docs/guide/second-factor.md +1 -1
  69. package/docs/guide/sessions.md +94 -1
  70. package/docs/guide/sign-in-code.md +54 -2
  71. package/docs/guide/users.md +49 -0
  72. package/docs/roadmap.md +28 -39
  73. package/docs/troubleshooting.md +120 -7
  74. 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
 
@@ -348,6 +350,11 @@ await clinic.staff.signIn({ username, password });
348
350
  const current = await clinic.authenticate(request);
349
351
  if (current?.user.type === 'staff') current.user.service; // narrowed by type
350
352
  await clinic.authenticate(request, { type: 'staff' }); // a patient's session → null
353
+
354
+ // Several users by id, in one query: a 100-row staff list, one round trip
355
+ const members = await clinic.staff.findMany(rows.map((row) => row.staffId));
356
+ const byId = new Map(members.map((member) => [member.id, member]));
357
+ const shown = rows.map((row) => ({ ...row, active: byId.get(row.staffId)?.active ?? false }));
351
358
  ```
352
359
 
353
360
  `janus()` assembles **synchronously and with no I/O**: it checks that every
@@ -372,11 +379,19 @@ else reaches the store and is asynchronous.
372
379
  `verifyEmail`, no `resetPassword`, no `signInCode` and no `magicLink` — they
373
380
  are absent from its type, not failing at run time. Changing the e-mail sets `emailVerified`
374
381
  back to `false`.
375
- - **Per type**: `create`, `find` (or `null`), `get` (or `NOT_FOUND`), `list`,
376
- `update(user, patch)` — merged over the stored fields, then validated whole —
377
- `setActive` and `delete`; with a password, `signUp`, `signIn`, `findByLogin`,
378
- `setPassword` and `changePassword`. Every write but `delete` takes an
379
- optional `ifVersion`.
382
+ - **Per type**: `create`, `find` (or `null`), `findMany`, `get` (or
383
+ `NOT_FOUND`), `list`, `update(user, patch)` — merged over the stored fields,
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`.
387
+ - **`findMany(ids)`** answers the type's users **in the order the ids were
388
+ given**, each once — a repeated id at its first place. An id `find` answers
389
+ `null` for — malformed, unknown, another type's — is **left out**, so match
390
+ by `user.id`, never by position. `[]` answers `[]` without reaching the
391
+ store; a long list is read 100 ids per query. One query when the users store
392
+ implements the optional `findUsers` (the reference store, `janus-drizzle`,
393
+ `janus-mongo`); otherwise `findUser`, ten at a time
394
+ ([users](docs/guide/users.md#several-users-at-once--findmany)).
380
395
  - **`delete(user)`** deletes the user together with every session and one-time
381
396
  token they had, so nothing of theirs is kept: a token holds the e-mail it was
382
397
  sent to. The user goes first, so an outage half-way leaves only sessions and
@@ -409,6 +424,8 @@ else reaches the store and is asynchronous.
409
424
  `magicLink.request`, `signInCode.request` and `resetPassword.request` — an
410
425
  address nobody holds is counted and refused alike — and per user for
411
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)).
412
429
  `mail: { throttle: { attempts, window } }` changes it, `mail: { throttle:
413
430
  false }` turns it off; a store that cannot count throws `STORE_FAILED` and
414
431
  nothing is issued
@@ -711,6 +728,91 @@ to type.
711
728
  confirms from a `POST` so mail scanners spend nothing, every error, routes
712
729
  and a test.
713
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
+
714
816
  ### Step-up — `stepUp` and `assertFresh`
715
817
 
716
818
  ```ts
@@ -1005,7 +1107,7 @@ describeJanusStores({
1005
1107
  });
1006
1108
  ```
1007
1109
 
1008
- There are 55 cases. They cover:
1110
+ There are 58 cases. They cover:
1009
1111
  - round-trip, byte for byte — including every edge character the core lets
1010
1112
  through (control characters, U+FFFF, a surrogate pair);
1011
1113
  - uniqueness, as a constraint: of twenty concurrent inserts of one login,
@@ -1032,9 +1134,16 @@ There are 55 cases. They cover:
1032
1134
  removed by one that names `null`;
1033
1135
  - deletion: a user's logins are freed, and every session and token of theirs
1034
1136
  goes, with a replay answering `false` or `0` rather than failing;
1035
- - **outages**, one case for each of the fourteen methods whose honest answer can
1137
+ - the optional `users.findUsers`: each stored user once, whatever its type, an
1138
+ id nobody holds left out, and `[]` — never `null` — when nobody holds any;
1139
+ - **outages**, one case for each of the fifteen methods whose honest answer can
1036
1140
  be "nothing".
1037
1141
 
1142
+ **An optional method a store lacks skips its cases, with the reason** — a
1143
+ store without `sessions.deleteExpiredSessions` or `users.findUsers` passes the
1144
+ suite. A case's `needs` names what it cannot run without, one `CaseNeed` or a list
1145
+ (`outage.findUsers` needs `['faults', 'findUsers']`).
1146
+
1038
1147
  The suite imports no test framework and no assertion library. It runs under
1039
1148
  `bun test`, vitest and jest. Its cases are also exported as data
1040
1149
  (`allCases`, or by store: `userStoreCases`, `sessionStoreCases`,
@@ -1066,7 +1175,7 @@ runner-less layer.
1066
1175
  ## Traps
1067
1176
 
1068
1177
  **Once `secondFactor` is configured, switch on `signIn`'s `status`** — and
1069
- on `signInCode.confirm`'s and `magicLink.confirm`'s. A user whose factor is active gets
1178
+ on `signInCode.confirm`'s, `magicLink.confirm`'s and `signInProven`'s. A user whose factor is active gets
1070
1179
  `{ status: 'secondFactor', challenge, expiresAt, userId }`, with no `token`
1071
1180
  and no `session`: an e-mailed code or link proves the e-mail, not the factor.
1072
1181
  `userId` is for your logs and rate limits — answer the visitor the
@@ -1106,6 +1215,16 @@ user — a new `request` spends the one before — so the throttle bounds how
1106
1215
  often anyone who knows an address can fill its inbox or cancel its owner's
1107
1216
  code; it does not stop it.
1108
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
+
1109
1228
  **Confirm a sign-in link from a `POST`, never from its `GET`.** Mail
1110
1229
  scanners open every link in an e-mail before the user does: a route that
1111
1230
  calls `magicLink.confirm` on the link's `GET` spends it for the scanner, and
@@ -1243,6 +1362,17 @@ dummy hash when nobody holds the login, so the hashing time does not tell.
1243
1362
  denied. `resetPassword.request` answers `null` for an unknown e-mail for the
1244
1363
  same reason: answer the visitor the same page either way.
1245
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
+
1246
1376
  **`resetPassword.confirm` signs the user out everywhere, and opens no session.**
1247
1377
  Whoever had the old password loses their sessions, and a sign-in they left
1248
1378
  waiting on its second factor is spent with them — as it is by `setPassword`
@@ -1316,6 +1446,12 @@ stored fields and the result is checked against the schema, so a patch can
1316
1446
  never leave a user that the schema would refuse. Pass `ifVersion` to make the
1317
1447
  write conditional on what you read.
1318
1448
 
1449
+ **`findMany` answers fewer users than ids, never `null` in their place.** An
1450
+ unknown, malformed or other type's id is left out and a repeated one answered
1451
+ once, so `users[i]` is not the user of `ids[i]`: build a `Map` by `user.id`.
1452
+ An outage is `STORE_FAILED`, never a shorter list — a row whose user is
1453
+ missing from the answer is one nobody holds.
1454
+
1319
1455
  **Under `bun test`, pass `runner: { describe, it }`.** Measured: Bun gives a
1320
1456
  test file `describe` and `it` as bare identifiers, not as properties of
1321
1457
  `globalThis`. jest, and vitest with `globals: true`, are found without it.
@@ -1381,18 +1517,18 @@ that sends one, since it is awaited: queue the event and return.
1381
1517
 
1382
1518
  ## Type safety, counted
1383
1519
 
1384
- **One hundred and fifty-two plausible mistakes, one hundred and fifty-two refused at compile time — and
1520
+ **One hundred and sixty-three plausible mistakes, one hundred and sixty-three refused at compile time — and
1385
1521
  two gaps, named.**
1386
1522
 
1387
1523
  The lists are typechecked and never run, with one `@ts-expect-error` per
1388
1524
  mistake beside the shapes that must keep compiling. One is a single file:
1389
1525
  `test/types/refusals.ts` (fifteen, on the shared vocabulary). The other three
1390
- are folders with one file per behaviour: `test/types/port/` (twenty-four, on
1526
+ are folders with one file per behaviour: `test/types/port/` (twenty-five, on
1391
1527
  the identity stores' port, from the point of view of the person implementing
1392
- it), `test/types/auth/` (sixty-five, on `janus()`, from the point of view of
1528
+ it), `test/types/auth/` (seventy-five, on `janus()`, from the point of view of
1393
1529
  the application — twelve of them on the second factor, three on sign-in codes,
1394
1530
  five on user events, four on step-ups, six on the sign-in throttle, five on the mail throttle, four on
1395
- sign-in links, six on devices) and `test/types/permissions/` (forty-eight, on the
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
1396
1532
  permission model and the questions asked of it). The rule comes from
1397
1533
  `nxgt-data`, and so does the reason to distrust the claim without the files:
1398
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;AAMpB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAGjD,KAAK,aAAa,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC,eAAe,CAAC,CAAC;AAEhE;;;GAGG;AACH,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,YAAY,EAClB,EAAE,EAAE,EAAE,GACJ,aAAa,CA8Cf"}
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"}
@@ -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` and `magicLink.confirm`, when
34
- * given a `device` its token did not prove. Never by `signUp`, nor without
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';
@@ -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
@@ -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;AAGzB,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"}
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;CACvB;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"}
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"}
@@ -1 +1 @@
1
- {"version":3,"file":"assert-stores.d.ts","sourceRoot":"","sources":["../../../src/auth/port/assert-stores.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAoC9D;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAC3B,MAAM,EAAE,OAAO,EACf,KAAK,EAAE,MAAM,GACX,iBAAiB,CAmCnB"}
1
+ {"version":3,"file":"assert-stores.d.ts","sourceRoot":"","sources":["../../../src/auth/port/assert-stores.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAoC9D;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAC3B,MAAM,EAAE,OAAO,EACf,KAAK,EAAE,MAAM,GACX,iBAAiB,CA+BnB"}
@@ -1 +1 @@
1
- {"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../../../src/auth/port/memory/users.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,UAAU,CAAC;AAYtD,mFAAmF;AACnF,wBAAgB,eAAe,IAAI,SAAS,CAiE3C"}
1
+ {"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../../../src/auth/port/memory/users.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,UAAU,CAAC;AAYtD,mFAAmF;AACnF,wBAAgB,eAAe,IAAI,SAAS,CAwE3C"}
@@ -24,5 +24,10 @@ export interface JanusStores {
24
24
  export interface StoreCapabilities {
25
25
  /** Whether `sessions.deleteExpiredSessions` is implemented. */
26
26
  readonly collectExpired: boolean;
27
+ /**
28
+ * Whether `users.findUsers` is implemented: `findMany` answers in one query
29
+ * when it is, and with `findUser`, a few ids at a time, when it is not.
30
+ */
31
+ readonly findUsers: boolean;
27
32
  }
28
33
  //# sourceMappingURL=stores.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stores.d.ts","sourceRoot":"","sources":["../../../../src/auth/port/types/stores.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;CAC5B;AAED,6DAA6D;AAC7D,MAAM,WAAW,iBAAiB;IACjC,+DAA+D;IAC/D,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CACjC"}
1
+ {"version":3,"file":"stores.d.ts","sourceRoot":"","sources":["../../../../src/auth/port/types/stores.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;CAC5B;AAED,6DAA6D;AAC7D,MAAM,WAAW,iBAAiB;IACjC,+DAA+D;IAC/D,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC5B"}
@@ -129,6 +129,23 @@ export interface UserStore {
129
129
  insertUser(record: UserRecord): Promise<UserRecord>;
130
130
  /** The user with this id, whatever their type, or `null`. */
131
131
  findUser(id: Id): Promise<UserRecord | null>;
132
+ /**
133
+ * **Optional capability.** The users holding these ids, whatever their
134
+ * type, in **one query** — `@nxgt/janus-drizzle`'s `inArray`,
135
+ * `@nxgt/janus-mongo`'s `$in`.
136
+ *
137
+ * An id no user holds is **left out**: an absence here is a shorter list,
138
+ * never `null` and never a rejection. Each record appears once, in any
139
+ * order — the core puts them back in the caller's order. A failure throws,
140
+ * as everywhere on this port: answering `[]` for an outage turns it into
141
+ * "nobody", which is the lockout rule 2 exists to prevent.
142
+ *
143
+ * The core calls it with **1 to 100 distinct, well-formed ids**, never an
144
+ * empty list, and reads a longer list in several calls. A store that does
145
+ * not implement it is read with `findUser`, a few ids at a time, so every
146
+ * store answers `findMany`; this method only makes it one round trip.
147
+ */
148
+ findUsers?(ids: readonly Id[]): Promise<readonly UserRecord[]>;
132
149
  /**
133
150
  * The user of this type holding this login, or `null`.
134
151
  *
@@ -1 +1 @@
1
- {"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../../../src/auth/port/types/users.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../../../src/auth/port/types/users.ts"],"names":[],"mappings":"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"}
@@ -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;AAYzB,OAAO,KAAK,EAEX,aAAa,EAEb,YAAY,EACZ,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;;GAcG;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,CAqB7D"}
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 by e-mail — a code or a link — answers: a session, or a
20
- * challenge when the type has a password in an instance given a
21
- * `secondFactor`, since the e-mail proves the address and not the factor.
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 EmailSignInAnswer<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>>;
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>, EmailSignInAnswer<Name, Def, TwoFactor>> & MagicLinkApi<UserOfType<Name, Def>, EmailSignInAnswer<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>>);
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;;;;GAIG;AACH,KAAK,iBAAiB,CACrB,IAAI,SAAS,MAAM,EACnB,GAAG,EACH,SAAS,SAAS,OAAO,IACtB,SAAS,SAAS,IAAI,GACvB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAC7B,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,GAC/B,YAAY,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,GACpC,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;AAEnC;;;GAGG;AACH,MAAM,MAAM,OAAO,CAClB,IAAI,SAAS,MAAM,EACnB,GAAG,EACH,SAAS,SAAS,OAAO,GAAG,KAAK,IAC9B,WAAW,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,GACvD,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAC5B,OAAO,GACP,SAAS,SAAS,IAAI,GACrB,WAAW,CACX,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,EACrB,WAAW,CAAC,GAAG,CAAC,EAChB,OAAO,CAAC,GAAG,CAAC,EACZ,YAAY,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CACnC,GACA,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,GACtC,WAAW,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GACvE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAC5B,OAAO,GACP,cAAc,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,GACrC,aAAa,CACZ,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,EACrB,iBAAiB,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,CAAC,CACvC,GACD,YAAY,CACX,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,EACrB,iBAAiB,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,CAAC,CACvC,GACD,SAAS,CACR,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,EACrB,SAAS,SAAS,IAAI,GACnB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAC7B,aAAa,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,GAElC,aAAa,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,GACpC,WAAW,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,GACrC,aAAa,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CACvC,CAAC,GACL,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAC5B,OAAO,GACP,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAC7B,OAAO,GACP,gBAAgB,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AAE9C,iEAAiE;AACjE,MAAM,WAAW,SAAS,CAAC,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE;IAC7D;;;;;;;;;;OAUG;IACH,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,EAC3C,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;KAAE,GAC7B,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAEnE,gGAAgG;IAChG,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEhD,uEAAuE;IACvE,iBAAiB,CAChB,IAAI,EAAE,OAAO,EACb,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GACpC,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAExC,kEAAkE;IAClE,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAEhC,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,EAAE;QAChB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC;QACnD,KAAK,IAAI,MAAM,CAAC;KAChB,CAAC;IAEF;;;;OAIG;IACH,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAElC,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;CACrC;AAED;;;;GAIG;AACH,KAAK,WAAW,CAAC,CAAC,IAAI,cAAc,SAAS,MAAM,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC;AAEpE,oCAAoC;AACpC,MAAM,MAAM,KAAK,CAAC,CAAC,SAAS,WAAW,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAC9D,CAAC,CAAC,SAAS,eAAe,GACvB;IACA,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,MAAM,GAAG,OAAO,CACjD,CAAC,EACD,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EACb,WAAW,CAAC,CAAC,CAAC,CACd;CACD,GACA,CAAC,SAAS,gBAAgB,GACzB,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,GAChD,KAAK,CAAC,CAAC"}
1
+ {"version":3,"file":"janus.d.ts","sourceRoot":"","sources":["../../../src/auth/types/janus.ts"],"names":[],"mappings":"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"}