@nxgt/janus-mongo 0.6.1 → 0.7.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 +4 -0
- package/dist/collections.d.ts +2 -0
- package/dist/collections.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +3 -3
- package/docs/guide/sync.md +4 -2
- package/docs/roadmap.md +3 -0
- package/docs/troubleshooting.md +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -125,6 +125,10 @@ spend the same one.
|
|
|
125
125
|
refuses it: until `syncMongoAdapter(db)` has run, every step-up request
|
|
126
126
|
fails with `STORE_FAILED`, caused by `Document failed validation`. No
|
|
127
127
|
document is rewritten.
|
|
128
|
+
- **Upgrading to 0.7: the sync again, for the same reason.** The token kind
|
|
129
|
+
`magicLink` — `@nxgt/janus` 0.15's sign-in link — is new: until the sync
|
|
130
|
+
has run, every `magicLink.request` fails with `STORE_FAILED`, caused by
|
|
131
|
+
`Document failed validation`. No document is rewritten.
|
|
128
132
|
- **The TTL indexes are storage hygiene, not the expiry.** MongoDB's TTL monitor
|
|
129
133
|
runs every sixty seconds, so a lapsed session can stay readable for up to a
|
|
130
134
|
minute. The core compares `expiresAt` on every read, and that is what expires
|
package/dist/collections.d.ts
CHANGED
|
@@ -38,6 +38,7 @@ export declare const tokens: import("@nxgt/mongo").CollectionDefinition<import("
|
|
|
38
38
|
verifyEmail: "verifyEmail";
|
|
39
39
|
resetPassword: "resetPassword";
|
|
40
40
|
signInCode: "signInCode";
|
|
41
|
+
magicLink: "magicLink";
|
|
41
42
|
stepUp: "stepUp";
|
|
42
43
|
}>;
|
|
43
44
|
userId: z.ZodString;
|
|
@@ -86,6 +87,7 @@ export declare const janusCollections: readonly [import("@nxgt/mongo").Collectio
|
|
|
86
87
|
verifyEmail: "verifyEmail";
|
|
87
88
|
resetPassword: "resetPassword";
|
|
88
89
|
signInCode: "signInCode";
|
|
90
|
+
magicLink: "magicLink";
|
|
89
91
|
stepUp: "stepUp";
|
|
90
92
|
}>;
|
|
91
93
|
userId: z.ZodString;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collections.d.ts","sourceRoot":"","sources":["../src/collections.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAuBxB,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;+FAqDhB,CAAC;AAEH,eAAO,MAAM,QAAQ;;;;;;;;+FA6BnB,CAAC;AAEH,eAAO,MAAM,MAAM
|
|
1
|
+
{"version":3,"file":"collections.d.ts","sourceRoot":"","sources":["../src/collections.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAuBxB,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;+FAqDhB,CAAC;AAEH,eAAO,MAAM,QAAQ;;;;;;;;+FA6BnB,CAAC;AAEH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;+FA6BjB,CAAC;AAEH,wEAAwE;AACxE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gGAAqC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -74,6 +74,7 @@ var tokens = defineCollection({
|
|
|
74
74
|
"resetPassword",
|
|
75
75
|
"secondFactor",
|
|
76
76
|
"signInCode",
|
|
77
|
+
"magicLink",
|
|
77
78
|
"stepUp"
|
|
78
79
|
]),
|
|
79
80
|
userId: z.string(),
|
|
@@ -594,5 +595,5 @@ export {
|
|
|
594
595
|
users
|
|
595
596
|
};
|
|
596
597
|
|
|
597
|
-
//# debugId=
|
|
598
|
+
//# debugId=9576378C5D4AE00164756E2164756E21
|
|
598
599
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"sources": ["../src/adapter.ts", "../src/collections.ts", "../src/relations/index.ts", "../src/translate.ts", "../src/relations/collection.ts", "../src/relations/reads.ts", "../src/relations/tuples.ts", "../src/relations/writes.ts", "../src/stores/index.ts", "../src/stores/sessions.ts", "../src/stores/records.ts", "../src/stores/tokens.ts", "../src/stores/users.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import type { JanusStores } from '@nxgt/janus';\nimport type { RelationStore } from '@nxgt/janus/permissions';\nimport {\n\ttype SyncOptions,\n\ttype SyncReport,\n\tsyncCollections,\n} from '@nxgt/mongo';\nimport type { Db } from 'mongodb';\nimport { janusCollections } from './collections';\nimport { createMongoRelations, relations } from './relations';\nimport { createMongoStores } from './stores';\n\n/** The whole adapter over one database, keyed as `janus()` takes it. */\nexport interface MongoAdapter {\n\t/** The identity stores: `createMongoStores(db)`. */\n\treadonly store: JanusStores;\n\t/** The relation store: `createMongoRelations(db)`. */\n\treadonly relations: RelationStore;\n}\n\n/**\n * The identity stores and the relation store over one database, under the\n * names `janus()` takes them — so one spread wires both, and deleting a user\n * deletes every tuple naming them:\n *\n * ```ts\n * const mongo = createMongoAdapter(db);\n * const auth = janus({ user, password: { login: 'email' }, hasher, ...mongo });\n * const access = permissions({ model, store: mongo.relations });\n * ```\n *\n * It connects to nothing and sends nothing, as the two it combines. An\n * application that only authenticates can take `createMongoStores(db)` alone.\n */\nexport function createMongoAdapter(db: Db): MongoAdapter {\n\treturn { store: createMongoStores(db), relations: createMongoRelations(db) };\n}\n\n/**\n * Creates the four collections, their validators and their indexes, and says\n * what it changed: `syncMongoStores` and `syncMongoRelations` in one\n * deployment step. Run it twice and the second run sends nothing.\n */\nexport function syncMongoAdapter(\n\tdb: Db,\n\toptions?: SyncOptions,\n): Promise<SyncReport[]> {\n\treturn syncCollections(db, [...janusCollections, relations], options);\n}\n",
|
|
6
|
-
"import { defineCollection } from '@nxgt/mongo';\nimport { z } from 'zod';\n\n/**\n * The three collections, as `@nxgt/mongo` definitions.\n *\n * **What the database holds is the port's record**, with the id under `_id`.\n * Nothing else is renamed and nothing is encoded, so a record comes back byte\n * for byte (rule 4) and a document read in a shell reads like the record in\n * the code.\n *\n * Defining them registers them with `@nxgt/mongo`, so an application that\n * deploys with `syncAll(db)` creates these three with the rest of its own.\n *\n * `@nxgt/mongo`'s optimistic lock and soft delete stay off. The port keeps its\n * own `version`, because it must tell `NOT_FOUND` from `VERSION_CONFLICT`,\n * which takes a second read the lock does not make; and the port has no\n * deletion to soften.\n */\n\n/** Anything JSON. The core validated it against the application's schema already. */\nconst jsonObject = z.record(z.string(), z.unknown());\nconst at = z.date();\n\nexport const users = defineCollection({\n\tname: 'users',\n\tschema: z.object({\n\t\t/** The UUIDv7 the core minted. A string, never an `ObjectId`: the store mints nothing. */\n\t\t_id: z.string(),\n\t\ttype: z.string(),\n\t\tschemaVersion: z.string(),\n\t\tactive: z.boolean(),\n\t\tfields: jsonObject,\n\t\tlogins: z.array(z.string()),\n\t\tpassword: z.object({ hash: z.string(), updatedAt: at }).nullable(),\n\t\t/**\n\t\t * Absent on a user written before 0.3 — read as `null`, so no\n\t\t * migration is needed.\n\t\t */\n\t\tsecondFactor: z\n\t\t\t.object({\n\t\t\t\tmethod: z.literal('totp'),\n\t\t\t\tsecret: z.string(),\n\t\t\t\tconfirmedAt: at.nullable(),\n\t\t\t\tlastStep: z.int().nonnegative().nullable(),\n\t\t\t\t/**\n\t\t\t\t * The recovery codes' keyed hashes, in order. Absent on a factor\n\t\t\t\t * written before 0.5 — read as `[]`, so no migration is needed.\n\t\t\t\t */\n\t\t\t\trecoveryCodes: z.array(z.string()).optional(),\n\t\t\t})\n\t\t\t.nullable()\n\t\t\t.optional(),\n\t\temailVerifiedAt: at.nullable(),\n\t\tversion: z.int().nonnegative(),\n\t\tcreatedAt: at,\n\t\tupdatedAt: at,\n\t}),\n\tindexes: [\n\t\t/**\n\t\t * A login is unique **per type**: a scalar `type` and a flat array of\n\t\t * strings, so the multikey semantics are the plain ones, no collation is\n\t\t * needed, and the driver's `keyValue` names both the type and the login\n\t\t * that collided.\n\t\t */\n\t\t{\n\t\t\tkey: { type: 1, logins: 1 },\n\t\t\tname: 'loginUnique',\n\t\t\tunique: true,\n\t\t\t// Without it, two users holding no login at all collide: an empty\n\t\t\t// array is indexed as one missing value, and a unique index admits\n\t\t\t// one of those per type.\n\t\t\tpartialFilterExpression: { logins: { $type: 'string' } },\n\t\t},\n\t\t/** `listUsers` reads one type in `_id` order. */\n\t\t{ key: { type: 1, _id: 1 }, name: 'typeId' },\n\t],\n});\n\nexport const sessions = defineCollection({\n\tname: 'sessions',\n\tschema: z.object({\n\t\t_id: z.string(),\n\t\ttokenHash: z.string(),\n\t\tuserId: z.string(),\n\t\tauthenticatedAt: at,\n\t\texpiresAt: at,\n\t\trevokedAt: at.nullable(),\n\t\tcreatedAt: at,\n\t}),\n\tindexes: [\n\t\t{\n\t\t\tkey: { tokenHash: 1 },\n\t\t\tname: 'tokenHashUnique',\n\t\t\tunique: true,\n\t\t},\n\t\t{ key: { userId: 1 }, name: 'userId' },\n\t\t/**\n\t\t * Storage hygiene, **not** the expiry: MongoDB's TTL monitor runs every\n\t\t * sixty seconds, so a lapsed session stays readable for up to a minute.\n\t\t * The core compares `expiresAt` on every read, which is what expires it.\n\t\t */\n\t\t{\n\t\t\tkey: { expiresAt: 1 },\n\t\t\tname: 'expiry',\n\t\t\texpireAfterSeconds: 0,\n\t\t},\n\t],\n});\n\nexport const tokens = defineCollection({\n\tname: 'tokens',\n\tschema: z.object({\n\t\t/** The token's `sha256`. Unique by construction, so it is the key itself. */\n\t\t_id: z.string(),\n\t\tkind: z.enum([\n\t\t\t'verifyEmail',\n\t\t\t'resetPassword',\n\t\t\t'secondFactor',\n\t\t\t'signInCode',\n\t\t\t'stepUp',\n\t\t]),\n\t\tuserId: z.string(),\n\t\taddress: z.string(),\n\t\t/** Absent on a token written before 0.3 — read as `null` and `0`. */\n\t\tcodeHash: z.string().nullable().optional(),\n\t\tattempts: z.int().nonnegative().optional(),\n\t\texpiresAt: at,\n\t\tspentAt: at.nullable(),\n\t\tcreatedAt: at,\n\t}),\n\tindexes: [\n\t\t// The same hygiene as sessions'. A token the monitor dropped is answered\n\t\t// `null`, which the port allows: a lapsed token is refused either way.\n\t\t{ key: { expiresAt: 1 }, name: 'expiry', expireAfterSeconds: 0 },\n\t\t/** `deleteUserTokens` reads one user's tokens. */\n\t\t{ key: { userId: 1 }, name: 'userId' },\n\t],\n});\n\n/** The three definitions, in the order `syncMongoStores` syncs them. */\nexport const janusCollections = [users, sessions, tokens] as const;\n",
|
|
6
|
+
"import { defineCollection } from '@nxgt/mongo';\nimport { z } from 'zod';\n\n/**\n * The three collections, as `@nxgt/mongo` definitions.\n *\n * **What the database holds is the port's record**, with the id under `_id`.\n * Nothing else is renamed and nothing is encoded, so a record comes back byte\n * for byte (rule 4) and a document read in a shell reads like the record in\n * the code.\n *\n * Defining them registers them with `@nxgt/mongo`, so an application that\n * deploys with `syncAll(db)` creates these three with the rest of its own.\n *\n * `@nxgt/mongo`'s optimistic lock and soft delete stay off. The port keeps its\n * own `version`, because it must tell `NOT_FOUND` from `VERSION_CONFLICT`,\n * which takes a second read the lock does not make; and the port has no\n * deletion to soften.\n */\n\n/** Anything JSON. The core validated it against the application's schema already. */\nconst jsonObject = z.record(z.string(), z.unknown());\nconst at = z.date();\n\nexport const users = defineCollection({\n\tname: 'users',\n\tschema: z.object({\n\t\t/** The UUIDv7 the core minted. A string, never an `ObjectId`: the store mints nothing. */\n\t\t_id: z.string(),\n\t\ttype: z.string(),\n\t\tschemaVersion: z.string(),\n\t\tactive: z.boolean(),\n\t\tfields: jsonObject,\n\t\tlogins: z.array(z.string()),\n\t\tpassword: z.object({ hash: z.string(), updatedAt: at }).nullable(),\n\t\t/**\n\t\t * Absent on a user written before 0.3 — read as `null`, so no\n\t\t * migration is needed.\n\t\t */\n\t\tsecondFactor: z\n\t\t\t.object({\n\t\t\t\tmethod: z.literal('totp'),\n\t\t\t\tsecret: z.string(),\n\t\t\t\tconfirmedAt: at.nullable(),\n\t\t\t\tlastStep: z.int().nonnegative().nullable(),\n\t\t\t\t/**\n\t\t\t\t * The recovery codes' keyed hashes, in order. Absent on a factor\n\t\t\t\t * written before 0.5 — read as `[]`, so no migration is needed.\n\t\t\t\t */\n\t\t\t\trecoveryCodes: z.array(z.string()).optional(),\n\t\t\t})\n\t\t\t.nullable()\n\t\t\t.optional(),\n\t\temailVerifiedAt: at.nullable(),\n\t\tversion: z.int().nonnegative(),\n\t\tcreatedAt: at,\n\t\tupdatedAt: at,\n\t}),\n\tindexes: [\n\t\t/**\n\t\t * A login is unique **per type**: a scalar `type` and a flat array of\n\t\t * strings, so the multikey semantics are the plain ones, no collation is\n\t\t * needed, and the driver's `keyValue` names both the type and the login\n\t\t * that collided.\n\t\t */\n\t\t{\n\t\t\tkey: { type: 1, logins: 1 },\n\t\t\tname: 'loginUnique',\n\t\t\tunique: true,\n\t\t\t// Without it, two users holding no login at all collide: an empty\n\t\t\t// array is indexed as one missing value, and a unique index admits\n\t\t\t// one of those per type.\n\t\t\tpartialFilterExpression: { logins: { $type: 'string' } },\n\t\t},\n\t\t/** `listUsers` reads one type in `_id` order. */\n\t\t{ key: { type: 1, _id: 1 }, name: 'typeId' },\n\t],\n});\n\nexport const sessions = defineCollection({\n\tname: 'sessions',\n\tschema: z.object({\n\t\t_id: z.string(),\n\t\ttokenHash: z.string(),\n\t\tuserId: z.string(),\n\t\tauthenticatedAt: at,\n\t\texpiresAt: at,\n\t\trevokedAt: at.nullable(),\n\t\tcreatedAt: at,\n\t}),\n\tindexes: [\n\t\t{\n\t\t\tkey: { tokenHash: 1 },\n\t\t\tname: 'tokenHashUnique',\n\t\t\tunique: true,\n\t\t},\n\t\t{ key: { userId: 1 }, name: 'userId' },\n\t\t/**\n\t\t * Storage hygiene, **not** the expiry: MongoDB's TTL monitor runs every\n\t\t * sixty seconds, so a lapsed session stays readable for up to a minute.\n\t\t * The core compares `expiresAt` on every read, which is what expires it.\n\t\t */\n\t\t{\n\t\t\tkey: { expiresAt: 1 },\n\t\t\tname: 'expiry',\n\t\t\texpireAfterSeconds: 0,\n\t\t},\n\t],\n});\n\nexport const tokens = defineCollection({\n\tname: 'tokens',\n\tschema: z.object({\n\t\t/** The token's `sha256`. Unique by construction, so it is the key itself. */\n\t\t_id: z.string(),\n\t\tkind: z.enum([\n\t\t\t'verifyEmail',\n\t\t\t'resetPassword',\n\t\t\t'secondFactor',\n\t\t\t'signInCode',\n\t\t\t'magicLink',\n\t\t\t'stepUp',\n\t\t]),\n\t\tuserId: z.string(),\n\t\taddress: z.string(),\n\t\t/** Absent on a token written before 0.3 — read as `null` and `0`. */\n\t\tcodeHash: z.string().nullable().optional(),\n\t\tattempts: z.int().nonnegative().optional(),\n\t\texpiresAt: at,\n\t\tspentAt: at.nullable(),\n\t\tcreatedAt: at,\n\t}),\n\tindexes: [\n\t\t// The same hygiene as sessions'. A token the monitor dropped is answered\n\t\t// `null`, which the port allows: a lapsed token is refused either way.\n\t\t{ key: { expiresAt: 1 }, name: 'expiry', expireAfterSeconds: 0 },\n\t\t/** `deleteUserTokens` reads one user's tokens. */\n\t\t{ key: { userId: 1 }, name: 'userId' },\n\t],\n});\n\n/** The three definitions, in the order `syncMongoStores` syncs them. */\nexport const janusCollections = [users, sessions, tokens] as const;\n",
|
|
7
7
|
"import type { RelationStore } from '@nxgt/janus/permissions';\nimport {\n\tgetCollection,\n\ttype SyncOptions,\n\ttype SyncReport,\n\tsyncCollections,\n} from '@nxgt/mongo';\nimport type { Db } from 'mongodb';\nimport { run } from '../translate';\nimport { relations } from './collection';\nimport type { RelationContext } from './context';\nimport { findEntities, findObjects, findSubjectSets, has } from './reads';\nimport { deleteEntity, write } from './writes';\n\nexport { relations } from './collection';\n\n/**\n * The relation store `permissions()` takes, over one MongoDB database — and\n * the one `janus({ relations })` deletes a user's tuples from.\n *\n * ```ts\n * await syncMongoRelations(db); // a deployment step: creates the indexes\n * const access = permissions({ model, store: createMongoRelations(db) });\n * ```\n *\n * **A write of more than one tuple is a transaction**, which MongoDB runs on\n * a replica set only — as every production deployment is. `grant` and\n * `revoke` write one tuple, and run anywhere. The transaction is not retried\n * here: the driver's `withTransaction` would retry an outage for two minutes\n * before answering, and a write is idempotent, so the caller retries.\n */\nexport function createMongoRelations(db: Db): RelationStore {\n\tconst context: RelationContext = {\n\t\tdb,\n\t\tcollection: getCollection(db, relations).raw,\n\t};\n\tconst run$ = <T>(operation: string, body: () => Promise<T>) =>\n\t\trun('relations', operation, body);\n\n\treturn {\n\t\twrite: ({ add = [], remove = [] }) =>\n\t\t\trun$('write', () => write(context, add, remove)),\n\t\thas: (tuple) => run$('has', () => has(context, tuple)),\n\t\tfindSubjectSets: (object, relation) =>\n\t\t\trun$('findSubjectSets', () => findSubjectSets(context, object, relation)),\n\t\tfindEntities: (object, relation) =>\n\t\t\trun$('findEntities', () => findEntities(context, object, relation)),\n\t\t// Unpacked before `run$`, as `write`'s is and as on develop, so a\n\t\t// malformed request throws instead of reading as an outage.\n\t\tfindObjects: ({ type, relation, subject, after, limit }) =>\n\t\t\trun$('findObjects', () =>\n\t\t\t\tfindObjects(context, { type, relation, subject, after, limit }),\n\t\t\t),\n\t\tdeleteEntity: (entity) =>\n\t\t\trun$('deleteEntity', () => deleteEntity(context, entity)),\n\t};\n}\n\n/**\n * Creates the collection and its indexes, and says what it changed. A\n * deployment step, as `syncMongoStores` is — and a separate one, because an\n * application that only authenticates keeps no tuples.\n */\nexport function syncMongoRelations(\n\tdb: Db,\n\toptions?: SyncOptions,\n): Promise<SyncReport[]> {\n\treturn syncCollections(db, [relations], options);\n}\n",
|
|
8
8
|
"import { JanusError, StoreConflict, StoreFailure } from '@nxgt/janus';\n\n/**\n * **The driver's errors, as the port's.** One file, and one default.\n *\n * | What happens | Becomes |\n * | --- | --- |\n * | A duplicate key on `(type, logins)` | `StoreConflict('login')`, carrying `login` and `userType` |\n * | A duplicate key on `_id` | nothing — the insert is a retry, and answers what is stored |\n * | A duplicate key on **any other index** | **`StoreFailure`** |\n * | A `$jsonSchema` validation failure (121) | **`StoreFailure`** |\n * | Anything else, absolutely | `StoreFailure`, with the driver error as `cause` |\n *\n * The two bold rows go against the obvious reading. A duplicate on an index\n * the adapter did not mean to collide on is an adapter bug: reporting it as\n * `LOGIN_TAKEN` would tell somebody their login is taken when it is\n * not. And the core has validated every record before it reaches a store, so a\n * validator refusing one means the adapter and the port disagree — never the\n * caller's fault, never a 400.\n *\n * **The default is a failure, not an absence.** That branch is what keeps the\n * port's first rule: nothing here answers `null` for an error.\n */\n\n/** Runs one port method, and makes every rejection one the port allows. */\nexport async function run<T>(\n\tslot: 'users' | 'sessions' | 'tokens' | 'relations',\n\toperation: string,\n\tbody: () => Promise<T>,\n): Promise<T> {\n\ttry {\n\t\treturn await body();\n\t} catch (error) {\n\t\t// Already the port's — a conflict, a NOT_FOUND after a read — or a\n\t\t// failure raised below with its own message.\n\t\tif (error instanceof JanusError) throw error;\n\t\tthrow new StoreFailure(`${slot}.${operation}: the store could not answer`, {\n\t\t\tslot,\n\t\t\toperation,\n\t\t\tcause: error,\n\t\t});\n\t}\n}\n\n/** The shape of the driver's `E11000`, as far as this file reads it. */\nexport interface DuplicateKey {\n\treadonly code: 11000;\n\treadonly keyPattern?: Readonly<Record<string, unknown>>;\n\treadonly keyValue?: Readonly<Record<string, unknown>>;\n}\n\nexport function isDuplicateKey(error: unknown): error is DuplicateKey {\n\treturn (\n\t\ttypeof error === 'object' &&\n\t\terror !== null &&\n\t\t(error as { code?: unknown }).code === 11000\n\t);\n}\n\n/**\n * Settles a write: what it answered when it landed, or the duplicate-key error\n * when an index refused it. **Any other rejection is rethrown**, so a caller\n * of this is only ever told \"written\" or \"duplicate\", and never \"nothing\".\n */\nexport function settle<T>(\n\twrite: Promise<T>,\n): Promise<\n\t| { readonly written: T }\n\t| { readonly written?: never; duplicate: DuplicateKey }\n> {\n\treturn write.then(\n\t\t(written) => ({ written }),\n\t\t(error: unknown) => {\n\t\t\tif (isDuplicateKey(error)) return { duplicate: error };\n\t\t\tthrow error;\n\t\t},\n\t);\n}\n\n/** A login one type holds. */\nexport interface TypedLogin {\n\treadonly type: string;\n\treadonly login: string;\n}\n\n/**\n * The login a duplicate names, when it is the login index that refused the\n * write — and `null` for every other index, which the caller then reports as\n * a failure.\n */\nexport function takenLogin(duplicate: DuplicateKey): TypedLogin | null {\n\tconst type = duplicate.keyValue?.type;\n\tconst login = duplicate.keyValue?.logins;\n\tif (typeof type !== 'string' || typeof login !== 'string') return null;\n\treturn { type, login };\n}\n\n/** The refusal the port promises for a taken login. */\nexport function loginTaken(\n\toperation: string,\n\t{ type, login }: TypedLogin,\n\tcause: unknown,\n): StoreConflict {\n\treturn new StoreConflict(\n\t\t'login',\n\t\t`${operation}: the login is taken by another ${type}`,\n\t\t{ login, userType: type, operation, cause },\n\t);\n}\n\n/** A duplicate on the login index as the port's conflict, and any other as a bug. */\nexport function refuseDuplicate(\n\toperation: string,\n\tduplicate: DuplicateKey,\n): StoreConflict | StoreFailure {\n\tconst taken = takenLogin(duplicate);\n\treturn taken === null\n\t\t? unexpectedDuplicate('users', operation, duplicate)\n\t\t: loginTaken(operation, taken, duplicate);\n}\n\n/** A duplicate on an index the adapter never meant to collide on: a bug, reported as one. */\nexport function unexpectedDuplicate(\n\tslot: 'users' | 'sessions' | 'tokens',\n\toperation: string,\n\tduplicate: DuplicateKey,\n): StoreFailure {\n\treturn new StoreFailure(\n\t\t`${slot}.${operation}: a duplicate key on ${Object.keys(duplicate.keyPattern ?? {}).join(', ') || 'an unknown index'}, which this adapter never writes on purpose`,\n\t\t{ slot, operation, cause: duplicate },\n\t);\n}\n",
|
|
9
9
|
"import { type DocumentOf, defineCollection } from '@nxgt/mongo';\nimport { z } from 'zod';\n\n/**\n * The tuples, one document each, **keyed by the tuple itself**:\n * `{ _id: { object: { type, id }, relation, subject: { type, id, relation? } } }`.\n *\n * The key is the port's `RelationTuple`, as written, so uniqueness is the\n * `_id` index every collection has — a constraint, never a read — an insert\n * of a stored tuple is a retry, and a document read in a shell is the tuple\n * in the code. A subject set carries `relation`, an entity does not, so\n * `team:t1#members` and `team:t1` are two keys.\n *\n * The key is always built in one fixed field order: MongoDB compares\n * embedded documents field by field, in order.\n */\nexport const relations = defineCollection({\n\tname: 'relations',\n\tschema: z.object({\n\t\t_id: z.object({\n\t\t\tobject: z.object({ type: z.string(), id: z.string() }),\n\t\t\trelation: z.string(),\n\t\t\tsubject: z.object({\n\t\t\t\ttype: z.string(),\n\t\t\t\tid: z.string(),\n\t\t\t\trelation: z.string().optional(),\n\t\t\t}),\n\t\t}),\n\t}),\n\tindexes: [\n\t\t/** One hop forwards: `findSubjectSets`, `findEntities`, and `deleteEntity` as the object. */\n\t\t{\n\t\t\tkey: { '_id.object.type': 1, '_id.object.id': 1, '_id.relation': 1 },\n\t\t\tname: 'objectRelation',\n\t\t},\n\t\t/**\n\t\t * The reverse index `list()` walks, in the order `findObjects` pages it:\n\t\t * every equality first, the object id last. Its prefix is `deleteEntity`\n\t\t * as a subject. An entity has no `subject.relation`, which the index\n\t\t * holds as `null` and `findObjects` asks for as `null`.\n\t\t */\n\t\t{\n\t\t\tkey: {\n\t\t\t\t'_id.subject.type': 1,\n\t\t\t\t'_id.subject.id': 1,\n\t\t\t\t'_id.subject.relation': 1,\n\t\t\t\t'_id.relation': 1,\n\t\t\t\t'_id.object.type': 1,\n\t\t\t\t'_id.object.id': 1,\n\t\t\t},\n\t\t\tname: 'subjectObjects',\n\t\t},\n\t],\n});\n\nexport type RelationDocument = DocumentOf<typeof relations>;\nexport type Key = RelationDocument['_id'];\n",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"import type { TokenKind, TokenRecord, TokenStore } from '@nxgt/janus';\nimport { getCollection, type TypedCollection } from '@nxgt/mongo';\nimport type { Db } from 'mongodb';\nimport { tokens } from '../collections';\nimport { run, settle } from '../translate';\nimport { toToken, toTokenDocument } from './records';\n\ntype Tokens = TypedCollection<typeof tokens>;\n\nexport function tokenStore(db: Db): TokenStore {\n\tconst collection = getCollection(db, tokens);\n\tconst run$ = <T>(operation: string, body: () => Promise<T>) =>\n\t\trun('tokens', operation, body);\n\n\treturn {\n\t\tinsertToken: (record) =>\n\t\t\trun$('insertToken', async () => {\n\t\t\t\t// `_id` is the hash, the only unique index: a duplicate is a retry.\n\t\t\t\tawait settle(collection.raw.insertOne(toTokenDocument(record)));\n\t\t\t}),\n\n\t\tconsumeToken: (tokenHash, kind, at) =>\n\t\t\trun$('consumeToken', () => consumeToken(collection, tokenHash, kind, at)),\n\n\t\tcountAttempt: (tokenHash, kind) =>\n\t\t\trun$('countAttempt', () => countAttempt(collection, tokenHash, kind)),\n\n\t\tspendUserTokens: (userId, kind, at, except) =>\n\t\t\trun$('spendUserTokens', async () => {\n\t\t\t\t// Each document is matched and written in one step, as\n\t\t\t\t// `consumeToken` does: a token it spends at the same moment is\n\t\t\t\t// counted by exactly one of the two.\n\t\t\t\tconst result = await collection.raw.updateMany(\n\t\t\t\t\t{\n\t\t\t\t\t\tuserId,\n\t\t\t\t\t\tkind,\n\t\t\t\t\t\tspentAt: null,\n\t\t\t\t\t\t...(except === undefined ? {} : { _id: { $ne: except } }),\n\t\t\t\t\t},\n\t\t\t\t\t{ $set: { spentAt: at } },\n\t\t\t\t);\n\t\t\t\treturn result.modifiedCount;\n\t\t\t}),\n\n\t\tdeleteUserTokens: (userId) =>\n\t\t\trun$('deleteUserTokens', async () => {\n\t\t\t\tconst result = await collection.raw.deleteMany({ userId });\n\t\t\t\treturn result.deletedCount;\n\t\t\t}),\n\t};\n}\n\nasync function consumeToken(\n\tcollection: Tokens,\n\ttokenHash: string,\n\tkind: TokenKind,\n\tat: Date,\n): Promise<TokenRecord | null> {\n\t// **One conditional write**, answering the document as it was\n\t// before it. The pipeline keeps a first `spentAt`, so exactly one\n\t// caller ever reads `spentAt: null`.\n\tconst before = await collection.raw.findOneAndUpdate(\n\t\t{ _id: tokenHash, kind },\n\t\t[{ $set: { spentAt: { $ifNull: ['$spentAt', at] } } }],\n\t\t{ returnDocument: 'before' },\n\t);\n\treturn before === null ? null : toToken(before);\n}\n\nasync function countAttempt(\n\tcollection: Tokens,\n\ttokenHash: string,\n\tkind: TokenKind,\n): Promise<TokenRecord | null> {\n\t// **One conditional write**, answering the document after it: an\n\t// unspent token gets one more attempt, atomically. A spent one is\n\t// matched by the second read below, and written nothing.\n\tconst after = await collection.raw.findOneAndUpdate(\n\t\t{ _id: tokenHash, kind, spentAt: null },\n\t\t{ $inc: { attempts: 1 } },\n\t\t{ returnDocument: 'after' },\n\t);\n\tif (after !== null) return toToken(after);\n\tconst spent = await collection.raw.findOne({ _id: tokenHash, kind });\n\treturn spent === null ? null : toToken(spent);\n}\n",
|
|
17
17
|
"import type { UserPatch, UserRecord, UserStore } from '@nxgt/janus';\nimport { NotFoundError, StoreConflict } from '@nxgt/janus';\nimport { getCollection, type TypedCollection } from '@nxgt/mongo';\nimport type { Db } from 'mongodb';\nimport { users } from '../collections';\nimport { refuseDuplicate, run, settle } from '../translate';\nimport { toUser, toUserDocument, toUserSet } from './records';\n\ntype Users = TypedCollection<typeof users>;\n\nexport function userStore(db: Db): UserStore {\n\tconst collection = getCollection(db, users);\n\tconst run$ = <T>(operation: string, body: () => Promise<T>) =>\n\t\trun('users', operation, body);\n\n\treturn {\n\t\tinsertUser: (record) =>\n\t\t\trun$('insertUser', () => insertUser(collection, record)),\n\n\t\tfindUser: (id) => run$('findUser', () => findUser(collection, id)),\n\n\t\tfindUserByLogin: (type, login) =>\n\t\t\trun$('findUserByLogin', async () => {\n\t\t\t\tconst found = await collection.findFirst({ type, logins: login });\n\t\t\t\treturn found === undefined ? null : toUser(found);\n\t\t\t}),\n\n\t\tlistUsers: ({ type, after, limit }) =>\n\t\t\trun$('listUsers', async () => {\n\t\t\t\t// One more than the page, to know whether another follows.\n\t\t\t\tconst found = await collection.findMany({\n\t\t\t\t\tfilter: after === null ? { type } : { type, _id: { $gt: after } },\n\t\t\t\t\tsort: { _id: 1 },\n\t\t\t\t\tlimit: limit + 1,\n\t\t\t\t});\n\t\t\t\tconst items = found.slice(0, limit).map(toUser);\n\t\t\t\tconst last = items.at(-1);\n\n\t\t\t\treturn {\n\t\t\t\t\titems,\n\t\t\t\t\tnextCursor:\n\t\t\t\t\t\tfound.length > limit && last !== undefined ? last.id : null,\n\t\t\t\t};\n\t\t\t}),\n\n\t\tupdateUser: (id, patch, ifVersion) =>\n\t\t\trun$('updateUser', () => updateUser(collection, id, patch, ifVersion)),\n\n\t\tdeleteUser: (id) =>\n\t\t\trun$('deleteUser', async () => {\n\t\t\t\tconst result = await collection.raw.deleteOne({ _id: id });\n\t\t\t\treturn result.deletedCount === 1;\n\t\t\t}),\n\t};\n}\n\nasync function findUser(\n\tcollection: Users,\n\tid: string,\n): Promise<UserRecord | null> {\n\tconst found = await collection.findById(id);\n\treturn found === undefined ? null : toUser(found);\n}\n\nasync function insertUser(\n\tcollection: Users,\n\trecord: UserRecord,\n): Promise<UserRecord> {\n\tconst document = toUserDocument(record);\n\tconst outcome = await settle(collection.raw.insertOne(document));\n\tif (!('duplicate' in outcome)) return toUser(document);\n\n\t// A retry whose first attempt landed: whichever index reported it,\n\t// the user with this id is there, and is the answer. That includes\n\t// their own logins, which are not taken by them.\n\tconst stored = await findUser(collection, record.id);\n\tif (stored !== null) return stored;\n\tthrow refuseDuplicate('insertUser', outcome.duplicate);\n}\n\nasync function updateUser(\n\tcollection: Users,\n\tid: string,\n\tpatch: UserPatch,\n\tifVersion: number,\n): Promise<UserRecord> {\n\tconst outcome = await settle(\n\t\tcollection.raw.findOneAndUpdate(\n\t\t\t{ _id: id, version: ifVersion },\n\t\t\t{ $set: toUserSet(patch), $inc: { version: 1 } },\n\t\t\t{ returnDocument: 'after' },\n\t\t),\n\t);\n\n\tif ('duplicate' in outcome) {\n\t\tthrow refuseDuplicate('updateUser', outcome.duplicate);\n\t}\n\tif (outcome.written !== null) return toUser(outcome.written);\n\n\t// The write matched nothing, which alone cannot tell an unknown id\n\t// from a moved version: read again, and say which.\n\tconst stored = await findUser(collection, id);\n\tif (stored === null) {\n\t\tthrow new NotFoundError('updateUser: no user has this id', {\n\t\t\tuserId: id,\n\t\t\toperation: 'updateUser',\n\t\t});\n\t}\n\tthrow new StoreConflict(\n\t\t'version',\n\t\t`updateUser: expected version ${ifVersion}, found ${stored.version}`,\n\t\t{\n\t\t\tuserId: id,\n\t\t\texpectedVersion: ifVersion,\n\t\t\tactualVersion: stored.version,\n\t\t\toperation: 'updateUser',\n\t\t},\n\t);\n}\n"
|
|
18
18
|
],
|
|
19
|
-
"mappings": "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",
|
|
20
|
-
"debugId": "
|
|
19
|
+
"mappings": "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",
|
|
20
|
+
"debugId": "9576378C5D4AE00164756E2164756E21",
|
|
21
21
|
"names": []
|
|
22
22
|
}
|
package/docs/guide/sync.md
CHANGED
|
@@ -129,7 +129,8 @@ version adds a field, the validator the previous sync wrote refuses it: from
|
|
|
129
129
|
0.2 to 0.3, `secondFactor` on every new user and `codeHash` and `attempts` on
|
|
130
130
|
every new token; from 0.4 to 0.5, `recoveryCodes` on every second factor
|
|
131
131
|
written. The same holds for a new value: from 0.5 to 0.6, the token kind
|
|
132
|
-
`stepUp`,
|
|
132
|
+
`stepUp`, and from 0.6 to 0.7, the token kind `magicLink`, which the
|
|
133
|
+
previous validator's `kind` enum refuses. Run the sync
|
|
133
134
|
with the new version **before** the code that writes them:
|
|
134
135
|
|
|
135
136
|
```ts
|
|
@@ -145,7 +146,8 @@ nothing the previous version writes, so the previous version keeps working
|
|
|
145
146
|
against it while the deployment rolls. Deployed before the sync,
|
|
146
147
|
every sign-up and every one-time token fails with `STORE_FAILED`, caused by
|
|
147
148
|
`Document failed validation` (code 121) — from 0.5 to 0.6, every step-up
|
|
148
|
-
request only.
|
|
149
|
+
request only; from 0.6 to 0.7, every `magicLink.request` only. No document
|
|
150
|
+
is rewritten either way.
|
|
149
151
|
|
|
150
152
|
**From 0.4 to 0.5, finish the rollout before users hold recovery codes.** An
|
|
151
153
|
instance still on 0.4 reads a second factor without its `recoveryCodes`, and
|
package/docs/roadmap.md
CHANGED
|
@@ -40,6 +40,9 @@ Nothing yet.
|
|
|
40
40
|
|
|
41
41
|
Each entry names the version it came in; `CHANGELOG.md` holds the rest.
|
|
42
42
|
|
|
43
|
+
- **The sign-in link kind, v0.7.0** — for `@nxgt/janus` 0.15: the `kind`
|
|
44
|
+
enum admits `magicLink`, the token of a link that signs a user in, so run
|
|
45
|
+
the sync before deploying. No document is rewritten.
|
|
43
46
|
- **The step-up kind and `reauthenticateSession`, v0.6.0** — for
|
|
44
47
|
`@nxgt/janus` 0.12: one `findOneAndUpdate` filtered on `revokedAt: null`,
|
|
45
48
|
and the `kind` enum admits `stepUp`, so run the sync before deploying. No
|
package/docs/troubleshooting.md
CHANGED
|
@@ -125,7 +125,7 @@ idempotent, so retry it yourself.
|
|
|
125
125
|
|
|
126
126
|
**When:** a write — `insertUser`, `updateUser`, `insertSession`, … — rejected by the collection's `$jsonSchema` validator (MongoDB error code 121).
|
|
127
127
|
**Why:** the core validates every record before it reaches the store, so a validator refusing one means the collection and the adapter disagree: the collection's validator was set by another version of this adapter, or a collection of the same name (`users`, `sessions`, `tokens`, `relations`) already belonged to your application, with its own validator. It is never the caller's fault, and never a 400.
|
|
128
|
-
**Fix:** after upgrading this package, run `syncMongoStores(db)` again — upgrading to 0.3 is exactly this case: the validator the previous sync wrote refuses `secondFactor`, `codeHash` and `attempts` until it runs; so is upgrading to 0.5, whose `secondFactor.recoveryCodes` it refuses on every write of a second factor,
|
|
128
|
+
**Fix:** after upgrading this package, run `syncMongoStores(db)` again — upgrading to 0.3 is exactly this case: the validator the previous sync wrote refuses `secondFactor`, `codeHash` and `attempts` until it runs; so is upgrading to 0.5, whose `secondFactor.recoveryCodes` it refuses on every write of a second factor, upgrading to 0.6, whose token kind `stepUp` it refuses on every step-up request, and upgrading to 0.7, whose token kind `magicLink` it refuses on every `magicLink.request`. See [sync before you deploy](guide/sync.md#upgrading-sync-before-you-deploy). If your application already has a `users` collection, the adapter is sharing its database: give it one of its own, `janus`:
|
|
129
129
|
|
|
130
130
|
```ts
|
|
131
131
|
const auth = janus({ ..., store: createMongoStores(client.db('janus')) });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxgt/janus-mongo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "The MongoDB adapter for @nxgt/janus: users, sessions, one-time tokens and permission tuples",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
]
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@nxgt/janus": "^0.
|
|
51
|
+
"@nxgt/janus": "^0.15.0",
|
|
52
52
|
"@nxgt/mongo": "^0.18.1",
|
|
53
53
|
"@types/bun": "^1.4.2",
|
|
54
54
|
"mongodb": "^7.6.0",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"zod": "^4.6.5"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"@nxgt/janus": "^0.
|
|
59
|
+
"@nxgt/janus": "^0.15.0",
|
|
60
60
|
"@nxgt/mongo": ">=0.17.0 <1",
|
|
61
61
|
"mongodb": ">=7.0.0 <8",
|
|
62
62
|
"typescript": "^6.0.3",
|