@nxgt/janus 0.3.0 → 0.5.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 +135 -15
- package/dist/auth/config.d.ts +25 -1
- package/dist/auth/config.d.ts.map +1 -1
- package/dist/auth/context.d.ts.map +1 -1
- package/dist/auth/index.d.ts +4 -3
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/one-time.d.ts +39 -0
- package/dist/auth/one-time.d.ts.map +1 -0
- package/dist/auth/port/types.d.ts +74 -3
- package/dist/auth/port/types.d.ts.map +1 -1
- package/dist/auth/sealing.d.ts +39 -0
- package/dist/auth/sealing.d.ts.map +1 -0
- package/dist/auth/second-factor/challenge.d.ts +20 -0
- package/dist/auth/second-factor/challenge.d.ts.map +1 -0
- package/dist/auth/second-factor/factor.d.ts +30 -0
- package/dist/auth/second-factor/factor.d.ts.map +1 -0
- package/dist/auth/second-factor/flows.d.ts +19 -0
- package/dist/auth/second-factor/flows.d.ts.map +1 -0
- package/dist/auth/second-factor/lifecycle.d.ts +8 -0
- package/dist/auth/second-factor/lifecycle.d.ts.map +1 -0
- package/dist/auth/sessions.d.ts.map +1 -1
- package/dist/auth/totp.d.ts +36 -0
- package/dist/auth/totp.d.ts.map +1 -0
- package/dist/auth/types.d.ts +91 -7
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/auth/users.d.ts +2 -2
- package/dist/auth/users.d.ts.map +1 -1
- package/dist/chunks/{index-qwfkhqkk.js → index-06vp9c5r.js} +12 -3
- package/dist/chunks/{index-qwfkhqkk.js.map → index-06vp9c5r.js.map} +3 -3
- package/dist/chunks/{index-53y1afjz.js → index-5vr13kkb.js} +2 -2
- package/dist/chunks/{index-mgh85djb.js → index-c4v27jfr.js} +2 -2
- package/dist/chunks/{index-8tksqzkr.js → index-gbwn2tts.js} +14 -3
- package/dist/chunks/{index-8tksqzkr.js.map → index-gbwn2tts.js.map} +3 -3
- package/dist/conformance/cases/outage.d.ts.map +1 -1
- package/dist/conformance/cases/tokens.d.ts.map +1 -1
- package/dist/conformance/cases/users.d.ts.map +1 -1
- package/dist/conformance/fixtures.d.ts.map +1 -1
- package/dist/conformance/index.js +122 -5
- package/dist/conformance/index.js.map +6 -6
- package/dist/errors/janus-error.d.ts +28 -2
- package/dist/errors/janus-error.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +390 -40
- package/dist/index.js.map +15 -8
- package/dist/permissions/index.js +3 -3
- package/docs/README.md +2 -1
- package/docs/guide/adapters.md +129 -3
- package/docs/guide/errors.md +18 -6
- package/docs/guide/second-factor.md +569 -0
- package/docs/guide/sessions.md +18 -0
- package/docs/guide/users.md +8 -2
- package/docs/guide/vocabulary.md +6 -1
- package/docs/roadmap.md +33 -46
- package/docs/troubleshooting.md +276 -5
- package/package.json +1 -1
- /package/dist/chunks/{index-53y1afjz.js.map → index-5vr13kkb.js.map} +0 -0
- /package/dist/chunks/{index-mgh85djb.js.map → index-c4v27jfr.js.map} +0 -0
package/README.md
CHANGED
|
@@ -46,7 +46,7 @@ a published entry point is a promise.
|
|
|
46
46
|
## Three ways to use it
|
|
47
47
|
|
|
48
48
|
Janus has two sides. **Identities** answers *who is this?* — users, their
|
|
49
|
-
logins and passwords, sessions, one-time tokens. **Permissions** answers *may
|
|
49
|
+
logins and passwords, a TOTP second factor, sessions, one-time tokens. **Permissions** answers *may
|
|
50
50
|
they?* — a model, the tuples stored against it, and `can`. Each side is usable
|
|
51
51
|
alone, and neither loads the other's code: a spec reads the import graph of
|
|
52
52
|
each entry point and fails if one reaches into the other.
|
|
@@ -165,7 +165,7 @@ async function signIn(email: string, password: string): Promise<Response> {
|
|
|
165
165
|
```
|
|
166
166
|
|
|
167
167
|
`JanusError` is the base of everything thrown at call time. It extends `Error`,
|
|
168
|
-
so no consumer has to order their `catch` blocks. `code` is a union of
|
|
168
|
+
so no consumer has to order their `catch` blocks. `code` is a union of nineteen
|
|
169
169
|
string literals, so a `switch` over it is exhaustive and adding a code breaks the
|
|
170
170
|
compilation of callers that exhaust it:
|
|
171
171
|
|
|
@@ -177,6 +177,8 @@ compilation of callers that exhaust it:
|
|
|
177
177
|
| `USER_INVALID` | 400, field by field from `issues` |
|
|
178
178
|
| `PASSWORD_TOO_SHORT`, `HASH_UNSUPPORTED` | 400 |
|
|
179
179
|
| `CREDENTIALS_INVALID` | 401 — one code for an unknown login, no password and a wrong one |
|
|
180
|
+
| `CODE_INVALID` | 401 — a second factor's code that does not match or was already accepted; `attemptsLeft` from `confirm` belongs in the body |
|
|
181
|
+
| `SECOND_FACTOR_NOT_ENROLLED`, `SECOND_FACTOR_ACTIVE` | 409 — the factor is not in the state the call needs |
|
|
180
182
|
| `USER_INACTIVE` | 403 |
|
|
181
183
|
| `TOKEN_UNKNOWN`, `TOKEN_SPENT`, `TOKEN_EXPIRED`, `TOKEN_STALE` | 400 |
|
|
182
184
|
| `INVALID_CURSOR` | 400 |
|
|
@@ -185,13 +187,15 @@ compilation of callers that exhaust it:
|
|
|
185
187
|
|
|
186
188
|
Each code has its class, all exported: `StoreFailure`, `StoreConflict` (`on:
|
|
187
189
|
'login' | 'version'`), `NotFoundError`, `UserInvalidError`, `CredentialError`,
|
|
188
|
-
`UserInactiveError`, `TokenError
|
|
189
|
-
|
|
190
|
+
`UserInactiveError`, `TokenError` (the `TOKEN_*` codes and `CODE_INVALID`),
|
|
191
|
+
`SecondFactorError`, `InvalidCursorError`, `UnsupportedError` and
|
|
192
|
+
`PermissionDepthError`. `StoreFailure` and `StoreConflict` are exported
|
|
190
193
|
**because an adapter throws them**. An adapter defines no error class of its own, so `instanceof` holds
|
|
191
194
|
across the two packages.
|
|
192
195
|
|
|
193
196
|
**No message ever holds a secret** — not a password, not a hash, not a session
|
|
194
|
-
token, not a token's hash,
|
|
197
|
+
token, not a token's hash, not a challenge, a code or a TOTP secret, and not a
|
|
198
|
+
connection URI, because a connection string
|
|
195
199
|
holds a password. Nor a login: a message reports a shape, never a value, so
|
|
196
200
|
`LOGIN_TAKEN` names the login in `error.login`, not in its message.
|
|
197
201
|
|
|
@@ -299,8 +303,8 @@ const auth = janus({
|
|
|
299
303
|
hasher: scryptHasher(),
|
|
300
304
|
});
|
|
301
305
|
|
|
302
|
-
await auth.signUp({ email, name, password }); // { user, session, token }
|
|
303
|
-
await auth.signIn({ email, password }); // { user, session, token }
|
|
306
|
+
await auth.signUp({ email, name, password }); // { status: 'signedIn', user, session, token }
|
|
307
|
+
await auth.signIn({ email, password }); // { status: 'signedIn', user, session, token }
|
|
304
308
|
await auth.authenticate(request); // { user, session, token, renewed } | null
|
|
305
309
|
await auth.signOut(request);
|
|
306
310
|
await auth.verifyEmail.send(user); // { token, email, expiresAt } — sending it is yours
|
|
@@ -333,8 +337,8 @@ store answers every method of the port, and connects to nothing. Everything
|
|
|
333
337
|
else reaches the store and is asynchronous.
|
|
334
338
|
|
|
335
339
|
- **A user is your schema's fields, at the top level**, plus what `janus` sets:
|
|
336
|
-
`id`, `type`, `emailVerified`, `active`, `hasPassword`, `
|
|
337
|
-
`createdAt`, `updatedAt`. A schema declaring one of those, or a `password`, is
|
|
340
|
+
`id`, `type`, `emailVerified`, `active`, `hasPassword`, `hasSecondFactor`,
|
|
341
|
+
`version`, `createdAt`, `updatedAt`. A schema declaring one of those, or a `password`, is
|
|
338
342
|
refused at compile time. The password hash never reaches a user.
|
|
339
343
|
- **Schemas** are any [Standard Schema](https://standardschema.dev) — Zod 4,
|
|
340
344
|
Valibot, ArkType. There is no validation peer. The output must be JSON, and a
|
|
@@ -396,6 +400,93 @@ adapter. `assertStores(store, where)` is the check `janus()` runs on it, for an
|
|
|
396
400
|
adapter that wants to fail as early. The six rules an adapter keeps are
|
|
397
401
|
written on the port's types.
|
|
398
402
|
|
|
403
|
+
The port holds what one-time codes need: a user's `secondFactor` (a TOTP
|
|
404
|
+
secret the core seals before a store sees it, or `null`), a token's
|
|
405
|
+
`codeHash` and `attempts`, and `TokenStore.countAttempt`, which counts one
|
|
406
|
+
attempt in one conditional write:
|
|
407
|
+
|
|
408
|
+
```ts
|
|
409
|
+
import { createMemoryStores, mintId } from '@nxgt/janus';
|
|
410
|
+
|
|
411
|
+
const { tokens } = createMemoryStores();
|
|
412
|
+
const tokenHash = 'a'.repeat(64); // the core stores sha256 of the secret
|
|
413
|
+
await tokens.insertToken({
|
|
414
|
+
tokenHash,
|
|
415
|
+
kind: 'signInCode',
|
|
416
|
+
userId: mintId(),
|
|
417
|
+
address: 'ada@example.test',
|
|
418
|
+
codeHash: 'c'.repeat(64),
|
|
419
|
+
attempts: 0,
|
|
420
|
+
expiresAt: new Date(Date.now() + 10 * 60_000),
|
|
421
|
+
spentAt: null,
|
|
422
|
+
createdAt: new Date(),
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
await tokens.countAttempt(tokenHash, 'signInCode'); // { …, attempts: 1 }
|
|
426
|
+
await tokens.countAttempt(tokenHash, 'verifyEmail'); // null: no token of that kind
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
An adapter written against `@nxgt/janus` 0.3 does not compile against this
|
|
430
|
+
port until it implements `countAttempt`, and `janus()` refuses it at wiring —
|
|
431
|
+
[Writing an adapter](docs/guide/adapters.md#tokenstorecountattempt) has the
|
|
432
|
+
contract.
|
|
433
|
+
|
|
434
|
+
### Second factor — `secondFactor`
|
|
435
|
+
|
|
436
|
+
```ts
|
|
437
|
+
import { z } from 'zod';
|
|
438
|
+
import { createMemoryStores, janus, scryptHasher } from '@nxgt/janus';
|
|
439
|
+
|
|
440
|
+
const auth = janus({
|
|
441
|
+
user: z.object({ email: z.email() }),
|
|
442
|
+
password: { login: 'email' },
|
|
443
|
+
store: createMemoryStores(),
|
|
444
|
+
hasher: scryptHasher(),
|
|
445
|
+
secondFactor: {
|
|
446
|
+
issuer: 'Example', // shown in the authenticator app
|
|
447
|
+
keys: [{ id: '2026-09', key: process.env.TOTP_KEY ?? '' }], // openssl rand -base64 32
|
|
448
|
+
},
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
const { secret, uri } = await auth.secondFactor.enroll(user); // show uri as a QR code, secret beside it
|
|
452
|
+
await auth.secondFactor.activate(user, code); // the first code: the factor is active
|
|
453
|
+
|
|
454
|
+
const result = await auth.signIn({ email, password });
|
|
455
|
+
if (result.status === 'secondFactor') {
|
|
456
|
+
// no session yet: keep result.challenge for the next request — never in a URL or a log
|
|
457
|
+
const signedIn = await auth.secondFactor.confirm(result.challenge, code); // { status: 'signedIn', … }
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
await auth.secondFactor.disable(user);
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
A TOTP second factor — the six-digit codes of any authenticator app — for
|
|
464
|
+
every user type with a password.
|
|
465
|
+
|
|
466
|
+
- **`signIn` answers a union once `secondFactor` is configured**:
|
|
467
|
+
`{ status: 'signedIn', user, session, token }`, or
|
|
468
|
+
`{ status: 'secondFactor', challenge, expiresAt }` for a user whose factor
|
|
469
|
+
is active. Switch on `status`: reading `token` before that is a compile
|
|
470
|
+
error. Without `secondFactor`, `signIn` answers a session, as before.
|
|
471
|
+
- **A factor is enrolled, then active.** `enroll` answers the secret and its
|
|
472
|
+
`otpauth://` URI once; enrolling again replaces a factor still waiting.
|
|
473
|
+
`activate` checks a first code, and only then does `signIn` ask for one —
|
|
474
|
+
`hasSecondFactor` says so.
|
|
475
|
+
- **`confirm(challenge, code)`** opens the session. A challenge lives `'5m'`
|
|
476
|
+
(`secondFactor.challenge`) and takes five attempts: a wrong code is
|
|
477
|
+
`CODE_INVALID` with `attemptsLeft`, and the fifth spends the challenge. A
|
|
478
|
+
code is accepted once, so a replay is `CODE_INVALID` too.
|
|
479
|
+
- **`keys` seal every TOTP secret** with AES-256-GCM before a store sees it.
|
|
480
|
+
The first seals and every key opens, so keys rotate: put the new one first,
|
|
481
|
+
keep the old one until no secret is sealed with it.
|
|
482
|
+
- **Asking for a password or a code before `enroll` or `disable` is your
|
|
483
|
+
policy**, not the library's — a recent `session.authenticatedAt` is one
|
|
484
|
+
rule.
|
|
485
|
+
|
|
486
|
+
[The second factor guide](docs/guide/second-factor.md) has every option,
|
|
487
|
+
error and state, key rotation, and a sign-in route with the challenge in a
|
|
488
|
+
cookie.
|
|
489
|
+
|
|
399
490
|
### Permissions — `@nxgt/janus/permissions`
|
|
400
491
|
|
|
401
492
|
```ts
|
|
@@ -506,7 +597,7 @@ describeJanusStores({
|
|
|
506
597
|
});
|
|
507
598
|
```
|
|
508
599
|
|
|
509
|
-
There are
|
|
600
|
+
There are 45 cases. They cover:
|
|
510
601
|
- round-trip, byte for byte — including every edge character the core lets
|
|
511
602
|
through (control characters, U+FFFF, a surrogate pair);
|
|
512
603
|
- uniqueness, as a constraint: of twenty concurrent inserts of one login,
|
|
@@ -517,9 +608,14 @@ There are 38 cases. They cover:
|
|
|
517
608
|
- pagination;
|
|
518
609
|
- sessions;
|
|
519
610
|
- one-time tokens: of twenty concurrent redemptions, exactly one succeeds;
|
|
611
|
+
of twenty concurrent `countAttempt` calls, each answers a distinct count,
|
|
612
|
+
and none is counted once a racing redemption spent the token;
|
|
613
|
+
- a second-factor challenge, whose address is `''`, kept, counted and spent;
|
|
614
|
+
- a user's second factor: round-trip, kept by a patch that does not name it,
|
|
615
|
+
removed by one that names `null`;
|
|
520
616
|
- deletion: a user's logins are freed, and every session and token of theirs
|
|
521
617
|
goes, with a replay answering `false` or `0` rather than failing;
|
|
522
|
-
- **outages**, one case for each of the
|
|
618
|
+
- **outages**, one case for each of the twelve methods whose honest answer can
|
|
523
619
|
be "nothing".
|
|
524
620
|
|
|
525
621
|
The suite imports no test framework and no assertion library. It runs under
|
|
@@ -551,6 +647,29 @@ example; `allRelationCases`, `relationStoreCases`, `relationOutageCases` and
|
|
|
551
647
|
|
|
552
648
|
## Traps
|
|
553
649
|
|
|
650
|
+
**Once `secondFactor` is configured, switch on `signIn`'s `status`.** A user
|
|
651
|
+
whose factor is active gets `{ status: 'secondFactor', challenge }`, with no
|
|
652
|
+
`token` and no `session`: `if (result.status === 'secondFactor') …` before
|
|
653
|
+
anything reads them.
|
|
654
|
+
|
|
655
|
+
**A challenge is a secret, like a session token.** Keep it in a short-lived
|
|
656
|
+
`HttpOnly` cookie or the body of the code form — never in a URL, where logs,
|
|
657
|
+
proxies and the `Referer` header see it, and never in a log.
|
|
658
|
+
|
|
659
|
+
**Every `janus()` that signs users in needs the same `secondFactor`.** An
|
|
660
|
+
instance without keys never signs in a user whose factor is active: `signIn`
|
|
661
|
+
throws a `TypeError` rather than open a session on the password alone. Build
|
|
662
|
+
the configuration once and import it everywhere.
|
|
663
|
+
|
|
664
|
+
**Never remove a sealing key while a secret is sealed with it, nor change a
|
|
665
|
+
key under the same id.** That user's next sign-in is a `TypeError`, not a
|
|
666
|
+
refusal. Put the new key first and keep the old one until your database holds
|
|
667
|
+
no secret starting `v1.<old id>.`.
|
|
668
|
+
|
|
669
|
+
**`enroll` and `disable` ask for nothing.** Whether the user proves their
|
|
670
|
+
password or a code first is yours to decide; without a check, a stolen
|
|
671
|
+
session can switch the factor off.
|
|
672
|
+
|
|
554
673
|
**On a user type, only `setOf` makes a set.** A user passed as it is — or
|
|
555
674
|
`{ type: 'staff', id, relation: 'managers' }` written out — is that one user,
|
|
556
675
|
even with a field named `relation`. The compiler refuses the written-out set
|
|
@@ -655,15 +774,16 @@ could not answer: that is a denial made of an outage.
|
|
|
655
774
|
|
|
656
775
|
## Type safety, counted
|
|
657
776
|
|
|
658
|
-
**
|
|
777
|
+
**One hundred and eleven plausible mistakes, one hundred and eleven refused at compile time — and
|
|
659
778
|
two gaps, named.**
|
|
660
779
|
|
|
661
780
|
The lists are typechecked and never run, with one `@ts-expect-error` per
|
|
662
781
|
mistake beside the shapes that must keep compiling:
|
|
663
782
|
`test/types/refusals.ts` (fourteen, on the shared vocabulary),
|
|
664
|
-
`test/types/port.ts` (
|
|
665
|
-
of view of the person implementing it), `test/types/auth.ts` (twenty, on
|
|
666
|
-
`janus()`, from the point of view of the application
|
|
783
|
+
`test/types/port.ts` (twenty-one, on the identity stores' port, from the point
|
|
784
|
+
of view of the person implementing it), `test/types/auth.ts` (twenty-eight, on
|
|
785
|
+
`janus()`, from the point of view of the application — eight of them on the
|
|
786
|
+
second factor) and `test/types/permissions.ts` (forty-eight, on the
|
|
667
787
|
permission model and the questions asked of it). The rule
|
|
668
788
|
comes from `nxgt-data`, and so does the reason to
|
|
669
789
|
distrust the claim without the files: when it was last measured on
|
package/dist/auth/config.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import type { RelationStore } from '../permissions/port/types';
|
|
|
10
10
|
import type { Clock } from '../time/clock';
|
|
11
11
|
import { type Duration } from '../time/duration';
|
|
12
12
|
import type { JanusStores } from './port/types';
|
|
13
|
+
import { type Sealer, type SealingKey } from './sealing';
|
|
13
14
|
import type { StandardSchemaV1 } from './standard-schema';
|
|
14
15
|
/**
|
|
15
16
|
* How a login is normalised before any store sees it. `'lowercaseTrim'` when
|
|
@@ -137,6 +138,24 @@ interface SharedConfig {
|
|
|
137
138
|
/** `'1h'` when absent. */
|
|
138
139
|
readonly resetPassword?: Duration;
|
|
139
140
|
};
|
|
141
|
+
/**
|
|
142
|
+
* A TOTP second factor, for every user type with a password. Absent, no
|
|
143
|
+
* `secondFactor` flows exist and `signIn` answers a session directly.
|
|
144
|
+
*/
|
|
145
|
+
readonly secondFactor?: SecondFactorConfig;
|
|
146
|
+
}
|
|
147
|
+
/** What a TOTP second factor needs: a name for the app, and the keys that seal. */
|
|
148
|
+
export interface SecondFactorConfig {
|
|
149
|
+
/** Shown in the authenticator app beside the account: your product's name. */
|
|
150
|
+
readonly issuer: string;
|
|
151
|
+
/**
|
|
152
|
+
* The keys every TOTP secret is sealed with before a store sees it. **The
|
|
153
|
+
* first seals, every one opens**: to rotate, put the new key first and keep
|
|
154
|
+
* the old one until no secret is sealed with it.
|
|
155
|
+
*/
|
|
156
|
+
readonly keys: readonly [SealingKey, ...SealingKey[]];
|
|
157
|
+
/** How long `signIn`'s challenge waits for a code. `'5m'` when absent. */
|
|
158
|
+
readonly challenge?: Duration;
|
|
140
159
|
}
|
|
141
160
|
/** An application with one user type: `user` is its schema. */
|
|
142
161
|
export interface SingleTypeConfig extends SharedConfig, Omit<UserTypeConfig, 'schema'> {
|
|
@@ -161,7 +180,7 @@ export declare const SINGLE_TYPE = "user";
|
|
|
161
180
|
* Keys `janus` sets on every user, so a schema may not declare them.
|
|
162
181
|
* `password` too: it is taken beside the fields, and never stored among them.
|
|
163
182
|
*/
|
|
164
|
-
export declare const RESERVED_FIELDS: readonly ["id", "type", "emailVerified", "active", "hasPassword", "version", "createdAt", "updatedAt", "password"];
|
|
183
|
+
export declare const RESERVED_FIELDS: readonly ["id", "type", "emailVerified", "active", "hasPassword", "hasSecondFactor", "version", "createdAt", "updatedAt", "password"];
|
|
165
184
|
/** Names on `janus()`'s answer, so a user type may not take one. */
|
|
166
185
|
export declare const RESERVED_TYPES: readonly ["authenticate", "signOut", "signOutEverywhere", "findUser", "getUser", "cookie", "collectExpired", "types"];
|
|
167
186
|
/** One user type, with every default applied and every duration in milliseconds. */
|
|
@@ -185,6 +204,11 @@ export interface ResolvedConfig {
|
|
|
185
204
|
readonly verifyEmail: number;
|
|
186
205
|
readonly resetPassword: number;
|
|
187
206
|
};
|
|
207
|
+
readonly secondFactor: {
|
|
208
|
+
readonly issuer: string;
|
|
209
|
+
readonly sealer: Sealer;
|
|
210
|
+
readonly challengeTtlMs: number;
|
|
211
|
+
} | null;
|
|
188
212
|
readonly cookie: {
|
|
189
213
|
readonly name: string;
|
|
190
214
|
readonly domain: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/auth/config.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/auth/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/auth/context.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAEN,KAAK,cAAc,EAEnB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,MAAM,UAAU,CAAC;AAElB,OAAO,KAAK,EACX,WAAW,EAEX,UAAU,EACV,iBAAiB,EACjB,SAAS,EACT,UAAU,EACV,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE3D,MAAM,WAAW,OAAO;IACvB,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,iDAAiD;IACjD,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,YAAY,EAAE,iBAAiB,CAAC;IACzC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IACvC,kFAAkF;IAClF,QAAQ,CAAC,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IAC9C,+EAA+E;IAC/E,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC7B;AAED,wBAAgB,aAAa,CAC5B,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,WAAW,EAClB,SAAS,EAAE,aAAa,GAAG,IAAI,EAC/B,YAAY,EAAE,iBAAiB,EAC/B,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,cAAc,GAAG,IAAI,EAC7B,SAAS,EAAE,SAAS,cAAc,EAAE,GAClC,OAAO,CAmBT;AAED,kEAAkE;AAClE,MAAM,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE5D;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/auth/context.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAEN,KAAK,cAAc,EAEnB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,MAAM,UAAU,CAAC;AAElB,OAAO,KAAK,EACX,WAAW,EAEX,UAAU,EACV,iBAAiB,EACjB,SAAS,EACT,UAAU,EACV,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE3D,MAAM,WAAW,OAAO;IACvB,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,iDAAiD;IACjD,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,YAAY,EAAE,iBAAiB,CAAC;IACzC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IACvC,kFAAkF;IAClF,QAAQ,CAAC,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IAC9C,+EAA+E;IAC/E,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC7B;AAED,wBAAgB,aAAa,CAC5B,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,WAAW,EAClB,SAAS,EAAE,aAAa,GAAG,IAAI,EAC/B,YAAY,EAAE,iBAAiB,EAC/B,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,cAAc,GAAG,IAAI,EAC7B,SAAS,EAAE,SAAS,cAAc,EAAE,GAClC,OAAO,CAmBT;AAED,kEAAkE;AAClE,MAAM,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE5D;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAalD;AAED,sCAAsC;AACtC,eAAO,MAAM,IAAI,GAAI,MAAM,OAAO,KAAG,MACK,CAAC;AAE3C;;;GAGG;AACH,wBAAsB,cAAc,CACnC,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,CAAC,CAmCrB;AA+DD,gFAAgF;AAChF,wBAAgB,OAAO,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAG7E;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CACvB,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,MAAM,GACX,MAAM,EAAE,CAiCV;AAED,0FAA0F;AAC1F,wBAAgB,aAAa,CAC5B,IAAI,EAAE,YAAY,EAClB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACX,IAAI,CASN;AAED,0FAA0F;AAC1F,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,CAO7E;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACpC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC,CAiBlB;AAED;;;;;;;;GAQG;AACH,wBAAsB,QAAQ,CAC7B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,MAAM,GACd,OAAO,CAAC,UAAU,CAAC,CAyBrB;AAUD;;;;;GAKG;AACH,wBAAsB,UAAU,CAC/B,OAAO,EAAE,OAAO,EAChB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,GAAG,IAAI,GACjB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAM5B;AAED,gCAAgC;AAChC,wBAAsB,SAAS,CAC9B,OAAO,EAAE,OAAO,EAChB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,GAAG,IAAI,EACnB,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,CAAC,CAIrB;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAC9B,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,OAAO,EACb,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,YAAY,GAAG,SAAS,EACjC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,CACR,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,IAAI,KACL,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,GACvE,OAAO,CAAC,UAAU,CAAC,CAyBrB"}
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export type { CookieConfig, FieldsJson, JanusConfig, MultiTypeConfig, Normalize, PasswordConfig, PasswordHasher, SessionConfig, SingleTypeConfig, UserSchema, UserTypeConfig, } from './config';
|
|
1
|
+
export type { CookieConfig, FieldsJson, JanusConfig, MultiTypeConfig, Normalize, PasswordConfig, PasswordHasher, SecondFactorConfig, SessionConfig, SingleTypeConfig, UserSchema, UserTypeConfig, } from './config';
|
|
2
2
|
export { bunHasher, scryptHasher } from './hashers';
|
|
3
3
|
export { janus } from './janus';
|
|
4
4
|
export { assertStores } from './port/assert-stores';
|
|
5
5
|
export { createMemoryStores } from './port/memory';
|
|
6
|
-
export type { JanusStores, Json, JsonObject, PasswordRecord, SessionId, SessionRecord, SessionStore, StoreCapabilities, TokenKind, TokenRecord, TokenStore, UserPageRequest, UserPatch, UserRecord, UserStore, } from './port/types';
|
|
6
|
+
export type { JanusStores, Json, JsonObject, PasswordRecord, SecondFactorRecord, SessionId, SessionRecord, SessionStore, StoreCapabilities, TokenKind, TokenRecord, TokenStore, UserPageRequest, UserPatch, UserRecord, UserStore, } from './port/types';
|
|
7
|
+
export type { SealingKey } from './sealing';
|
|
7
8
|
export type { StandardSchemaV1 } from './standard-schema';
|
|
8
|
-
export type { Authenticated, Checked, EmailOf, HeaderRecord, IssuedToken, Janus, LoginOf, PasswordApi, RequestLike, RequiredStringKeys, ResetPasswordApi, Session, SharedApi, SignedIn, TypeApi, TypesOf, User, UserBase, UserOf, UserRef, UserTypeApi, VerifyEmailApi, WriteOptions, } from './types';
|
|
9
|
+
export type { Authenticated, Checked, EmailOf, HeaderRecord, IssuedToken, Janus, LoginOf, PasswordApi, RequestLike, RequiredStringKeys, ResetPasswordApi, SecondFactorApi, SecondFactorEnrolment, SecondFactorRequired, Session, SharedApi, SignedIn, SignInResult, TypeApi, TypesOf, User, UserBase, UserOf, UserRef, UserTypeApi, VerifyEmailApi, WriteOptions, } from './types';
|
|
9
10
|
//# 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,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,cAAc,GACd,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,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,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,YAAY,EACX,aAAa,EACb,OAAO,EACP,OAAO,EACP,YAAY,EACZ,WAAW,EACX,KAAK,EACL,OAAO,EACP,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAChB,OAAO,EACP,SAAS,EACT,QAAQ,EACR,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,UAAU,EACV,WAAW,EACX,eAAe,EACf,SAAS,EACT,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,cAAc,GACd,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,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,YAAY,EACX,aAAa,EACb,OAAO,EACP,OAAO,EACP,YAAY,EACZ,WAAW,EACX,KAAK,EACL,OAAO,EACP,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,oBAAoB,EACpB,OAAO,EACP,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,OAAO,EACP,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,OAAO,EACP,WAAW,EACX,cAAc,EACd,YAAY,GACZ,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { TokenError } from '../errors/janus-error';
|
|
2
|
+
import type { Context } from './context';
|
|
3
|
+
import type { TokenKind, TokenRecord } from './port/types';
|
|
4
|
+
/**
|
|
5
|
+
* The rules every one-time token shares — an e-mail link, a second-factor
|
|
6
|
+
* challenge — kept in one place so the two cannot drift apart.
|
|
7
|
+
*
|
|
8
|
+
* `noun` is what the messages call it: `token` for a link, `challenge` for
|
|
9
|
+
* what `signIn` answers. No message names the secret or its hash.
|
|
10
|
+
*/
|
|
11
|
+
export type OneTimeNoun = 'token' | 'challenge';
|
|
12
|
+
/**
|
|
13
|
+
* Refuses a token that cannot be used: none, spent, or lapsed. What a store
|
|
14
|
+
* answered — before a `consumeToken`, after a `countAttempt` — is read the
|
|
15
|
+
* same way: `spentAt` set means somebody else used it.
|
|
16
|
+
*/
|
|
17
|
+
export declare function refuseUnusable(token: TokenRecord | null, now: Date, where: string, noun: OneTimeNoun): asserts token is TokenRecord;
|
|
18
|
+
/** The refusal for a token whose user is gone, or of another type. */
|
|
19
|
+
export declare const unknownOneTime: (where: string, noun: OneTimeNoun) => TokenError;
|
|
20
|
+
/**
|
|
21
|
+
* Spends a token, and refuses it when this call did not: the store answers it
|
|
22
|
+
* **as it was before**, so exactly one call ever reads `spentAt: null`. A
|
|
23
|
+
* lapsed token is spent all the same, so it cannot be retried.
|
|
24
|
+
*/
|
|
25
|
+
export declare function spendOneTime(context: Context, secret: string, kind: TokenKind, where: string, noun: OneTimeNoun): Promise<TokenRecord>;
|
|
26
|
+
/**
|
|
27
|
+
* Issues a one-time token: 32 random bytes, given back once, and only their
|
|
28
|
+
* hash stored.
|
|
29
|
+
*/
|
|
30
|
+
export declare function issueOneTime(context: Context, token: {
|
|
31
|
+
readonly kind: TokenKind;
|
|
32
|
+
readonly userId: string;
|
|
33
|
+
readonly address: string;
|
|
34
|
+
readonly ttlMs: number;
|
|
35
|
+
}): Promise<{
|
|
36
|
+
readonly secret: string;
|
|
37
|
+
readonly expiresAt: Date;
|
|
38
|
+
}>;
|
|
39
|
+
//# sourceMappingURL=one-time.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"one-time.d.ts","sourceRoot":"","sources":["../../src/auth/one-time.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG3D;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,WAAW,CAAC;AAEhD;;;;GAIG;AACH,wBAAgB,cAAc,CAC7B,KAAK,EAAE,WAAW,GAAG,IAAI,EACzB,GAAG,EAAE,IAAI,EACT,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,WAAW,GACf,OAAO,CAAC,KAAK,IAAI,WAAW,CAkB9B;AAED,sEAAsE;AACtE,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,EAAE,MAAM,WAAW,eAG5D,CAAC;AAEJ;;;;GAIG;AACH,wBAAsB,YAAY,CACjC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,WAAW,GACf,OAAO,CAAC,WAAW,CAAC,CAStB;AAED;;;GAGG;AACH,wBAAsB,YAAY,CACjC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE;IACN,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,GACC,OAAO,CAAC;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAA;CAAE,CAAC,CAiBhE"}
|
|
@@ -84,6 +84,31 @@ export interface PasswordRecord {
|
|
|
84
84
|
readonly hash: string;
|
|
85
85
|
readonly updatedAt: Date;
|
|
86
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* A second factor, as the store holds it: a TOTP secret.
|
|
89
|
+
*
|
|
90
|
+
* **The secret is opaque to a store.** The core seals it with a key the
|
|
91
|
+
* application holds — AES-256-GCM, `v1.<key id>.<iv>.<ciphertext>` — before a
|
|
92
|
+
* store ever sees it, so a dump of the users cannot produce a code. A store
|
|
93
|
+
* keeps the string byte for byte, like a password hash, and never parses it.
|
|
94
|
+
*/
|
|
95
|
+
export interface SecondFactorRecord {
|
|
96
|
+
/** How the codes are made. `'totp'`, the codes of an authenticator app, is the only one. */
|
|
97
|
+
readonly method: 'totp';
|
|
98
|
+
/** The secret, opaque to a store: kept byte for byte. */
|
|
99
|
+
readonly secret: string;
|
|
100
|
+
/**
|
|
101
|
+
* When the user proved their app holds the secret, with a first code — or
|
|
102
|
+
* `null` while the enrolment waits for it. A second factor is asked for at
|
|
103
|
+
* sign-in only once confirmed.
|
|
104
|
+
*/
|
|
105
|
+
readonly confirmedAt: Date | null;
|
|
106
|
+
/**
|
|
107
|
+
* The time step of the last code accepted, or `null` before the first. A
|
|
108
|
+
* code of this step or an earlier one is refused, so a code works once.
|
|
109
|
+
*/
|
|
110
|
+
readonly lastStep: number | null;
|
|
111
|
+
}
|
|
87
112
|
/**
|
|
88
113
|
* A user, as a store holds it.
|
|
89
114
|
*
|
|
@@ -122,6 +147,8 @@ export interface UserRecord {
|
|
|
122
147
|
readonly logins: readonly string[];
|
|
123
148
|
/** `null` when the user has no password. */
|
|
124
149
|
readonly password: PasswordRecord | null;
|
|
150
|
+
/** `null` when the user has no second factor. */
|
|
151
|
+
readonly secondFactor: SecondFactorRecord | null;
|
|
125
152
|
/**
|
|
126
153
|
* When the user proved they hold their current e-mail, or `null`. The core
|
|
127
154
|
* sets it back to `null` in the same write that changes the e-mail.
|
|
@@ -166,6 +193,7 @@ export interface UserPatch {
|
|
|
166
193
|
readonly fields?: JsonObject;
|
|
167
194
|
readonly logins?: readonly string[];
|
|
168
195
|
readonly password?: PasswordRecord | null;
|
|
196
|
+
readonly secondFactor?: SecondFactorRecord | null;
|
|
169
197
|
readonly emailVerifiedAt?: Date | null;
|
|
170
198
|
}
|
|
171
199
|
/** Which users a page lists, where it starts, and how much of it to read. */
|
|
@@ -328,16 +356,40 @@ export interface SessionStore {
|
|
|
328
356
|
*/
|
|
329
357
|
deleteExpiredSessions?(before: Date): Promise<number>;
|
|
330
358
|
}
|
|
331
|
-
/**
|
|
332
|
-
|
|
359
|
+
/**
|
|
360
|
+
* What a one-time token is for. A token redeemed for another purpose is
|
|
361
|
+
* unknown.
|
|
362
|
+
*
|
|
363
|
+
* - `verifyEmail`, `resetPassword`: a link sent by e-mail.
|
|
364
|
+
* - `secondFactor`: the challenge a sign-in answers when the user has a second
|
|
365
|
+
* factor, redeemed with a code from their app.
|
|
366
|
+
* - `signInCode`: a code sent by e-mail to sign in without a password.
|
|
367
|
+
*/
|
|
368
|
+
export type TokenKind = 'verifyEmail' | 'resetPassword' | 'secondFactor' | 'signInCode';
|
|
333
369
|
/** A one-time token, as a store holds it: its hash, never its secret. */
|
|
334
370
|
export interface TokenRecord {
|
|
335
371
|
/** `sha256` of the token's secret, hex. Unique across the store. */
|
|
336
372
|
readonly tokenHash: string;
|
|
337
373
|
readonly kind: TokenKind;
|
|
338
374
|
readonly userId: Id;
|
|
339
|
-
/**
|
|
375
|
+
/**
|
|
376
|
+
* The e-mail the token was sent to — the one a verification marks
|
|
377
|
+
* verified. `''` for a second-factor challenge, which nothing was sent for.
|
|
378
|
+
*/
|
|
340
379
|
readonly address: string;
|
|
380
|
+
/**
|
|
381
|
+
* For a token redeemed with a code — `signInCode` — the code's hash, keyed
|
|
382
|
+
* by the token's secret, so the tokens alone do not reveal it. `null` for
|
|
383
|
+
* every other kind: the core writes it so, and a store keeps what it is
|
|
384
|
+
* given.
|
|
385
|
+
*/
|
|
386
|
+
readonly codeHash: string | null;
|
|
387
|
+
/**
|
|
388
|
+
* How many codes were tried against it: `0` at insertion, and one more on
|
|
389
|
+
* every {@link TokenStore.countAttempt}. What bounds the attempts at a
|
|
390
|
+
* six-digit code.
|
|
391
|
+
*/
|
|
392
|
+
readonly attempts: number;
|
|
341
393
|
readonly expiresAt: Date;
|
|
342
394
|
/** `null` until spent. Once set, never changes. */
|
|
343
395
|
readonly spentAt: Date | null;
|
|
@@ -370,6 +422,25 @@ export interface TokenStore {
|
|
|
370
422
|
* job, after the call, so a lapsed token can never be retried.
|
|
371
423
|
*/
|
|
372
424
|
consumeToken(tokenHash: string, kind: TokenKind, at: Date): Promise<TokenRecord | null>;
|
|
425
|
+
/**
|
|
426
|
+
* Counts one attempt at a code against a token, and answers the token **as
|
|
427
|
+
* it is after this call**.
|
|
428
|
+
*
|
|
429
|
+
* - An **unspent** token of this `kind` has `attempts` one higher, and is
|
|
430
|
+
* answered with it. Twenty concurrent calls answer twenty distinct
|
|
431
|
+
* counts: one conditional write, never a read followed by a write — a
|
|
432
|
+
* count two guesses both read is a guess for free.
|
|
433
|
+
* - A **spent** token is answered as it is, and nothing is written.
|
|
434
|
+
* - `null` means no token of this `kind` has this hash.
|
|
435
|
+
*
|
|
436
|
+
* A **lapsed** token is counted all the same, or answered `null` by a store
|
|
437
|
+
* that already dropped it — as for `consumeToken`, comparing `expiresAt` is
|
|
438
|
+
* the core's job, after the call.
|
|
439
|
+
*
|
|
440
|
+
* Whether the count is past the limit, and whether the code matches, is the
|
|
441
|
+
* core's decision, after the call; spending the token is `consumeToken`.
|
|
442
|
+
*/
|
|
443
|
+
countAttempt(tokenHash: string, kind: TokenKind): Promise<TokenRecord | null>;
|
|
373
444
|
/**
|
|
374
445
|
* Deletes every token of one user, spent or not, and answers how many.
|
|
375
446
|
* What deleting a user calls: a token holds the e-mail it was sent to, which
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/auth/port/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/auth/port/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A second factor's secret, sealed before any store sees it: AES-256-GCM
|
|
3
|
+
* under a key the application holds, so a dump of the users is not a dump of
|
|
4
|
+
* everyone's authenticator.
|
|
5
|
+
*
|
|
6
|
+
* The sealed form is `v1.<key id>.<iv>.<ciphertext and tag>`, the last two in
|
|
7
|
+
* base64url. It names its key, so keys rotate: the first key seals, every key
|
|
8
|
+
* opens, and a secret sealed under an older one is sealed again under the
|
|
9
|
+
* first the next time a code is accepted. The user's id is the additional
|
|
10
|
+
* data, so a sealed secret copied onto another user does not open.
|
|
11
|
+
*/
|
|
12
|
+
/** One key, as `janus({ secondFactor: { keys } })` takes it. */
|
|
13
|
+
export interface SealingKey {
|
|
14
|
+
/** Names the key in every secret it seals: letters, digits, `_` and `-`. */
|
|
15
|
+
readonly id: string;
|
|
16
|
+
/** 32 random bytes, in base64 or base64url: `openssl rand -base64 32`. */
|
|
17
|
+
readonly key: string;
|
|
18
|
+
}
|
|
19
|
+
/** The keys, decoded and checked: the first seals. */
|
|
20
|
+
export interface Sealer {
|
|
21
|
+
readonly sealWith: string;
|
|
22
|
+
readonly keys: ReadonlyMap<string, Buffer>;
|
|
23
|
+
}
|
|
24
|
+
/** Decodes the keys and refuses what cannot seal. `where` names the option. */
|
|
25
|
+
export declare function resolveSealer(keys: unknown, where: string): Sealer;
|
|
26
|
+
/** Seals `plain` under the first key, bound to `boundTo` — the user's id. */
|
|
27
|
+
export declare function seal(sealer: Sealer, plain: string, boundTo: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Opens a sealed secret, and says which key sealed it.
|
|
30
|
+
*
|
|
31
|
+
* Every failure is a **wiring** mistake, a bare `TypeError`: a key taken out
|
|
32
|
+
* of `keys` while secrets it sealed are still stored, or a key changed under
|
|
33
|
+
* the same id. None of them comes from a request.
|
|
34
|
+
*/
|
|
35
|
+
export declare function unseal(sealer: Sealer, sealed: string, boundTo: string, where: string): {
|
|
36
|
+
readonly plain: string;
|
|
37
|
+
readonly keyId: string;
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=sealing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sealing.d.ts","sourceRoot":"","sources":["../../src/auth/sealing.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,gEAAgE;AAChE,MAAM,WAAW,UAAU;IAC1B,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACrB;AAED,sDAAsD;AACtD,MAAM,WAAW,MAAM;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AAQD,+EAA+E;AAC/E,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CA0BlE;AAED,6EAA6E;AAC7E,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAW3E;AAED;;;;;;GAMG;AACH,wBAAgB,MAAM,CACrB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GACX;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAwCpD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ResolvedType } from '../config';
|
|
2
|
+
import { type AnyUser, type Context } from '../context';
|
|
3
|
+
import type { UserRecord } from '../port/types';
|
|
4
|
+
import type { SecondFactorRequired, SignedIn } from '../types';
|
|
5
|
+
/**
|
|
6
|
+
* How many codes one challenge takes. A six-digit code has a million values:
|
|
7
|
+
* five tries is a one-in-200,000 chance per password guessed right, and the
|
|
8
|
+
* attempts are counted by the store in one write, never read then written.
|
|
9
|
+
*/
|
|
10
|
+
export declare const CHALLENGE_ATTEMPTS = 5;
|
|
11
|
+
/**
|
|
12
|
+
* The challenge `signIn` answers instead of a session, and the code that
|
|
13
|
+
* redeems it. **Only the challenge's hash is stored**, like a session
|
|
14
|
+
* token's.
|
|
15
|
+
*/
|
|
16
|
+
export declare function challengeFlows(context: Context, type: ResolvedType, at: (operation: string) => string): {
|
|
17
|
+
issue(record: UserRecord, where: string): Promise<SecondFactorRequired>;
|
|
18
|
+
confirm(challenge: string, code: string): Promise<SignedIn<AnyUser>>;
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=challenge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"challenge.d.ts","sourceRoot":"","sources":["../../../src/auth/second-factor/challenge.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,OAAO,EAAc,MAAM,YAAY,CAAC;AAOpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,KAAK,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAG/D;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC;;;;GAIG;AACH,wBAAgB,cAAc,CAC7B,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,YAAY,EAClB,EAAE,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM;kBAQvB,UAAU,SACX,MAAM,GACX,OAAO,CAAC,oBAAoB,CAAC;uBAgBP,MAAM,QAAQ,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;EAmE3E"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { TokenError } from '../../errors/janus-error';
|
|
2
|
+
import type { ResolvedConfig, ResolvedType } from '../config';
|
|
3
|
+
import type { Context } from '../context';
|
|
4
|
+
import type { SecondFactorRecord, UserRecord } from '../port/types';
|
|
5
|
+
/**
|
|
6
|
+
* What the second factor's flows share: its configuration, its states, and
|
|
7
|
+
* the one check of a code against a sealed secret.
|
|
8
|
+
*
|
|
9
|
+
* A factor is **enrolled** once `enroll` wrote it, **active** once a first
|
|
10
|
+
* code confirmed it, and gone after `disable`. Only an active one is asked
|
|
11
|
+
* for at sign-in.
|
|
12
|
+
*/
|
|
13
|
+
export type Settings = NonNullable<ResolvedConfig['secondFactor']>;
|
|
14
|
+
type ActiveFactor = SecondFactorRecord & {
|
|
15
|
+
readonly confirmedAt: Date;
|
|
16
|
+
};
|
|
17
|
+
export declare const isActive: (factor: SecondFactorRecord | null) => factor is ActiveFactor;
|
|
18
|
+
/** The configuration, or a wiring refusal: no keys, no second factor. */
|
|
19
|
+
export declare function requireSettings(context: Context, where: string, why: string): Settings;
|
|
20
|
+
/**
|
|
21
|
+
* Checks a code against the user's secret. Answers the factor as it is to be
|
|
22
|
+
* written — the step accepted, and the secret sealed again under the first
|
|
23
|
+
* key when an older one sealed it — or `null` for a code that does not match,
|
|
24
|
+
* or was already used.
|
|
25
|
+
*/
|
|
26
|
+
export declare function acceptCode(configured: Settings, record: UserRecord, factor: SecondFactorRecord, code: string, now: Date, where: string): SecondFactorRecord | null;
|
|
27
|
+
/** A code that does not match. `attemptsLeft` only when a challenge counted it. */
|
|
28
|
+
export declare function codeInvalid(type: ResolvedType, where: string, userId: string, attemptsLeft?: number): TokenError;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=factor.d.ts.map
|