@nxgt/janus-telemetry 0.12.0 → 0.13.1
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 -3
- package/dist/index.js +35 -2
- package/dist/index.js.map +3 -3
- package/dist/permissions.d.ts +7 -3
- package/dist/permissions.d.ts.map +1 -1
- package/docs/guide/tracing.md +3 -1
- package/docs/roadmap.md +5 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -49,7 +49,7 @@ every CI run.
|
|
|
49
49
|
| Export | What it is |
|
|
50
50
|
| --- | --- |
|
|
51
51
|
| `instrumentJanus(auth)` | The same `janus()` instance, frozen, with every flow traced under its call path — `auth.signIn` as `janus.signIn`, `auth.patient.signIn` as `janus.patient.signIn` — and the security events written as logs. `cookie` stays synchronous and untraced |
|
|
52
|
-
| `instrumentPermissions(access)` | The same `permissions()` instance, frozen, with `can`, `list`, `grant` and `
|
|
52
|
+
| `instrumentPermissions(access)` | The same `permissions()` instance, frozen, with `can`, `list`, `grant`, `revoke` and `replace` traced, and one audit event per tuple written, granted or revoked — for `replace`, one per tuple it added and one per tuple it removed |
|
|
53
53
|
| `JanusLike`, `PermissionsLike` | What each accepts: `instrumentJanus(access)` and `instrumentPermissions(auth)` do not compile. `PermissionsLike.model.subjects`, which `permissions()` answers, tells a user from a subject set; an instance without it has every `{ type, id, relation }` recorded as a set |
|
|
54
54
|
|
|
55
55
|
## What is written
|
|
@@ -58,10 +58,11 @@ every CI run.
|
|
|
58
58
|
|
|
59
59
|
| Span | Attributes |
|
|
60
60
|
| --- | --- |
|
|
61
|
-
| `janus.<flow>`, `janus.<type>.<flow>` — `janus.secondFactor.confirm`, `janus.signInCode.confirm`, `janus.magicLink.confirm`, `janus.signInProven` and `janus.verifyEmail.proveFirst` included, the reads as well — `janus.<type>.findByEmail` among them — and a prepared request's `send()` as `janus.magicLink.prepare.send` | `janus.user.type`; `user.id` once the answer names a user, never the address or login a read was asked for; `janus.session.renewed` for `authenticate`; `janus.signIn.status` for `signIn`, `signInCode.confirm`, `magicLink.confirm` and `signInProven` — `signedIn`, or `secondFactor` when it answered a challenge; for `stepUp.confirm`, the `user.id` of the session it stamped, never the session's id |
|
|
61
|
+
| `janus.<flow>`, `janus.<type>.<flow>` — `janus.secondFactor.confirm`, `janus.signInCode.confirm`, `janus.magicLink.confirm`, `janus.signInProven` and `janus.verifyEmail.proveFirst` included, the reads as well — `janus.<type>.findByEmail` and `janus.<type>.findOrCreate` among them — and a prepared request's `send()` as `janus.magicLink.prepare.send` | `janus.user.type`; `user.id` once the answer names a user, never the address or login a read was asked for; `janus.session.renewed` for `authenticate`; `janus.signIn.status` for `signIn`, `signInCode.confirm`, `magicLink.confirm` and `signInProven` — `signedIn`, or `secondFactor` when it answered a challenge; for `stepUp.confirm`, the `user.id` of the session it stamped, never the session's id |
|
|
62
62
|
| `janus.can` | `janus.subject.type`, `janus.subject.id`, `janus.permission`, `janus.object.type`, `janus.object.id`, and the answer, `janus.allowed` |
|
|
63
63
|
| `janus.list` | the subject, `janus.permission`, `janus.object.type`, and `janus.page.items`, how many it found |
|
|
64
64
|
| `janus.grant`, `janus.revoke` | the object, `janus.relation`, and the subject — `janus.subject.relation` for a subject set, read as `permissions()` reads it: a user with a field named `relation` is that user, and a set on a user type is one only when `setOf()` made it |
|
|
65
|
+
| `janus.replace` | the object and `janus.relation`; the tuples it added and removed are the audit events, below, each with the object, relation and subject a `grant` or `revoke` writes — a subject set always with its `janus.subject.relation`, since a stored tuple names it |
|
|
65
66
|
|
|
66
67
|
**A refusal is an answer, not a failure.** A wrong password, a taken login, a
|
|
67
68
|
spent token, a denial: the span is `ok`, and a refusal carries
|
|
@@ -97,7 +98,7 @@ when the flow knows them — `janus.signOut` carries neither:
|
|
|
97
98
|
| `janus.password.changed`, `janus.password.set`, `janus.password.reset` | info | the user's change, an admin's, a reset |
|
|
98
99
|
| `janus.email.verified` | info | an e-mail was confirmed — by `verifyEmail.confirm`, or proved on the application's own proof by `verifyEmail.proveFirst`, which adds `janus.email.proveFirst: true` and writes it only when it proved (an e-mail already proved writes nothing) |
|
|
99
100
|
| `janus.email.changed` | info | a user's e-mail moved, with `janus.user.type`, `user.id` and `janus.email.proved` — never the former or the new address. `changeEmail.confirm` writes it with `janus.email.proved: true` (and no `janus.email.verified` besides: the move is the proof); `update` writes it with `janus.email.proved: false` when its patch names the `email` field, even if the address turns out unchanged (the field name janus defaults to — a renamed e-mail field is not seen on `update`, nor an `update` that moved the address and then answered `STORE_FAILED` while spending the change links) |
|
|
100
|
-
| `janus.tuple.granted`, `janus.tuple.revoked` | info | a tuple was written, with the object, relation and subject |
|
|
101
|
+
| `janus.tuple.granted`, `janus.tuple.revoked` | info | a tuple was written by `grant`, `revoke` or `replace` — one event per tuple, `replace` one per tuple added and one per tuple removed — with the object, relation and subject |
|
|
101
102
|
|
|
102
103
|
## Traps
|
|
103
104
|
|
package/dist/index.js
CHANGED
|
@@ -472,8 +472,41 @@ var tracersFor = (userTypes) => ({
|
|
|
472
472
|
}
|
|
473
473
|
}),
|
|
474
474
|
grant: (fn) => tupleWrite("janus.grant", granted, fn, userTypes),
|
|
475
|
-
revoke: (fn) => tupleWrite("janus.revoke", revoked, fn, userTypes)
|
|
475
|
+
revoke: (fn) => tupleWrite("janus.revoke", revoked, fn, userTypes),
|
|
476
|
+
replace: (fn) => replaceWrite(fn)
|
|
476
477
|
});
|
|
478
|
+
function storedFields(tuple) {
|
|
479
|
+
if (typeof tuple !== "object" || tuple === null)
|
|
480
|
+
return {};
|
|
481
|
+
const { object, relation, subject } = tuple;
|
|
482
|
+
const setRelation = typeof subject === "object" && subject !== null && "relation" in subject ? subject.relation : undefined;
|
|
483
|
+
return fieldsOf({
|
|
484
|
+
...objectFields(object),
|
|
485
|
+
"janus.relation": typeof relation === "string" ? relation : undefined,
|
|
486
|
+
"janus.subject.type": typeOf(subject),
|
|
487
|
+
"janus.subject.id": idOf(subject),
|
|
488
|
+
"janus.subject.relation": typeof setRelation === "string" ? setRelation : undefined
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
function replaceWrite(fn) {
|
|
492
|
+
return (...args) => traced("janus.replace", fieldsOf({
|
|
493
|
+
...objectFields(args[0]),
|
|
494
|
+
"janus.relation": typeof args[1] === "string" ? args[1] : undefined
|
|
495
|
+
}), () => fn(...args), (_scope, outcome) => {
|
|
496
|
+
if (!outcome.ok || typeof outcome.value !== "object")
|
|
497
|
+
return;
|
|
498
|
+
const { added, removed } = outcome.value ?? {};
|
|
499
|
+
for (const [tuples, written] of [
|
|
500
|
+
[added, granted],
|
|
501
|
+
[removed, revoked]
|
|
502
|
+
]) {
|
|
503
|
+
if (!Array.isArray(tuples))
|
|
504
|
+
continue;
|
|
505
|
+
for (const tuple of tuples)
|
|
506
|
+
log3.info(written(storedFields(tuple)));
|
|
507
|
+
}
|
|
508
|
+
});
|
|
509
|
+
}
|
|
477
510
|
function tupleWrite(name, written, fn, userTypes) {
|
|
478
511
|
return (...args) => {
|
|
479
512
|
const fields = fieldsOf({
|
|
@@ -503,5 +536,5 @@ export {
|
|
|
503
536
|
instrumentPermissions
|
|
504
537
|
};
|
|
505
538
|
|
|
506
|
-
//# debugId=
|
|
539
|
+
//# debugId=D06ADE7604EC6B3A64756E2164756E21
|
|
507
540
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
"import type { Outcome } from '../traced';\nimport type { Call } from './call';\nimport { events, issued, log, markedSignIn } from './events';\nimport {\n\targumentUser,\n\tprovedOf,\n\trecoveryCodesLeft,\n\trefusalFields,\n\tsecondFactorFields,\n\tsessionUserFields,\n\tsignedInFields,\n\tstatusOf,\n\tuserFields,\n\tviaOf,\n} from './fields';\nimport { mailRequest } from './mail';\n\n/** The name `update`'s patch gives the e-mail, the field name janus defaults to. */\nconst EMAIL_FIELD = 'email';\n\n/** Whether `update`'s patch (its second argument) names the e-mail field. */\nfunction patchNamesEmail(call: Call): boolean {\n\tconst patch = call.args[1];\n\treturn (\n\t\ttypeof patch === 'object' &&\n\t\tpatch !== null &&\n\t\t(patch as Record<string, unknown>)[EMAIL_FIELD] !== undefined\n\t);\n}\n\n/**\n * What each flow writes once it answered. Nothing here reads a login, an\n * e-mail, a password or a token: only user types, ids, codes and reasons.\n */\nexport const WRITTEN: Readonly<\n\tRecord<string, (call: Call, outcome: Outcome) => void>\n> = {\n\tsignUp: (call, outcome) => {\n\t\tif (outcome.ok) log.info(events.signedUp(userFields(call, outcome.value)));\n\t},\n\tsignIn: (call, outcome) => {\n\t\tif (!outcome.ok && outcome.refusal.reason === 'throttled') {\n\t\t\t// Too many passwords at one login: no password was compared.\n\t\t\tlog.warn(\n\t\t\t\tevents.signInThrottled({\n\t\t\t\t\t...refusalFields(call, outcome.refusal),\n\t\t\t\t\t'janus.signIn.retryAfter': outcome.refusal.retryAfter,\n\t\t\t\t}),\n\t\t\t);\n\t\t} else if (!outcome.ok) {\n\t\t\tlog.warn(events.signInRefused(refusalFields(call, outcome.refusal)));\n\t\t} else if (statusOf(outcome.value) === 'secondFactor') {\n\t\t\t// The password was right; the session waits for a code.\n\t\t\tlog.info(\n\t\t\t\tevents.secondFactorAsked(secondFactorFields(call, outcome.value)),\n\t\t\t);\n\t\t} else {\n\t\t\tlog.info(events.signedIn(signedInFields(call, outcome.value)));\n\t\t}\n\t},\n\t'signInCode.request': mailRequest(issued(events.signInCodeSent)),\n\t// In two steps: prepare is counted, and send issues — what request writes.\n\t'signInCode.prepare': mailRequest(),\n\t'signInCode.prepare.send': issued(events.signInCodeSent),\n\t'signInCode.confirm': markedSignIn('janus.signIn.code'),\n\t'magicLink.request': mailRequest(issued(events.magicLinkSent)),\n\t'magicLink.prepare': mailRequest(),\n\t'magicLink.prepare.send': issued(events.magicLinkSent),\n\t'magicLink.confirm': markedSignIn('janus.signIn.magicLink'),\n\t// No credential checked here: the application carried the proof.\n\tsignInProven: markedSignIn('janus.signIn.proven'),\n\t'stepUp.request': mailRequest((call, outcome) => {\n\t\t// Which code confirms it — e-mailed, or from the app — never the code.\n\t\tif (outcome.ok) {\n\t\t\tlog.info(\n\t\t\t\tevents.stepUpAsked({\n\t\t\t\t\t...userFields(call, outcome.value),\n\t\t\t\t\t'janus.stepUp.via': viaOf(outcome.value),\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t}),\n\t'stepUp.confirm': (call, outcome) => {\n\t\tif (outcome.ok) {\n\t\t\tlog.info(events.stepUpConfirmed(sessionUserFields(call, outcome.value)));\n\t\t} else {\n\t\t\tlog.warn(events.stepUpRefused(refusalFields(call, outcome.refusal)));\n\t\t}\n\t},\n\t'secondFactor.confirm': (call, outcome) => {\n\t\tif (outcome.ok) {\n\t\t\tlog.info(\n\t\t\t\tevents.signedIn({\n\t\t\t\t\t...signedInFields(call, outcome.value),\n\t\t\t\t\t'janus.signIn.secondFactor': true,\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\tlog.warn(events.signInRefused(refusalFields(call, outcome.refusal)));\n\t\t}\n\t},\n\t'secondFactor.recover': (call, outcome) => {\n\t\t// Marked, so an alert can watch sign-ins made without the phone.\n\t\tif (outcome.ok) {\n\t\t\tlog.info(\n\t\t\t\tevents.signedIn({\n\t\t\t\t\t...signedInFields(call, outcome.value),\n\t\t\t\t\t'janus.signIn.recoveryCode': true,\n\t\t\t\t\t'janus.secondFactor.recoveryCodesLeft': recoveryCodesLeft(\n\t\t\t\t\t\toutcome.value,\n\t\t\t\t\t),\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\tlog.warn(\n\t\t\t\tevents.signInRefused({\n\t\t\t\t\t...refusalFields(call, outcome.refusal),\n\t\t\t\t\t'janus.signIn.recoveryCode': true,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t},\n\t'secondFactor.regenerateRecoveryCodes': (call, outcome) => {\n\t\tif (outcome.ok) {\n\t\t\tlog.info(events.recoveryCodesRegenerated(argumentUser(call)));\n\t\t}\n\t},\n\t'secondFactor.enroll': (call, outcome) => {\n\t\tif (outcome.ok) log.info(events.secondFactorEnrolled(argumentUser(call)));\n\t},\n\t'secondFactor.activate': (call, outcome) => {\n\t\tif (outcome.ok) log.info(events.secondFactorActivated(argumentUser(call)));\n\t},\n\t'secondFactor.disable': (call, outcome) => {\n\t\tif (outcome.ok) log.info(events.secondFactorDisabled(argumentUser(call)));\n\t},\n\tsignOut: (_call, outcome) => {\n\t\tif (outcome.ok && outcome.value === true) log.info(events.signedOut());\n\t},\n\tsignOutEverywhere: (call, outcome) => {\n\t\tif (outcome.ok) log.info(events.signedOutEverywhere(argumentUser(call)));\n\t},\n\tdelete: (call, outcome) => {\n\t\tif (outcome.ok && outcome.value === true) {\n\t\t\tlog.info(events.userDeleted(argumentUser(call)));\n\t\t}\n\t},\n\tsetActive: (call, outcome) => {\n\t\tif (!outcome.ok) return;\n\t\tconst written =\n\t\t\tcall.args[1] === true ? events.userActivated : events.userDeactivated;\n\t\tlog.info(written(argumentUser(call)));\n\t},\n\tchangePassword: (call, outcome) => {\n\t\tif (outcome.ok) log.info(events.passwordChanged(argumentUser(call)));\n\t},\n\tsetPassword: (call, outcome) => {\n\t\tif (outcome.ok) log.info(events.passwordSet(argumentUser(call)));\n\t},\n\t'resetPassword.request': mailRequest(),\n\t'resetPassword.prepare': mailRequest(),\n\t'verifyEmail.send': mailRequest(),\n\t'changeEmail.send': mailRequest(),\n\t'resetPassword.confirm': (call, outcome) => {\n\t\tif (outcome.ok)\n\t\t\tlog.info(events.passwordReset(userFields(call, outcome.value)));\n\t},\n\t'verifyEmail.confirm': (call, outcome) => {\n\t\tif (outcome.ok)\n\t\t\tlog.info(events.emailVerified(userFields(call, outcome.value)));\n\t},\n\t// One event, not two: the move is the proof; no address is written.\n\t'changeEmail.confirm': (call, outcome) => {\n\t\tif (outcome.ok) {\n\t\t\tlog.info(\n\t\t\t\tevents.emailChanged({\n\t\t\t\t\t...userFields(call, outcome.value),\n\t\t\t\t\t'janus.email.proved': true,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t},\n\t// Moved without proof, whatever the application decided to trust. Read\n\t// from the patch: it names the `email` field (the default name; telemetry\n\t// does not know a renamed one), even when the value turns out unchanged.\n\tupdate: (call, outcome) => {\n\t\tif (outcome.ok && patchNamesEmail(call)) {\n\t\t\tlog.info(\n\t\t\t\tevents.emailChanged({\n\t\t\t\t\t...userFields(call, outcome.value),\n\t\t\t\t\t'janus.email.proved': false,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t},\n\t// Only when it proved: an e-mail already proved changed nothing.\n\t'verifyEmail.proveFirst': (call, outcome) => {\n\t\tif (outcome.ok && provedOf(outcome.value)) {\n\t\t\tlog.info(\n\t\t\t\tevents.emailVerified({\n\t\t\t\t\t...userFields(call, outcome.value),\n\t\t\t\t\t'janus.email.proveFirst': true,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t},\n};\n",
|
|
10
10
|
"import type { SpanScope } from '@nxgt/telemetry';\nimport { fieldsOf, type Outcome, traced } from '../traced';\nimport type { Call } from './call';\nimport { sessionUserFields, statusOf, userFields } from './fields';\nimport { WRITTEN } from './written';\n\n/** What a span learns from an answer: whose it is, never what it holds. */\nfunction answered(scope: SpanScope, call: Call, outcome: Outcome): void {\n\tif (outcome.ok) {\n\t\t// A session is answered by `stepUp.confirm`: its user is its `userId`.\n\t\tconst fields =\n\t\t\tcall.flow === 'stepUp.confirm'\n\t\t\t\t? sessionUserFields(call, outcome.value)\n\t\t\t\t: userFields(call, outcome.value);\n\t\tfor (const [key, value] of Object.entries(fields))\n\t\t\tscope.attribute(key, value);\n\t\tconst value = outcome.value;\n\t\tif (typeof value === 'object' && value !== null && 'renewed' in value) {\n\t\t\tscope.attribute('janus.session.renewed', value.renewed === true);\n\t\t}\n\t\tconst status = SIGN_INS.has(call.flow) ? statusOf(value) : undefined;\n\t\tif (status !== undefined) scope.attribute('janus.signIn.status', status);\n\t}\n\tWRITTEN[call.flow]?.(call, outcome);\n}\n\n/** The flows whose answer is a sign-in's: a session, or a second factor asked for. */\nconst SIGN_INS = new Set([\n\t'signIn',\n\t'signInCode.confirm',\n\t'magicLink.confirm',\n\t'signInProven',\n]);\n\n/** `cookie` answers synchronously: it is the one part of `janus()` not traced. */\nconst UNTRACED = new Set(['cookie']);\n\n/** Which user type and flow a path names: `['patient', 'signIn']`. */\ntype Split = (path: readonly string[]) => {\n\treadonly userType: string | undefined;\n\treadonly flow: readonly string[];\n};\n\n/**\n * A traced copy of `target`, frozen: its functions traced, its plain objects —\n * a user type's flows, `verifyEmail` — copied the same way. A copy rather\n * than a Proxy, which may not answer differently for a frozen property.\n */\nexport function traceObject<O extends object>(\n\ttarget: O,\n\tpath: readonly string[],\n\tsplit: Split,\n): O {\n\tconst copy: Record<string, unknown> = {};\n\tfor (const [key, value] of Object.entries(target)) {\n\t\tif (UNTRACED.has(key)) {\n\t\t\tcopy[key] = value;\n\t\t} else if (typeof value === 'function') {\n\t\t\tcopy[key] = traceFunction(\n\t\t\t\tvalue as (...args: unknown[]) => unknown,\n\t\t\t\ttarget,\n\t\t\t\t[...path, key],\n\t\t\t\tsplit,\n\t\t\t);\n\t\t} else if (\n\t\t\ttypeof value === 'object' &&\n\t\t\tvalue !== null &&\n\t\t\t!Array.isArray(value)\n\t\t) {\n\t\t\tcopy[key] = traceObject(value, [...path, key], split);\n\t\t} else {\n\t\t\tcopy[key] = value;\n\t\t}\n\t}\n\treturn Object.freeze(copy) as O;\n}\n\nfunction traceFunction(\n\tfn: (...args: unknown[]) => unknown,\n\tself: object,\n\tpath: readonly string[],\n\tsplit: Split,\n): (...args: unknown[]) => Promise<unknown> {\n\tconst { userType, flow } = split(path);\n\tconst name = `janus.${path.join('.')}`;\n\tconst fields = fieldsOf({ 'janus.user.type': userType });\n\treturn (...args) => {\n\t\tconst call: Call = { flow: flow.join('.'), userType, args };\n\t\tconst answer = traced(\n\t\t\tname,\n\t\t\tfields,\n\t\t\t() => Promise.resolve(fn.apply(self, args)),\n\t\t\t(scope, outcome) => answered(scope, call, outcome),\n\t\t);\n\t\treturn path.at(-1) === 'prepare'\n\t\t\t? answer.then((value) => tracePrepared(value, path, split))\n\t\t\t: answer;\n\t};\n}\n\n/**\n * What `prepare` answers — `magicLink.prepare(email)` — traced in turn, so\n * its `send()` is a span of its own, `janus.magicLink.prepare.send`, and\n * writes what `request` writes once it issued. Anything else is answered\n * as it came.\n */\nfunction tracePrepared(\n\tvalue: unknown,\n\tpath: readonly string[],\n\tsplit: Split,\n): unknown {\n\treturn typeof value === 'object' && value !== null\n\t\t? traceObject(value, path, split)\n\t\t: value;\n}\n",
|
|
11
11
|
"import { traceObject } from './trace';\n\n/** What `janus()` answers, as far as it is read: its user types and its flows. */\nexport interface JanusLike {\n\treadonly types: readonly string[];\n\treadonly authenticate: (...args: never[]) => Promise<unknown>;\n}\n\n/**\n * The same `janus()` instance, with every flow traced — a span per call,\n * named `janus.signIn` or `janus.patient.signIn` — and the events a security\n * review reads written as logs: sign-ups, sign-ins and the reason one was\n * refused, a second factor asked for, enrolled, activated or disabled, a\n * sign-in by recovery code and the codes left, recovery codes regenerated,\n * sign-outs, deleted and deactivated users, changed passwords.\n *\n * ```ts\n * const auth = instrumentJanus(janus({ users, store, hasher }));\n * ```\n *\n * **A refusal is an answer**: a wrong password leaves its span `ok`, with\n * `janus.refusal` set, and is a `janus.signIn.refused` warning — never a\n * failed span. A store that cannot answer is one, with `janus.store.slot`.\n *\n * Nothing written carries a login, an e-mail, a password, a token, a\n * challenge, a code, a TOTP secret or a session id: user types, user ids,\n * codes and reasons only.\n */\nexport function instrumentJanus<A extends JanusLike>(auth: A): A {\n\tconst types = auth.types.filter((type) => typeof type === 'string');\n\tconst only = types.length === 1 ? types[0] : undefined;\n\treturn traceObject(auth, [], (path) =>\n\t\tpath[0] !== undefined && types.includes(path[0])\n\t\t\t? { userType: path[0], flow: path.slice(1) }\n\t\t\t: { userType: only, flow: path },\n\t);\n}\n",
|
|
12
|
-
"import { isSetOf } from '@nxgt/janus';\nimport { createLogger, event, type TelemetryEvent } from '@nxgt/telemetry';\nimport { type Fields, fieldsOf, idOf, traced, typeOf } from './traced';\n\nconst log = createLogger('@nxgt/janus');\n\n/** The audit trail of who was given what: one event per tuple written. */\nconst granted = event('janus.tuple.granted');\nconst revoked = event('janus.tuple.revoked');\n\n/**\n * A subject — a user, an object, or a subject set — as fields, read as\n * `permissions()` reads it: a value of a user type is that user, even with a\n * field named `relation`, unless `setOf()` made it.\n */\nfunction subjectFields(\n\tsubject: unknown,\n\tuserTypes: ReadonlySet<string>,\n): Fields {\n\tconst type = typeOf(subject);\n\tconst relation =\n\t\ttypeof subject === 'object' && subject !== null && 'relation' in subject\n\t\t\t? subject.relation\n\t\t\t: undefined;\n\tconst isSet =\n\t\ttypeof relation === 'string' &&\n\t\t(isSetOf(subject) || type === undefined || !userTypes.has(type));\n\treturn fieldsOf({\n\t\t'janus.subject.type': type,\n\t\t'janus.subject.id': idOf(subject),\n\t\t'janus.subject.relation': isSet ? relation : undefined,\n\t});\n}\n\nfunction objectFields(object: unknown): Fields {\n\treturn fieldsOf({\n\t\t'janus.object.type': typeOf(object),\n\t\t'janus.object.id': idOf(object),\n\t});\n}\n\n/** What `permissions()` answers, as far as it is traced. */\nexport interface PermissionsLike {\n\t/** Its user types tell a user from a subject set of the same shape. */\n\treadonly model?: { readonly subjects: readonly string[] };\n\treadonly can: (...args: never[]) => Promise<boolean>;\n\treadonly list: (...args: never[]) => Promise<unknown>;\n\treadonly grant: (...args: never[]) => Promise<unknown>;\n\treadonly revoke: (...args: never[]) => Promise<unknown>;\n}\n\ntype Traced = (...args: unknown[]) => Promise<unknown>;\n\n/** How each method of `permissions()` is traced. */\nconst tracersFor = (\n\tuserTypes: ReadonlySet<string>,\n): Readonly<Record<string, (fn: Traced) => Traced>> => ({\n\tcan:\n\t\t(fn) =>\n\t\t(...args) =>\n\t\t\ttraced(\n\t\t\t\t'janus.can',\n\t\t\t\tfieldsOf({\n\t\t\t\t\t...subjectFields(args[0], userTypes),\n\t\t\t\t\t'janus.permission': typeof args[1] === 'string' ? args[1] : undefined,\n\t\t\t\t\t...objectFields(args[2]),\n\t\t\t\t}),\n\t\t\t\t() => fn(...args),\n\t\t\t\t(scope, outcome) => {\n\t\t\t\t\tif (outcome.ok)\n\t\t\t\t\t\tscope.attribute('janus.allowed', outcome.value === true);\n\t\t\t\t},\n\t\t\t),\n\tlist:\n\t\t(fn) =>\n\t\t(...args) =>\n\t\t\ttraced(\n\t\t\t\t'janus.list',\n\t\t\t\tfieldsOf({\n\t\t\t\t\t...subjectFields(args[0], userTypes),\n\t\t\t\t\t'janus.permission': typeof args[1] === 'string' ? args[1] : undefined,\n\t\t\t\t\t'janus.object.type':\n\t\t\t\t\t\ttypeof args[2] === 'string' ? args[2] : undefined,\n\t\t\t\t}),\n\t\t\t\t() => fn(...args),\n\t\t\t\t(scope, outcome) => {\n\t\t\t\t\tconst page = outcome.ok ? outcome.value : undefined;\n\t\t\t\t\tif (typeof page === 'object' && page !== null && 'items' in page) {\n\t\t\t\t\t\tconst items = page.items;\n\t\t\t\t\t\tif (Array.isArray(items))\n\t\t\t\t\t\t\tscope.attribute('janus.page.items', items.length);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\tgrant: (fn) => tupleWrite('janus.grant', granted, fn, userTypes),\n\trevoke: (fn) => tupleWrite('janus.revoke', revoked, fn, userTypes),\n});\n\nfunction tupleWrite(\n\tname: string,\n\twritten: (fields: Fields) => TelemetryEvent,\n\tfn: Traced,\n\tuserTypes: ReadonlySet<string>,\n): Traced {\n\treturn (...args) => {\n\t\tconst fields = fieldsOf({\n\t\t\t...objectFields(args[0]),\n\t\t\t'janus.relation': typeof args[1] === 'string' ? args[1] : undefined,\n\t\t\t...subjectFields(args[2], userTypes),\n\t\t});\n\t\treturn traced(\n\t\t\tname,\n\t\t\tfields,\n\t\t\t() => fn(...args),\n\t\t\t(_scope, outcome) => {\n\t\t\t\tif (outcome.ok) log.info(written(fields));\n\t\t\t},\n\t\t);\n\t};\n}\n\n/**\n * The same `permissions()` instance, traced: a span per `can` — its subject,\n * permission, object and whether it was allowed — and per `list`,
|
|
12
|
+
"import { isSetOf } from '@nxgt/janus';\nimport { createLogger, event, type TelemetryEvent } from '@nxgt/telemetry';\nimport { type Fields, fieldsOf, idOf, traced, typeOf } from './traced';\n\nconst log = createLogger('@nxgt/janus');\n\n/** The audit trail of who was given what: one event per tuple written. */\nconst granted = event('janus.tuple.granted');\nconst revoked = event('janus.tuple.revoked');\n\n/**\n * A subject — a user, an object, or a subject set — as fields, read as\n * `permissions()` reads it: a value of a user type is that user, even with a\n * field named `relation`, unless `setOf()` made it.\n */\nfunction subjectFields(\n\tsubject: unknown,\n\tuserTypes: ReadonlySet<string>,\n): Fields {\n\tconst type = typeOf(subject);\n\tconst relation =\n\t\ttypeof subject === 'object' && subject !== null && 'relation' in subject\n\t\t\t? subject.relation\n\t\t\t: undefined;\n\tconst isSet =\n\t\ttypeof relation === 'string' &&\n\t\t(isSetOf(subject) || type === undefined || !userTypes.has(type));\n\treturn fieldsOf({\n\t\t'janus.subject.type': type,\n\t\t'janus.subject.id': idOf(subject),\n\t\t'janus.subject.relation': isSet ? relation : undefined,\n\t});\n}\n\nfunction objectFields(object: unknown): Fields {\n\treturn fieldsOf({\n\t\t'janus.object.type': typeOf(object),\n\t\t'janus.object.id': idOf(object),\n\t});\n}\n\n/** What `permissions()` answers, as far as it is traced. */\nexport interface PermissionsLike {\n\t/** Its user types tell a user from a subject set of the same shape. */\n\treadonly model?: { readonly subjects: readonly string[] };\n\treadonly can: (...args: never[]) => Promise<boolean>;\n\treadonly list: (...args: never[]) => Promise<unknown>;\n\treadonly grant: (...args: never[]) => Promise<unknown>;\n\treadonly revoke: (...args: never[]) => Promise<unknown>;\n\t/** Traced when present: an instance made before `replace` has none. */\n\treadonly replace?: (...args: never[]) => Promise<unknown>;\n}\n\ntype Traced = (...args: unknown[]) => Promise<unknown>;\n\n/** How each method of `permissions()` is traced. */\nconst tracersFor = (\n\tuserTypes: ReadonlySet<string>,\n): Readonly<Record<string, (fn: Traced) => Traced>> => ({\n\tcan:\n\t\t(fn) =>\n\t\t(...args) =>\n\t\t\ttraced(\n\t\t\t\t'janus.can',\n\t\t\t\tfieldsOf({\n\t\t\t\t\t...subjectFields(args[0], userTypes),\n\t\t\t\t\t'janus.permission': typeof args[1] === 'string' ? args[1] : undefined,\n\t\t\t\t\t...objectFields(args[2]),\n\t\t\t\t}),\n\t\t\t\t() => fn(...args),\n\t\t\t\t(scope, outcome) => {\n\t\t\t\t\tif (outcome.ok)\n\t\t\t\t\t\tscope.attribute('janus.allowed', outcome.value === true);\n\t\t\t\t},\n\t\t\t),\n\tlist:\n\t\t(fn) =>\n\t\t(...args) =>\n\t\t\ttraced(\n\t\t\t\t'janus.list',\n\t\t\t\tfieldsOf({\n\t\t\t\t\t...subjectFields(args[0], userTypes),\n\t\t\t\t\t'janus.permission': typeof args[1] === 'string' ? args[1] : undefined,\n\t\t\t\t\t'janus.object.type':\n\t\t\t\t\t\ttypeof args[2] === 'string' ? args[2] : undefined,\n\t\t\t\t}),\n\t\t\t\t() => fn(...args),\n\t\t\t\t(scope, outcome) => {\n\t\t\t\t\tconst page = outcome.ok ? outcome.value : undefined;\n\t\t\t\t\tif (typeof page === 'object' && page !== null && 'items' in page) {\n\t\t\t\t\t\tconst items = page.items;\n\t\t\t\t\t\tif (Array.isArray(items))\n\t\t\t\t\t\t\tscope.attribute('janus.page.items', items.length);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\tgrant: (fn) => tupleWrite('janus.grant', granted, fn, userTypes),\n\trevoke: (fn) => tupleWrite('janus.revoke', revoked, fn, userTypes),\n\treplace: (fn) => replaceWrite(fn),\n});\n\n/** A stored tuple as fields: its subject is a set when it names a relation. */\nfunction storedFields(tuple: unknown): Fields {\n\tif (typeof tuple !== 'object' || tuple === null) return {};\n\tconst { object, relation, subject } = tuple as Record<string, unknown>;\n\tconst setRelation =\n\t\ttypeof subject === 'object' && subject !== null && 'relation' in subject\n\t\t\t? subject.relation\n\t\t\t: undefined;\n\treturn fieldsOf({\n\t\t...objectFields(object),\n\t\t'janus.relation': typeof relation === 'string' ? relation : undefined,\n\t\t'janus.subject.type': typeOf(subject),\n\t\t'janus.subject.id': idOf(subject),\n\t\t'janus.subject.relation':\n\t\t\ttypeof setRelation === 'string' ? setRelation : undefined,\n\t});\n}\n\n/** `replace`: the object and relation on the span, an event per tuple it answers. */\nfunction replaceWrite(fn: Traced): Traced {\n\treturn (...args) =>\n\t\ttraced(\n\t\t\t'janus.replace',\n\t\t\tfieldsOf({\n\t\t\t\t...objectFields(args[0]),\n\t\t\t\t'janus.relation': typeof args[1] === 'string' ? args[1] : undefined,\n\t\t\t}),\n\t\t\t() => fn(...args),\n\t\t\t(_scope, outcome) => {\n\t\t\t\tif (!outcome.ok || typeof outcome.value !== 'object') return;\n\t\t\t\tconst { added, removed } = (outcome.value ?? {}) as Record<\n\t\t\t\t\tstring,\n\t\t\t\t\tunknown\n\t\t\t\t>;\n\t\t\t\tfor (const [tuples, written] of [\n\t\t\t\t\t[added, granted],\n\t\t\t\t\t[removed, revoked],\n\t\t\t\t] as const) {\n\t\t\t\t\tif (!Array.isArray(tuples)) continue;\n\t\t\t\t\tfor (const tuple of tuples) log.info(written(storedFields(tuple)));\n\t\t\t\t}\n\t\t\t},\n\t\t);\n}\n\nfunction tupleWrite(\n\tname: string,\n\twritten: (fields: Fields) => TelemetryEvent,\n\tfn: Traced,\n\tuserTypes: ReadonlySet<string>,\n): Traced {\n\treturn (...args) => {\n\t\tconst fields = fieldsOf({\n\t\t\t...objectFields(args[0]),\n\t\t\t'janus.relation': typeof args[1] === 'string' ? args[1] : undefined,\n\t\t\t...subjectFields(args[2], userTypes),\n\t\t});\n\t\treturn traced(\n\t\t\tname,\n\t\t\tfields,\n\t\t\t() => fn(...args),\n\t\t\t(_scope, outcome) => {\n\t\t\t\tif (outcome.ok) log.info(written(fields));\n\t\t\t},\n\t\t);\n\t};\n}\n\n/**\n * The same `permissions()` instance, traced: a span per `can` — its subject,\n * permission, object and whether it was allowed — and per `list`, a span per\n * `grant`, `revoke` and `replace`, and a `janus.tuple.granted` or\n * `janus.tuple.revoked` event for every tuple written, the audit trail of who\n * was given what. `replace` writes one event per tuple it added and one per\n * tuple it removed.\n *\n * ```ts\n * const access = instrumentPermissions(permissions({ model, store }));\n * ```\n *\n * A denial is an answer, not a failure: `janus.allowed` is `false` and the\n * span is `ok`. A relation store that cannot answer fails the span.\n */\nexport function instrumentPermissions<A extends PermissionsLike>(access: A): A {\n\t// `permissions()` answers a frozen object, which a Proxy may not answer\n\t// differently for: the traced methods go on a copy, frozen in turn.\n\tconst copy: Record<string, unknown> = Object.fromEntries(\n\t\tObject.entries(access),\n\t);\n\tconst userTypes = new Set(access.model?.subjects ?? []);\n\tfor (const [key, tracer] of Object.entries(tracersFor(userTypes))) {\n\t\tconst method: unknown = copy[key];\n\t\tif (typeof method !== 'function') continue;\n\t\tcopy[key] = tracer((...args) =>\n\t\t\tPromise.resolve(method.apply(access, args)),\n\t\t);\n\t}\n\treturn Object.freeze(copy) as A;\n}\n"
|
|
13
13
|
],
|
|
14
|
-
"mappings": "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",
|
|
15
|
-
"debugId": "
|
|
14
|
+
"mappings": "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",
|
|
15
|
+
"debugId": "D06ADE7604EC6B3A64756E2164756E21",
|
|
16
16
|
"names": []
|
|
17
17
|
}
|
package/dist/permissions.d.ts
CHANGED
|
@@ -8,12 +8,16 @@ export interface PermissionsLike {
|
|
|
8
8
|
readonly list: (...args: never[]) => Promise<unknown>;
|
|
9
9
|
readonly grant: (...args: never[]) => Promise<unknown>;
|
|
10
10
|
readonly revoke: (...args: never[]) => Promise<unknown>;
|
|
11
|
+
/** Traced when present: an instance made before `replace` has none. */
|
|
12
|
+
readonly replace?: (...args: never[]) => Promise<unknown>;
|
|
11
13
|
}
|
|
12
14
|
/**
|
|
13
15
|
* The same `permissions()` instance, traced: a span per `can` — its subject,
|
|
14
|
-
* permission, object and whether it was allowed — and per `list`,
|
|
15
|
-
* `
|
|
16
|
-
* written, the audit trail of who
|
|
16
|
+
* permission, object and whether it was allowed — and per `list`, a span per
|
|
17
|
+
* `grant`, `revoke` and `replace`, and a `janus.tuple.granted` or
|
|
18
|
+
* `janus.tuple.revoked` event for every tuple written, the audit trail of who
|
|
19
|
+
* was given what. `replace` writes one event per tuple it added and one per
|
|
20
|
+
* tuple it removed.
|
|
17
21
|
*
|
|
18
22
|
* ```ts
|
|
19
23
|
* const access = instrumentPermissions(permissions({ model, store }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAyCA,4DAA4D;AAC5D,MAAM,WAAW,eAAe;IAC/B,uEAAuE;IACvE,QAAQ,CAAC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,CAAC;IAC1D,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACrD,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACtD,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAyCA,4DAA4D;AAC5D,MAAM,WAAW,eAAe;IAC/B,uEAAuE;IACvE,QAAQ,CAAC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,CAAC;IAC1D,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACrD,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACtD,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACxD,uEAAuE;IACvE,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1D;AAsHD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,eAAe,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAe7E"}
|
package/docs/guide/tracing.md
CHANGED
|
@@ -112,7 +112,9 @@ janus.magicLink.request ok janus.refusal=MAIL_THROTTLED
|
|
|
112
112
|
```
|
|
113
113
|
|
|
114
114
|
`janus.tuple.granted` and `janus.tuple.revoked` are the record of who was
|
|
115
|
-
given what:
|
|
115
|
+
given what: one per tuple a `grant` or `revoke` writes, and, for a `replace`
|
|
116
|
+
(span `janus.replace`), one `granted` per tuple it added and one `revoked` per
|
|
117
|
+
tuple it removed:
|
|
116
118
|
|
|
117
119
|
```
|
|
118
120
|
janus.tuple.granted janus.object.type=record janus.object.id=r1 janus.relation=owners janus.subject.type=patient janus.subject.id=u1
|
package/docs/roadmap.md
CHANGED
|
@@ -33,6 +33,11 @@ Nothing yet.
|
|
|
33
33
|
|
|
34
34
|
Newest first; the [CHANGELOG](../CHANGELOG.md) holds every release.
|
|
35
35
|
|
|
36
|
+
- **Tracing `replace`, v0.13.0** — `instrumentPermissions` traces
|
|
37
|
+
`access.replace(object, relation, subjects)` like `grant` and `revoke`: a
|
|
38
|
+
`janus.replace` span with the object and `janus.relation`, and one
|
|
39
|
+
`janus.tuple.granted` audit event per tuple it added and one
|
|
40
|
+
`janus.tuple.revoked` per tuple it removed.
|
|
36
41
|
- **E-mail changes in the audit trail** — `changeEmail.confirm` writes
|
|
37
42
|
`janus.email.changed` with the `user.id` and `janus.email.proved: true`,
|
|
38
43
|
never an address (an `update` whose patch names `email` writes it with
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxgt/janus-telemetry",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.1",
|
|
4
4
|
"description": "Observability for @nxgt/janus on @nxgt/telemetry: a span per flow and per permission check, and the security events worth an audit trail — never a login, an e-mail, a password, a session token, a one-time token or a session id",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -49,13 +49,13 @@
|
|
|
49
49
|
]
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@nxgt/janus": "^0.
|
|
52
|
+
"@nxgt/janus": "^0.25.0",
|
|
53
53
|
"@nxgt/telemetry": "0.2.2",
|
|
54
54
|
"@types/bun": "^1.4.2",
|
|
55
55
|
"zod": "^4.6.5"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
|
-
"@nxgt/janus": "^0.
|
|
58
|
+
"@nxgt/janus": "^0.25.0",
|
|
59
59
|
"@nxgt/telemetry": ">=0.2.1 <1",
|
|
60
60
|
"typescript": "^6.0.3 || ^7.0.0"
|
|
61
61
|
}
|