@cogenta/auth 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api-keys.d.ts +93 -4
- package/dist/api-keys.d.ts.map +1 -1
- package/dist/api-keys.js +260 -27
- package/dist/api-keys.js.map +1 -1
- package/dist/audit-integrity.d.ts +61 -0
- package/dist/audit-integrity.d.ts.map +1 -0
- package/dist/audit-integrity.js +130 -0
- package/dist/audit-integrity.js.map +1 -0
- package/dist/audit.d.ts +78 -2
- package/dist/audit.d.ts.map +1 -1
- package/dist/audit.js +168 -24
- package/dist/audit.js.map +1 -1
- package/dist/credentials.d.ts +27 -0
- package/dist/credentials.d.ts.map +1 -1
- package/dist/credentials.js +61 -0
- package/dist/credentials.js.map +1 -1
- package/dist/index.d.ts +11 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/login.d.ts +63 -6
- package/dist/login.d.ts.map +1 -1
- package/dist/login.js +90 -10
- package/dist/login.js.map +1 -1
- package/dist/mfa.d.ts +1 -1
- package/dist/mfa.d.ts.map +1 -1
- package/dist/mfa.js +3 -1
- package/dist/mfa.js.map +1 -1
- package/dist/recovery-codes.d.ts +25 -0
- package/dist/recovery-codes.d.ts.map +1 -0
- package/dist/recovery-codes.js +56 -0
- package/dist/recovery-codes.js.map +1 -0
- package/dist/resets.d.ts +15 -1
- package/dist/resets.d.ts.map +1 -1
- package/dist/resets.js +10 -0
- package/dist/resets.js.map +1 -1
- package/dist/sessions.d.ts +24 -0
- package/dist/sessions.d.ts.map +1 -1
- package/dist/sessions.js +25 -4
- package/dist/sessions.js.map +1 -1
- package/dist/store.d.ts +3 -0
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +4 -1
- package/dist/store.js.map +1 -1
- package/dist/tables.d.ts +17 -0
- package/dist/tables.d.ts.map +1 -1
- package/dist/tables.js +129 -1
- package/dist/tables.js.map +1 -1
- package/dist/types.d.ts +89 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +10 -1
- package/dist/types.js.map +1 -1
- package/dist/user-agent.d.ts +18 -0
- package/dist/user-agent.d.ts.map +1 -0
- package/dist/user-agent.js +39 -0
- package/dist/user-agent.js.map +1 -0
- package/dist/users.d.ts +24 -1
- package/dist/users.d.ts.map +1 -1
- package/dist/users.js +72 -3
- package/dist/users.js.map +1 -1
- package/package.json +3 -3
package/dist/types.d.ts
CHANGED
|
@@ -7,20 +7,54 @@
|
|
|
7
7
|
* This package is that concern: it is what turns a role name into an actual
|
|
8
8
|
* signed-in person.
|
|
9
9
|
*/
|
|
10
|
-
export declare const CREDENTIAL_KINDS: readonly ['password', 'totp', 'webauthn'];
|
|
10
|
+
export declare const CREDENTIAL_KINDS: readonly ['password', 'totp', 'webauthn', 'recovery_codes'];
|
|
11
11
|
export type CredentialKind = (typeof CREDENTIAL_KINDS)[number];
|
|
12
|
+
/**
|
|
13
|
+
* `invited` (fiche 17 task 1) and `anonymized` (fiche 17 task 5) joined
|
|
14
|
+
* `active`/`disabled` on the same grounds: neither is a role or a permission,
|
|
15
|
+
* both are states of the *account* itself, and both are enforced the same way
|
|
16
|
+
* every non-`active` status already was — `passwordLogin` and `resolveActor`
|
|
17
|
+
* both refuse anything but `active`, so an invited account (no password yet)
|
|
18
|
+
* and an anonymized one (deliberately made permanent) are blocked from
|
|
19
|
+
* signing in for free, with no new check anywhere.
|
|
20
|
+
*/
|
|
21
|
+
export type UserStatus = 'active' | 'disabled' | 'invited' | 'anonymized';
|
|
12
22
|
export interface User {
|
|
13
23
|
readonly id: string;
|
|
14
24
|
readonly email: string;
|
|
15
25
|
/** An open set of names, exactly as contract A's collection permissions expect. */
|
|
16
26
|
readonly roles: readonly string[];
|
|
17
|
-
readonly status:
|
|
27
|
+
readonly status: UserStatus;
|
|
18
28
|
readonly createdAt: string;
|
|
19
29
|
readonly updatedAt: string;
|
|
30
|
+
/**
|
|
31
|
+
* Public profile (fiche 17 task 3) — volunteered by the account itself,
|
|
32
|
+
* never inferred. `null` means "not set", not "empty string": a theme or an
|
|
33
|
+
* audit view falls back to the email only when this is genuinely absent.
|
|
34
|
+
*/
|
|
35
|
+
readonly displayName: string | null;
|
|
36
|
+
/** A media asset id (`@cogenta/schema`'s media store), not a URL — resolved the same way any other avatar-shaped field is. */
|
|
37
|
+
readonly avatarMediaId: string | null;
|
|
38
|
+
readonly bio: string | null;
|
|
39
|
+
/** BCP-47-ish tag for the admin's own interface language, e.g. `en` or `fr-CA`. */
|
|
40
|
+
readonly locale: string | null;
|
|
20
41
|
}
|
|
21
42
|
export interface CreateUserInput {
|
|
22
43
|
readonly email: string;
|
|
23
44
|
readonly roles: readonly string[];
|
|
45
|
+
/**
|
|
46
|
+
* Defaults to `active`. Only `invited` (fiche 17 task 1) is meant to be
|
|
47
|
+
* passed by a caller today — `anonymized` is reached through
|
|
48
|
+
* `UserStore.anonymize`, never through `create`.
|
|
49
|
+
*/
|
|
50
|
+
readonly status?: UserStatus;
|
|
51
|
+
}
|
|
52
|
+
/** Self-service only (fiche 17 task 3) — see `UserStore.updateProfile`'s doc comment for why. */
|
|
53
|
+
export interface UpdateProfileInput {
|
|
54
|
+
readonly displayName?: string | null;
|
|
55
|
+
readonly avatarMediaId?: string | null;
|
|
56
|
+
readonly bio?: string | null;
|
|
57
|
+
readonly locale?: string | null;
|
|
24
58
|
}
|
|
25
59
|
export interface Session {
|
|
26
60
|
readonly id: string;
|
|
@@ -30,6 +64,14 @@ export interface Session {
|
|
|
30
64
|
readonly lastSeenAt: string;
|
|
31
65
|
/** Free text, shown in "your sessions" so a person can recognise a device. */
|
|
32
66
|
readonly label: string | undefined;
|
|
67
|
+
/**
|
|
68
|
+
* Browser family and device type, distilled from the `User-Agent` header at
|
|
69
|
+
* creation time and never anything more (fiche 18 task 2) — no IP address,
|
|
70
|
+
* no raw user-agent string, no third-party geolocation (R1, and privacy).
|
|
71
|
+
* `'unknown'` for a session created without one (a script, an old row).
|
|
72
|
+
*/
|
|
73
|
+
readonly browser: string;
|
|
74
|
+
readonly device: string;
|
|
33
75
|
}
|
|
34
76
|
/**
|
|
35
77
|
* A session as returned once, at creation. `token` is the bearer credential; it
|
|
@@ -49,6 +91,16 @@ export interface AuditEntry {
|
|
|
49
91
|
readonly collection: string | null;
|
|
50
92
|
readonly entryId: string | null;
|
|
51
93
|
readonly diff: Readonly<Record<string, unknown>> | null;
|
|
94
|
+
/**
|
|
95
|
+
* The content version this action produced, when it produced one
|
|
96
|
+
* (`content.create`/`content.update`/`content.restore`; `null` for every
|
|
97
|
+
* other action, and for an action a site recorded before this field
|
|
98
|
+
* existed). Fiche 21 task 1: this is what lets the entry's detail view ask
|
|
99
|
+
* `GET .../diff?from={version-1}&to={version}` instead of re-deriving a
|
|
100
|
+
* diff from `at`, which a concurrent write could make point at the wrong
|
|
101
|
+
* pair of versions.
|
|
102
|
+
*/
|
|
103
|
+
readonly version: number | null;
|
|
52
104
|
/** Chains to the previous entry's hash. The first entry chains to null. */
|
|
53
105
|
readonly hash: string;
|
|
54
106
|
readonly previousHash: string | null;
|
|
@@ -60,7 +112,15 @@ export interface RecordAuditInput {
|
|
|
60
112
|
readonly collection?: string | undefined;
|
|
61
113
|
readonly entryId?: string | undefined;
|
|
62
114
|
readonly diff?: Readonly<Record<string, unknown>> | undefined;
|
|
115
|
+
/** See `AuditEntry.version`. Omitted (not `null`) for an action that never produces one. */
|
|
116
|
+
readonly version?: number | undefined;
|
|
63
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Who or what an entry names, from signals the log already carries — see
|
|
120
|
+
* `classifyAuditActor` in `audit.ts`.
|
|
121
|
+
*/
|
|
122
|
+
export declare const AUDIT_ACTOR_KINDS: readonly ['human', 'agent', 'api_key', 'system'];
|
|
123
|
+
export type AuditActorKind = (typeof AUDIT_ACTOR_KINDS)[number];
|
|
64
124
|
/**
|
|
65
125
|
* A machine-to-machine bearer credential (L13 task 8).
|
|
66
126
|
*
|
|
@@ -80,15 +140,42 @@ export interface ApiKey {
|
|
|
80
140
|
readonly expiresAt: string | undefined;
|
|
81
141
|
readonly revokedAt: string | undefined;
|
|
82
142
|
readonly lastUsedAt: string | undefined;
|
|
143
|
+
/** Requests per minute this key may make (fiche 20 task 3). Always a real number — `DEFAULT_RATE_LIMIT_PER_MINUTE` when none was chosen. */
|
|
144
|
+
readonly rateLimitPerMinute: number;
|
|
145
|
+
/**
|
|
146
|
+
* The id of the key that replaced this one, once rotated (fiche 20 task 2).
|
|
147
|
+
* `undefined` for a key that has never been rotated, or that *is* the
|
|
148
|
+
* result of a rotation. `expiresAt` is what actually ends this key's grace
|
|
149
|
+
* window; this field only names what it was superseded by.
|
|
150
|
+
*/
|
|
151
|
+
readonly supersededBy: string | undefined;
|
|
83
152
|
}
|
|
84
153
|
export interface CreateApiKeyInput {
|
|
85
154
|
readonly name: string;
|
|
86
155
|
readonly scope: readonly string[];
|
|
87
156
|
readonly createdBy: string | null;
|
|
88
157
|
readonly expiresAt?: string | undefined;
|
|
158
|
+
/** Omit for `DEFAULT_RATE_LIMIT_PER_MINUTE`. */
|
|
159
|
+
readonly rateLimitPerMinute?: number | undefined;
|
|
89
160
|
}
|
|
90
161
|
/** An API key as returned once, at creation — `key` is never stored or shown again. */
|
|
91
162
|
export interface IssuedApiKey extends ApiKey {
|
|
92
163
|
readonly key: string;
|
|
93
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* "Faire tourner cette clé" (fiche 20 task 2): a fresh key with the same name,
|
|
167
|
+
* scope and quota as the one it replaces, and the replaced key kept valid
|
|
168
|
+
* for a chosen grace window rather than dying mid-flight.
|
|
169
|
+
*/
|
|
170
|
+
export interface ApiKeyRotationResult {
|
|
171
|
+
/** The new key, raw value included exactly once — same rule as `create`. */
|
|
172
|
+
readonly issued: IssuedApiKey;
|
|
173
|
+
/** The old key, now expiring at the end of its grace window. */
|
|
174
|
+
readonly previous: ApiKey;
|
|
175
|
+
}
|
|
176
|
+
/** Aggregated call counts for one key (fiche 20 task 4) — never a line per call. */
|
|
177
|
+
export interface ApiKeyUsage {
|
|
178
|
+
readonly last7Days: number;
|
|
179
|
+
readonly last30Days: number;
|
|
180
|
+
}
|
|
94
181
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,eAAO,MAAM,gBAAgB,YAAI,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,gBAAgB,CAAU,CAAA;AAC3F,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE9D;;;;;;;;GAQG;AACH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,YAAY,CAAA;AAEzE,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,mFAAmF;IACnF,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,8HAA8H;IAC9H,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IACrC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,mFAAmF;IACnF,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,CAAA;CAC7B;AAED,iGAAiG;AACjG,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAChC;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAc,SAAQ,OAAO;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,oEAAoE;IACpE,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,CAAA;IACvD;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;CACrC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACxC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAAA;IAC7D,4FAA4F;IAC5F,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACtC;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,YAAI,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAU,CAAA;AACjF,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE/D;;;;;;;GAOG;AACH,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,oEAAoE;IACpE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IACtC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,4IAA4I;IAC5I,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAA;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAA;CAC1C;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,gDAAgD;IAChD,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACjD;AAED,uFAAuF;AACvF,MAAM,WAAW,YAAa,SAAQ,MAAM;IAC1C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;IAC7B,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAED,oFAAoF;AACpF,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B"}
|
package/dist/types.js
CHANGED
|
@@ -7,5 +7,14 @@
|
|
|
7
7
|
* This package is that concern: it is what turns a role name into an actual
|
|
8
8
|
* signed-in person.
|
|
9
9
|
*/
|
|
10
|
-
|
|
10
|
+
// `recovery_codes` (fiche 18 task 1) stores a JSON blob of hashed, single-use
|
|
11
|
+
// codes — the way back in for an account that enrolled TOTP and then lost
|
|
12
|
+
// the device. Same shape as every other kind here: interpreted only by
|
|
13
|
+
// `credentials.ts`, never by this layer.
|
|
14
|
+
export const CREDENTIAL_KINDS = ['password', 'totp', 'webauthn', 'recovery_codes'];
|
|
15
|
+
/**
|
|
16
|
+
* Who or what an entry names, from signals the log already carries — see
|
|
17
|
+
* `classifyAuditActor` in `audit.ts`.
|
|
18
|
+
*/
|
|
19
|
+
export const AUDIT_ACTOR_KINDS = ['human', 'agent', 'api_key', 'system'];
|
|
11
20
|
//# sourceMappingURL=types.js.map
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,CAAU,CAAA"}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,8EAA8E;AAC9E,0EAA0E;AAC1E,uEAAuE;AACvE,yCAAyC;AACzC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,gBAAgB,CAAU,CAAA;AAqH3F;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAU,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Just enough of a `User-Agent` parse to answer "which of my sessions is my
|
|
3
|
+
* phone" — never more (fiche 18 task 2).
|
|
4
|
+
*
|
|
5
|
+
* A `User-Agent` string is personal data the moment it is stored whole: it
|
|
6
|
+
* fingerprints a browser build, an OS patch level, sometimes a device model.
|
|
7
|
+
* `sessions.ts` calls this once, at session creation, and keeps only the
|
|
8
|
+
* two-word answer below — the raw header itself is never written to a row
|
|
9
|
+
* and is discarded the instant this function returns. No dependency (R9): a
|
|
10
|
+
* handful of substring checks is the entire "library" a session list needs.
|
|
11
|
+
*/
|
|
12
|
+
export interface ParsedUserAgent {
|
|
13
|
+
readonly browser: string;
|
|
14
|
+
readonly device: string;
|
|
15
|
+
}
|
|
16
|
+
/** Distils a raw `User-Agent` header into a browser family and a device type. Never keeps anything else. */
|
|
17
|
+
export declare function parseUserAgent(userAgent: string | null | undefined): ParsedUserAgent;
|
|
18
|
+
//# sourceMappingURL=user-agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-agent.d.ts","sourceRoot":"","sources":["../src/user-agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AA0BD,4GAA4G;AAC5G,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,eAAe,CAKpF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const UNKNOWN = Object.freeze({ browser: 'unknown', device: 'unknown' });
|
|
2
|
+
function deviceOf(ua) {
|
|
3
|
+
if (/ipad|tablet|kindle|playbook/iu.test(ua))
|
|
4
|
+
return 'tablet';
|
|
5
|
+
if (/mobi|iphone|ipod|android.*mobile|windows phone|blackberry/iu.test(ua))
|
|
6
|
+
return 'mobile';
|
|
7
|
+
if (/bot|crawler|spider|curl\/|wget\/|python-requests|axios\//iu.test(ua))
|
|
8
|
+
return 'bot';
|
|
9
|
+
return 'desktop';
|
|
10
|
+
}
|
|
11
|
+
function browserOf(ua) {
|
|
12
|
+
// Order matters: Edge and Opera both carry "Chrome" in their UA string, and
|
|
13
|
+
// Chrome itself carries "Safari" in its — the more specific token has to be
|
|
14
|
+
// checked first, or every Edge or Opera user would be reported as Chrome,
|
|
15
|
+
// and every Chrome user as Safari.
|
|
16
|
+
if (/edg\//iu.test(ua))
|
|
17
|
+
return 'edge';
|
|
18
|
+
if (/opr\/|opera/iu.test(ua))
|
|
19
|
+
return 'opera';
|
|
20
|
+
if (/firefox\/|fxios\//iu.test(ua))
|
|
21
|
+
return 'firefox';
|
|
22
|
+
if (/crios\//iu.test(ua))
|
|
23
|
+
return 'chrome';
|
|
24
|
+
if (/chrome\//iu.test(ua) && !/chromium/iu.test(ua))
|
|
25
|
+
return 'chrome';
|
|
26
|
+
if (/safari\//iu.test(ua))
|
|
27
|
+
return 'safari';
|
|
28
|
+
if (/bot|crawler|spider/iu.test(ua))
|
|
29
|
+
return 'bot';
|
|
30
|
+
return 'other';
|
|
31
|
+
}
|
|
32
|
+
/** Distils a raw `User-Agent` header into a browser family and a device type. Never keeps anything else. */
|
|
33
|
+
export function parseUserAgent(userAgent) {
|
|
34
|
+
if (userAgent === null || userAgent === undefined || userAgent.trim().length === 0) {
|
|
35
|
+
return UNKNOWN;
|
|
36
|
+
}
|
|
37
|
+
return { browser: browserOf(userAgent), device: deviceOf(userAgent) };
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=user-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-agent.js","sourceRoot":"","sources":["../src/user-agent.ts"],"names":[],"mappings":"AAgBA,MAAM,OAAO,GAAoB,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAA;AAEzF,SAAS,QAAQ,CAAC,EAAU;IAC1B,IAAI,+BAA+B,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,QAAQ,CAAA;IAC7D,IAAI,6DAA6D,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,QAAQ,CAAA;IAC3F,IAAI,4DAA4D,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,KAAK,CAAA;IACvF,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAS,SAAS,CAAC,EAAU;IAC3B,4EAA4E;IAC5E,4EAA4E;IAC5E,0EAA0E;IAC1E,mCAAmC;IACnC,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,MAAM,CAAA;IACrC,IAAI,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,OAAO,CAAA;IAC5C,IAAI,qBAAqB,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,SAAS,CAAA;IACpD,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,QAAQ,CAAA;IACzC,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,QAAQ,CAAA;IACpE,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,QAAQ,CAAA;IAC1C,IAAI,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,KAAK,CAAA;IACjD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,4GAA4G;AAC5G,MAAM,UAAU,cAAc,CAAC,SAAoC;IACjE,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnF,OAAO,OAAO,CAAA;IAChB,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAA;AACvE,CAAC"}
|
package/dist/users.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type DatabaseHandle } from '@cogenta/core';
|
|
2
|
-
import type { CreateUserInput, User } from './types.js';
|
|
2
|
+
import type { CreateUserInput, UpdateProfileInput, User } from './types.js';
|
|
3
3
|
export interface UserStore {
|
|
4
4
|
create(input: CreateUserInput): Promise<User>;
|
|
5
5
|
byEmail(email: string): Promise<User | null>;
|
|
@@ -7,6 +7,29 @@ export interface UserStore {
|
|
|
7
7
|
setRoles(id: string, roles: readonly string[]): Promise<void>;
|
|
8
8
|
setStatus(id: string, status: User['status']): Promise<void>;
|
|
9
9
|
list(): Promise<readonly User[]>;
|
|
10
|
+
/** Self-service profile fields (fiche 17 task 3) — see `UpdateProfileInput`'s doc comment. */
|
|
11
|
+
updateProfile(id: string, input: UpdateProfileInput): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Real, hard deletion — the one exception to "accounts are disabled, never
|
|
14
|
+
* removed" (this file's header, and `users-router.ts`'s). The exception
|
|
15
|
+
* holds only because of what an `invited` account structurally cannot be:
|
|
16
|
+
* signing in requires `status === 'active'` (`login.ts`), so an account
|
|
17
|
+
* still sitting in `invited` has never authenticated and therefore cannot
|
|
18
|
+
* have authored a single row anywhere — there is nothing for the audit log
|
|
19
|
+
* or a `createdBy` column to lose. The caller (`users-router.ts`'s cancel
|
|
20
|
+
* route) is what enforces that this is only ever reached for such a row;
|
|
21
|
+
* this method itself does not re-check the status, the same way `setRoles`
|
|
22
|
+
* does not re-check who is asking.
|
|
23
|
+
*/
|
|
24
|
+
delete(id: string): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* The RGPD-erasure half of fiche 17 task 5. Irreversible by construction:
|
|
27
|
+
* the original email is never stored anywhere, hashed or otherwise — there
|
|
28
|
+
* is nothing left in this table (or this process) that could reconstruct
|
|
29
|
+
* it. Returns the updated row so the caller can build one response instead
|
|
30
|
+
* of anonymizing and then re-reading.
|
|
31
|
+
*/
|
|
32
|
+
anonymize(id: string): Promise<User>;
|
|
10
33
|
}
|
|
11
34
|
export declare function createUserStore(db: DatabaseHandle, now?: () => number): UserStore;
|
|
12
35
|
//# sourceMappingURL=users.d.ts.map
|
package/dist/users.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../src/users.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../src/users.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,cAAc,EAKpB,MAAM,eAAe,CAAA;AAEtB,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AA8C3E,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7C,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAA;IAC5C,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAA;IACtC,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7D,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5D,IAAI,IAAI,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAA;IAChC,8FAA8F;IAC9F,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACnE;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACjC;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACrC;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,GAAE,MAAM,MAAiB,GAAG,SAAS,CA6H3F"}
|
package/dist/users.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { CogentaError, identifier, newId, sql, } from '@cogenta/core';
|
|
2
3
|
import { TABLES } from './tables.js';
|
|
3
4
|
function fromRow(row) {
|
|
4
5
|
return {
|
|
@@ -8,8 +9,23 @@ function fromRow(row) {
|
|
|
8
9
|
status: row.status,
|
|
9
10
|
createdAt: row.created_at,
|
|
10
11
|
updatedAt: row.updated_at,
|
|
12
|
+
displayName: row.display_name ?? null,
|
|
13
|
+
avatarMediaId: row.avatar_media_id ?? null,
|
|
14
|
+
bio: row.bio ?? null,
|
|
15
|
+
locale: row.locale ?? null,
|
|
11
16
|
};
|
|
12
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* The non-reversible token an anonymized account's email becomes (fiche 17
|
|
20
|
+
* task 5). `.invalid` is the reserved TLD RFC 2606 sets aside for exactly
|
|
21
|
+
* this — an address guaranteed to never resolve, so nobody could ever
|
|
22
|
+
* mistake it for a real, deliverable mailbox. Random rather than derived from
|
|
23
|
+
* the old address: derivation would be a second, weaker encoding of the very
|
|
24
|
+
* thing this is meant to erase.
|
|
25
|
+
*/
|
|
26
|
+
function anonymizedEmail() {
|
|
27
|
+
return `anon-${randomBytes(16).toString('hex')}@anonymized.invalid`;
|
|
28
|
+
}
|
|
13
29
|
function normaliseEmail(email) {
|
|
14
30
|
return email.trim().toLowerCase();
|
|
15
31
|
}
|
|
@@ -28,16 +44,21 @@ export function createUserStore(db, now = Date.now) {
|
|
|
28
44
|
}
|
|
29
45
|
const id = newId();
|
|
30
46
|
const timestamp = new Date(now()).toISOString();
|
|
47
|
+
const status = input.status ?? 'active';
|
|
31
48
|
await db.query(sql `
|
|
32
49
|
insert into ${table} (id, email, roles, status, created_at, updated_at)
|
|
33
|
-
values (${id}, ${email}, ${JSON.stringify(input.roles)}, ${
|
|
50
|
+
values (${id}, ${email}, ${JSON.stringify(input.roles)}, ${status}, ${timestamp}, ${timestamp})`);
|
|
34
51
|
return {
|
|
35
52
|
id,
|
|
36
53
|
email,
|
|
37
54
|
roles: input.roles,
|
|
38
|
-
status
|
|
55
|
+
status,
|
|
39
56
|
createdAt: timestamp,
|
|
40
57
|
updatedAt: timestamp,
|
|
58
|
+
displayName: null,
|
|
59
|
+
avatarMediaId: null,
|
|
60
|
+
bio: null,
|
|
61
|
+
locale: null,
|
|
41
62
|
};
|
|
42
63
|
},
|
|
43
64
|
byEmail: async (email) => {
|
|
@@ -64,6 +85,54 @@ export function createUserStore(db, now = Date.now) {
|
|
|
64
85
|
const result = await db.query(sql `select * from ${table} order by created_at asc`);
|
|
65
86
|
return result.rows.map(fromRow);
|
|
66
87
|
},
|
|
88
|
+
updateProfile: async (id, input) => {
|
|
89
|
+
// Only the fields actually present in `input` are touched — `undefined`
|
|
90
|
+
// means "leave alone", `null` means "clear it". A caller that wants a
|
|
91
|
+
// partial update (change just the bio) must not have the other three
|
|
92
|
+
// silently wiped by a full-row overwrite.
|
|
93
|
+
const assignments = [];
|
|
94
|
+
if ('displayName' in input) {
|
|
95
|
+
assignments.push(sql `${identifier('display_name', db.dialect)} = ${input.displayName ?? null}`);
|
|
96
|
+
}
|
|
97
|
+
if ('avatarMediaId' in input) {
|
|
98
|
+
assignments.push(sql `${identifier('avatar_media_id', db.dialect)} = ${input.avatarMediaId ?? null}`);
|
|
99
|
+
}
|
|
100
|
+
if ('bio' in input) {
|
|
101
|
+
assignments.push(sql `${identifier('bio', db.dialect)} = ${input.bio ?? null}`);
|
|
102
|
+
}
|
|
103
|
+
if ('locale' in input) {
|
|
104
|
+
assignments.push(sql `${identifier('locale', db.dialect)} = ${input.locale ?? null}`);
|
|
105
|
+
}
|
|
106
|
+
if (assignments.length === 0)
|
|
107
|
+
return;
|
|
108
|
+
const set = assignments.reduce((left, right) => sql `${left}, ${right}`);
|
|
109
|
+
await db.query(sql `
|
|
110
|
+
update ${table} set ${set}, updated_at = ${new Date(now()).toISOString()}
|
|
111
|
+
where id = ${id}`);
|
|
112
|
+
},
|
|
113
|
+
delete: async (id) => {
|
|
114
|
+
await db.query(sql `delete from ${table} where id = ${id}`);
|
|
115
|
+
},
|
|
116
|
+
anonymize: async (id) => {
|
|
117
|
+
const timestamp = new Date(now()).toISOString();
|
|
118
|
+
const email = anonymizedEmail();
|
|
119
|
+
await db.query(sql `
|
|
120
|
+
update ${table}
|
|
121
|
+
set email = ${email}, status = ${'anonymized'},
|
|
122
|
+
display_name = ${null}, avatar_media_id = ${null}, bio = ${null}, locale = ${null},
|
|
123
|
+
updated_at = ${timestamp}
|
|
124
|
+
where id = ${id}`);
|
|
125
|
+
const result = await db.query(sql `select * from ${table} where id = ${id}`);
|
|
126
|
+
const row = result.rows[0];
|
|
127
|
+
if (row === undefined) {
|
|
128
|
+
throw new CogentaError({
|
|
129
|
+
code: 'AUTH_USER_NOT_FOUND',
|
|
130
|
+
message: 'No account with that id.',
|
|
131
|
+
hint: 'It may have been removed between the check and this call.',
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
return fromRow(row);
|
|
135
|
+
},
|
|
67
136
|
};
|
|
68
137
|
}
|
|
69
138
|
//# sourceMappingURL=users.js.map
|
package/dist/users.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"users.js","sourceRoot":"","sources":["../src/users.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"users.js","sourceRoot":"","sources":["../src/users.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cogenta/auth",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Identity, sessions and credentials: password, TOTP and WebAuthn, plus the append-only audit log.",
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@simplewebauthn/server": "^13.3.2",
|
|
31
|
-
"@cogenta/core": "0.
|
|
32
|
-
"@cogenta/schema": "0.
|
|
31
|
+
"@cogenta/core": "0.6.0",
|
|
32
|
+
"@cogenta/schema": "0.4.1"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"typescript": "^7.0.2",
|