@nxgt/janus 0.11.0 → 0.13.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 +109 -15
- package/dist/auth/config/janus-config.d.ts +2 -0
- package/dist/auth/config/janus-config.d.ts.map +1 -1
- package/dist/auth/config/resolved-config.d.ts +1 -0
- package/dist/auth/config/resolved-config.d.ts.map +1 -1
- package/dist/auth/email-flows/reset-password.d.ts.map +1 -1
- package/dist/auth/index.d.ts +2 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/password-written.d.ts +21 -5
- package/dist/auth/password-written.d.ts.map +1 -1
- package/dist/auth/port/assert-stores.d.ts.map +1 -1
- package/dist/auth/port/memory/sessions.d.ts.map +1 -1
- package/dist/auth/port/types/sessions.d.ts +16 -1
- package/dist/auth/port/types/sessions.d.ts.map +1 -1
- package/dist/auth/port/types/tokens.d.ts +10 -4
- package/dist/auth/port/types/tokens.d.ts.map +1 -1
- package/dist/auth/second-factor/{regenerate-attempts.d.ts → app-code-attempts.d.ts} +13 -10
- package/dist/auth/second-factor/app-code-attempts.d.ts.map +1 -0
- package/dist/auth/sessions/authenticate.d.ts.map +1 -1
- package/dist/auth/sessions/fresh.d.ts +26 -0
- package/dist/auth/sessions/fresh.d.ts.map +1 -0
- package/dist/auth/sessions/standing.d.ts +20 -0
- package/dist/auth/sessions/standing.d.ts.map +1 -0
- package/dist/auth/step-up/codes.d.ts +29 -0
- package/dist/auth/step-up/codes.d.ts.map +1 -0
- package/dist/auth/step-up/flows.d.ts +19 -0
- package/dist/auth/step-up/flows.d.ts.map +1 -0
- package/dist/auth/step-up/open.d.ts +23 -0
- package/dist/auth/step-up/open.d.ts.map +1 -0
- package/dist/auth/step-up/request.d.ts +12 -0
- package/dist/auth/step-up/request.d.ts.map +1 -0
- package/dist/auth/types/email-flows.d.ts +6 -3
- package/dist/auth/types/email-flows.d.ts.map +1 -1
- package/dist/auth/types/index.d.ts +1 -0
- package/dist/auth/types/index.d.ts.map +1 -1
- package/dist/auth/types/janus.d.ts +2 -1
- package/dist/auth/types/janus.d.ts.map +1 -1
- package/dist/auth/types/step-up.d.ts +79 -0
- package/dist/auth/types/step-up.d.ts.map +1 -0
- package/dist/auth/users/any-type-api.d.ts +2 -2
- package/dist/auth/users/any-type-api.d.ts.map +1 -1
- package/dist/auth/users/type-api.d.ts +1 -1
- package/dist/auth/users/type-api.d.ts.map +1 -1
- package/dist/chunks/{index-5e2fw7he.js → index-j2gd8fry.js} +12 -3
- package/dist/chunks/{index-5e2fw7he.js.map → index-j2gd8fry.js.map} +4 -4
- package/dist/chunks/{index-5tm04t5p.js → index-jp2kka6d.js} +2 -2
- package/dist/chunks/{index-6f6wja93.js → index-km7ffctx.js} +2 -2
- package/dist/chunks/{index-4m49cye4.js → index-rd2rddvv.js} +15 -12
- package/dist/chunks/{index-4m49cye4.js.map → index-rd2rddvv.js.map} +3 -3
- package/dist/conformance/cases/outage.d.ts.map +1 -1
- package/dist/conformance/cases/sessions/index.d.ts.map +1 -1
- package/dist/conformance/cases/sessions/reauthentication.d.ts +4 -0
- package/dist/conformance/cases/sessions/reauthentication.d.ts.map +1 -0
- package/dist/conformance/cases/tokens/index.d.ts.map +1 -1
- package/dist/conformance/cases/tokens/kinds.d.ts +4 -0
- package/dist/conformance/cases/tokens/kinds.d.ts.map +1 -0
- package/dist/conformance/index.js +147 -60
- package/dist/conformance/index.js.map +8 -6
- package/dist/errors/janus-error/codes.d.ts +7 -0
- package/dist/errors/janus-error/codes.d.ts.map +1 -1
- package/dist/errors/janus-error/index.d.ts +1 -1
- package/dist/errors/janus-error/index.d.ts.map +1 -1
- package/dist/errors/janus-error/refusals.d.ts +8 -0
- package/dist/errors/janus-error/refusals.d.ts.map +1 -1
- package/dist/errors/janus-error/status.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +185 -23
- package/dist/index.js.map +20 -14
- package/dist/permissions/index.js +3 -3
- package/docs/README.md +2 -1
- package/docs/guide/adapters.md +41 -6
- package/docs/guide/email-flows.md +40 -1
- package/docs/guide/errors.md +1 -0
- package/docs/guide/events.md +1 -1
- package/docs/guide/passwords.md +22 -0
- package/docs/guide/second-factor.md +22 -16
- package/docs/guide/sessions.md +7 -0
- package/docs/guide/step-up.md +178 -0
- package/docs/guide/users.md +8 -3
- package/docs/guide/vocabulary.md +3 -2
- package/docs/roadmap.md +19 -24
- package/docs/troubleshooting.md +193 -8
- package/package.json +1 -1
- package/dist/auth/second-factor/regenerate-attempts.d.ts.map +0 -1
- /package/dist/chunks/{index-5tm04t5p.js.map → index-jp2kka6d.js.map} +0 -0
- /package/dist/chunks/{index-6f6wja93.js.map → index-km7ffctx.js.map} +0 -0
package/dist/index.js.map
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/auth/hashers.ts", "../src/time/clock.ts", "../src/auth/config/normalize.ts", "../src/auth/config/reserved.ts", "../src/time/duration.ts", "../src/auth/config/names.ts", "../src/auth/config/resolve-cookie.ts", "../src/auth/sealing.ts", "../src/auth/config/resolve-second-factor.ts", "../src/auth/config/resolve-type.ts", "../src/auth/config/resolve-config.ts", "../src/auth/context/create-context.ts", "../src/auth/context/logins.ts", "../src/auth/outage.ts", "../src/auth/context/password.ts", "../src/auth/context/user.ts", "../src/auth/context/records.ts", "../src/auth/context/validate-fields.ts", "../src/auth/events.ts", "../src/auth/port/assert-stores.ts", "../src/auth/secrets.ts", "../src/auth/sessions/open-session.ts", "../src/auth/sessions/presented-token.ts", "../src/auth/sessions/authenticate.ts", "../src/auth/sessions/cookie.ts", "../src/auth/sessions/shared-api.ts", "../src/auth/one-time/codes.ts", "../src/auth/one-time/refusals.ts", "../src/auth/one-time/spend.ts", "../src/auth/one-time/issue.ts", "../src/auth/password-written.ts", "../src/auth/email-flows/email-token.ts", "../src/auth/email-flows/reset-password.ts", "../src/auth/email-flows/verify-email.ts", "../src/auth/email-flows/flows.ts", "../src/auth/totp.ts", "../src/auth/second-factor/factor.ts", "../src/auth/second-factor/redeem.ts", "../src/auth/second-factor/challenge.ts", "../src/auth/second-factor/codes-left.ts", "../src/auth/second-factor/recovery-codes.ts", "../src/auth/second-factor/refusal.ts", "../src/auth/second-factor/activate.ts", "../src/auth/second-factor/disable.ts", "../src/auth/second-factor/enroll.ts", "../src/auth/second-factor/
|
|
3
|
+
"sources": ["../src/auth/hashers.ts", "../src/time/clock.ts", "../src/auth/config/normalize.ts", "../src/auth/config/reserved.ts", "../src/time/duration.ts", "../src/auth/config/names.ts", "../src/auth/config/resolve-cookie.ts", "../src/auth/sealing.ts", "../src/auth/config/resolve-second-factor.ts", "../src/auth/config/resolve-type.ts", "../src/auth/config/resolve-config.ts", "../src/auth/context/create-context.ts", "../src/auth/context/logins.ts", "../src/auth/outage.ts", "../src/auth/context/password.ts", "../src/auth/context/user.ts", "../src/auth/context/records.ts", "../src/auth/context/validate-fields.ts", "../src/auth/events.ts", "../src/auth/port/assert-stores.ts", "../src/auth/secrets.ts", "../src/auth/sessions/open-session.ts", "../src/auth/sessions/presented-token.ts", "../src/auth/sessions/standing.ts", "../src/auth/sessions/authenticate.ts", "../src/auth/sessions/cookie.ts", "../src/auth/sessions/shared-api.ts", "../src/auth/one-time/codes.ts", "../src/auth/one-time/refusals.ts", "../src/auth/one-time/spend.ts", "../src/auth/one-time/issue.ts", "../src/auth/password-written.ts", "../src/auth/email-flows/email-token.ts", "../src/auth/email-flows/reset-password.ts", "../src/auth/email-flows/verify-email.ts", "../src/auth/email-flows/flows.ts", "../src/auth/totp.ts", "../src/auth/second-factor/factor.ts", "../src/auth/second-factor/redeem.ts", "../src/auth/second-factor/challenge.ts", "../src/auth/second-factor/codes-left.ts", "../src/auth/second-factor/recovery-codes.ts", "../src/auth/second-factor/refusal.ts", "../src/auth/second-factor/activate.ts", "../src/auth/second-factor/disable.ts", "../src/auth/second-factor/enroll.ts", "../src/auth/second-factor/app-code-attempts.ts", "../src/auth/second-factor/regenerate.ts", "../src/auth/second-factor/lifecycle.ts", "../src/auth/second-factor/recovery.ts", "../src/auth/second-factor/flows.ts", "../src/auth/sign-in-code.ts", "../src/auth/step-up/codes.ts", "../src/auth/step-up/open.ts", "../src/auth/step-up/request.ts", "../src/auth/step-up/flows.ts", "../src/auth/users/by-login.ts", "../src/auth/users/change-password.ts", "../src/auth/users/insert.ts", "../src/auth/users/sign-in.ts", "../src/auth/users/password-flows.ts", "../src/auth/users/delete.ts", "../src/auth/users/fields-patch.ts", "../src/auth/users/record-flows.ts", "../src/auth/users/type-api.ts", "../src/auth/janus.ts", "../src/auth/sessions/fresh.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import { randomBytes, scrypt, timingSafeEqual } from 'node:crypto';\nimport type { PasswordHasher } from './config';\n\n/**\n * scrypt through `node:crypto` — the hasher that runs **everywhere**: Node and\n * Bun both implement it, and it needs no dependency.\n *\n * Measured before choosing it: `bun build --target node` leaves `Bun.password`\n * in the output as it is — a target changes the bundle's format, not which\n * APIs exist — and `crypto.argon2` is absent from Node 22. scrypt is the one\n * memory-hard function both runtimes ship.\n *\n * The defaults are OWASP's: N = 2^17, r = 8, p = 1, about 128 MiB per hash.\n * The parameters are written into the hash —\n * `$scrypt$ln=17,r=8,p=1$<salt>$<key>` — and read back from it to verify, so\n * raising `cost` later leaves every existing hash readable.\n *\n * `cost` is log2(N). Lower it only in tests: 10 is fast and still exercises\n * every line.\n *\n * A hash written with other parameters than these is rewritten with these the\n * next time its owner signs in (`needsRehash`), so raising `cost` reaches every\n * active user without a migration.\n */\nexport function scryptHasher(options?: {\n\treadonly cost?: number;\n}): PasswordHasher {\n\tconst cost = options?.cost ?? 17;\n\tif (!Number.isInteger(cost) || cost < 10 || cost > 20) {\n\t\tthrow new TypeError(\n\t\t\t'scryptHasher: cost is log2(N), an integer from 10 to 20 — 17 is the recommended value',\n\t\t);\n\t}\n\n\treturn {\n\t\tprefix: SCRYPT_PREFIX,\n\t\tasync hash(plain) {\n\t\t\tconst salt = randomBytes(16);\n\t\t\tconst key = await derive(plain, salt, cost, 8, 1);\n\t\t\treturn `${SCRYPT_PREFIX}ln=${cost},r=8,p=1$${salt.toString('base64')}$${key.toString('base64')}`;\n\t\t},\n\t\tasync verify(plain, hash) {\n\t\t\tconst parsed = SCRYPT_HASH.exec(hash);\n\t\t\t// A hash this hasher cannot parse is not a wrong password, and not\n\t\t\t// something to guess at: the core picked this verifier by prefix, so\n\t\t\t// the stored hash is corrupt.\n\t\t\tif (parsed === null) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t'scryptHasher: the stored hash has the $scrypt$ prefix and not its format',\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst [, ln, r, p, salt, key] = parsed as unknown as [\n\t\t\t\tstring,\n\t\t\t\tstring,\n\t\t\t\tstring,\n\t\t\t\tstring,\n\t\t\t\tstring,\n\t\t\t\tstring,\n\t\t\t];\n\t\t\tconst expected = Buffer.from(key, 'base64');\n\t\t\tconst actual = await derive(\n\t\t\t\tplain,\n\t\t\t\tBuffer.from(salt, 'base64'),\n\t\t\t\tNumber(ln),\n\t\t\t\tNumber(r),\n\t\t\t\tNumber(p),\n\t\t\t\texpected.length,\n\t\t\t);\n\t\t\treturn timingSafeEqual(actual, expected);\n\t\t},\n\t\tneedsRehash(hash) {\n\t\t\tconst parsed = SCRYPT_HASH.exec(hash);\n\t\t\t// Unparseable is verify's refusal to make, not a reason to rewrite.\n\t\t\tif (parsed === null) return false;\n\t\t\tconst [, ln, r, p] = parsed;\n\t\t\treturn Number(ln) !== cost || r !== '8' || p !== '1';\n\t\t},\n\t};\n}\n\nconst SCRYPT_PREFIX = '$scrypt$';\nconst SCRYPT_HASH =\n\t/^\\$scrypt\\$ln=(\\d+),r=(\\d+),p=(\\d+)\\$([A-Za-z0-9+/=]+)\\$([A-Za-z0-9+/=]+)$/;\n\nfunction derive(\n\tplain: string,\n\tsalt: Buffer,\n\tln: number,\n\tr: number,\n\tp: number,\n\tlength = 32,\n): Promise<Buffer> {\n\t// Node's camelCase aliases for N, r and p: this repository has no other\n\t// casing, and Node accepts both spellings.\n\tconst n = 2 ** ln;\n\treturn new Promise((resolve, reject) => {\n\t\t// maxmem: Node's default (32 MiB) is below what N = 2^17, r = 8 needs.\n\t\t// `error` is null on Node and undefined on Bun when there is none —\n\t\t// measured: testing `=== null` rejected every hash under Bun.\n\t\tscrypt(\n\t\t\tplain,\n\t\t\tsalt,\n\t\t\tlength,\n\t\t\t{ cost: n, blockSize: r, parallelization: p, maxmem: 256 * n * r },\n\t\t\t(error, key) => (error ? reject(error) : resolve(key)),\n\t\t);\n\t});\n}\n\n/**\n * argon2id through `Bun.password`.\n *\n * **Loaded only when named**: nothing reads `Bun` until this function is called,\n * so the package imports cleanly under Node. On Node, `scryptHasher()` is the\n * hasher; a hash written here reads anywhere a verifier for `$argon2id$` is\n * wired, so a database can move between the two runtimes.\n */\nexport function bunHasher(): PasswordHasher {\n\t// `typeof` on an undeclared global is 'undefined' rather than a throw, so\n\t// this line is safe under Node.\n\tconst password: BunPassword | undefined =\n\t\ttypeof Bun === 'undefined' ? undefined : Bun.password;\n\n\tif (password === undefined) {\n\t\tthrow new TypeError(\n\t\t\t'bunHasher: Bun.password is not available — this runtime is not Bun; wire scryptHasher() instead',\n\t\t);\n\t}\n\n\treturn {\n\t\tprefix: '$argon2id$',\n\t\thash: (plain) => password.hash(plain, ARGON2ID),\n\t\tverify: (plain, hash) => password.verify(plain, hash),\n\t\tneedsRehash: (hash) => !hash.startsWith(ARGON2ID_PARAMETERS),\n\t};\n}\n\n/**\n * Pinned rather than left to `Bun.password`'s defaults — which they equal\n * today, measured: `$argon2id$v=19$m=65536,t=2,p=1$` — so that a change of\n * default in a Bun release is a rehash this package decided, not one it\n * inherited.\n */\nconst ARGON2ID = {\n\talgorithm: 'argon2id',\n\tmemoryCost: 65_536,\n\ttimeCost: 2,\n} as const;\nconst ARGON2ID_PARAMETERS = '$argon2id$v=19$m=65536,t=2,p=1$';\n\ninterface BunPassword {\n\thash(plain: string, options: typeof ARGON2ID): Promise<string>;\n\tverify(plain: string, hash: string): Promise<boolean>;\n}\n",
|
|
6
6
|
"/**\n * Where `now` comes from.\n *\n * Injected rather than read from `Date` directly, for one practical reason:\n * every expiry in this package — sessions, one-time tokens, refresh windows —\n * is a comparison against the current time, and a spec that has to move the\n * real clock to test one is a spec that needs fake timers, leaks them, and\n * fails differently under load. A `Clock` makes those specs synchronous and\n * exact.\n *\n * It is also the seam an application needs if it ever has to reason about a\n * store's clock rather than its own: MongoDB stamps a TTL against the server's\n * time, not the process's.\n */\nexport interface Clock {\n\tnow(): Date;\n}\n\n/** The process's own clock. The default everywhere. */\nexport const systemClock: Clock = {\n\tnow: () => new Date(),\n};\n\n/**\n * A clock a spec drives by hand.\n *\n * Shipped rather than kept in `test/`: a consumer writing their own tests\n * against this package needs exactly this, and writing it again is how two\n * subtly different versions of \"advance time\" come to exist.\n */\nexport function fixedClock(start: Date | number = 0): Clock & {\n\tadvance(ms: number): void;\n\tset(at: Date | number): void;\n} {\n\tlet ms = start instanceof Date ? start.getTime() : start;\n\n\treturn {\n\t\tnow: () => new Date(ms),\n\t\tadvance: (by) => {\n\t\t\tms += by;\n\t\t},\n\t\tset: (at) => {\n\t\t\tms = at instanceof Date ? at.getTime() : at;\n\t\t},\n\t};\n}\n",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';\n\n/**\n * A second factor's secret, sealed before any store sees it: AES-256-GCM\n * under a key the application holds, so a dump of the users is not a dump of\n * everyone's authenticator.\n *\n * The sealed form is `v1.<key id>.<iv>.<ciphertext and tag>`, the last two in\n * base64url. It names its key, so keys rotate: the first key seals, every key\n * opens, and a secret sealed under an older one is sealed again under the\n * first the next time a code is accepted. The user's id is the additional\n * data, so a sealed secret copied onto another user does not open.\n */\n\n/** One key, as `janus({ secondFactor: { keys } })` takes it. */\nexport interface SealingKey {\n\t/** Names the key in every secret it seals: letters, digits, `_` and `-`. */\n\treadonly id: string;\n\t/** 32 random bytes, in base64 or base64url: `openssl rand -base64 32`. */\n\treadonly key: string;\n}\n\n/** The keys, decoded and checked: the first seals. */\nexport interface Sealer {\n\treadonly sealWith: string;\n\treadonly keys: ReadonlyMap<string, Buffer>;\n}\n\n/** GCM's tag, always the full 16 bytes: a shorter one is easier to forge. */\nconst TAG_BYTES = 16;\n\nconst KEY_ID = /^[A-Za-z0-9_-]{1,64}$/;\nconst KEY = /^[A-Za-z0-9+/_-]{43}=?$/;\n\n/** Decodes the keys and refuses what cannot seal. `where` names the option. */\nexport function resolveSealer(keys: unknown, where: string): Sealer {\n\tif (!Array.isArray(keys) || keys.length === 0) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: expected at least one key — [{ id, key }], the first seals`,\n\t\t);\n\t}\n\tconst decoded = new Map<string, Buffer>();\n\tfor (const entry of keys as readonly SealingKey[]) {\n\t\tconst id = entry?.id;\n\t\tif (typeof id !== 'string' || !KEY_ID.test(id)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`${where}: every key needs an id of letters, digits, _ and -, at most 64 of them`,\n\t\t\t);\n\t\t}\n\t\tif (decoded.has(id)) {\n\t\t\tthrow new TypeError(`${where}: two keys have the id \"${id}\"`);\n\t\t}\n\t\tconst key = entry.key;\n\t\tif (typeof key !== 'string' || !KEY.test(key)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`${where}: the key \"${id}\" is not 32 bytes in base64 — make one with openssl rand -base64 32`,\n\t\t\t);\n\t\t}\n\t\tdecoded.set(id, Buffer.from(key, 'base64'));\n\t}\n\treturn { sealWith: (keys[0] as SealingKey).id, keys: decoded };\n}\n\n/** Seals `plain` under the first key, bound to `boundTo` — the user's id. */\nexport function seal(sealer: Sealer, plain: string, boundTo: string): string {\n\tconst key = sealer.keys.get(sealer.sealWith) as Buffer;\n\tconst iv = randomBytes(12);\n\tconst cipher = createCipheriv('aes-256-gcm', key, iv);\n\tcipher.setAAD(Buffer.from(boundTo));\n\tconst sealed = Buffer.concat([\n\t\tcipher.update(plain, 'utf8'),\n\t\tcipher.final(),\n\t\tcipher.getAuthTag(),\n\t]);\n\treturn `v1.${sealer.sealWith}.${iv.toString('base64url')}.${sealed.toString('base64url')}`;\n}\n\n/**\n * Opens a sealed secret, and says which key sealed it.\n *\n * Every failure is a **wiring** mistake, a bare `TypeError`: a key taken out\n * of `keys` while secrets it sealed are still stored, or a key changed under\n * the same id. None of them comes from a request.\n */\nexport function unseal(\n\tsealer: Sealer,\n\tsealed: string,\n\tboundTo: string,\n\twhere: string,\n): { readonly plain: string; readonly keyId: string } {\n\tconst parts = sealed.split('.');\n\tconst [version, keyId, iv, body] = parts;\n\tconst bytes = Buffer.from(body ?? '', 'base64url');\n\t// Exactly four parts, and a body longer than its 16-byte tag.\n\tif (\n\t\tparts.length !== 4 ||\n\t\tversion !== 'v1' ||\n\t\tkeyId === undefined ||\n\t\tiv === undefined ||\n\t\tbytes.length <= TAG_BYTES\n\t) {\n\t\tthrow new TypeError(`${where}: the stored secret is not a sealed one`);\n\t}\n\tconst key = sealer.keys.get(keyId);\n\tif (key === undefined) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: the secret is sealed with the key \"${keyId}\", which secondFactor.keys no longer holds — keep a key until no secret is sealed with it`,\n\t\t);\n\t}\n\ttry {\n\t\tconst decipher = createDecipheriv(\n\t\t\t'aes-256-gcm',\n\t\t\tkey,\n\t\t\tBuffer.from(iv, 'base64url'),\n\t\t\t{ authTagLength: TAG_BYTES },\n\t\t);\n\t\tdecipher.setAAD(Buffer.from(boundTo));\n\t\tdecipher.setAuthTag(bytes.subarray(bytes.length - TAG_BYTES));\n\t\tconst plain = Buffer.concat([\n\t\t\tdecipher.update(bytes.subarray(0, bytes.length - TAG_BYTES)),\n\t\t\tdecipher.final(),\n\t\t]).toString('utf8');\n\t\treturn { plain, keyId };\n\t} catch (cause) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: the secret does not open with the key \"${keyId}\" — was that key changed under the same id, or the secret copied from another user?`,\n\t\t\t{ cause },\n\t\t);\n\t}\n}\n",
|
|
13
13
|
"/** Resolves the TOTP second factor: its issuer, its sealer, its challenge's lifespan. */\n\nimport { parseDuration } from '../../time/duration';\nimport { resolveSealer } from '../sealing';\nimport type { SecondFactorConfig } from './janus-config';\nimport type { ResolvedConfig } from './resolved-config';\n\nexport function resolveSecondFactor(\n\tconfig: SecondFactorConfig | undefined,\n\twhere: string,\n): ResolvedConfig['secondFactor'] {\n\tif (config === undefined) return null;\n\tconst at = `${where}: secondFactor`;\n\tif (typeof config?.issuer !== 'string' || config.issuer.trim() === '') {\n\t\tthrow new TypeError(\n\t\t\t`${at}.issuer must name your application — the authenticator app shows it beside the account`,\n\t\t);\n\t}\n\treturn {\n\t\tissuer: config.issuer,\n\t\tsealer: resolveSealer(config.keys, `${at}.keys`),\n\t\tchallengeTtlMs: parseDuration(config.challenge ?? '5m', `${at}.challenge`),\n\t};\n}\n",
|
|
14
14
|
"/** Resolves one user type: its schema, its password policy, its sessions. */\n\nimport { parseDuration } from '../../time/duration';\nimport { fieldName } from './names';\nimport { normalizer } from './normalize';\nimport type { PasswordConfig } from './password-config';\nimport type { ResolvedType } from './resolved-config';\nimport type { UserTypeConfig } from './user-type';\n\n/** `at` names the type in a refusal; `schemaKey` is the key its schema came in. */\nexport function resolveType(\n\tname: string,\n\ttype: UserTypeConfig,\n\tat: string,\n\tschemaKey: string,\n): ResolvedType {\n\tif (\n\t\ttypeof type?.schema !== 'object' ||\n\t\ttype.schema === null ||\n\t\ttypeof type.schema['~standard']?.validate !== 'function'\n\t) {\n\t\tthrow new TypeError(\n\t\t\t`${at}: ${schemaKey} must be a Standard Schema — a Zod 4, Valibot or ArkType schema`,\n\t\t);\n\t}\n\n\tconst password =\n\t\ttype.password === undefined ? null : resolvePassword(type.password, at);\n\n\tconst renewAfter = type.session?.renewAfter ?? '1d';\n\n\treturn {\n\t\tname,\n\t\tschema: type.schema,\n\t\tschemaVersion: type.schemaVersion ?? '1',\n\t\tpassword,\n\t\temail: fieldName(type.email ?? 'email', `${at}: email`),\n\t\tlifespanMs: parseDuration(\n\t\t\ttype.session?.lifespan ?? '7d',\n\t\t\t`${at}: session.lifespan`,\n\t\t),\n\t\trenewAfterMs:\n\t\t\trenewAfter === false\n\t\t\t\t? null\n\t\t\t\t: parseDuration(renewAfter, `${at}: session.renewAfter`),\n\t};\n}\n\nfunction resolvePassword(\n\tpassword: PasswordConfig,\n\tat: string,\n): NonNullable<ResolvedType['password']> {\n\tconst minLength = password.minLength ?? 8;\n\tif (!Number.isInteger(minLength) || minLength < 1) {\n\t\tthrow new TypeError(\n\t\t\t`${at}: password.minLength must be an integer of at least 1`,\n\t\t);\n\t}\n\treturn {\n\t\tlogin: fieldName(password.login, `${at}: password.login`),\n\t\tnormalize: normalizer(\n\t\t\tpassword.normalize ?? 'lowercaseTrim',\n\t\t\t`${at}: password.normalize`,\n\t\t),\n\t\tminLength,\n\t};\n}\n",
|
|
15
|
-
"/**\n * Resolves what `janus()` was given: applies the defaults and refuses what\n * cannot be wired, with a bare `TypeError` naming where.\n */\n\nimport { parseDuration } from '../../time/duration';\nimport type {\n\tJanusConfig,\n\tMultiTypeConfig,\n\tSingleTypeConfig,\n} from './janus-config';\nimport { NAME } from './names';\nimport { RESERVED_TYPES, SINGLE_TYPE } from './reserved';\nimport { resolveCookie } from './resolve-cookie';\nimport { resolveSecondFactor } from './resolve-second-factor';\nimport { resolveType } from './resolve-type';\nimport type { ResolvedConfig, ResolvedType } from './resolved-config';\nimport type { UserSchema, UserTypeConfig } from './user-type';\n\n/** Applies the defaults and refuses what cannot be wired. `where` names the call. */\nexport function resolveConfig(\n\tconfig: JanusConfig,\n\twhere: string,\n): ResolvedConfig {\n\tif (typeof config !== 'object' || config === null) {\n\t\tthrow new TypeError(`${where}: expected a configuration object`);\n\t}\n\n\tconst hasUser = config.user !== undefined;\n\tconst hasUsers = config.users !== undefined;\n\tif (hasUser === hasUsers) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: pass either user (one user type) or users (several user types), and exactly one of them`,\n\t\t);\n\t}\n\n\tconst types = resolveTypes(entriesOf(config, hasUsers), hasUsers, where);\n\trefuseHashingWithoutHasher(config, types, where);\n\n\treturn {\n\t\tsingle: !hasUsers,\n\t\ttypes,\n\t\ttokenTtlMs: resolveTokenTtls(config, where),\n\t\tcookie: resolveCookie(config.cookie ?? {}, where),\n\t\tsecondFactor: resolveSecondFactor(config.secondFactor, where),\n\t};\n}\n\n/** Every user type declared, by name: the single-type form's under {@link SINGLE_TYPE}. */\nfunction entriesOf(\n\tconfig: JanusConfig,\n\thasUsers: boolean,\n): [string, UserTypeConfig][] {\n\treturn hasUsers\n\t\t? Object.entries(config.users as MultiTypeConfig['users'])\n\t\t: [\n\t\t\t\t[\n\t\t\t\t\tSINGLE_TYPE,\n\t\t\t\t\t{\n\t\t\t\t\t\t...(config as SingleTypeConfig),\n\t\t\t\t\t\tschema: config.user as UserSchema,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t];\n}\n\nfunction resolveTypes(\n\tentries: [string, UserTypeConfig][],\n\thasUsers: boolean,\n\twhere: string,\n): Map<string, ResolvedType> {\n\tif (entries.length === 0) {\n\t\tthrow new TypeError(`${where}: users declares no user type`);\n\t}\n\n\tconst types = new Map<string, ResolvedType>();\n\tfor (const [name, type] of entries) {\n\t\tconst at = hasUsers ? `${where}: users.${name}` : where;\n\n\t\tif (!NAME.test(name)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`${where}: the user type \"${name}\" must be a camelCase name — letters and digits, starting with a letter`,\n\t\t\t);\n\t\t}\n\t\tif ((RESERVED_TYPES as readonly string[]).includes(name)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`${where}: \"${name}\" cannot name a user type — janus() answers a method of that name`,\n\t\t\t);\n\t\t}\n\t\ttypes.set(name, resolveType(name, type, at, hasUsers ? 'schema' : 'user'));\n\t}\n\treturn types;\n}\n\nfunction refuseHashingWithoutHasher(\n\tconfig: JanusConfig,\n\ttypes: ReadonlyMap<string, ResolvedType>,\n\twhere: string,\n): void {\n\tconst hashing = [...types.values()].some((type) => type.password !== null);\n\tif (hashing && config.hasher === undefined) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: a user type signs in with a password and no hasher is wired — pass hasher: scryptHasher(), or bunHasher() on Bun. There is no silent fallback`,\n\t\t);\n\t}\n}\n\nfunction resolveTokenTtls(\n\tconfig: JanusConfig,\n\twhere: string,\n): ResolvedConfig['tokenTtlMs'] {\n\treturn {\n\t\tverifyEmail: parseDuration(\n\t\t\tconfig.tokens?.verifyEmail ?? '24h',\n\t\t\t`${where}: tokens.verifyEmail`,\n\t\t),\n\t\tresetPassword: parseDuration(\n\t\t\tconfig.tokens?.resetPassword ?? '1h',\n\t\t\t`${where}: tokens.resetPassword`,\n\t\t),\n\t\tsignInCode: parseDuration(\n\t\t\tconfig.tokens?.signInCode ?? '10m',\n\t\t\t`${where}: tokens.signInCode`,\n\t\t),\n\t};\n}\n",
|
|
15
|
+
"/**\n * Resolves what `janus()` was given: applies the defaults and refuses what\n * cannot be wired, with a bare `TypeError` naming where.\n */\n\nimport { parseDuration } from '../../time/duration';\nimport type {\n\tJanusConfig,\n\tMultiTypeConfig,\n\tSingleTypeConfig,\n} from './janus-config';\nimport { NAME } from './names';\nimport { RESERVED_TYPES, SINGLE_TYPE } from './reserved';\nimport { resolveCookie } from './resolve-cookie';\nimport { resolveSecondFactor } from './resolve-second-factor';\nimport { resolveType } from './resolve-type';\nimport type { ResolvedConfig, ResolvedType } from './resolved-config';\nimport type { UserSchema, UserTypeConfig } from './user-type';\n\n/** Applies the defaults and refuses what cannot be wired. `where` names the call. */\nexport function resolveConfig(\n\tconfig: JanusConfig,\n\twhere: string,\n): ResolvedConfig {\n\tif (typeof config !== 'object' || config === null) {\n\t\tthrow new TypeError(`${where}: expected a configuration object`);\n\t}\n\n\tconst hasUser = config.user !== undefined;\n\tconst hasUsers = config.users !== undefined;\n\tif (hasUser === hasUsers) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: pass either user (one user type) or users (several user types), and exactly one of them`,\n\t\t);\n\t}\n\n\tconst types = resolveTypes(entriesOf(config, hasUsers), hasUsers, where);\n\trefuseHashingWithoutHasher(config, types, where);\n\n\treturn {\n\t\tsingle: !hasUsers,\n\t\ttypes,\n\t\ttokenTtlMs: resolveTokenTtls(config, where),\n\t\tcookie: resolveCookie(config.cookie ?? {}, where),\n\t\tsecondFactor: resolveSecondFactor(config.secondFactor, where),\n\t};\n}\n\n/** Every user type declared, by name: the single-type form's under {@link SINGLE_TYPE}. */\nfunction entriesOf(\n\tconfig: JanusConfig,\n\thasUsers: boolean,\n): [string, UserTypeConfig][] {\n\treturn hasUsers\n\t\t? Object.entries(config.users as MultiTypeConfig['users'])\n\t\t: [\n\t\t\t\t[\n\t\t\t\t\tSINGLE_TYPE,\n\t\t\t\t\t{\n\t\t\t\t\t\t...(config as SingleTypeConfig),\n\t\t\t\t\t\tschema: config.user as UserSchema,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t];\n}\n\nfunction resolveTypes(\n\tentries: [string, UserTypeConfig][],\n\thasUsers: boolean,\n\twhere: string,\n): Map<string, ResolvedType> {\n\tif (entries.length === 0) {\n\t\tthrow new TypeError(`${where}: users declares no user type`);\n\t}\n\n\tconst types = new Map<string, ResolvedType>();\n\tfor (const [name, type] of entries) {\n\t\tconst at = hasUsers ? `${where}: users.${name}` : where;\n\n\t\tif (!NAME.test(name)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`${where}: the user type \"${name}\" must be a camelCase name — letters and digits, starting with a letter`,\n\t\t\t);\n\t\t}\n\t\tif ((RESERVED_TYPES as readonly string[]).includes(name)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`${where}: \"${name}\" cannot name a user type — janus() answers a method of that name`,\n\t\t\t);\n\t\t}\n\t\ttypes.set(name, resolveType(name, type, at, hasUsers ? 'schema' : 'user'));\n\t}\n\treturn types;\n}\n\nfunction refuseHashingWithoutHasher(\n\tconfig: JanusConfig,\n\ttypes: ReadonlyMap<string, ResolvedType>,\n\twhere: string,\n): void {\n\tconst hashing = [...types.values()].some((type) => type.password !== null);\n\tif (hashing && config.hasher === undefined) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: a user type signs in with a password and no hasher is wired — pass hasher: scryptHasher(), or bunHasher() on Bun. There is no silent fallback`,\n\t\t);\n\t}\n}\n\nfunction resolveTokenTtls(\n\tconfig: JanusConfig,\n\twhere: string,\n): ResolvedConfig['tokenTtlMs'] {\n\treturn {\n\t\tverifyEmail: parseDuration(\n\t\t\tconfig.tokens?.verifyEmail ?? '24h',\n\t\t\t`${where}: tokens.verifyEmail`,\n\t\t),\n\t\tresetPassword: parseDuration(\n\t\t\tconfig.tokens?.resetPassword ?? '1h',\n\t\t\t`${where}: tokens.resetPassword`,\n\t\t),\n\t\tsignInCode: parseDuration(\n\t\t\tconfig.tokens?.signInCode ?? '10m',\n\t\t\t`${where}: tokens.signInCode`,\n\t\t),\n\t\tstepUp: parseDuration(\n\t\t\tconfig.tokens?.stepUp ?? '10m',\n\t\t\t`${where}: tokens.stepUp`,\n\t\t),\n\t};\n}\n",
|
|
16
16
|
"/**\n * What every operation of the core is handed: the resolved configuration, the\n * guarded stores, the clock, the hashers and the events listener.\n */\n\nimport { mintId } from '../../ids/id';\nimport type { RelationStore } from '../../permissions/port/types';\nimport type { Clock } from '../../time/clock';\nimport type { PasswordHasher, ResolvedConfig } from '../config';\nimport type { UserEventListener } from '../events';\nimport type { JanusStores, StoreCapabilities } from '../port/types';\n\nexport interface Context {\n\treadonly config: ResolvedConfig;\n\t/** Already guarded, by `src/stores/guard.ts`. */\n\treadonly store: JanusStores;\n\t/** Already guarded. `null` when no relation store is wired. */\n\treadonly relations: RelationStore | null;\n\treadonly capabilities: StoreCapabilities;\n\treadonly clock: Clock;\n\treadonly hasher: PasswordHasher | null;\n\t/** The hasher first, then every verifier: whoever claims a prefix verifies it. */\n\treadonly verifiers: readonly PasswordHasher[];\n\t/** Hashed once, lazily: what a missing user's password is compared against. */\n\tdummyHash(): Promise<string>;\n\t/** What `janus({ events })` was given, or `null`. */\n\treadonly events: UserEventListener | null;\n}\n\nexport function createContext(\n\tconfig: ResolvedConfig,\n\tstore: JanusStores,\n\trelations: RelationStore | null,\n\tcapabilities: StoreCapabilities,\n\tclock: Clock,\n\thasher: PasswordHasher | null,\n\tverifiers: readonly PasswordHasher[],\n\tevents: UserEventListener | null = null,\n): Context {\n\tlet dummy: Promise<string> | null = null;\n\n\treturn {\n\t\tconfig,\n\t\tstore,\n\t\trelations,\n\t\tcapabilities,\n\t\tclock,\n\t\thasher,\n\t\tverifiers,\n\t\tevents,\n\t\tdummyHash: () => {\n\t\t\tif (hasher === null) {\n\t\t\t\tthrow new TypeError('janus: no hasher to compare a dummy hash with');\n\t\t\t}\n\t\t\tdummy ??= hasher.hash(`janus-dummy-${mintId()}`);\n\t\t\treturn dummy;\n\t\t},\n\t};\n}\n",
|
|
17
17
|
"/**\n * What a user signs in with, and is found by: the login field and the e-mail,\n * each normalised by its own rule.\n */\n\nimport { UserInvalidError } from '../../errors/janus-error';\nimport { isStorable, UNSTORABLE } from '../../stores/storable';\nimport { normalizeEmail, type ResolvedType } from '../config';\nimport type { JsonObject, UserRecord } from '../port/types';\nimport type { Context } from './create-context';\n\n/** The user's e-mail, as stored, or `null` when the schema let it be absent. */\nexport function emailOf(type: ResolvedType, fields: JsonObject): string | null {\n\tconst value = fields[type.email];\n\treturn typeof value === 'string' ? value : null;\n}\n\n/**\n * What a user signs in with, normalised: the login field, by its own rule,\n * and the e-mail, by the e-mail rule — so a user whose login is a username can\n * still be found by the e-mail a reset is requested for.\n */\nexport function loginsOf(\n\ttype: ResolvedType,\n\tfields: JsonObject,\n\twhere: string,\n): string[] {\n\tconst logins = new Set<string>();\n\n\tif (type.password !== null) {\n\t\tconst login = fields[type.password.login];\n\t\tif (typeof login !== 'string') {\n\t\t\tthrow new TypeError(\n\t\t\t\t`janus: password.login \"${type.password.login}\" did not name a string in validated ${type.name} fields — it must name a required string field`,\n\t\t\t);\n\t\t}\n\t\tconst normalized = type.password.normalize(login);\n\t\t// The fields were checked; a function normaliser can still cut a\n\t\t// surrogate pair in half. Refused here, or the user is written with a\n\t\t// login nobody can sign in with — or not written at all, on PostgreSQL.\n\t\tif (!isStorable(normalized)) {\n\t\t\tconst path = [type.password.login];\n\t\t\tthrow new UserInvalidError(\n\t\t\t\t`${where}: the fields do not match the ${type.name} schema (1 issue, at ${path.join('.')})`,\n\t\t\t\t{\n\t\t\t\t\tissues: [\n\t\t\t\t\t\t{ path, message: `normalises to a login that ${UNSTORABLE}` },\n\t\t\t\t\t],\n\t\t\t\t\tuserType: type.name,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t\tlogins.add(normalized);\n\t}\n\n\tconst email = emailOf(type, fields);\n\tif (email !== null) logins.add(normalizeEmail(email));\n\n\treturn [...logins];\n}\n\n/**\n * The user of this type whose e-mail this is, or `null`. Looked up as a\n * login — every e-mail is one — and then compared, so a username that only\n * looks like an e-mail is nobody's.\n */\nexport async function holderOfEmail(\n\tcontext: Context,\n\ttype: ResolvedType,\n\temail: string,\n): Promise<UserRecord | null> {\n\tconst wanted = normalizeEmail(email);\n\tif (!isStorable(wanted)) return null;\n\tconst record = await context.store.users.findUserByLogin(type.name, wanted);\n\tconst held = record === null ? null : emailOf(type, record.fields);\n\treturn held !== null && normalizeEmail(held) === wanted ? record : null;\n}\n",
|
|
18
18
|
"/**\n * **The identity side's two conversions**, and the one place a `null` becomes\n * an error.\n *\n * > An absence is `null`. A failure throws.\n *\n * {@link guardStores} puts the three identity stores behind the shared guard\n * (`src/stores/guard.ts`), the one place a store's answer is caught.\n * {@link required} turns an absence the caller cannot accept into its refusal,\n * and {@link unlessVersionConflict} absorbs one named conflict and rethrows\n * everything else.\n *\n * `outage.scan.spec.ts` reads every other file of `src/auth/`, `src/permissions/`\n * and `src/stores/` and fails if a `catch` appears in one, because the failure\n * this design exists to prevent is a single careless `catch { return null }`.\n */\n\nimport { type JanusError, StoreConflict } from '../errors/janus-error';\nimport { guardStore } from '../stores/guard';\nimport type { JanusStores } from './port/types';\n\n/**\n * The stores, with every method guarded.\n *\n * - A `JanusError` the adapter threw — `StoreFailure`, `StoreConflict`,\n * `NotFoundError` — passes through untouched, so `instanceof` still holds.\n * - **Anything else it threw is a failure**: a driver error, a `TypeError` from\n * a bug in the adapter, a string. It becomes `StoreFailure` with the original\n * as `cause`, naming the slot and the method. It is never an absence.\n * - A method that answers `undefined` where the port says `null` is a store\n * that forgot to answer, and becomes `StoreFailure` rather than \"not found\".\n * Rule 2 of the port, enforced at run time for the JavaScript adapter the\n * compiler never saw.\n *\n * The optional `deleteExpiredSessions` is guarded when present and left absent\n * when absent, so capability detection still reads the truth.\n */\nexport function guardStores(stores: JanusStores): JanusStores {\n\treturn {\n\t\tusers: guardStore('users', stores.users),\n\t\tsessions: guardStore('sessions', stores.sessions),\n\t\ttokens: guardStore('tokens', stores.tokens),\n\t};\n}\n\n/**\n * A value the caller requires, or the refusal an absence deserves.\n *\n * The only place in the core where a `null` from a store turns into an error —\n * `get` becoming `NOT_FOUND`. Written as a function so that the conversion is\n * visible at every call site and nowhere else.\n */\nexport function required<T>(value: T | null, absent: () => JanusError): T {\n\tif (value === null) throw absent();\n\treturn value;\n}\n\n/**\n * A write that may lose a race, and is allowed to: its answer, or `null` when\n * the record's version moved under it.\n *\n * **Only `StoreConflict('version')` is absorbed.** A failure still throws, a\n * taken login still throws, `NOT_FOUND` still throws: an outage never reads as\n * \"somebody else wrote first\". It exists for writes the caller did not ask for\n * — rewriting a password hash on sign-in — where losing to a concurrent update\n * means only that the next sign-in tries again.\n */\nexport async function unlessVersionConflict<T>(\n\twrite: Promise<T>,\n): Promise<T | null> {\n\ttry {\n\t\treturn await write;\n\t} catch (error) {\n\t\tif (error instanceof StoreConflict && error.on === 'version') return null;\n\t\tthrow error;\n\t}\n}\n",
|
|
@@ -21,20 +21,21 @@
|
|
|
21
21
|
"/**\n * Reading a user's record by id — an absence is `null`, `getRecord` makes it\n * `NOT_FOUND` — and the one write that follows such a read, under a version.\n */\n\nimport { NotFoundError, StoreConflict } from '../../errors/janus-error';\nimport { isId } from '../../ids/id';\nimport type { ResolvedType } from '../config';\nimport { required } from '../outage';\nimport type { UserPatch, UserRecord } from '../port/types';\nimport type { UserRef, WriteOptions } from '../types';\nimport type { Context } from './create-context';\nimport { idOf } from './user';\n\nconst notFound = (where: string, id: string, type: string | null) =>\n\tnew NotFoundError(\n\t\t`${where}: no ${type ?? 'user'} has this id`,\n\t\ttype === null\n\t\t\t? { userId: id, operation: where }\n\t\t\t: { userId: id, userType: type, operation: where },\n\t);\n\n/**\n * The user — of this type, when one is given — or `null`. A malformed id is an\n * absence decided without reaching the store: it arrives off a URL, and it is\n * \"no such user\", not a query and not an outage. A user of another type is\n * absent too: `auth.staff.find(patientId)` finds nobody.\n */\nexport async function findRecord(\n\tcontext: Context,\n\tid: string,\n\ttype: string | null,\n): Promise<UserRecord | null> {\n\tif (!isId(id)) return null;\n\tconst record = await context.store.users.findUser(id);\n\treturn record !== null && (type === null || record.type === type)\n\t\t? record\n\t\t: null;\n}\n\n/** The user, or `NOT_FOUND`. */\nexport async function getRecord(\n\tcontext: Context,\n\tid: string,\n\ttype: string | null,\n\twhere: string,\n): Promise<UserRecord> {\n\treturn required(await findRecord(context, id, type), () =>\n\t\tnotFound(where, id, type),\n\t);\n}\n\n/**\n * One write that follows a read, under a version: the core reads the user,\n * checks `ifVersion` against what it read, computes the patch from the record,\n * and writes under the version it read. A user who changed in between is\n * `VERSION_CONFLICT`, and nothing is written.\n */\nexport async function writeUser(\n\tcontext: Context,\n\tuser: UserRef,\n\ttype: ResolvedType,\n\toptions: WriteOptions | undefined,\n\twhere: string,\n\tpatchOf: (\n\t\trecord: UserRecord,\n\t\tnow: Date,\n\t) => Omit<UserPatch, 'updatedAt'> | Promise<Omit<UserPatch, 'updatedAt'>>,\n): Promise<UserRecord> {\n\tconst id = idOf(user);\n\tconst record = await getRecord(context, id, type.name, where);\n\tconst ifVersion = options?.ifVersion;\n\n\tif (ifVersion !== undefined && ifVersion !== record.version) {\n\t\tthrow new StoreConflict(\n\t\t\t'version',\n\t\t\t`${where}: expected version ${ifVersion}, found ${record.version}`,\n\t\t\t{\n\t\t\t\tuserId: id,\n\t\t\t\texpectedVersion: ifVersion,\n\t\t\t\tactualVersion: record.version,\n\t\t\t\toperation: where,\n\t\t\t},\n\t\t);\n\t}\n\n\tconst now = context.clock.now();\n\tconst patch = await patchOf(record, now);\n\treturn context.store.users.updateUser(\n\t\trecord.id,\n\t\t{ ...patch, updatedAt: now },\n\t\trecord.version,\n\t);\n}\n",
|
|
22
22
|
"/**\n * A user's fields, validated against the type's schema and answered as the\n * port holds them — or refused, reporting where and never the values.\n */\n\nimport { type Issue, UserInvalidError } from '../../errors/janus-error';\nimport { isStorable, UNSTORABLE } from '../../stores/storable';\nimport { RESERVED_FIELDS, type ResolvedType } from '../config';\nimport type { Json, JsonObject } from '../port/types';\nimport type { StandardSchemaV1 } from '../standard-schema';\n\n/**\n * Validates fields against the type's schema, and answers them as the port\n * holds them: an `undefined` property dropped, at every depth.\n */\nexport async function validateFields(\n\ttype: ResolvedType,\n\tinput: unknown,\n\twhere: string,\n): Promise<JsonObject> {\n\tconst result = await type.schema['~standard'].validate(input);\n\n\tconst issues: Issue[] =\n\t\tresult.issues === undefined\n\t\t\t? []\n\t\t\t: result.issues.map((issue) => ({\n\t\t\t\t\tpath: storablePrefix((issue.path ?? []).map(segmentKey)),\n\t\t\t\t\tmessage: issue.message,\n\t\t\t\t}));\n\n\t// A schema that passes unknown keys through would let a request set `id` or\n\t// `active` among the fields. `toUser` would shadow them anyway; refusing\n\t// them says so to whoever sent them.\n\tif (result.issues === undefined) {\n\t\tconst value = result.value as Record<string, unknown>;\n\t\tfor (const key of RESERVED_FIELDS) {\n\t\t\tif (Object.hasOwn(value, key)) {\n\t\t\t\tissues.push({ path: [key], message: 'set by janus, not by a request' });\n\t\t\t}\n\t\t}\n\t\tunstorableIn(value, [], issues);\n\t}\n\n\tif (issues.length > 0) {\n\t\t// The message reports how many and where, never the values: a field may\n\t\t// be anything the application chose to store, including something\n\t\t// private.\n\t\tthrow new UserInvalidError(\n\t\t\t`${where}: the fields do not match the ${type.name} schema (${issues.length} issue${issues.length === 1 ? '' : 's'}, at ${issues.map((i) => i.path.join('.') || '(root)').join(', ')})`,\n\t\t\t{ issues, userType: type.name },\n\t\t);\n\t}\n\n\treturn withoutUndefined((result as { value: unknown }).value) as JsonObject;\n}\n\n/** Pushes an issue for every key and every string no store can keep. */\nfunction unstorableIn(\n\tvalue: unknown,\n\tpath: (string | number)[],\n\tissues: Issue[],\n): void {\n\tif (typeof value === 'string') {\n\t\tif (!isStorable(value)) issues.push({ path, message: UNSTORABLE });\n\t\treturn;\n\t}\n\tif (Array.isArray(value)) {\n\t\tfor (const [index, inner] of value.entries()) {\n\t\t\tunstorableIn(inner, [...path, index], issues);\n\t\t}\n\t\treturn;\n\t}\n\tif (typeof value === 'object' && value !== null) {\n\t\tfor (const [key, inner] of Object.entries(value)) {\n\t\t\t// The key itself stays out of the path: the path reaches the message,\n\t\t\t// and a NUL has no business in a log line.\n\t\t\tif (!isStorable(key)) {\n\t\t\t\tissues.push({ path, message: `a key ${UNSTORABLE}` });\n\t\t\t} else {\n\t\t\t\tunstorableIn(inner, [...path, key], issues);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * A path up to its first key no store can keep: the path reaches the message,\n * and a NUL has no business in a log line.\n */\nfunction storablePrefix(path: (string | number)[]): (string | number)[] {\n\tconst cut = path.findIndex(\n\t\t(segment) => typeof segment === 'string' && !isStorable(segment),\n\t);\n\treturn cut === -1 ? path : path.slice(0, cut);\n}\n\nfunction segmentKey(\n\tsegment: PropertyKey | StandardSchemaV1.PathSegment,\n): string | number {\n\tconst key = typeof segment === 'object' ? segment.key : segment;\n\treturn typeof key === 'number' ? key : String(key);\n}\n\nfunction withoutUndefined(value: unknown): Json {\n\tif (Array.isArray(value)) return value.map(withoutUndefined);\n\n\tif (typeof value === 'object' && value !== null) {\n\t\tconst out: Record<string, Json> = {};\n\t\tfor (const [key, inner] of Object.entries(value)) {\n\t\t\tif (inner !== undefined) out[key] = withoutUndefined(inner);\n\t\t}\n\t\treturn out;\n\t}\n\n\treturn value as Json;\n}\n",
|
|
23
23
|
"import { type Id, mintId } from '../ids/id';\nimport type { Context } from './context';\n\n/**\n * What happened to a user, once it is written:\n *\n * - `user.created` — by `create` or `signUp`;\n * - `user.emailVerified` — by `verifyEmail.confirm`, or by the link of\n * `resetPassword.confirm` or the code of `signInCode.confirm`, which prove\n * the e-mail too; never for an e-mail already verified;\n * - `user.passwordReset` — by `resetPassword.confirm`;\n * - `user.secondFactorEnabled` — by `secondFactor.activate`, once the factor\n * is active: not by `enroll`, which leaves it waiting for its first code;\n * - `user.secondFactorDisabled` — by `secondFactor.disable`, when it removed\n * an active factor; never for a user who had none, or one still waiting;\n * - `user.recoveryCodesRegenerated` — by `secondFactor.regenerateRecoveryCodes`:\n * the codes the user held stopped working. Not by `activate`, whose codes\n * come with `user.secondFactorEnabled`;\n * - `user.recoveryCodeUsed` — by `secondFactor.recover`, once the code is\n * spent: a sign-in without the user's phone;\n * - `user.deleted` — by `delete`, once; a replay that finds nobody is none.\n */\nexport type UserEventType =\n\t| 'user.created'\n\t| 'user.emailVerified'\n\t| 'user.passwordReset'\n\t| 'user.secondFactorEnabled'\n\t| 'user.secondFactorDisabled'\n\t| 'user.recoveryCodesRegenerated'\n\t| 'user.recoveryCodeUsed'\n\t| 'user.deleted';\n\n/**\n * A user event: **the user named by id, and nothing else** — no login, no\n * e-mail, no field, no password, no token. Whoever receives it reads the rest\n * from where it is kept, if they may.\n */\nexport interface UserEvent {\n\t/** A UUIDv7 minted for this event: the key to deliver it once. */\n\treadonly id: Id;\n\treadonly type: UserEventType;\n\t/**\n\t * When the write landed: the `createdAt` or `updatedAt` it wrote, or, for\n\t * a deletion, the time read just before it — not when the listener ran.\n\t */\n\treadonly occurredAt: Date;\n\treadonly userId: Id;\n\treadonly userType: string;\n}\n\n/**\n * What `janus({ events })` takes: called once per event, **after** the write\n * landed and before the flow answers — awaited, so a queue that stores the\n * event durably has done so by then. A listener that throws fails nothing:\n * the write happened, and the flow answers as it would have. The failure is a\n * `JANUS_EVENT_FAILED` warning naming the event, never silence.\n */\nexport type UserEventListener = (event: UserEvent) => void | Promise<void>;\n\n/** The listener given to `janus()`, or a wiring refusal for a JavaScript caller. */\nexport function resolveEvents(\n\tevents: unknown,\n\twhere: string,\n): UserEventListener | null {\n\tif (events === undefined) return null;\n\tif (typeof events !== 'function') {\n\t\tthrow new TypeError(\n\t\t\t`${where}: events must be a function that takes a user event — webhooks({ … }) from @nxgt/janus-webhooks, or your own`,\n\t\t);\n\t}\n\treturn events as UserEventListener;\n}\n\n/**\n * Hands one event to the listener after the write it reports. A flow whose\n * steps after the write matter to the listener — a reset's revocation, a\n * deletion's cleanup — runs them in a `try` and emits from its `finally`, so\n * an outage there does not lose the event for good. Its failure is the application's, not the flow's: warned about, with what\n * it takes to send the event again — never thrown, since the write has landed.\n */\nexport async function emit(\n\tcontext: Context,\n\ttype: UserEventType,\n\tuser: { readonly id: Id; readonly type: string },\n\toccurredAt: Date,\n): Promise<void> {\n\tconst listener = context.events;\n\tif (listener === null) return;\n\n\tconst event: UserEvent = Object.freeze({\n\t\tid: mintId(occurredAt.getTime()),\n\t\ttype,\n\t\t// A copy: the record's own Date is also the user the flow answers.\n\t\toccurredAt: new Date(occurredAt.getTime()),\n\t\tuserId: user.id,\n\t\tuserType: user.type,\n\t});\n\ttry {\n\t\tawait listener(event);\n\t} catch (failure) {\n\t\tprocess.emitWarning(\n\t\t\t`janus: the events listener failed on ${type} ${event.id} for user ${user.id}: ${failure instanceof Error ? failure.name : typeof failure}`,\n\t\t\t{ code: 'JANUS_EVENT_FAILED' },\n\t\t);\n\t}\n}\n",
|
|
24
|
-
"import type { JanusStores, StoreCapabilities } from './types';\n\n/**\n * The methods each slot must answer, in the order the port declares them.\n *\n * Kept beside the interfaces rather than derived from them: a type does not\n * exist at runtime, and this list is the net for the JavaScript caller the\n * compiler never saw.\n */\nconst REQUIRED = {\n\tusers: [\n\t\t'insertUser',\n\t\t'findUser',\n\t\t'findUserByLogin',\n\t\t'listUsers',\n\t\t'updateUser',\n\t\t'deleteUser',\n\t],\n\tsessions: [\n\t\t'insertSession',\n\t\t'findSessionByTokenHash',\n\t\t'extendSession',\n\t\t'revokeSession',\n\t\t'revokeUserSessions',\n\t\t'deleteUserSessions',\n\t],\n\ttokens: [\n\t\t'insertToken',\n\t\t'consumeToken',\n\t\t'countAttempt',\n\t\t'spendUserTokens',\n\t\t'deleteUserTokens',\n\t],\n} as const satisfies Record<keyof JanusStores, readonly string[]>;\n\n/**\n * Checks that every slot answers every method the port declares, and reports\n * the optional capabilities found.\n *\n * TypeScript already refuses a partial store and names the missing method;\n * this is the net for a JavaScript caller, and for a store assembled from\n * `any`. A bare `TypeError`, because a missing method can only come from how\n * the application was wired — no request produces one, and no handler should\n * answer one.\n *\n * `where` names the call the consumer wrote — `janus` — so the\n * sentence says which call to fix and which slot to change.\n */\nexport function assertStores(\n\tstores: unknown,\n\twhere: string,\n): StoreCapabilities {\n\tif (typeof stores !== 'object' || stores === null) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: store must be an object with users, sessions and tokens`,\n\t\t);\n\t}\n\n\tfor (const slot of Object.keys(REQUIRED) as (keyof typeof REQUIRED)[]) {\n\t\tconst store: unknown = (stores as Record<string, unknown>)[slot];\n\n\t\tif (typeof store !== 'object' || store === null) {\n\t\t\tthrow new TypeError(`${where}: store.${slot} is missing`);\n\t\t}\n\n\t\tfor (const method of REQUIRED[slot]) {\n\t\t\tif (typeof (store as Record<string, unknown>)[method] !== 'function') {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t`${where}: store.${slot} has no method ${method}, which the port requires`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst sessions = (stores as { sessions: Record<string, unknown> }).sessions;\n\tconst collect = sessions.deleteExpiredSessions;\n\n\t// Present but not a function is a wiring mistake, not an absent capability:\n\t// reporting it as \"unsupported\" would send the reader to the wrong fix.\n\tif (collect !== undefined && typeof collect !== 'function') {\n\t\tthrow new TypeError(\n\t\t\t`${where}: store.sessions.deleteExpiredSessions must be a function or absent`,\n\t\t);\n\t}\n\n\treturn { collectExpired: collect !== undefined };\n}\n",
|
|
24
|
+
"import type { JanusStores, StoreCapabilities } from './types';\n\n/**\n * The methods each slot must answer, in the order the port declares them.\n *\n * Kept beside the interfaces rather than derived from them: a type does not\n * exist at runtime, and this list is the net for the JavaScript caller the\n * compiler never saw.\n */\nconst REQUIRED = {\n\tusers: [\n\t\t'insertUser',\n\t\t'findUser',\n\t\t'findUserByLogin',\n\t\t'listUsers',\n\t\t'updateUser',\n\t\t'deleteUser',\n\t],\n\tsessions: [\n\t\t'insertSession',\n\t\t'findSessionByTokenHash',\n\t\t'extendSession',\n\t\t'reauthenticateSession',\n\t\t'revokeSession',\n\t\t'revokeUserSessions',\n\t\t'deleteUserSessions',\n\t],\n\ttokens: [\n\t\t'insertToken',\n\t\t'consumeToken',\n\t\t'countAttempt',\n\t\t'spendUserTokens',\n\t\t'deleteUserTokens',\n\t],\n} as const satisfies Record<keyof JanusStores, readonly string[]>;\n\n/**\n * Checks that every slot answers every method the port declares, and reports\n * the optional capabilities found.\n *\n * TypeScript already refuses a partial store and names the missing method;\n * this is the net for a JavaScript caller, and for a store assembled from\n * `any`. A bare `TypeError`, because a missing method can only come from how\n * the application was wired — no request produces one, and no handler should\n * answer one.\n *\n * `where` names the call the consumer wrote — `janus` — so the\n * sentence says which call to fix and which slot to change.\n */\nexport function assertStores(\n\tstores: unknown,\n\twhere: string,\n): StoreCapabilities {\n\tif (typeof stores !== 'object' || stores === null) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: store must be an object with users, sessions and tokens`,\n\t\t);\n\t}\n\n\tfor (const slot of Object.keys(REQUIRED) as (keyof typeof REQUIRED)[]) {\n\t\tconst store: unknown = (stores as Record<string, unknown>)[slot];\n\n\t\tif (typeof store !== 'object' || store === null) {\n\t\t\tthrow new TypeError(`${where}: store.${slot} is missing`);\n\t\t}\n\n\t\tfor (const method of REQUIRED[slot]) {\n\t\t\tif (typeof (store as Record<string, unknown>)[method] !== 'function') {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t`${where}: store.${slot} has no method ${method}, which the port requires`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst sessions = (stores as { sessions: Record<string, unknown> }).sessions;\n\tconst collect = sessions.deleteExpiredSessions;\n\n\t// Present but not a function is a wiring mistake, not an absent capability:\n\t// reporting it as \"unsupported\" would send the reader to the wrong fix.\n\tif (collect !== undefined && typeof collect !== 'function') {\n\t\tthrow new TypeError(\n\t\t\t`${where}: store.sessions.deleteExpiredSessions must be a function or absent`,\n\t\t);\n\t}\n\n\treturn { collectExpired: collect !== undefined };\n}\n",
|
|
25
25
|
"import { createHash, randomBytes } from 'node:crypto';\n\n/**\n * A fresh secret: 32 random bytes, base64url — safe in a header, a cookie and a\n * URL without escaping.\n *\n * Given to the application **once**. No store ever holds it.\n */\nexport function mintSecret(): string {\n\treturn randomBytes(32).toString('base64url');\n}\n\n/**\n * What a store holds instead of the secret: `sha256`, hex.\n *\n * SHA-256 and not argon2, on purpose. The secret carries 256 bits of entropy, so\n * there is nothing to brute-force, and an argon2 per request would put ~50 ms on\n * every authenticated call. What the hash buys is that a dump of the store\n * cannot be replayed.\n */\nexport function hashSecret(secret: string): string {\n\treturn createHash('sha256').update(secret).digest('hex');\n}\n",
|
|
26
26
|
"/**\n * Opening a session once a user proved who they are, and the session as\n * application code sees it.\n */\n\nimport { mintId } from '../../ids/id';\nimport type { ResolvedType } from '../config';\nimport { type AnyUser, type Context, toUser } from '../context';\nimport type { SessionRecord, UserRecord } from '../port/types';\nimport { hashSecret, mintSecret } from '../secrets';\nimport type { Session, SignedIn } from '../types';\n\n/** A session as application code sees it: everything but the token's hash. */\nexport function toSession(record: SessionRecord): Session {\n\tconst { tokenHash: _, ...session } = record;\n\treturn session;\n}\n\n/**\n * Opens a session for a user who just proved who they are. The token is in\n * the answer and nowhere else: the store holds its hash.\n */\nexport async function openSession(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tuser: UserRecord,\n): Promise<SignedIn<AnyUser>> {\n\tconst now = context.clock.now();\n\tconst token = mintSecret();\n\tconst record: SessionRecord = {\n\t\tid: mintId(now.getTime()),\n\t\ttokenHash: hashSecret(token),\n\t\tuserId: user.id,\n\t\tauthenticatedAt: now,\n\t\texpiresAt: new Date(now.getTime() + type.lifespanMs),\n\t\trevokedAt: null,\n\t\tcreatedAt: now,\n\t};\n\n\tawait context.store.sessions.insertSession(record);\n\treturn {\n\t\tstatus: 'signedIn',\n\t\tuser: toUser(user),\n\t\tsession: toSession(record),\n\t\ttoken,\n\t};\n}\n",
|
|
27
27
|
"/**\n * Reading the session token a request presents, whatever shape the request\n * arrives in.\n */\n\nimport type { HeaderRecord, RequestLike } from '../types';\n\n/**\n * The session token a request presents: `Authorization: Bearer`, then\n * `X-Session-Token`, then the cookie.\n *\n * **The first credential present wins, not the first valid one.** A browser\n * sending a lapsed bearer beside a live cookie is anonymous, and should fix its\n * header rather than be rescued in silence — the rule `resolve` in `nxgt-ory`'s\n * SDK learned. An `Authorization` header of another scheme (`Basic`) is not a\n * session credential, and does not count as one.\n */\nexport function presentedToken(\n\trequest: RequestLike,\n\tcookieName: string,\n): string | null {\n\tconst headers = headersOf(request);\n\tconst read = (name: string): string | null => {\n\t\tif (headers instanceof Headers) return headers.get(name);\n\t\tfor (const [key, value] of Object.entries(headers)) {\n\t\t\tif (key.toLowerCase() !== name || value === undefined) continue;\n\t\t\treturn typeof value === 'string' ? value : value.join(', ');\n\t\t}\n\t\treturn null;\n\t};\n\n\tconst authorization = read('authorization');\n\tif (authorization !== null) {\n\t\tconst match = /^bearer(?:\\s+(.*))?$/i.exec(authorization.trim());\n\t\tif (match) return match[1]?.trim() ?? '';\n\t}\n\n\tconst header = read('x-session-token');\n\tif (header !== null) return header.trim();\n\n\tconst cookie = read('cookie');\n\tif (cookie !== null) {\n\t\tfor (const pair of cookie.split(';')) {\n\t\t\tconst at = pair.indexOf('=');\n\t\t\tif (at !== -1 && pair.slice(0, at).trim() === cookieName) {\n\t\t\t\treturn pair.slice(at + 1).trim();\n\t\t\t}\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * The headers of whatever was passed: a `Request`, `Headers`, anything with a\n * `headers` property — Node's `IncomingMessage` — or a plain record.\n */\nfunction headersOf(request: RequestLike): Headers | HeaderRecord {\n\tif (request instanceof Headers) return request;\n\tconst inner = (request as { headers?: unknown }).headers;\n\tif (inner instanceof Headers) return inner;\n\tif (typeof inner === 'object' && inner !== null) return inner as HeaderRecord;\n\treturn request as HeaderRecord;\n}\n",
|
|
28
|
-
"/**\n *
|
|
28
|
+
"/**\n * The standing session a request presents — one rule for `authenticate` and\n * `stepUp.confirm`, so the two never disagree on what \"signed in\" means.\n */\n\nimport type { Context } from '../context';\nimport type { SessionRecord } from '../port/types';\nimport { hashSecret } from '../secrets';\nimport type { RequestLike } from '../types';\nimport { presentedToken } from './presented-token';\n\n/** A standing session, and the session token that presented it. */\nexport interface Presented {\n\treadonly token: string;\n\treadonly session: SessionRecord;\n}\n\n/**\n * Answers the session `request` presents, with its token — or `null` when\n * none stands: no token, or a session gone, revoked or lapsed. Expiry is\n * decided here, against the context's clock: a store may still hold a\n * session past its term.\n */\nexport async function standingSession(\n\tcontext: Context,\n\trequest: RequestLike,\n): Promise<Presented | null> {\n\tconst token = presentedToken(request, context.config.cookie.name);\n\tif (token === null) return null;\n\n\tconst session = await context.store.sessions.findSessionByTokenHash(\n\t\thashSecret(token),\n\t);\n\tconst now = context.clock.now().getTime();\n\treturn session === null ||\n\t\tsession.revokedAt !== null ||\n\t\tsession.expiresAt.getTime() <= now\n\t\t? null\n\t\t: { token, session };\n}\n",
|
|
29
|
+
"/**\n * `authenticate`: the user and the session a request presents, or `null` for\n * anonymous — and the renewal of a session used past its `renewAfter`.\n */\n\nimport type { ResolvedType } from '../config';\nimport { type AnyUser, type Context, toUser } from '../context';\nimport type { SessionRecord } from '../port/types';\nimport type { Authenticated, RequestLike } from '../types';\nimport { toSession } from './open-session';\nimport { standingSession } from './standing';\n\n/** Answers the user and the session `request` presents, or `null` for anonymous. */\nexport async function authenticate(\n\tcontext: Context,\n\trequest: RequestLike,\n\toptions?: { readonly type?: string },\n): Promise<Authenticated<AnyUser> | null> {\n\tconst { store, clock, config } = context;\n\t// Lapsed, revoked, or gone: anonymous.\n\tconst presented = await standingSession(context, request);\n\tif (presented === null) return null;\n\tconst { token, session } = presented;\n\tconst now = clock.now().getTime();\n\n\t// A user gone, inactive, or of another type than asked for is\n\t// anonymous: the session stands, and proves nothing here.\n\tconst user = await store.users.findUser(session.userId);\n\tif (\n\t\tuser === null ||\n\t\t!user.active ||\n\t\t(options?.type !== undefined && user.type !== options.type)\n\t) {\n\t\treturn null;\n\t}\n\n\tconst type = config.types.get(user.type);\n\tif (type === undefined || !renewalDue(type, session, now)) {\n\t\treturn {\n\t\t\tuser: toUser(user),\n\t\t\tsession: toSession(session),\n\t\t\ttoken,\n\t\t\trenewed: false,\n\t\t};\n\t}\n\n\tconst extended = await store.sessions.extendSession(\n\t\tsession.id,\n\t\tnew Date(now + type.lifespanMs),\n\t);\n\t// Revoked between the read and the renewal: anonymous, and never\n\t// brought back.\n\tif (extended === null) return null;\n\treturn {\n\t\tuser: toUser(user),\n\t\tsession: toSession(extended),\n\t\ttoken,\n\t\trenewed: true,\n\t};\n}\n\n/**\n * Whether a session is renewed now: once `renewAfter` has passed since it\n * was opened or last renewed — the lifespan minus what is left — so a busy\n * session is written at most once per period.\n */\nfunction renewalDue(\n\ttype: ResolvedType,\n\tsession: SessionRecord,\n\tnow: number,\n): boolean {\n\treturn (\n\t\ttype.renewAfterMs !== null &&\n\t\ttype.lifespanMs - (session.expiresAt.getTime() - now) >= type.renewAfterMs\n\t);\n}\n",
|
|
29
30
|
"/**\n * The session cookie: its name, and the `Set-Cookie` values that set and\n * clear it, under the attributes the configuration resolved.\n */\n\nimport type { AnyUser, Context } from '../context';\nimport type { Session, SharedApi } from '../types';\n\n/** The session cookie's name, and how to set it for a session and clear it. */\nexport function cookieOf(context: Context): SharedApi<AnyUser>['cookie'] {\n\tconst { name, domain, path, sameSite, secure } = context.config.cookie;\n\tconst attributes = [\n\t\t`Path=${path}`,\n\t\t...(domain === null ? [] : [`Domain=${domain}`]),\n\t\t'HttpOnly',\n\t\t`SameSite=${sameSite[0]?.toUpperCase()}${sameSite.slice(1)}`,\n\t\t...(secure ? ['Secure'] : []),\n\t].join('; ');\n\n\treturn {\n\t\tname,\n\t\tserialize: (token: string, session: Session) =>\n\t\t\t`${name}=${token}; Expires=${session.expiresAt.toUTCString()}; ${attributes}`,\n\t\tclear: () =>\n\t\t\t`${name}=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; ${attributes}`,\n\t};\n}\n",
|
|
30
31
|
"/**\n * What `janus()` answers whatever its user types: authenticating a request,\n * signing out, finding a user by id, the cookie, and collecting expired\n * sessions.\n */\n\nimport { UnsupportedError } from '../../errors/janus-error';\nimport { isId } from '../../ids/id';\nimport {\n\ttype AnyUser,\n\ttype Context,\n\tfindRecord,\n\tgetRecord,\n\tidOf,\n\ttoUser,\n} from '../context';\nimport { hashSecret } from '../secrets';\nimport type { Authenticated, RequestLike, SharedApi } from '../types';\nimport { authenticate } from './authenticate';\nimport { cookieOf } from './cookie';\nimport { presentedToken } from './presented-token';\n\n/** `SharedApi`, degenericised: `janus()` casts it to the typed form once. */\nexport type InternalSharedApi = Omit<SharedApi<AnyUser>, 'authenticate'> & {\n\tauthenticate(\n\t\trequest: RequestLike,\n\t\toptions?: { readonly type?: string },\n\t): Promise<Authenticated<AnyUser> | null>;\n};\n\n/** Everything `janus()` answers whatever its user types. */\nexport function sharedApi(context: Context): InternalSharedApi {\n\tconst { store, clock, config } = context;\n\n\treturn {\n\t\tasync authenticate(request, options) {\n\t\t\treturn authenticate(context, request, options);\n\t\t},\n\n\t\tasync signOut(request) {\n\t\t\tconst token = presentedToken(request, config.cookie.name);\n\t\t\tif (token === null) return false;\n\n\t\t\tconst session = await store.sessions.findSessionByTokenHash(\n\t\t\t\thashSecret(token),\n\t\t\t);\n\t\t\tif (session === null) return false;\n\t\t\treturn store.sessions.revokeSession(session.id, clock.now());\n\t\t},\n\n\t\tasync signOutEverywhere(user, options) {\n\t\t\tconst id = idOf(user);\n\t\t\tif (!isId(id)) return 0;\n\t\t\t// An `except` that is no id this package minted names no session:\n\t\t\t// every session goes, as it would for an unknown one.\n\t\t\treturn options?.except === undefined || !isId(options.except)\n\t\t\t\t? store.sessions.revokeUserSessions(id, clock.now())\n\t\t\t\t: store.sessions.revokeUserSessions(id, clock.now(), options.except);\n\t\t},\n\n\t\tasync findUser(id) {\n\t\t\tconst record = await findRecord(context, id, null);\n\t\t\treturn record === null ? null : toUser(record);\n\t\t},\n\n\t\tasync getUser(id) {\n\t\t\treturn toUser(await getRecord(context, id, null, 'getUser'));\n\t\t},\n\n\t\tcookie: cookieOf(context),\n\n\t\tasync collectExpired() {\n\t\t\tconst collect = store.sessions.deleteExpiredSessions;\n\t\t\tif (!context.capabilities.collectExpired || collect === undefined) {\n\t\t\t\tthrow new UnsupportedError(\n\t\t\t\t\t'collectExpired: store.sessions does not implement deleteExpiredSessions — its store expires sessions on its own, or implement the method',\n\t\t\t\t\t{ slot: 'sessions', operation: 'deleteExpiredSessions' },\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn collect(clock.now());\n\t\t},\n\n\t\ttypes: [...config.types.keys()],\n\t};\n}\n",
|
|
31
32
|
"/**\n * The six-digit code a challenge carries — a second factor's or an e-mailed\n * one: its attempts, counted before anything is compared, its hash, keyed by\n * the challenge, and the refusal of one that does not match.\n */\n\nimport { timingSafeEqual } from 'node:crypto';\nimport { TokenError } from '../../errors/janus-error';\nimport type { Context } from '../context';\nimport type { TokenKind, TokenRecord } from '../port/types';\nimport { hashSecret } from '../secrets';\nimport { refuseUnusable, unknownOneTime } from './refusals';\nimport { burnOneTime } from './spend';\n\n/**\n * How many codes one challenge takes — a second factor's or an e-mail\n * code's. A six-digit code has a million values: five attempts is a\n * one-in-200,000 chance **per challenge**, and the attempts are counted by\n * the store in one write, never read then written.\n */\nexport const CODE_ATTEMPTS = 5;\n\n/**\n * Counts one attempt at a challenge's code, before anything is compared: a\n * guess that fails for any reason has still cost one. Refuses a challenge\n * that cannot be used, and one past its last attempt — a call that raced the\n * one that spent it — unread.\n */\nexport async function countCodeAttempt(\n\tcontext: Context,\n\tsecret: string,\n\tkind: TokenKind,\n\twhere: string,\n\tuserType: string,\n): Promise<{ readonly token: TokenRecord; readonly attemptsLeft: number }> {\n\tconst token = await context.store.tokens.countAttempt(\n\t\thashSecret(secret),\n\t\tkind,\n\t);\n\trefuseUnusable(token, context.clock.now(), where, 'challenge');\n\tif (token.attempts > CODE_ATTEMPTS) {\n\t\tthrow codeInvalid(where, token.userId, userType, 0);\n\t}\n\treturn { token, attemptsLeft: CODE_ATTEMPTS - token.attempts };\n}\n\n/**\n * A code that does not match — a second factor's or an e-mailed one — or a\n * TOTP code already used. `attemptsLeft` only when a challenge counted it.\n */\nexport function codeInvalid(\n\twhere: string,\n\tuserId: string,\n\tuserType: string,\n\tattemptsLeft?: number,\n): TokenError {\n\treturn new TokenError(\n\t\t'CODE_INVALID',\n\t\t`${where}: the code does not match, or was already used`,\n\t\t{\n\t\t\toperation: where,\n\t\t\tuserId,\n\t\t\tuserType,\n\t\t\t...(attemptsLeft === undefined ? {} : { attemptsLeft }),\n\t\t},\n\t);\n}\n\n/**\n * The refusal for a challenge whose user is gone, or of another type — the\n * API of the wrong type compares no code. Its attempt was counted all the\n * same, before the type was known, so the last one spends the challenge, as\n * a wrong code would: past it, every call answers `TOKEN_SPENT`.\n */\nexport async function unknownChallenge(\n\tcontext: Context,\n\ttoken: TokenRecord,\n\tsecret: string,\n\twhere: string,\n): Promise<TokenError> {\n\tif (token.attempts === CODE_ATTEMPTS) {\n\t\tawait burnOneTime(context, secret, token.kind);\n\t}\n\treturn unknownOneTime(where, 'challenge');\n}\n\n/**\n * A code's hash, **keyed by its challenge**: the tokens alone — a dump, a\n * log of the table — do not reveal the code, since a million guesses at it\n * each need the challenge, which only the visitor holds.\n */\nexport const hashCode = (challenge: string, code: string): string =>\n\thashSecret(`${challenge}${code}`);\n\n/** Whether `code` is the one whose hash the token holds, compared in constant time. */\nexport function codeMatches(\n\ttoken: TokenRecord,\n\tchallenge: string,\n\tcode: string,\n): boolean {\n\tif (token.codeHash === null || !/^\\d{6}$/.test(code)) return false;\n\tconst given = Buffer.from(hashCode(challenge, code));\n\tconst held = Buffer.from(token.codeHash);\n\treturn given.length === held.length && timingSafeEqual(given, held);\n}\n",
|
|
32
33
|
"/**\n * The refusals of a one-time token that could not be used: none, spent,\n * lapsed, or sent to an e-mail the user no longer has.\n */\n\nimport { TokenError } from '../../errors/janus-error';\nimport { normalizeEmail, type ResolvedType } from '../config';\nimport { emailOf } from '../context';\nimport type { TokenRecord, UserRecord } from '../port/types';\n\n/**\n * `noun` is what the messages call it: `token` for a link, `challenge` for\n * what `signIn` answers. No message names the secret or its hash.\n */\nexport type OneTimeNoun = 'token' | 'challenge';\n\n/**\n * Refuses a token sent to an e-mail the user no longer has: redeeming it\n * would prove an address nobody holds any more.\n */\nexport function refuseStale(\n\ttype: ResolvedType,\n\tuser: UserRecord,\n\ttoken: TokenRecord,\n\twhere: string,\n\tnoun: 'token' | 'code',\n): void {\n\tconst email = emailOf(type, user.fields);\n\tif (\n\t\temail === null ||\n\t\tnormalizeEmail(email) !== normalizeEmail(token.address)\n\t) {\n\t\tthrow new TokenError(\n\t\t\t'TOKEN_STALE',\n\t\t\t`${where}: the ${noun} was sent to an e-mail the user no longer has`,\n\t\t\t{ operation: where, userId: user.id, userType: type.name },\n\t\t);\n\t}\n}\n\n/**\n * Refuses a token that cannot be used: none, spent, or lapsed. What a store\n * answered — before a `consumeToken`, after a `countAttempt` — is read the\n * same way: `spentAt` set means somebody else used it.\n */\nexport function refuseUnusable(\n\ttoken: TokenRecord | null,\n\tnow: Date,\n\twhere: string,\n\tnoun: OneTimeNoun,\n): asserts token is TokenRecord {\n\tif (token === null) {\n\t\tthrow new TokenError('TOKEN_UNKNOWN', `${where}: no such ${noun}`, {\n\t\t\toperation: where,\n\t\t});\n\t}\n\tif (token.spentAt !== null) {\n\t\tthrow new TokenError(\n\t\t\t'TOKEN_SPENT',\n\t\t\t`${where}: the ${noun} was already used`,\n\t\t\t{ operation: where },\n\t\t);\n\t}\n\tif (token.expiresAt.getTime() <= now.getTime()) {\n\t\tthrow new TokenError('TOKEN_EXPIRED', `${where}: the ${noun} has expired`, {\n\t\t\toperation: where,\n\t\t});\n\t}\n}\n\n/** The refusal for a token whose user is gone, or of another type. */\nexport const unknownOneTime = (where: string, noun: OneTimeNoun) =>\n\tnew TokenError('TOKEN_UNKNOWN', `${where}: no such ${noun}`, {\n\t\toperation: where,\n\t});\n",
|
|
33
34
|
"/**\n * Spending a one-time token: once when it is redeemed, and once more when its\n * last attempt failed.\n */\n\nimport type { Context } from '../context';\nimport type { TokenKind, TokenRecord } from '../port/types';\nimport { hashSecret } from '../secrets';\nimport { type OneTimeNoun, refuseUnusable } from './refusals';\n\n/**\n * Spends a token, and refuses it when this call did not: the store answers it\n * **as it was before**, so exactly one call ever reads `spentAt: null`. A\n * lapsed token is spent all the same, so it cannot be retried.\n */\nexport async function spendOneTime(\n\tcontext: Context,\n\tsecret: string,\n\tkind: TokenKind,\n\twhere: string,\n\tnoun: OneTimeNoun,\n): Promise<TokenRecord> {\n\tconst now = context.clock.now();\n\tconst token = await context.store.tokens.consumeToken(\n\t\thashSecret(secret),\n\t\tkind,\n\t\tnow,\n\t);\n\trefuseUnusable(token, now, where, noun);\n\treturn token;\n}\n\n/**\n * Spends a token whose last attempt failed. Its answer is not read: a racing\n * call that spent it first changes nothing for this one, which is refused\n * for its code either way.\n */\nexport async function burnOneTime(\n\tcontext: Context,\n\tsecret: string,\n\tkind: TokenKind,\n): Promise<void> {\n\tawait context.store.tokens.consumeToken(\n\t\thashSecret(secret),\n\t\tkind,\n\t\tcontext.clock.now(),\n\t);\n}\n",
|
|
34
35
|
"/**\n * Issuing a one-time token — a link's, or a challenge carrying a code for a\n * person to type. The secret is given back once; the store holds its hash.\n */\n\nimport { randomInt } from 'node:crypto';\nimport type { Context } from '../context';\nimport type { TokenKind } from '../port/types';\nimport { hashSecret, mintSecret } from '../secrets';\nimport { hashCode } from './codes';\n\ninterface OneTimeRequest {\n\treadonly kind: TokenKind;\n\treadonly userId: string;\n\treadonly address: string;\n\treadonly ttlMs: number;\n}\n\n/**\n * Issues a one-time token: 32 random bytes, given back once, and only their\n * hash stored.\n */\nexport async function issueOneTime(\n\tcontext: Context,\n\ttoken: OneTimeRequest,\n): Promise<{ readonly secret: string; readonly expiresAt: Date }> {\n\treturn insertOneTime(context, token, null);\n}\n\n/**\n * Issues a one-time token with a six-digit code for a person to type: the\n * token is the challenge, and only the code's hash is stored, keyed by it.\n */\nexport async function issueCode(\n\tcontext: Context,\n\ttoken: OneTimeRequest,\n): Promise<{\n\treadonly secret: string;\n\treadonly expiresAt: Date;\n\treadonly code: string;\n}> {\n\tconst code = String(randomInt(1_000_000)).padStart(6, '0');\n\treturn { ...(await insertOneTime(context, token, code)), code };\n}\n\nasync function insertOneTime(\n\tcontext: Context,\n\ttoken: OneTimeRequest,\n\tcode: string | null,\n): Promise<{ readonly secret: string; readonly expiresAt: Date }> {\n\tconst now = context.clock.now();\n\tconst secret = mintSecret();\n\tconst expiresAt = new Date(now.getTime() + token.ttlMs);\n\n\tawait context.store.tokens.insertToken({\n\t\ttokenHash: hashSecret(secret),\n\t\tkind: token.kind,\n\t\tuserId: token.userId,\n\t\taddress: token.address,\n\t\tcodeHash: code === null ? null : hashCode(secret, code),\n\t\tattempts: 0,\n\t\texpiresAt,\n\t\tspentAt: null,\n\t\tcreatedAt: now,\n\t});\n\treturn { secret, expiresAt };\n}\n",
|
|
35
|
-
"import type { Id } from '../ids/id';\nimport type { ResolvedType } from './config';\nimport {\n\ttype AnyUser,\n\ttype Context,\n\tfindRecord,\n\tpasswordMatches,\n} from './context';\nimport { burnOneTime } from './one-time';\nimport type { UserRecord } from './port/types';\nimport type { SignInResult } from './types';\n\n/**\n * What writing a password ends besides
|
|
36
|
+
"import type { Id } from '../ids/id';\nimport type { ResolvedType } from './config';\nimport {\n\ttype AnyUser,\n\ttype Context,\n\tfindRecord,\n\tpasswordMatches,\n} from './context';\nimport { burnOneTime } from './one-time';\nimport type { UserRecord } from './port/types';\nimport type { SignInResult } from './types';\n\n/**\n * What writing a password ends besides. A reset, a change and a set each call\n * it **after** the write, and a failure here throws — it is never ignored:\n *\n * - The user's reset links still unspent. A link answers a request to\n * replace the password; once it is replaced, an older link would replace\n * it again, without knowing the new one.\n * - Every second-factor challenge still open, so a sign-in started with the\n * old password cannot be finished — the other half of\n * {@link heldByPassword}, which reads **after** it issued.\n *\n * Both spends are attempted even when one fails, so a store failing one kind\n * still spends the other; the first failure is then thrown.\n *\n * After the write, not before: a link issued while the password is written\n * is spent too, where one issued between an earlier spend and the write\n * would survive. So an outage here leaves the password written and the\n * older links live, and the caller is told, with `STORE_FAILED`; the next\n * `resetPassword.request` spends them. Sign-in codes and step-ups are left\n * alone: the password proves neither, and a step-up belongs to a session,\n * which a reset revokes.\n */\nexport async function endWhatThePasswordOpened(\n\tcontext: Context,\n\tuserId: Id,\n): Promise<void> {\n\tconst now = context.clock.now();\n\tconst spent = await Promise.allSettled(\n\t\t(['resetPassword', 'secondFactor'] as const).map((kind) =>\n\t\t\tcontext.store.tokens.spendUserTokens(userId, kind, now),\n\t\t),\n\t);\n\tconst failed = spent.find(\n\t\t(result): result is PromiseRejectedResult => result.status === 'rejected',\n\t);\n\tif (failed !== undefined) throw failed.reason;\n}\n\n/**\n * Whether the password a sign-in verified is still the user's, once the\n * sign-in answered. A password written meanwhile ends the sign-in: its\n * session is revoked, or its challenge spent, and `false` is answered.\n *\n * A password writer writes, then spends the challenges waiting; a sign-in\n * issues, then reads here. Whichever order they interleave in, one of the two\n * sees the other. A hash that changed with the same password — a concurrent\n * sign-in rehashing it — is not a change: the password is compared again.\n */\nexport async function heldByPassword(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tverified: UserRecord,\n\tpassword: string,\n\tresult: SignInResult<AnyUser>,\n\twhere: string,\n): Promise<boolean> {\n\tconst now = await findRecord(context, verified.id, type.name);\n\tconst kept =\n\t\tnow !== null &&\n\t\tnow.password !== null &&\n\t\t(now.password.hash === verified.password?.hash ||\n\t\t\t(await passwordMatches(context, now, password, where)));\n\tif (kept) return true;\n\n\tif (result.status === 'signedIn') {\n\t\tawait context.store.sessions.revokeSession(\n\t\t\tresult.session.id,\n\t\t\tcontext.clock.now(),\n\t\t);\n\t} else {\n\t\tawait burnOneTime(context, result.challenge, 'secondFactor');\n\t}\n\treturn false;\n}\n",
|
|
36
37
|
"/**\n * The token an e-mail flow sends and redeems: issued for the user's current\n * e-mail, and refused on redemption when that e-mail is not the one it was\n * sent to any more.\n */\n\nimport { NotFoundError } from '../../errors/janus-error';\nimport type { ResolvedType } from '../config';\nimport { type Context, emailOf, findRecord } from '../context';\nimport {\n\tissueOneTime,\n\trefuseStale,\n\tspendOneTime,\n\tunknownOneTime,\n} from '../one-time';\nimport type { TokenKind, TokenRecord, UserRecord } from '../port/types';\nimport type { IssuedToken } from '../types';\n\n/**\n * Spends a token and says why it cannot be used, when it cannot. A user\n * gone since, or of another type, is as good as no token; a token sent to\n * an e-mail the user no longer has is stale.\n */\nexport async function redeemEmailToken(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tkind: TokenKind,\n\tsecret: string,\n\twhere: string,\n): Promise<{ token: TokenRecord; user: UserRecord }> {\n\tconst token = await spendOneTime(context, secret, kind, where, 'token');\n\tconst user = await findRecord(context, token.userId, type.name);\n\tif (user === null) throw unknownOneTime(where, 'token');\n\n\trefuseStale(type, user, token, where, 'token');\n\treturn { token, user };\n}\n\n/** Issues a one-time token for the user's current e-mail. */\nexport async function issueEmailToken(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tkind: 'verifyEmail' | 'resetPassword',\n\tuser: UserRecord,\n\twhere: string,\n): Promise<IssuedToken> {\n\tconst email = emailOf(type, user.fields);\n\tif (email === null) {\n\t\tthrow new NotFoundError(`${where}: the user has no e-mail`, {\n\t\t\tuserId: user.id,\n\t\t\tuserType: type.name,\n\t\t\toperation: where,\n\t\t});\n\t}\n\n\tconst { secret, expiresAt } = await issueOneTime(context, {\n\t\tkind,\n\t\tuserId: user.id,\n\t\taddress: email,\n\t\tttlMs: context.config.tokenTtlMs[kind],\n\t});\n\treturn { token: secret, email, expiresAt };\n}\n",
|
|
37
|
-
"/**\n * Resetting a password: send a token to the holder of an e-mail, then redeem\n * it to set the password — which proves the e-mail, and signs the user out\n * everywhere.\n */\n\nimport type { At } from '../at';\nimport type { ResolvedType } from '../config';\nimport {\n\ttype AnyUser,\n\ttype Context,\n\tcheckPassword,\n\tholderOfEmail,\n\tpasswordRule,\n\trequireHasher,\n\ttoUser,\n\twriteUser,\n} from '../context';\nimport { emit } from '../events';\nimport { refuseStale } from '../one-time';\nimport {
|
|
38
|
+
"/**\n * Resetting a password: send a token to the holder of an e-mail, then redeem\n * it to set the password — which proves the e-mail, and signs the user out\n * everywhere.\n */\n\nimport type { At } from '../at';\nimport type { ResolvedType } from '../config';\nimport {\n\ttype AnyUser,\n\ttype Context,\n\tcheckPassword,\n\tholderOfEmail,\n\tpasswordRule,\n\trequireHasher,\n\ttoUser,\n\twriteUser,\n} from '../context';\nimport { emit } from '../events';\nimport { refuseStale } from '../one-time';\nimport { endWhatThePasswordOpened } from '../password-written';\nimport { hashSecret } from '../secrets';\nimport type { ResetPasswordApi } from '../types';\nimport { issueEmailToken, redeemEmailToken } from './email-token';\n\ntype ResetPassword = ResetPasswordApi<AnyUser>['resetPassword'];\n\n/**\n * `resetPassword` of one user type: `request` a token for the holder of an\n * e-mail, then `confirm` it with a new password.\n */\nexport function resetPasswordFlows(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tat: At,\n): ResetPassword {\n\treturn {\n\t\tasync request(email) {\n\t\t\tconst where = at('resetPassword.request');\n\t\t\tpasswordRule(type, where);\n\t\t\tconst record = await holderOfEmail(context, type, String(email));\n\t\t\tif (record === null) return null;\n\n\t\t\tconst issued = await issueEmailToken(\n\t\t\t\tcontext,\n\t\t\t\ttype,\n\t\t\t\t'resetPassword',\n\t\t\t\trecord,\n\t\t\t\twhere,\n\t\t\t);\n\t\t\t// One live link per user: the ones sent before stop working.\n\t\t\t// Issued first, spent after, as for a sign-in code, so requests\n\t\t\t// that race leave at most one live — never one each.\n\t\t\tawait context.store.tokens.spendUserTokens(\n\t\t\t\trecord.id,\n\t\t\t\t'resetPassword',\n\t\t\t\tcontext.clock.now(),\n\t\t\t\thashSecret(issued.token),\n\t\t\t);\n\t\t\treturn { ...issued, user: toUser(record) };\n\t\t},\n\n\t\tasync confirm(secret, password) {\n\t\t\treturn confirmReset(\n\t\t\t\tcontext,\n\t\t\t\ttype,\n\t\t\t\tsecret,\n\t\t\t\tpassword,\n\t\t\t\tat('resetPassword.confirm'),\n\t\t\t);\n\t\t},\n\t};\n}\n\n/** Redeems a reset token: sets the password, proves the e-mail, signs out everywhere. */\nasync function confirmReset(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tsecret: string,\n\tpassword: string,\n\twhere: string,\n): Promise<AnyUser> {\n\tpasswordRule(type, where);\n\t// Checked before the token is spent: a password refused for its\n\t// length must not cost the visitor their link.\n\tcheckPassword(type, password, where);\n\tconst hash = await requireHasher(context, where).hash(password);\n\n\tconst { token, user } = await redeemEmailToken(\n\t\tcontext,\n\t\ttype,\n\t\t'resetPassword',\n\t\tsecret,\n\t\twhere,\n\t);\n\tlet newlyVerified = false;\n\tconst written = await writeUser(\n\t\tcontext,\n\t\tuser.id,\n\t\ttype,\n\t\tundefined,\n\t\twhere,\n\t\t(record, now) => {\n\t\t\t// Checked again on the record written, as for verifyEmail.\n\t\t\trefuseStale(type, record, token, where, 'token');\n\t\t\tnewlyVerified = record.emailVerifiedAt === null;\n\t\t\treturn {\n\t\t\t\tpassword: { hash, updatedAt: now },\n\t\t\t\t// The link reached the inbox: that proves the e-mail.\n\t\t\t\t...(record.emailVerifiedAt === null ? { emailVerifiedAt: now } : {}),\n\t\t\t};\n\t\t},\n\t);\n\ttry {\n\t\t// Whoever had the old password is signed out, a sign-in they\n\t\t// left waiting on its second factor cannot be finished, and no\n\t\t// other link replaces the password again — before the listener\n\t\t// runs, however long it takes.\n\t\tawait context.store.sessions.revokeUserSessions(\n\t\t\twritten.id,\n\t\t\tcontext.clock.now(),\n\t\t);\n\t\tawait endWhatThePasswordOpened(context, written.id);\n\t} finally {\n\t\t// Reported even when an outage interrupts the steps above:\n\t\t// the link is spent, so a retry is refused and could not.\n\t\tawait emit(context, 'user.passwordReset', written, written.updatedAt);\n\t\tif (newlyVerified) {\n\t\t\tawait emit(context, 'user.emailVerified', written, written.updatedAt);\n\t\t}\n\t}\n\treturn toUser(written);\n}\n",
|
|
38
39
|
"/**\n * Verifying an e-mail: send a token to it, then redeem the token to mark the\n * address verified.\n */\n\nimport type { At } from '../at';\nimport type { ResolvedType } from '../config';\nimport {\n\ttype AnyUser,\n\ttype Context,\n\tgetRecord,\n\tidOf,\n\ttoUser,\n\twriteUser,\n} from '../context';\nimport { emit } from '../events';\nimport { refuseStale } from '../one-time';\nimport type { VerifyEmailApi } from '../types';\nimport { issueEmailToken, redeemEmailToken } from './email-token';\n\n/** `verifyEmail` of one user type: `send` a token to its e-mail, then `confirm` it. */\nexport function verifyEmailFlows(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tat: At,\n): VerifyEmailApi<AnyUser>['verifyEmail'] {\n\treturn {\n\t\tasync send(user) {\n\t\t\tconst where = at('verifyEmail.send');\n\t\t\tconst record = await getRecord(context, idOf(user), type.name, where);\n\t\t\treturn issueEmailToken(context, type, 'verifyEmail', record, where);\n\t\t},\n\n\t\tasync confirm(secret) {\n\t\t\tconst where = at('verifyEmail.confirm');\n\t\t\tconst { token, user } = await redeemEmailToken(\n\t\t\t\tcontext,\n\t\t\t\ttype,\n\t\t\t\t'verifyEmail',\n\t\t\t\tsecret,\n\t\t\t\twhere,\n\t\t\t);\n\t\t\tlet newlyVerified = false;\n\t\t\tconst written = await writeUser(\n\t\t\t\tcontext,\n\t\t\t\tuser.id,\n\t\t\t\ttype,\n\t\t\t\tundefined,\n\t\t\t\twhere,\n\t\t\t\t(record, now) => {\n\t\t\t\t\t// Checked again on the record written: an e-mail changed\n\t\t\t\t\t// since the read above is not the one the link proved.\n\t\t\t\t\trefuseStale(type, record, token, where, 'token');\n\t\t\t\t\tnewlyVerified = record.emailVerifiedAt === null;\n\t\t\t\t\treturn { emailVerifiedAt: now };\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (newlyVerified) {\n\t\t\t\tawait emit(context, 'user.emailVerified', written, written.updatedAt);\n\t\t\t}\n\t\t\treturn toUser(written);\n\t\t},\n\t};\n}\n",
|
|
39
40
|
"/** The e-mail flows of one user type, assembled from the files beside this one. */\n\nimport type { At } from '../at';\nimport type { ResolvedType } from '../config';\nimport type { AnyUser, Context } from '../context';\nimport type { ResetPasswordApi, VerifyEmailApi } from '../types';\nimport { resetPasswordFlows } from './reset-password';\nimport { verifyEmailFlows } from './verify-email';\n\n/**\n * The e-mail flows: send a one-time token by e-mail, then confirm it —\n * verifying the address, or resetting the password. Both confirm the same\n * way: spend the token, read the user, and check the address again on the\n * very record the write replaces.\n */\nexport function emailFlows(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tat: At,\n): VerifyEmailApi<AnyUser> & ResetPasswordApi<AnyUser> {\n\treturn {\n\t\tverifyEmail: verifyEmailFlows(context, type, at),\n\t\tresetPassword: resetPasswordFlows(context, type, at),\n\t};\n}\n",
|
|
40
41
|
"import { createHmac, randomBytes } from 'node:crypto';\n\n/**\n * RFC 6238 as every authenticator app reads it: HMAC-SHA-1, six digits, a\n * thirty-second step. None of the three is configurable, on purpose — an app\n * that ignores `algorithm` or `digits` in the URI, and several do, would show\n * a code the server never accepts.\n */\nexport const TOTP = { digits: 6, stepMs: 30_000, drift: 1 } as const;\n\nconst BASE32 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';\n\n/** A fresh TOTP secret: 20 random bytes — SHA-1's block of key — in base32. */\nexport function mintTotpSecret(): string {\n\treturn toBase32(randomBytes(20));\n}\n\n/** RFC 4648 base32, without padding: what an `otpauth://` URI carries. */\nexport function toBase32(bytes: Uint8Array): string {\n\tlet bits = 0;\n\tlet value = 0;\n\tlet out = '';\n\tfor (const byte of bytes) {\n\t\tvalue = (value << 8) | byte;\n\t\tbits += 8;\n\t\twhile (bits >= 5) {\n\t\t\tout += BASE32[(value >>> (bits - 5)) & 31];\n\t\t\tbits -= 5;\n\t\t}\n\t}\n\tif (bits > 0) out += BASE32[(value << (5 - bits)) & 31];\n\treturn out;\n}\n\nexport function fromBase32(text: string): Buffer {\n\tlet bits = 0;\n\tlet value = 0;\n\tconst out: number[] = [];\n\tfor (const char of text) {\n\t\tconst index = BASE32.indexOf(char);\n\t\tif (index === -1) throw new TypeError('totp: the secret is not base32');\n\t\tvalue = (value << 5) | index;\n\t\tbits += 5;\n\t\tif (bits >= 8) {\n\t\t\tout.push((value >>> (bits - 8)) & 255);\n\t\t\tbits -= 8;\n\t\t}\n\t}\n\treturn Buffer.from(out);\n}\n\n/** The step a moment falls in: whole thirty-second periods since the epoch. */\nexport const stepAt = (now: Date): number =>\n\tMath.floor(now.getTime() / TOTP.stepMs);\n\n/** RFC 4226's code for one counter value, zero-padded to six digits. */\nexport function codeAt(secret: Buffer, step: number): string {\n\tconst counter = Buffer.alloc(8);\n\tcounter.writeBigUInt64BE(BigInt(step));\n\tconst digest = createHmac('sha1', secret).update(counter).digest();\n\tconst offset = (digest[19] as number) & 0x0f;\n\tconst binary = digest.readUInt32BE(offset) & 0x7fffffff;\n\treturn String(binary % 10 ** TOTP.digits).padStart(TOTP.digits, '0');\n}\n\n/**\n * The step this code was shown at — the current one, or one either side for a\n * clock that drifted — or `null`.\n *\n * **Only a step after `lastStep` counts**, so a code is used once: the caller\n * writes the step it got back, and a replay of the same code finds nothing.\n * Every candidate is computed, so the time taken does not say which matched.\n */\nexport function matchStep(\n\tsecret: Buffer,\n\tcode: string,\n\tnow: Date,\n\tlastStep: number | null,\n): number | null {\n\tif (!/^\\d{6}$/.test(code)) return null;\n\tconst current = stepAt(now);\n\tlet matched: number | null = null;\n\tfor (let step = current - TOTP.drift; step <= current + TOTP.drift; step++) {\n\t\tconst fresh = lastStep === null || step > lastStep;\n\t\tif (equalCodes(codeAt(secret, step), code) && fresh && matched === null) {\n\t\t\tmatched = step;\n\t\t}\n\t}\n\treturn matched;\n}\n\n/** Compares two six-digit strings without stopping at the first difference. */\nfunction equalCodes(a: string, b: string): boolean {\n\tlet difference = a.length ^ b.length;\n\tfor (let i = 0; i < a.length; i++) {\n\t\tdifference |= a.charCodeAt(i) ^ b.charCodeAt(i);\n\t}\n\treturn difference === 0;\n}\n\n/**\n * The `otpauth://` URI an authenticator app reads from a QR code. The label is\n * `issuer:account`, each part percent-encoded, and `issuer` is repeated as a\n * parameter, as Google Authenticator requires.\n */\nexport function otpauthUri(\n\tissuer: string,\n\taccount: string,\n\tsecret: string,\n): string {\n\tconst label = `${encodeURIComponent(issuer)}:${encodeURIComponent(account)}`;\n\tconst query = new URLSearchParams({\n\t\tsecret,\n\t\tissuer,\n\t\talgorithm: 'SHA1',\n\t\tdigits: String(TOTP.digits),\n\t\tperiod: String(TOTP.stepMs / 1000),\n\t});\n\treturn `otpauth://totp/${label}?${query}`;\n}\n",
|
|
@@ -47,24 +48,29 @@
|
|
|
47
48
|
"import type { ResolvedType } from '../config';\nimport { type AnyUser, type Context, toUser, writeUser } from '../context';\nimport { emit } from '../events';\nimport { codeInvalid } from '../one-time';\nimport type { RecoveryCodesIssued, UserRef, WriteOptions } from '../types';\nimport { acceptCode, isActive, requireSettings } from './factor';\nimport { hashRecoveryCode, mintRecoveryCodes } from './recovery-codes';\nimport { refusal } from './refusal';\n\n/**\n * Confirms a waiting factor with its first code: from then on, it is asked\n * for. Its recovery codes are written in the same write, and answered once.\n */\nexport async function activateFactor(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tuser: UserRef,\n\tcode: string,\n\toptions: WriteOptions | undefined,\n\twhere: string,\n): Promise<RecoveryCodesIssued<AnyUser>> {\n\tconst configured = requireSettings(\n\t\tcontext,\n\t\twhere,\n\t\t'a second factor is being activated',\n\t);\n\tconst recoveryCodes = mintRecoveryCodes();\n\n\tconst written = await writeUser(\n\t\tcontext,\n\t\tuser,\n\t\ttype,\n\t\toptions,\n\t\twhere,\n\t\t(record, now) => {\n\t\t\tconst factor = record.secondFactor;\n\t\t\tif (factor === null) {\n\t\t\t\tthrow refusal(\n\t\t\t\t\ttype,\n\t\t\t\t\t'SECOND_FACTOR_NOT_ENROLLED',\n\t\t\t\t\t'the user has no second factor waiting — call enroll first',\n\t\t\t\t\twhere,\n\t\t\t\t\trecord,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (isActive(factor)) {\n\t\t\t\tthrow refusal(\n\t\t\t\t\ttype,\n\t\t\t\t\t'SECOND_FACTOR_ACTIVE',\n\t\t\t\t\t\"the user's second factor is already active\",\n\t\t\t\t\twhere,\n\t\t\t\t\trecord,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst accepted = acceptCode(\n\t\t\t\tconfigured,\n\t\t\t\trecord,\n\t\t\t\tfactor,\n\t\t\t\tString(code),\n\t\t\t\tnow,\n\t\t\t\twhere,\n\t\t\t);\n\t\t\tif (accepted === null) throw codeInvalid(where, record.id, type.name);\n\t\t\treturn {\n\t\t\t\tsecondFactor: {\n\t\t\t\t\t...accepted,\n\t\t\t\t\tconfirmedAt: now,\n\t\t\t\t\trecoveryCodes: recoveryCodes.map((one) =>\n\t\t\t\t\t\thashRecoveryCode(configured.sealer, record.id, one),\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t);\n\t// After the write, the flow's last step: the factor is asked for from now.\n\tawait emit(context, 'user.secondFactorEnabled', written, written.updatedAt);\n\treturn { user: toUser(written), recoveryCodes };\n}\n",
|
|
48
49
|
"import type { ResolvedType } from '../config';\nimport { type AnyUser, type Context, toUser, writeUser } from '../context';\nimport { emit } from '../events';\nimport type { UserRef, WriteOptions } from '../types';\nimport { isActive } from './factor';\n\n/**\n * Removes the factor, active or waiting. Reported only when an active one\n * went: a user who had none, or whose factor never received its first code,\n * was never asked for one, and still is not.\n */\nexport async function disableFactor(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tuser: UserRef,\n\toptions: WriteOptions | undefined,\n\twhere: string,\n): Promise<AnyUser> {\n\tlet wasActive = false;\n\tconst written = await writeUser(\n\t\tcontext,\n\t\tuser,\n\t\ttype,\n\t\toptions,\n\t\twhere,\n\t\t(record) => {\n\t\t\twasActive = isActive(record.secondFactor);\n\t\t\treturn { secondFactor: null };\n\t\t},\n\t);\n\tif (wasActive) {\n\t\tawait emit(\n\t\t\tcontext,\n\t\t\t'user.secondFactorDisabled',\n\t\t\twritten,\n\t\t\twritten.updatedAt,\n\t\t);\n\t}\n\treturn toUser(written);\n}\n",
|
|
49
50
|
"import type { ResolvedType } from '../config';\nimport { type Context, writeUser } from '../context';\nimport type { UserRecord } from '../port/types';\nimport { seal } from '../sealing';\nimport { mintTotpSecret, otpauthUri } from '../totp';\nimport type { SecondFactorEnrolment, UserRef, WriteOptions } from '../types';\nimport { isActive, requireSettings } from './factor';\nimport { refusal } from './refusal';\n\n/** Writes a factor waiting for its first code, and answers the secret to show. */\nexport async function enrollFactor(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tuser: UserRef,\n\toptions: WriteOptions | undefined,\n\twhere: string,\n): Promise<SecondFactorEnrolment> {\n\tconst configured = requireSettings(\n\t\tcontext,\n\t\twhere,\n\t\t'a second factor is being enrolled',\n\t);\n\tconst secret = mintTotpSecret();\n\n\tconst written = await writeUser(\n\t\tcontext,\n\t\tuser,\n\t\ttype,\n\t\toptions,\n\t\twhere,\n\t\t(record) => {\n\t\t\tif (isActive(record.secondFactor)) {\n\t\t\t\tthrow refusal(\n\t\t\t\t\ttype,\n\t\t\t\t\t'SECOND_FACTOR_ACTIVE',\n\t\t\t\t\t\"the user's second factor is active — disable it first\",\n\t\t\t\t\twhere,\n\t\t\t\t\trecord,\n\t\t\t\t);\n\t\t\t}\n\t\t\taccountOf(type, record, where);\n\t\t\treturn {\n\t\t\t\tsecondFactor: {\n\t\t\t\t\tmethod: 'totp',\n\t\t\t\t\tsecret: seal(configured.sealer, secret, record.id),\n\t\t\t\t\tconfirmedAt: null,\n\t\t\t\t\tlastStep: null,\n\t\t\t\t\trecoveryCodes: [],\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t);\n\n\treturn {\n\t\tsecret,\n\t\turi: otpauthUri(configured.issuer, accountOf(type, written, where), secret),\n\t};\n}\n\n/** The login a user signs in with: the account name the app shows. */\nfunction accountOf(\n\ttype: ResolvedType,\n\trecord: UserRecord,\n\twhere: string,\n): string {\n\tif (type.password === null) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: the ${type.name} type does not sign in with a password, so it has no second factor`,\n\t\t);\n\t}\n\treturn String(record.fields[type.password.login]);\n}\n",
|
|
50
|
-
"import { createHmac, hkdfSync } from 'node:crypto';\nimport { StoreConflict, TokenError } from '../../errors/janus-error';\nimport type { Context } from '../context';\nimport { CODE_ATTEMPTS } from '../one-time';\nimport type { TokenRecord, UserRecord } from '../port/types';\nimport type { Sealer } from '../sealing';\nimport { hashSecret } from '../secrets';\n\n/**\n * The attempts at `regenerateRecoveryCodes
|
|
51
|
-
"import type { ResolvedType } from '../config';\nimport { type AnyUser, type Context, toUser, writeUser } from '../context';\nimport { emit } from '../events';\nimport { codeInvalid } from '../one-time';\nimport type { RecoveryCodesIssued, UserRef, WriteOptions } from '../types';\nimport { acceptCode, isActive, requireSettings } from './factor';\nimport { hashRecoveryCode, mintRecoveryCodes } from './recovery-codes';\nimport { refusal } from './refusal';\
|
|
51
|
+
"import { createHmac, hkdfSync } from 'node:crypto';\nimport { StoreConflict, TokenError } from '../../errors/janus-error';\nimport type { Context } from '../context';\nimport { CODE_ATTEMPTS } from '../one-time';\nimport type { TokenRecord, UserRecord } from '../port/types';\nimport type { Sealer } from '../sealing';\nimport { hashSecret } from '../secrets';\n\n/**\n * The attempts at an app's code outside a sign-in — `regenerateRecoveryCodes`\n * and a step-up confirmed with the app — counted by the store, in one count\n * both share: the same {@link CODE_ATTEMPTS} a challenge takes, per user and\n * per window, so a stolen session cannot guess the app's code at leisure,\n * nor buy more guesses by switching from one to the other.\n *\n * **No port of its own.** The count is a one-time token of kind\n * `secondFactor`, counted by `countAttempt` like a challenge's: one\n * conditional write per attempt, never read then written. Its secret is\n * never given out; it is a keyed hash of what the count is for, so nobody\n * without the sealing keys can name it — nor redeem it as a challenge.\n *\n * What it is for decides when it starts again: the **window**, a fixed\n * {@link APP_CODE_WINDOW_MS} slice of the clock, and the factor's\n * `lastStep`, which **any code accepted** moves — a regenerate that\n * succeeded starts the count again, and so does a sign-in finished with the\n * app.\n *\n * Writing a password spends every `secondFactor` token of the user, this one\n * included, and a spent token counts nothing more. So the count is a chain:\n * a spent link keeps the attempts it holds, and the next one carries on\n * from them — a password written between guesses buys none.\n */\n\n/** How long the attempts of one window last: fifteen minutes. */\nexport const APP_CODE_WINDOW_MS = 15 * 60_000;\n\nconst WINDOW_MINUTES = APP_CODE_WINDOW_MS / 60_000;\n\n/**\n * What the key is derived for: never the key that seals a secret itself.\n * Named after the first flow that counted, and kept: renamed, every count\n * in progress would start over.\n */\nconst PURPOSE = 'janus/second-factor/regenerate-attempts/v1';\n\n/** More links than this in one window is more passwords written than guesses. */\nconst MAX_LINKS = 32;\n\nconst derived = new WeakMap<Sealer, Buffer>();\n\nfunction counterKey(sealer: Sealer): Buffer {\n\tlet key = derived.get(sealer);\n\tif (key === undefined) {\n\t\tconst secret = sealer.keys.get(sealer.sealWith) as Buffer;\n\t\tkey = Buffer.from(hkdfSync('sha256', secret, Buffer.alloc(0), PURPOSE, 32));\n\t\tderived.set(sealer, key);\n\t}\n\treturn key;\n}\n\n/** A link's token hash: its secret is never given out, nor stored. */\nfunction linkHash(\n\tsealer: Sealer,\n\trecord: UserRecord,\n\twindow: number,\n\tlink: number,\n): string {\n\tconst parts = [\n\t\trecord.id,\n\t\tString(window),\n\t\tString(record.secondFactor?.lastStep ?? ''),\n\t\tString(link),\n\t];\n\treturn hashSecret(\n\t\tcreateHmac('sha256', counterKey(sealer))\n\t\t\t.update(parts.join('\\u0000'))\n\t\t\t.digest('base64url'),\n\t);\n}\n\n/**\n * Counts one attempt at the app's code — to regenerate the user's recovery\n * codes, or to confirm a step-up — before the code is compared, and\n * answers how many are left. Past the last one, it refuses — the right\n * code included — until the window ends.\n */\nexport async function countAppCodeAttempt(\n\tcontext: Context,\n\tsealer: Sealer,\n\trecord: UserRecord,\n\twhere: string,\n): Promise<number> {\n\tconst now = context.clock.now().getTime();\n\tconst window = Math.floor(now / APP_CODE_WINDOW_MS);\n\t// A window of slack: a store whose clock runs ahead of this one must not\n\t// drop a link before its window ends. The window is in the hash, so a\n\t// link never counts for the next one.\n\tconst times = { now, expiresAt: (window + 2) * APP_CODE_WINDOW_MS };\n\tlet spent = 0;\n\tfor (let link = 0; link < MAX_LINKS; link += 1) {\n\t\tconst hash = linkHash(sealer, record, window, link);\n\t\tconst counted = await countLink(context, hash, record, times, where);\n\t\tconst attempts = spent + counted.attempts;\n\t\tif (counted.spentAt === null) return attemptsLeft(attempts, record, where);\n\t\tspent = attempts;\n\t}\n\treturn attemptsLeft(Number.POSITIVE_INFINITY, record, where);\n}\n\n/** One attempt on one link: inserted on the first, and counted. */\nasync function countLink(\n\tcontext: Context,\n\ttokenHash: string,\n\trecord: UserRecord,\n\ttimes: { readonly now: number; readonly expiresAt: number },\n\twhere: string,\n): Promise<TokenRecord> {\n\tconst tokens = context.store.tokens;\n\tconst counted = await tokens.countAttempt(tokenHash, 'secondFactor');\n\tif (counted !== null) return counted;\n\t// Idempotent: of two first attempts at once, one inserts, both count.\n\tawait tokens.insertToken({\n\t\ttokenHash,\n\t\tkind: 'secondFactor',\n\t\tuserId: record.id,\n\t\taddress: '',\n\t\tcodeHash: null,\n\t\tattempts: 0,\n\t\texpiresAt: new Date(times.expiresAt),\n\t\tspentAt: null,\n\t\tcreatedAt: new Date(times.now),\n\t});\n\tconst inserted = await tokens.countAttempt(tokenHash, 'secondFactor');\n\tif (inserted !== null) return inserted;\n\t// Gone right after it was stored: the user was deleted meanwhile.\n\tthrow new StoreConflict(\n\t\t'version',\n\t\t`${where}: the user changed while the code was checked — read it again and retry`,\n\t\t{ userId: record.id, expectedVersion: record.version, operation: where },\n\t);\n}\n\n/** Attempts left after `attempts`, or the refusal past the last one. */\nfunction attemptsLeft(\n\tattempts: number,\n\trecord: UserRecord,\n\twhere: string,\n): number {\n\tif (attempts > CODE_ATTEMPTS) {\n\t\tthrow new TokenError(\n\t\t\t'CODE_INVALID',\n\t\t\t`${where}: too many codes tried — wait for the next ${WINDOW_MINUTES}-minute window`,\n\t\t\t{\n\t\t\t\toperation: where,\n\t\t\t\tuserId: record.id,\n\t\t\t\tuserType: record.type,\n\t\t\t\tattemptsLeft: 0,\n\t\t\t},\n\t\t);\n\t}\n\treturn CODE_ATTEMPTS - attempts;\n}\n",
|
|
52
|
+
"import type { ResolvedType } from '../config';\nimport { type AnyUser, type Context, toUser, writeUser } from '../context';\nimport { emit } from '../events';\nimport { codeInvalid } from '../one-time';\nimport type { RecoveryCodesIssued, UserRef, WriteOptions } from '../types';\nimport { countAppCodeAttempt } from './app-code-attempts';\nimport { acceptCode, isActive, requireSettings } from './factor';\nimport { hashRecoveryCode, mintRecoveryCodes } from './recovery-codes';\nimport { refusal } from './refusal';\n\n/**\n * Replaces a user's recovery codes with new ones, and answers them once: the\n * old ones, used or not, stop working. Takes a **fresh code from the app** —\n * whoever holds a session alone cannot mint codes that outlive it — and\n * spends it, as a code accepted anywhere else is spent. The attempts are\n * counted first, five per user per window, as a challenge's are.\n */\nexport async function regenerateRecoveryCodes(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tuser: UserRef,\n\tcode: string,\n\toptions: WriteOptions | undefined,\n\twhere: string,\n): Promise<RecoveryCodesIssued<AnyUser>> {\n\tconst configured = requireSettings(\n\t\tcontext,\n\t\twhere,\n\t\t'recovery codes are being regenerated',\n\t);\n\tconst recoveryCodes = mintRecoveryCodes();\n\n\tconst written = await writeUser(\n\t\tcontext,\n\t\tuser,\n\t\ttype,\n\t\toptions,\n\t\twhere,\n\t\tasync (record, now) => {\n\t\t\tconst factor = record.secondFactor;\n\t\t\tif (!isActive(factor)) {\n\t\t\t\tthrow refusal(\n\t\t\t\t\ttype,\n\t\t\t\t\t'SECOND_FACTOR_NOT_ENROLLED',\n\t\t\t\t\t'the user has no active second factor — recovery codes come with one',\n\t\t\t\t\twhere,\n\t\t\t\t\trecord,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst left = await countAppCodeAttempt(\n\t\t\t\tcontext,\n\t\t\t\tconfigured.sealer,\n\t\t\t\trecord,\n\t\t\t\twhere,\n\t\t\t);\n\t\t\tconst accepted = acceptCode(\n\t\t\t\tconfigured,\n\t\t\t\trecord,\n\t\t\t\tfactor,\n\t\t\t\tString(code),\n\t\t\t\tnow,\n\t\t\t\twhere,\n\t\t\t);\n\t\t\tif (accepted === null) {\n\t\t\t\tthrow codeInvalid(where, record.id, type.name, left);\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tsecondFactor: {\n\t\t\t\t\t...accepted,\n\t\t\t\t\trecoveryCodes: recoveryCodes.map((one) =>\n\t\t\t\t\t\thashRecoveryCode(configured.sealer, record.id, one),\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t);\n\tawait emit(\n\t\tcontext,\n\t\t'user.recoveryCodesRegenerated',\n\t\twritten,\n\t\twritten.updatedAt,\n\t);\n\treturn { user: toUser(written), recoveryCodes };\n}\n",
|
|
52
53
|
"import type { At } from '../at';\nimport type { ResolvedType } from '../config';\nimport type { AnyUser, Context } from '../context';\nimport type { SecondFactorApi } from '../types';\nimport { activateFactor } from './activate';\nimport { disableFactor } from './disable';\nimport { enrollFactor } from './enroll';\nimport { regenerateRecoveryCodes } from './regenerate';\n\ntype Lifecycle = Pick<\n\tSecondFactorApi<AnyUser>['secondFactor'],\n\t'enroll' | 'activate' | 'regenerateRecoveryCodes' | 'disable'\n>;\n\n/**\n * Enrolling, activating, regenerating its recovery codes and disabling a\n * factor: each one write under a version. This module only names each call;\n * each step is a module of its own — `./enroll`, `./activate`,\n * `./regenerate`, `./disable`.\n */\nexport function lifecycleFlows(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tat: At,\n): Lifecycle {\n\treturn {\n\t\tasync enroll(user, options) {\n\t\t\treturn enrollFactor(\n\t\t\t\tcontext,\n\t\t\t\ttype,\n\t\t\t\tuser,\n\t\t\t\toptions,\n\t\t\t\tat('secondFactor.enroll'),\n\t\t\t);\n\t\t},\n\n\t\tasync activate(user, code, options) {\n\t\t\treturn activateFactor(\n\t\t\t\tcontext,\n\t\t\t\ttype,\n\t\t\t\tuser,\n\t\t\t\tcode,\n\t\t\t\toptions,\n\t\t\t\tat('secondFactor.activate'),\n\t\t\t);\n\t\t},\n\n\t\tasync regenerateRecoveryCodes(user, code, options) {\n\t\t\treturn regenerateRecoveryCodes(\n\t\t\t\tcontext,\n\t\t\t\ttype,\n\t\t\t\tuser,\n\t\t\t\tcode,\n\t\t\t\toptions,\n\t\t\t\tat('secondFactor.regenerateRecoveryCodes'),\n\t\t\t);\n\t\t},\n\n\t\tasync disable(user, options) {\n\t\t\treturn disableFactor(\n\t\t\t\tcontext,\n\t\t\t\ttype,\n\t\t\t\tuser,\n\t\t\t\toptions,\n\t\t\t\tat('secondFactor.disable'),\n\t\t\t);\n\t\t},\n\t};\n}\n",
|
|
53
54
|
"import type { At } from '../at';\nimport type { ResolvedType } from '../config';\nimport type { AnyUser, Context } from '../context';\nimport { emit } from '../events';\nimport { openSession } from '../sessions';\nimport type { RecoveredSignIn } from '../types';\nimport { findRecoveryCode } from './recovery-codes';\nimport { openChallenge, refuseCode, spendChallenge } from './redeem';\n\n/**\n * Redeems `signIn`'s challenge with a recovery code instead of an app's\n * code: for a user whose phone is gone.\n *\n * The challenge is counted and its user checked exactly as for `confirm`.\n * A code that matches is **removed** — its hash dropped from the factor — in\n * one write under the version read, as `confirm` writes its last step: of\n * two sign-ins spending the same code at once, the second write is\n * `VERSION_CONFLICT`, and that sign-in opens nothing.\n */\nexport async function recoverWithCode(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tchallenge: string,\n\tcode: string,\n\tat: At,\n): Promise<RecoveredSignIn<AnyUser>> {\n\tconst where = at('secondFactor.recover');\n\tconst opened = await openChallenge(context, type, challenge, where);\n\tconst { record } = opened;\n\tconst factor = record.secondFactor;\n\n\tconst found = findRecoveryCode(\n\t\topened.configured.sealer,\n\t\trecord.id,\n\t\tfactor.recoveryCodes,\n\t\tString(code),\n\t\twhere,\n\t);\n\tif (found === -1) return refuseCode(context, type, opened, where);\n\n\tconst recoveryCodes = factor.recoveryCodes.filter(\n\t\t(_, index) => index !== found,\n\t);\n\tconst written = await context.store.users.updateUser(\n\t\trecord.id,\n\t\t{\n\t\t\tsecondFactor: { ...factor, recoveryCodes },\n\t\t\tupdatedAt: context.clock.now(),\n\t\t},\n\t\trecord.version,\n\t);\n\t// The code is spent once written, whatever follows: the event reports it\n\t// even when spending the challenge or opening the session fails.\n\ttry {\n\t\tawait spendChallenge(context, opened.secret, where);\n\t\tconst signedIn = await openSession(context, type, written);\n\t\treturn { ...signedIn, recoveryCodesLeft: recoveryCodes.length };\n\t} finally {\n\t\tawait emit(context, 'user.recoveryCodeUsed', written, written.updatedAt);\n\t}\n}\n",
|
|
54
55
|
"import type { At } from '../at';\nimport type { ResolvedType } from '../config';\nimport type { AnyUser, Context } from '../context';\nimport type { UserRecord } from '../port/types';\nimport { openSession } from '../sessions';\nimport type { SecondFactorApi, SignInResult } from '../types';\nimport { challengeFlows } from './challenge';\nimport { recoveryCodesLeftOf } from './codes-left';\nimport { isActive } from './factor';\nimport { lifecycleFlows } from './lifecycle';\nimport { recoverWithCode } from './recovery';\n\n/**\n * The second factor of one user type: the flows its API answers, and what\n * `signIn` needs — whether to ask for a code, and the challenge to answer.\n */\nexport function secondFactorFlows(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tat: At,\n) {\n\tconst challenges = challengeFlows(context, type, at);\n\tconst api: SecondFactorApi<AnyUser>['secondFactor'] = {\n\t\t...lifecycleFlows(context, type, at),\n\t\tconfirm: challenges.confirm,\n\t\trecover: (challenge, code) =>\n\t\t\trecoverWithCode(context, type, challenge, code, at),\n\t\trecoveryCodesLeft: (user) =>\n\t\t\trecoveryCodesLeftOf(\n\t\t\t\tcontext,\n\t\t\t\ttype,\n\t\t\t\tuser,\n\t\t\t\tat('secondFactor.recoveryCodesLeft'),\n\t\t\t),\n\t};\n\n\treturn {\n\t\tapi,\n\t\t/**\n\t\t * What a sign-in answers once the user proved who they are — by\n\t\t * password or by an e-mail code: a session, or a challenge when their\n\t\t * second factor is active. The first factor alone opens nothing then.\n\t\t */\n\t\tfinish: (\n\t\t\trecord: UserRecord,\n\t\t\twhere: string,\n\t\t): Promise<SignInResult<AnyUser>> =>\n\t\t\tisActive(record.secondFactor)\n\t\t\t\t? challenges.issue(record, where)\n\t\t\t\t: openSession(context, type, record),\n\t};\n}\n",
|
|
55
56
|
"import { UserInactiveError } from '../errors/janus-error';\nimport type { At } from './at';\nimport type { ResolvedType } from './config';\nimport {\n\ttype AnyUser,\n\ttype Context,\n\tfindRecord,\n\tholderOfEmail,\n\ttoUser,\n\twriteUser,\n} from './context';\nimport { emit } from './events';\nimport {\n\tburnOneTime,\n\tCODE_ATTEMPTS,\n\tcodeInvalid,\n\tcodeMatches,\n\tcountCodeAttempt,\n\tissueCode,\n\trefuseStale,\n\tspendOneTime,\n\tunknownChallenge,\n} from './one-time';\nimport type { UserRecord } from './port/types';\nimport { hashSecret } from './secrets';\nimport type { IssuedCode, SignInCodeApi, SignInResult } from './types';\n\n/**\n * Signing in with a code sent to the user's e-mail: no password, and the\n * code proves the address.\n *\n * The code is six digits, so it is guessable where a link is not. What\n * bounds that is the same as for a second factor: the store counts every\n * attempt in one write, before the code is compared, and the fifth wrong one\n * spends the challenge. **At most one code is live per user**: `request`\n * spends every other once it issued its own, so concurrent requests cannot\n * each keep one. Yet anybody who knows an e-mail can ask for another — and\n * each request cancels the code before — so the application rate-limits\n * `request`, per address. The code's hash is keyed by the challenge, so the\n * tokens alone do not reveal it.\n */\nexport function signInCodeFlows(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tat: At,\n\tfinish: Finish,\n): SignInCodeApi<AnyUser, SignInResult<AnyUser>>['signInCode'] {\n\treturn {\n\t\tasync request(email) {\n\t\t\treturn requestCode(context, type, String(email));\n\t\t},\n\n\t\tasync confirm(challenge, code) {\n\t\t\treturn confirmCode(context, type, finish, challenge, code, at);\n\t\t},\n\t};\n}\n\ntype Finish = (\n\trecord: UserRecord,\n\twhere: string,\n) => Promise<SignInResult<AnyUser>>;\n\n/** Issues a code for the holder of `email`, and spends every other they had. */\nasync function requestCode(\n\tcontext: Context,\n\ttype: ResolvedType,\n\temail: string,\n): Promise<IssuedCode<AnyUser> | null> {\n\t// Nobody, and an inactive user, get the same answer: no code.\n\tconst record = await holderOfEmail(context, type, email);\n\tif (record === null || !record.active) return null;\n\n\tconst { secret, code, expiresAt } = await issueCode(context, {\n\t\tkind: 'signInCode',\n\t\tuserId: record.id,\n\t\taddress: String(record.fields[type.email]),\n\t\tttlMs: context.config.tokenTtlMs.signInCode,\n\t});\n\t// One live code per user: the ones sent before stop working. Issued\n\t// first, spent after, so requests that race leave at most one live\n\t// — maybe none, and the visitor asks again — never one each.\n\tawait context.store.tokens.spendUserTokens(\n\t\trecord.id,\n\t\t'signInCode',\n\t\tcontext.clock.now(),\n\t\thashSecret(secret),\n\t);\n\treturn {\n\t\tcode,\n\t\tchallenge: secret,\n\t\temail: String(record.fields[type.email]),\n\t\texpiresAt,\n\t\tuser: toUser(record),\n\t};\n}\n\n/** Redeems a challenge's code, proves the e-mail, and finishes the sign-in. */\nasync function confirmCode(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tfinish: Finish,\n\tchallenge: string,\n\tcode: string,\n\tat: At,\n): Promise<SignInResult<AnyUser>> {\n\tconst where = at('signInCode.confirm');\n\tconst secret = String(challenge);\n\tconst { token, attemptsLeft } = await countCodeAttempt(\n\t\tcontext,\n\t\tsecret,\n\t\t'signInCode',\n\t\twhere,\n\t\ttype.name,\n\t);\n\n\t// A user gone since, or of another type, is as good as no challenge:\n\t// another type's API compares nothing — though the attempt, counted\n\t// before the type is known, is gone, and the last one spends it.\n\tconst user = await findRecord(context, token.userId, type.name);\n\tif (user === null) {\n\t\tthrow await unknownChallenge(context, token, secret, where);\n\t}\n\n\tif (!codeMatches(token, secret, String(code))) {\n\t\t// The last attempt, and a wrong code: the challenge is spent.\n\t\tif (token.attempts === CODE_ATTEMPTS) {\n\t\t\tawait burnOneTime(context, secret, 'signInCode');\n\t\t}\n\t\tthrow codeInvalid(where, user.id, type.name, attemptsLeft);\n\t}\n\n\tawait spendOneTime(context, secret, 'signInCode', where, 'challenge');\n\trefuseStale(type, user, token, where, 'code');\n\tif (!user.active) {\n\t\tthrow new UserInactiveError(`${where}: the user is inactive`, {\n\t\t\tuserId: user.id,\n\t\t\tuserType: type.name,\n\t\t});\n\t}\n\n\t// The code reached the inbox: that proves the e-mail — under the\n\t// version read, so an address changed since is not the one proved.\n\tif (user.emailVerifiedAt !== null) return finish(user, where);\n\tconst proved = await writeUser(\n\t\tcontext,\n\t\tuser.id,\n\t\ttype,\n\t\t{ ifVersion: user.version },\n\t\twhere,\n\t\t(_, now) => ({ emailVerifiedAt: now }),\n\t);\n\tawait emit(context, 'user.emailVerified', proved, proved.updatedAt);\n\treturn finish(proved, where);\n}\n",
|
|
57
|
+
"/**\n * The two codes that confirm a step-up: the one e-mailed with the challenge,\n * and, for a user whose second factor is active, the one their app shows.\n * Each spends the challenge once it matched.\n */\n\nimport { SecondFactorError } from '../../errors/janus-error';\nimport type { ResolvedType } from '../config';\nimport type { Context } from '../context';\nimport {\n\tburnOneTime,\n\tcodeInvalid,\n\tcodeMatches,\n\trefuseStale,\n\tspendOneTime,\n} from '../one-time';\nimport type { TokenRecord, UserRecord } from '../port/types';\nimport { countAppCodeAttempt } from '../second-factor/app-code-attempts';\nimport { acceptCode, isActive, requireSettings } from '../second-factor/factor';\n\n/** A challenge counted: the token as counted, its secret, and what is left of its attempts. */\nexport interface CountedStepUp {\n\treadonly token: TokenRecord;\n\treadonly secret: string;\n\treadonly attemptsLeft: number;\n}\n\nconst spend = (context: Context, secret: string, where: string) =>\n\tspendOneTime(context, secret, 'stepUp', where, 'challenge');\n\n/**\n * Checks the e-mailed code. Refused when the user's second factor became\n * active since it was sent — their app is what confirms now — and when the\n * e-mail it was sent to is not theirs any more.\n */\nexport async function checkEmailedCode(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tuser: UserRecord,\n\tcounted: CountedStepUp,\n\tcode: string,\n\twhere: string,\n): Promise<void> {\n\tconst { token, secret, attemptsLeft } = counted;\n\tif (isActive(user.secondFactor)) {\n\t\tawait spend(context, secret, where);\n\t\tthrow new SecondFactorError(\n\t\t\t'SECOND_FACTOR_ACTIVE',\n\t\t\t`${where}: the user's second factor became active since the code was sent — request a step-up again`,\n\t\t\t{ operation: where, userId: user.id, userType: type.name },\n\t\t);\n\t}\n\tif (!codeMatches(token, secret, code)) {\n\t\tif (attemptsLeft === 0) await burnOneTime(context, secret, 'stepUp');\n\t\tthrow codeInvalid(where, user.id, type.name, attemptsLeft);\n\t}\n\tawait spend(context, secret, where);\n\trefuseStale(type, user, token, where, 'code');\n}\n\n/**\n * Checks a code from the user's app. Its attempts are counted twice before it\n * is compared: against the challenge, and per user and window, as\n * `regenerateRecoveryCodes`' are — a stolen session asking for challenge\n * after challenge still gets five guesses per window, not five per\n * challenge. The code accepted is written, so it confirms nothing else.\n */\nexport async function checkAppCode(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tuser: UserRecord,\n\tcounted: CountedStepUp,\n\tcode: string,\n\twhere: string,\n): Promise<void> {\n\tconst { secret, attemptsLeft } = counted;\n\tconst factor = user.secondFactor;\n\tif (!isActive(factor)) {\n\t\tawait spend(context, secret, where);\n\t\tthrow new SecondFactorError(\n\t\t\t'SECOND_FACTOR_NOT_ENROLLED',\n\t\t\t`${where}: the user no longer has a second factor — request a step-up again`,\n\t\t\t{ operation: where, userId: user.id, userType: type.name },\n\t\t);\n\t}\n\tconst configured = requireSettings(\n\t\tcontext,\n\t\twhere,\n\t\t\"the user's second factor is active\",\n\t);\n\tconst windowLeft = await countAppCodeAttempt(\n\t\tcontext,\n\t\tconfigured.sealer,\n\t\tuser,\n\t\twhere,\n\t);\n\n\tconst now = context.clock.now();\n\tconst accepted = acceptCode(configured, user, factor, code, now, where);\n\tif (accepted === null) {\n\t\tif (attemptsLeft === 0) await burnOneTime(context, secret, 'stepUp');\n\t\tthrow codeInvalid(\n\t\t\twhere,\n\t\t\tuser.id,\n\t\t\ttype.name,\n\t\t\tMath.min(attemptsLeft, windowLeft),\n\t\t);\n\t}\n\t// Written under the version read: of two codes accepted at once, the\n\t// second write is VERSION_CONFLICT.\n\tawait context.store.users.updateUser(\n\t\tuser.id,\n\t\t{ secondFactor: accepted, updatedAt: now },\n\t\tuser.version,\n\t);\n\tawait spend(context, secret, where);\n}\n",
|
|
58
|
+
"/**\n * What confirming a step-up takes before any code is compared: the session\n * the request presents, and the user the challenge is for — the two the\n * same, both standing.\n */\n\nimport { UserInactiveError } from '../../errors/janus-error';\nimport type { ResolvedType } from '../config';\nimport { type Context, findRecord } from '../context';\nimport { spendOneTime, unknownChallenge } from '../one-time';\nimport type { SessionRecord, TokenRecord, UserRecord } from '../port/types';\nimport { standingSession } from '../sessions/standing';\nimport type { RequestLike } from '../types';\n\n/** The session a step-up confirms, and its user. */\nexport interface OpenedStepUp {\n\treadonly session: SessionRecord;\n\treadonly user: UserRecord;\n}\n\n/**\n * Reads the session the request presents and the user the challenge is for.\n * A session absent, revoked, lapsed, or another user's is as good as no\n * challenge — a challenge is confirmed on its user's own session, never on\n * somebody else's — and so is a user gone since, or of another type. Each\n * attempt was counted before, so the last one spends the challenge.\n */\nexport async function openStepUp(\n\tcontext: Context,\n\ttype: ResolvedType,\n\trequest: RequestLike,\n\ttoken: TokenRecord,\n\tsecret: string,\n\twhere: string,\n): Promise<OpenedStepUp> {\n\tconst session = (await standingSession(context, request))?.session ?? null;\n\tif (session === null || session.userId !== token.userId) {\n\t\tthrow await unknownChallenge(context, token, secret, where);\n\t}\n\n\tconst user = await findRecord(context, token.userId, type.name);\n\tif (user === null) {\n\t\tthrow await unknownChallenge(context, token, secret, where);\n\t}\n\tif (!user.active) {\n\t\tawait spendOneTime(context, secret, 'stepUp', where, 'challenge');\n\t\tthrow new UserInactiveError(`${where}: the user is inactive`, {\n\t\t\tuserId: user.id,\n\t\t\tuserType: type.name,\n\t\t});\n\t}\n\treturn { session, user };\n}\n",
|
|
59
|
+
"/**\n * Issuing a step-up: a challenge for the user, with a code to e-mail, or to\n * confirm with their app when their second factor is active.\n */\n\nimport { NotFoundError, UserInactiveError } from '../../errors/janus-error';\nimport type { ResolvedType } from '../config';\nimport {\n\ttype AnyUser,\n\ttype Context,\n\temailOf,\n\tgetRecord,\n\tidOf,\n\ttoUser,\n} from '../context';\nimport { issueCode, issueOneTime } from '../one-time';\nimport type { UserRecord } from '../port/types';\nimport { isActive, requireSettings } from '../second-factor/factor';\nimport { hashSecret } from '../secrets';\nimport type { StepUpByApp, StepUpByEmail, UserRef } from '../types';\n\n/** What `stepUp.request` answers, whatever the type's configuration. */\nexport type IssuedStepUp = StepUpByEmail<AnyUser> | StepUpByApp<AnyUser>;\n\n/** Issues a step-up for the user, and spends every other they had. */\nexport async function requestStepUp(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tuser: UserRef,\n\twhere: string,\n): Promise<IssuedStepUp> {\n\tconst record = await getRecord(context, idOf(user), type.name, where);\n\tif (!record.active) {\n\t\tthrow new UserInactiveError(`${where}: the user is inactive`, {\n\t\t\tuserId: record.id,\n\t\t\tuserType: type.name,\n\t\t});\n\t}\n\n\tconst issued = isActive(record.secondFactor)\n\t\t? await byApp(context, record, where)\n\t\t: await byEmail(context, type, record, where);\n\t// One live step-up per user, as for a sign-in code: issued first, the\n\t// others spent after, so requests that race leave at most one.\n\tawait context.store.tokens.spendUserTokens(\n\t\trecord.id,\n\t\t'stepUp',\n\t\tcontext.clock.now(),\n\t\thashSecret(issued.challenge),\n\t);\n\treturn issued;\n}\n\n/** A challenge the user's app confirms: nothing is sent, so there is no address. */\nasync function byApp(\n\tcontext: Context,\n\trecord: UserRecord,\n\twhere: string,\n): Promise<StepUpByApp<AnyUser>> {\n\trequireSettings(context, where, \"the user's second factor is active\");\n\tconst { secret, expiresAt } = await issueOneTime(context, {\n\t\tkind: 'stepUp',\n\t\tuserId: record.id,\n\t\taddress: '',\n\t\tttlMs: context.config.tokenTtlMs.stepUp,\n\t});\n\treturn {\n\t\tvia: 'secondFactor',\n\t\tchallenge: secret,\n\t\texpiresAt,\n\t\tuser: toUser(record),\n\t};\n}\n\n/** A challenge with a six-digit code, for the user's current e-mail. */\nasync function byEmail(\n\tcontext: Context,\n\ttype: ResolvedType,\n\trecord: UserRecord,\n\twhere: string,\n): Promise<StepUpByEmail<AnyUser>> {\n\tconst email = emailOf(type, record.fields);\n\tif (email === null) {\n\t\tthrow new NotFoundError(`${where}: the user has no e-mail`, {\n\t\t\tuserId: record.id,\n\t\t\tuserType: type.name,\n\t\t\toperation: where,\n\t\t});\n\t}\n\tconst { secret, code, expiresAt } = await issueCode(context, {\n\t\tkind: 'stepUp',\n\t\tuserId: record.id,\n\t\taddress: email,\n\t\tttlMs: context.config.tokenTtlMs.stepUp,\n\t});\n\treturn {\n\t\tvia: 'email',\n\t\tcode,\n\t\tchallenge: secret,\n\t\temail,\n\t\texpiresAt,\n\t\tuser: toUser(record),\n\t};\n}\n",
|
|
60
|
+
"/**\n * A step-up: a signed-in user proving again who they are before a sensitive\n * action, with a code sent by e-mail — or from their app, when their second\n * factor is active — and **the session they are on stamped as freshly\n * confirmed**. It opens no session: its `authenticatedAt` moves, which is\n * what a route checks with `assertFresh`.\n *\n * The same six digits, challenge and five attempts as a sign-in code, on a\n * token kind of its own: a sign-in code never confirms an action, nor an\n * action's code signs anyone in.\n */\n\nimport { TokenError } from '../../errors/janus-error';\nimport type { At } from '../at';\nimport type { ResolvedType } from '../config';\nimport type { AnyUser, Context } from '../context';\nimport { countCodeAttempt } from '../one-time';\nimport { toSession } from '../sessions/open-session';\nimport type { RequestLike, Session, StepUpApi } from '../types';\nimport { checkAppCode, checkEmailedCode } from './codes';\nimport { openStepUp } from './open';\nimport { type IssuedStepUp, requestStepUp } from './request';\n\n/** The step-up of one user type. */\nexport function stepUpFlows(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tat: At,\n): StepUpApi<AnyUser, IssuedStepUp>['stepUp'] {\n\treturn {\n\t\tasync request(user) {\n\t\t\treturn requestStepUp(context, type, user, at('stepUp.request'));\n\t\t},\n\n\t\tasync confirm(request, challenge, code) {\n\t\t\treturn confirmStepUp(\n\t\t\t\tcontext,\n\t\t\t\ttype,\n\t\t\t\trequest,\n\t\t\t\tString(challenge),\n\t\t\t\tString(code),\n\t\t\t\tat('stepUp.confirm'),\n\t\t\t);\n\t\t},\n\t};\n}\n\n/**\n * Counts the attempt first — a guess that fails for any reason has still\n * cost one — then reads the session and the user, checks the code, and\n * stamps the session.\n */\nasync function confirmStepUp(\n\tcontext: Context,\n\ttype: ResolvedType,\n\trequest: RequestLike,\n\tsecret: string,\n\tcode: string,\n\twhere: string,\n): Promise<Session> {\n\tconst { token, attemptsLeft } = await countCodeAttempt(\n\t\tcontext,\n\t\tsecret,\n\t\t'stepUp',\n\t\twhere,\n\t\ttype.name,\n\t);\n\tconst { session, user } = await openStepUp(\n\t\tcontext,\n\t\ttype,\n\t\trequest,\n\t\ttoken,\n\t\tsecret,\n\t\twhere,\n\t);\n\n\tconst counted = { token, secret, attemptsLeft };\n\t// No code hash: the challenge was issued for the user's app.\n\tif (token.codeHash === null) {\n\t\tawait checkAppCode(context, type, user, counted, code, where);\n\t} else {\n\t\tawait checkEmailedCode(context, type, user, counted, code, where);\n\t}\n\n\tconst confirmed = await context.store.sessions.reauthenticateSession(\n\t\tsession.id,\n\t\tcontext.clock.now(),\n\t);\n\t// Revoked while the code was checked: signed out, and never brought back.\n\tif (confirmed === null) {\n\t\tthrow new TokenError(\n\t\t\t'TOKEN_UNKNOWN',\n\t\t\t`${where}: the session was signed out while the code was checked`,\n\t\t\t{ operation: where },\n\t\t);\n\t}\n\treturn toSession(confirmed);\n}\n",
|
|
56
61
|
"import { isStorable } from '../../stores/storable';\nimport type { ResolvedType } from '../config';\nimport type { Context } from '../context';\nimport type { UserRecord } from '../port/types';\n\n/**\n * The user holding this normalised login, or `null`. A login no store can\n * keep is nobody's: answered as an absence, without asking a store that\n * would fail on it.\n */\nexport const byLogin = async (\n\tcontext: Context,\n\ttype: ResolvedType,\n\tlogin: string,\n): Promise<UserRecord | null> =>\n\tisStorable(login)\n\t\t? context.store.users.findUserByLogin(type.name, login)\n\t\t: null;\n",
|
|
57
|
-
"import { CredentialError } from '../../errors/janus-error';\nimport type { ResolvedType } from '../config';\nimport {\n\ttype Context,\n\tcheckPassword,\n\tpasswordMatches,\n\tpasswordRule,\n\trequireHasher,\n\twriteUser,\n} from '../context';\nimport {
|
|
62
|
+
"import { CredentialError } from '../../errors/janus-error';\nimport type { ResolvedType } from '../config';\nimport {\n\ttype Context,\n\tcheckPassword,\n\tpasswordMatches,\n\tpasswordRule,\n\trequireHasher,\n\twriteUser,\n} from '../context';\nimport { endWhatThePasswordOpened } from '../password-written';\nimport type { UserRecord } from '../port/types';\nimport type { UserRef, WriteOptions } from '../types';\n\n/**\n * Replaces the password after checking the current one, in the write that\n * replaces it — so the check is made on the very record the write replaces.\n */\nexport async function changePassword(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tuser: UserRef,\n\tchange: { readonly current: string; readonly next: string },\n\toptions: WriteOptions | undefined,\n\twhere: string,\n): Promise<UserRecord> {\n\tpasswordRule(type, where);\n\tcheckPassword(type, change?.next, where);\n\tconst hasher = requireHasher(context, where);\n\n\tconst written = await writeUser(\n\t\tcontext,\n\t\tuser,\n\t\ttype,\n\t\toptions,\n\t\twhere,\n\t\tasync (record, now) => {\n\t\t\tif (\n\t\t\t\trecord.password === null ||\n\t\t\t\t!(await passwordMatches(context, record, change.current, where))\n\t\t\t) {\n\t\t\t\tthrow new CredentialError(\n\t\t\t\t\t'CREDENTIALS_INVALID',\n\t\t\t\t\t`${where}: the current password does not match`,\n\t\t\t\t\t{\n\t\t\t\t\t\treason: record.password === null ? 'noPassword' : 'wrongPassword',\n\t\t\t\t\t\tuserId: record.id,\n\t\t\t\t\t\tuserType: type.name,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tpassword: {\n\t\t\t\t\thash: await hasher.hash(change.next),\n\t\t\t\t\tupdatedAt: now,\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t);\n\tawait endWhatThePasswordOpened(context, written.id);\n\treturn written;\n}\n",
|
|
58
63
|
"import { mintId } from '../../ids/id';\nimport type { ResolvedType } from '../config';\nimport {\n\ttype Context,\n\tcheckPassword,\n\tloginsOf,\n\trequireHasher,\n\tvalidateFields,\n} from '../context';\nimport { emit } from '../events';\nimport type { UserRecord } from '../port/types';\nimport type { Input } from './flow-types';\n\n/** Validates, hashes, writes once. What `create` and `signUp` share. */\nexport async function insert(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tinput: Input,\n\twhere: string,\n): Promise<UserRecord> {\n\tconst { store, clock } = context;\n\tconst { password, active, ...rest } = input ?? {};\n\tconst now = clock.now();\n\tconst fields = await validateFields(type, rest, where);\n\n\tlet hash: UserRecord['password'] = null;\n\tif (password !== undefined) {\n\t\tcheckPassword(type, password as string, where);\n\t\thash = {\n\t\t\thash: await requireHasher(context, where).hash(password as string),\n\t\t\tupdatedAt: now,\n\t\t};\n\t}\n\n\tconst inserted = await store.users.insertUser({\n\t\tid: mintId(now.getTime()),\n\t\ttype: type.name,\n\t\tschemaVersion: type.schemaVersion,\n\t\tactive: active === undefined ? true : active === true,\n\t\tfields,\n\t\tlogins: loginsOf(type, fields, where),\n\t\tpassword: hash,\n\t\tsecondFactor: null,\n\t\temailVerifiedAt: null,\n\t\tversion: 0,\n\t\tcreatedAt: now,\n\t\tupdatedAt: now,\n\t});\n\t// Once the user exists: an outage opening signUp's session later still\n\t// leaves a user created, and reported.\n\tawait emit(context, 'user.created', inserted, inserted.createdAt);\n\treturn inserted;\n}\n",
|
|
59
64
|
"import {\n\tCredentialError,\n\ttype CredentialRefusal,\n\tUserInactiveError,\n} from '../../errors/janus-error';\nimport type { ResolvedType } from '../config';\nimport {\n\ttype AnyUser,\n\ttype Context,\n\tpasswordMatches,\n\tpasswordRule,\n\trehashed,\n\trequireHasher,\n} from '../context';\nimport { heldByPassword } from '../password-written';\nimport type { SignInResult } from '../types';\nimport { byLogin } from './by-login';\nimport type { Finish, Input } from './flow-types';\n\n/**\n * Checks the password and answers what `finish` answers for the user. One\n * refusal for an unknown login, no password and a wrong one; `USER_INACTIVE`\n * only once the password matched.\n */\nexport async function signIn(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tfinish: Finish,\n\tinput: Input,\n\twhere: string,\n): Promise<SignInResult<AnyUser>> {\n\tconst rule = passwordRule(type, where);\n\tconst hasher = requireHasher(context, where);\n\tconst login = input?.[rule.login];\n\tconst password = input?.password;\n\n\tconst record =\n\t\ttypeof login === 'string'\n\t\t\t? await byLogin(context, type, rule.normalize(login))\n\t\t\t: null;\n\tconst refuse = (reason: CredentialRefusal) =>\n\t\tnew CredentialError(\n\t\t\t'CREDENTIALS_INVALID',\n\t\t\t`${where}: the login and the password do not match`,\n\t\t\t{ reason, userType: type.name },\n\t\t);\n\n\tif (record === null || record.password === null) {\n\t\t// Compared all the same, so the response time does not say which\n\t\t// logins are registered. The store's own latency stays observable;\n\t\t// that limit is documented, not denied.\n\t\tawait hasher.verify(String(password), await context.dummyHash());\n\t\tthrow refuse(record === null ? 'unknownLogin' : 'noPassword');\n\t}\n\n\tif (!(await passwordMatches(context, record, String(password), where))) {\n\t\tthrow refuse('wrongPassword');\n\t}\n\t// Checked after the password, so an inactive account is only told to\n\t// somebody who knows its password.\n\tif (!record.active) {\n\t\tthrow new UserInactiveError(`${where}: the user is inactive`, {\n\t\t\tuserId: record.id,\n\t\t\tuserType: type.name,\n\t\t});\n\t}\n\n\tconst verified = await rehashed(context, record, String(password));\n\tconst result = await finish(verified, where);\n\t// A password written while this sign-in ran ends it: the password\n\t// verified above is no longer the user's.\n\tif (\n\t\t!(await heldByPassword(\n\t\t\tcontext,\n\t\t\ttype,\n\t\t\tverified,\n\t\t\tString(password),\n\t\t\tresult,\n\t\t\twhere,\n\t\t))\n\t) {\n\t\tthrow refuse('wrongPassword');\n\t}\n\treturn result;\n}\n",
|
|
60
|
-
"import type { At } from '../at';\nimport type { ResolvedType } from '../config';\nimport {\n\ttype AnyUser,\n\ttype Context,\n\tcheckPassword,\n\tpasswordRule,\n\trequireHasher,\n\ttoUser,\n\twriteUser,\n} from '../context';\nimport {
|
|
65
|
+
"import type { At } from '../at';\nimport type { ResolvedType } from '../config';\nimport {\n\ttype AnyUser,\n\ttype Context,\n\tcheckPassword,\n\tpasswordRule,\n\trequireHasher,\n\ttoUser,\n\twriteUser,\n} from '../context';\nimport { endWhatThePasswordOpened } from '../password-written';\nimport { openSession } from '../sessions';\nimport type { PasswordApi, SignInResult } from '../types';\nimport { byLogin } from './by-login';\nimport { changePassword } from './change-password';\nimport type { Finish, Input } from './flow-types';\nimport { insert } from './insert';\nimport { signIn } from './sign-in';\n\n/**\n * The password flows of one user type: signing up and in, finding a user by\n * the login they sign in with, and setting or changing their password.\n */\nexport function passwordFlows(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tat: At,\n\tfinish: Finish,\n): PasswordApi<AnyUser, Input, string, SignInResult<AnyUser>> {\n\treturn {\n\t\tasync signUp(input) {\n\t\t\tconst where = at('signUp');\n\t\t\tpasswordRule(type, where);\n\t\t\tif ((input as Input)?.password === undefined) {\n\t\t\t\tcheckPassword(type, undefined as unknown as string, where);\n\t\t\t}\n\t\t\tconst record = await insert(context, type, input as Input, where);\n\t\t\treturn openSession(context, type, record);\n\t\t},\n\n\t\tasync signIn(input) {\n\t\t\treturn signIn(context, type, finish, input as Input, at('signIn'));\n\t\t},\n\n\t\tasync findByLogin(login) {\n\t\t\tconst rule = passwordRule(type, at('findByLogin'));\n\t\t\tconst record = await byLogin(context, type, rule.normalize(login));\n\t\t\treturn record === null ? null : toUser(record);\n\t\t},\n\n\t\tasync setPassword(user, password, options) {\n\t\t\tconst where = at('setPassword');\n\t\t\tpasswordRule(type, where);\n\t\t\tcheckPassword(type, password, where);\n\t\t\tconst hash = await requireHasher(context, where).hash(password);\n\n\t\t\tconst written = await writeUser(\n\t\t\t\tcontext,\n\t\t\t\tuser,\n\t\t\t\ttype,\n\t\t\t\toptions,\n\t\t\t\twhere,\n\t\t\t\t(_, now) => ({ password: { hash, updatedAt: now } }),\n\t\t\t);\n\t\t\tawait endWhatThePasswordOpened(context, written.id);\n\t\t\treturn toUser(written);\n\t\t},\n\n\t\tasync changePassword(user, change, options) {\n\t\t\tconst where = at('changePassword');\n\t\t\treturn toUser(\n\t\t\t\tawait changePassword(context, type, user, change, options, where),\n\t\t\t);\n\t\t},\n\t};\n}\n",
|
|
61
66
|
"import { isId } from '../../ids/id';\nimport type { ResolvedType } from '../config';\nimport { type Context, idOf } from '../context';\nimport { emit } from '../events';\nimport type { UserRef } from '../types';\n\n/**\n * Deletes the user, then every session, token and tuple naming them. `true`\n * when this call deleted them; a replay finds nobody, answers `false`, and\n * still deletes what was left.\n */\nexport async function deleteUser(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tuser: UserRef,\n): Promise<boolean> {\n\tconst { store, clock } = context;\n\tconst id = idOf(user);\n\tif (!isId(id)) return false;\n\n\t// Read first, so a staff API never deletes a patient: another type's\n\t// id is answered as nobody, and nothing of theirs is touched.\n\tconst record = await store.users.findUser(id);\n\tif (record !== null && record.type !== type.name) return false;\n\n\t// The user first: from then on nobody can sign in as them, and what\n\t// is left — sessions, tokens — is refused for a user who is gone. An\n\t// outage between the steps leaves only that inert remainder, and a\n\t// replay, finding no user, still deletes it.\n\tconst deletedAt = clock.now();\n\tconst deleted = record !== null && (await store.users.deleteUser(id));\n\ttry {\n\t\tawait store.sessions.deleteUserSessions(id);\n\t\tawait store.tokens.deleteUserTokens(id);\n\t\t// Last, and on a replay too: the tuples naming them.\n\t\tawait context.relations?.deleteEntity({ type: type.name, id });\n\t} finally {\n\t\t// Once, when this call deleted them — even when an outage\n\t\t// interrupts the steps above: a replay deletes nobody, so it\n\t\t// could not send it.\n\t\tif (deleted) {\n\t\t\tawait emit(context, 'user.deleted', { id, type: type.name }, deletedAt);\n\t\t}\n\t}\n\treturn deleted;\n}\n",
|
|
62
67
|
"import { normalizeEmail, type ResolvedType } from '../config';\nimport { emailOf, loginsOf, validateFields } from '../context';\nimport type { UserRecord } from '../port/types';\nimport type { Input } from './flow-types';\n\n/**\n * What `update` writes: the patch merged over the stored fields, the whole\n * result validated, and the logins derived again from it.\n */\nexport async function fieldsPatch(\n\ttype: ResolvedType,\n\trecord: UserRecord,\n\tpatch: Input,\n\twhere: string,\n) {\n\tconst fields = await validateFields(\n\t\ttype,\n\t\t{ ...record.fields, ...patch },\n\t\twhere,\n\t);\n\tconst before = emailOf(type, record.fields);\n\tconst after = emailOf(type, fields);\n\tconst emailChanged =\n\t\t(before === null ? null : normalizeEmail(before)) !==\n\t\t(after === null ? null : normalizeEmail(after));\n\n\treturn {\n\t\tfields,\n\t\tlogins: loginsOf(type, fields, where),\n\t\tschemaVersion: type.schemaVersion,\n\t\t// A new e-mail is an unproven one.\n\t\t...(emailChanged ? { emailVerifiedAt: null } : {}),\n\t};\n}\n",
|
|
63
68
|
"import { isId } from '../../ids/id';\nimport { invalidCursor, pageLimit } from '../../pagination/cursor-page';\nimport type { At } from '../at';\nimport type { ResolvedType } from '../config';\nimport {\n\ttype AnyUser,\n\ttype Context,\n\tfindRecord,\n\tgetRecord,\n\ttoUser,\n\twriteUser,\n} from '../context';\nimport type { UserTypeApi } from '../types';\nimport { deleteUser } from './delete';\nimport { fieldsPatch } from './fields-patch';\nimport type { Input } from './flow-types';\nimport { insert } from './insert';\n\n/**\n * The flows every user type has, whatever its configuration: creating,\n * reading, listing, updating, deactivating and deleting its users.\n */\nexport function recordFlows(\n\tcontext: Context,\n\ttype: ResolvedType,\n\tat: At,\n): UserTypeApi<AnyUser, Input> {\n\tconst { store } = context;\n\n\treturn {\n\t\tasync create(input) {\n\t\t\treturn toUser(await insert(context, type, input as Input, at('create')));\n\t\t},\n\n\t\tasync find(id) {\n\t\t\tconst record = await findRecord(context, id, type.name);\n\t\t\treturn record === null ? null : toUser(record);\n\t\t},\n\n\t\tasync get(id) {\n\t\t\treturn toUser(await getRecord(context, id, type.name, at('get')));\n\t\t},\n\n\t\tasync list(page) {\n\t\t\tconst after = page?.after ?? null;\n\t\t\t// Never a silent first page: a caller paging a list would loop for\n\t\t\t// ever, and the loop would look like a slow query.\n\t\t\tif (after !== null && !isId(after)) {\n\t\t\t\tthrow invalidCursor(at('list'), after);\n\t\t\t}\n\n\t\t\tconst answer = await store.users.listUsers({\n\t\t\t\ttype: type.name,\n\t\t\t\tafter,\n\t\t\t\tlimit: pageLimit(page?.limit, at('list')),\n\t\t\t});\n\t\t\treturn { items: answer.items.map(toUser), nextCursor: answer.nextCursor };\n\t\t},\n\n\t\tasync update(user, patch, options) {\n\t\t\tconst where = at('update');\n\t\t\tconst written = await writeUser(\n\t\t\t\tcontext,\n\t\t\t\tuser,\n\t\t\t\ttype,\n\t\t\t\toptions,\n\t\t\t\twhere,\n\t\t\t\t(record) => fieldsPatch(type, record, patch as Input, where),\n\t\t\t);\n\t\t\treturn toUser(written);\n\t\t},\n\n\t\tasync setActive(user, active, options) {\n\t\t\treturn toUser(\n\t\t\t\tawait writeUser(context, user, type, options, at('setActive'), () => ({\n\t\t\t\t\tactive: active === true,\n\t\t\t\t})),\n\t\t\t);\n\t\t},\n\n\t\tasync delete(user) {\n\t\t\treturn deleteUser(context, type, user);\n\t\t},\n\t};\n}\n",
|
|
64
|
-
"import type { At } from '../at';\nimport type { ResolvedType } from '../config';\nimport type { Context } from '../context';\nimport { emailFlows } from '../email-flows';\nimport { secondFactorFlows } from '../second-factor/flows';\nimport { signInCodeFlows } from '../sign-in-code';\nimport type { AnyTypeApi } from './any-type-api';\nimport { passwordFlows } from './password-flows';\nimport { recordFlows } from './record-flows';\n\n/**\n * Everything one user type answers, gathered from its flows: its records,\n * its password, its second factor, its sign-in code and its e-mails.\n */\nexport function typeApi(context: Context, type: ResolvedType): AnyTypeApi {\n\tconst at: At = (operation) =>\n\t\tcontext.config.single ? operation : `${type.name}.${operation}`;\n\tconst secondFactor = secondFactorFlows(context, type, at);\n\tconst signInCode = signInCodeFlows(context, type, at, secondFactor.finish);\n\n\treturn {\n\t\t...recordFlows(context, type, at),\n\t\t...passwordFlows(context, type, at, secondFactor.finish),\n\n\t\tsecondFactor: secondFactor.api,\n\t\tsignInCode,\n\n\t\t...emailFlows(context, type, at),\n\t};\n}\n",
|
|
65
|
-
"import { guardRelations } from '../stores/guard';\nimport { systemClock } from '../time/clock';\nimport { type JanusConfig, resolveConfig } from './config';\nimport { createContext } from './context';\nimport { resolveEvents } from './events';\nimport { guardStores } from './outage';\nimport { assertStores } from './port/assert-stores';\nimport { sharedApi } from './sessions';\nimport type { Checked, Janus } from './types';\nimport { typeApi } from './users';\n\n/**\n * Wires the identities side over the stores the application opened. **Synchronous,\n * and does no I/O**: it connects to nothing.\n *\n * ```ts\n * // One user type\n * const auth = janus({\n * user: z.object({ email: z.email(), name: z.string() }),\n * password: { login: 'email' },\n * store: createMemoryStores(),\n * hasher: scryptHasher(),\n * });\n * const { user, token } = await auth.signUp({ email, name, password });\n *\n * // Several\n * const auth = janus({\n * users: {\n * patient: { schema: Patient, password: { login: 'email' } },\n * staff: { schema: Staff, password: { login: 'email' }, session: { lifespan: '8h' } },\n * },\n * store, hasher,\n * });\n * await auth.staff.signIn({ email, password });\n * const current = await auth.authenticate(request, { type: 'staff' });\n * ```\n *\n * The types refuse first, on the offending key: a login or an e-mail that\n * names no required string field, a schema declaring a field `janus` sets, a\n * user type named like a method. What follows at run time is the net for\n * JavaScript callers, each a bare `TypeError` because only wiring produces one:\n * a store slot missing or incomplete; a password type with no hasher — there\n * is no silent fallback; two hashers claiming the same prefix, which would make\n * verification depend on the order they were listed in.\n */\nexport function janus<const C extends JanusConfig>(\n\tconfig: C & Checked<C>,\n): Janus<C> {\n\tconst where = 'janus';\n\tconst resolved = resolveConfig(config, where);\n\tconst capabilities = assertStores(config.store, where);\n\n\tconst hasher = config.hasher ?? null;\n\tconst verifiers = [\n\t\t...(hasher === null ? [] : [hasher]),\n\t\t...(config.verifiers ?? []),\n\t];\n\tconst prefixes = new Set<string>();\n\tfor (const verifier of verifiers) {\n\t\tif (typeof verifier?.prefix !== 'string' || verifier.prefix === '') {\n\t\t\tthrow new TypeError(`${where}: every hasher needs a non-empty prefix`);\n\t\t}\n\t\tif (prefixes.has(verifier.prefix)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`${where}: two hashers claim the prefix \"${verifier.prefix}\" — which one verifies would depend on their order`,\n\t\t\t);\n\t\t}\n\t\tprefixes.add(verifier.prefix);\n\t}\n\n\tconst relations = config.relations ?? null;\n\tif (\n\t\trelations !== null &&\n\t\ttypeof (relations as { deleteEntity?: unknown }).deleteEntity !== 'function'\n\t) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: relations must be a relation store — relations.deleteEntity is missing`,\n\t\t);\n\t}\n\n\tconst context = createContext(\n\t\tresolved,\n\t\tguardStores(config.store),\n\t\trelations === null ? null : guardRelations(relations),\n\t\tcapabilities,\n\t\tconfig.clock ?? systemClock,\n\t\thasher,\n\t\tverifiers,\n\t\tresolveEvents(config.events, where),\n\t);\n\n\tconst shared = sharedApi(context);\n\tconst types = Object.fromEntries(\n\t\t[...resolved.types.values()].map((type) => [\n\t\t\ttype.name,\n\t\t\ttypeApi(context, type),\n\t\t]),\n\t);\n\n\t// The one cast at the boundary: every field was validated against its\n\t// type's schema before any of these answers was built.\n\tconst surface = resolved.single\n\t\t? { ...shared, ...types.user }\n\t\t: { ...shared, ...types };\n\treturn surface as unknown as Janus<C>;\n}\n"
|
|
69
|
+
"import type { At } from '../at';\nimport type { ResolvedType } from '../config';\nimport type { Context } from '../context';\nimport { emailFlows } from '../email-flows';\nimport { secondFactorFlows } from '../second-factor/flows';\nimport { signInCodeFlows } from '../sign-in-code';\nimport { stepUpFlows } from '../step-up/flows';\nimport type { AnyTypeApi } from './any-type-api';\nimport { passwordFlows } from './password-flows';\nimport { recordFlows } from './record-flows';\n\n/**\n * Everything one user type answers, gathered from its flows: its records,\n * its password, its second factor, its sign-in code, its step-up and its e-mails.\n */\nexport function typeApi(context: Context, type: ResolvedType): AnyTypeApi {\n\tconst at: At = (operation) =>\n\t\tcontext.config.single ? operation : `${type.name}.${operation}`;\n\tconst secondFactor = secondFactorFlows(context, type, at);\n\tconst signInCode = signInCodeFlows(context, type, at, secondFactor.finish);\n\n\treturn {\n\t\t...recordFlows(context, type, at),\n\t\t...passwordFlows(context, type, at, secondFactor.finish),\n\n\t\tsecondFactor: secondFactor.api,\n\t\tsignInCode,\n\t\tstepUp: stepUpFlows(context, type, at),\n\n\t\t...emailFlows(context, type, at),\n\t};\n}\n",
|
|
70
|
+
"import { guardRelations } from '../stores/guard';\nimport { systemClock } from '../time/clock';\nimport { type JanusConfig, resolveConfig } from './config';\nimport { createContext } from './context';\nimport { resolveEvents } from './events';\nimport { guardStores } from './outage';\nimport { assertStores } from './port/assert-stores';\nimport { sharedApi } from './sessions';\nimport type { Checked, Janus } from './types';\nimport { typeApi } from './users';\n\n/**\n * Wires the identities side over the stores the application opened. **Synchronous,\n * and does no I/O**: it connects to nothing.\n *\n * ```ts\n * // One user type\n * const auth = janus({\n * user: z.object({ email: z.email(), name: z.string() }),\n * password: { login: 'email' },\n * store: createMemoryStores(),\n * hasher: scryptHasher(),\n * });\n * const { user, token } = await auth.signUp({ email, name, password });\n *\n * // Several\n * const auth = janus({\n * users: {\n * patient: { schema: Patient, password: { login: 'email' } },\n * staff: { schema: Staff, password: { login: 'email' }, session: { lifespan: '8h' } },\n * },\n * store, hasher,\n * });\n * await auth.staff.signIn({ email, password });\n * const current = await auth.authenticate(request, { type: 'staff' });\n * ```\n *\n * The types refuse first, on the offending key: a login or an e-mail that\n * names no required string field, a schema declaring a field `janus` sets, a\n * user type named like a method. What follows at run time is the net for\n * JavaScript callers, each a bare `TypeError` because only wiring produces one:\n * a store slot missing or incomplete; a password type with no hasher — there\n * is no silent fallback; two hashers claiming the same prefix, which would make\n * verification depend on the order they were listed in.\n */\nexport function janus<const C extends JanusConfig>(\n\tconfig: C & Checked<C>,\n): Janus<C> {\n\tconst where = 'janus';\n\tconst resolved = resolveConfig(config, where);\n\tconst capabilities = assertStores(config.store, where);\n\n\tconst hasher = config.hasher ?? null;\n\tconst verifiers = [\n\t\t...(hasher === null ? [] : [hasher]),\n\t\t...(config.verifiers ?? []),\n\t];\n\tconst prefixes = new Set<string>();\n\tfor (const verifier of verifiers) {\n\t\tif (typeof verifier?.prefix !== 'string' || verifier.prefix === '') {\n\t\t\tthrow new TypeError(`${where}: every hasher needs a non-empty prefix`);\n\t\t}\n\t\tif (prefixes.has(verifier.prefix)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`${where}: two hashers claim the prefix \"${verifier.prefix}\" — which one verifies would depend on their order`,\n\t\t\t);\n\t\t}\n\t\tprefixes.add(verifier.prefix);\n\t}\n\n\tconst relations = config.relations ?? null;\n\tif (\n\t\trelations !== null &&\n\t\ttypeof (relations as { deleteEntity?: unknown }).deleteEntity !== 'function'\n\t) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: relations must be a relation store — relations.deleteEntity is missing`,\n\t\t);\n\t}\n\n\tconst context = createContext(\n\t\tresolved,\n\t\tguardStores(config.store),\n\t\trelations === null ? null : guardRelations(relations),\n\t\tcapabilities,\n\t\tconfig.clock ?? systemClock,\n\t\thasher,\n\t\tverifiers,\n\t\tresolveEvents(config.events, where),\n\t);\n\n\tconst shared = sharedApi(context);\n\tconst types = Object.fromEntries(\n\t\t[...resolved.types.values()].map((type) => [\n\t\t\ttype.name,\n\t\t\ttypeApi(context, type),\n\t\t]),\n\t);\n\n\t// The one cast at the boundary: every field was validated against its\n\t// type's schema before any of these answers was built.\n\tconst surface = resolved.single\n\t\t? { ...shared, ...types.user }\n\t\t: { ...shared, ...types };\n\treturn surface as unknown as Janus<C>;\n}\n",
|
|
71
|
+
"/**\n * `assertFresh`: whether a session proved who it is recently enough for a\n * sensitive action — signed in, or confirmed by a step-up, less than\n * `maxAge` ago.\n */\n\nimport { StepUpRequiredError } from '../../errors/janus-error';\nimport { type Clock, systemClock } from '../../time/clock';\nimport { type Duration, parseDuration } from '../../time/duration';\nimport type { Session } from '../types';\n\n/**\n * Refuses a session whose credentials were last presented `maxAge` ago or\n * more — at its sign-in, or since by `stepUp.confirm` — with\n * `STEP_UP_REQUIRED` (403): ask for a step-up, then run the action again. One\n * field of the session `authenticate` already answered, so no store is read.\n *\n * ```ts\n * const current = await auth.authenticate(request);\n * if (current === null) return new Response(null, { status: 401 });\n * assertFresh(current.session, '10m'); // STEP_UP_REQUIRED past ten minutes\n * ```\n *\n * Pass the `clock` given to `janus()` when it is not the system's. A\n * `maxAge` that is not a duration is a `TypeError`: it is written in the\n * code, never read from a request.\n */\nexport function assertFresh(\n\tsession: Pick<Session, 'authenticatedAt' | 'userId'>,\n\tmaxAge: Duration,\n\tclock: Clock = systemClock,\n): void {\n\tconst maxAgeMs = parseDuration(maxAge, 'assertFresh: maxAge');\n\tconst age = clock.now().getTime() - session.authenticatedAt.getTime();\n\tif (age >= maxAgeMs) {\n\t\tthrow new StepUpRequiredError(\n\t\t\t'assertFresh: the session proved who it is longer ago than maxAge — confirm with a step-up',\n\t\t\t{ userId: session.userId },\n\t\t);\n\t}\n}\n"
|
|
66
72
|
],
|
|
67
|
-
"mappings": "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",
|
|
68
|
-
"debugId": "
|
|
73
|
+
"mappings": "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",
|
|
74
|
+
"debugId": "D61F9F351D899C2964756E2164756E21",
|
|
69
75
|
"names": []
|
|
70
76
|
}
|