@fuzdev/fuz_app 0.110.0 → 0.111.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/actions/action_rpc.d.ts +2 -2
- package/dist/auth/CLAUDE.md +24 -5
- package/dist/auth/account_action_specs.d.ts +0 -2
- package/dist/auth/account_action_specs.d.ts.map +1 -1
- package/dist/auth/account_queries.d.ts +22 -0
- package/dist/auth/account_queries.d.ts.map +1 -1
- package/dist/auth/account_queries.js +49 -15
- package/dist/auth/account_schema.d.ts +7 -9
- package/dist/auth/account_schema.d.ts.map +1 -1
- package/dist/auth/account_schema.js +1 -2
- package/dist/auth/admin_action_specs.d.ts +0 -2
- package/dist/auth/admin_action_specs.d.ts.map +1 -1
- package/dist/auth/api_token_queries.d.ts +9 -4
- package/dist/auth/api_token_queries.d.ts.map +1 -1
- package/dist/auth/api_token_queries.js +29 -7
- package/dist/auth/app_settings_queries.d.ts +8 -0
- package/dist/auth/app_settings_queries.d.ts.map +1 -1
- package/dist/auth/app_settings_queries.js +14 -3
- package/dist/auth/audit_log_queries.d.ts +15 -3
- package/dist/auth/audit_log_queries.d.ts.map +1 -1
- package/dist/auth/audit_log_queries.js +32 -7
- package/dist/auth/audit_log_schema.d.ts +0 -1
- package/dist/auth/audit_log_schema.d.ts.map +1 -1
- package/dist/auth/auth_ddl.d.ts +6 -0
- package/dist/auth/auth_ddl.d.ts.map +1 -1
- package/dist/auth/auth_ddl.js +9 -0
- package/dist/auth/invite_queries.d.ts +10 -0
- package/dist/auth/invite_queries.d.ts.map +1 -1
- package/dist/auth/invite_queries.js +25 -6
- package/dist/auth/migrations.d.ts.map +1 -1
- package/dist/auth/migrations.js +10 -0
- package/dist/auth/role_grant_offer_ddl.d.ts +23 -2
- package/dist/auth/role_grant_offer_ddl.d.ts.map +1 -1
- package/dist/auth/role_grant_offer_ddl.js +43 -2
- package/dist/auth/role_grant_offer_queries.d.ts.map +1 -1
- package/dist/auth/role_grant_offer_queries.js +29 -48
- package/dist/auth/role_grant_queries.d.ts +18 -0
- package/dist/auth/role_grant_queries.d.ts.map +1 -1
- package/dist/auth/role_grant_queries.js +43 -17
- package/dist/auth/session_queries.d.ts +12 -3
- package/dist/auth/session_queries.d.ts.map +1 -1
- package/dist/auth/session_queries.js +21 -6
- package/dist/db/CLAUDE.md +15 -0
- package/dist/db/cell_audit_queries.d.ts.map +1 -1
- package/dist/db/cell_audit_queries.js +3 -1
- package/dist/db/cell_field_queries.d.ts +11 -2
- package/dist/db/cell_field_queries.d.ts.map +1 -1
- package/dist/db/cell_field_queries.js +23 -7
- package/dist/db/cell_grant_queries.d.ts +9 -1
- package/dist/db/cell_grant_queries.d.ts.map +1 -1
- package/dist/db/cell_grant_queries.js +25 -9
- package/dist/db/cell_item_queries.d.ts +12 -1
- package/dist/db/cell_item_queries.d.ts.map +1 -1
- package/dist/db/cell_item_queries.js +25 -7
- package/dist/db/cell_queries.d.ts +29 -0
- package/dist/db/cell_queries.d.ts.map +1 -1
- package/dist/db/cell_queries.js +53 -20
- package/dist/db/fact_queries.d.ts +7 -0
- package/dist/db/fact_queries.d.ts.map +1 -1
- package/dist/db/fact_queries.js +19 -2
- package/dist/db/schema_ready.d.ts +6 -1
- package/dist/db/schema_ready.d.ts.map +1 -1
- package/dist/db/schema_ready.js +6 -2
- package/dist/db/sql_columns.d.ts +67 -0
- package/dist/db/sql_columns.d.ts.map +1 -0
- package/dist/db/sql_columns.js +77 -0
- package/dist/db/sql_identifier.d.ts +6 -5
- package/dist/db/sql_identifier.d.ts.map +1 -1
- package/dist/db/sql_identifier.js +6 -5
- package/dist/http/CLAUDE.md +1 -1
- package/dist/http/route_spec.d.ts +2 -2
- package/dist/server/app_server.d.ts.map +1 -1
- package/dist/server/app_server.js +1 -2
- package/dist/testing/CLAUDE.md +2 -1
- package/dist/testing/admin_integration.d.ts.map +1 -1
- package/dist/testing/admin_integration.js +47 -18
- package/dist/testing/cross_backend/expected_schema.json +1 -1
- package/dist/testing/db.d.ts +18 -0
- package/dist/testing/db.d.ts.map +1 -1
- package/dist/testing/db.js +24 -1
- package/dist/ui/AdminOverview.svelte +5 -10
- package/dist/ui/AdminOverview.svelte.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -61,8 +61,8 @@ export interface ActionContext {
|
|
|
61
61
|
db: Db;
|
|
62
62
|
/**
|
|
63
63
|
* Eager fire-and-forget queue — push the in-flight `Promise<void>` for
|
|
64
|
-
* pool writes already running (audit emits,
|
|
65
|
-
*
|
|
64
|
+
* pool writes already running (audit emits, api-token usage
|
|
65
|
+
* tracking). Drained via `flush_pending_effects` after the
|
|
66
66
|
* handler returns.
|
|
67
67
|
*/
|
|
68
68
|
pending_effects: Array<Promise<void>>;
|
package/dist/auth/CLAUDE.md
CHANGED
|
@@ -69,7 +69,7 @@ Convention — `*_schema.ts` is Zod-only; `*_ddl.ts` holds DDL strings.
|
|
|
69
69
|
- `auth/invite_schema.ts` — `Invite`, `CreateInviteInput`.
|
|
70
70
|
- `auth/app_settings_schema.ts` — `AppSettings`, `UpdateAppSettingsInput` (single-row via `CHECK (id = 1)`).
|
|
71
71
|
- `auth/role_grant_offer_schema.ts` — `RoleGrantOffer`, `RoleGrantOfferJson`, `to_role_grant_offer_json`, scope-sentinel constants.
|
|
72
|
-
- `auth/role_grant_offer_ddl.ts` — `role_grant_offer` table + indexes + `ROLE_GRANT_OFFER_SCOPE_SENTINEL_UUID` / `_GLOBAL_TOKEN
|
|
72
|
+
- `auth/role_grant_offer_ddl.ts` — `role_grant_offer` table + indexes + `ROLE_GRANT_OFFER_SCOPE_SENTINEL_UUID` / `_GLOBAL_TOKEN` + `ROLE_GRANT_OFFER_COLUMNS` and the shared `ROLE_GRANT_OFFER_WITH_GRANTOR_SELECT` CTE tail (homed here per the placement rule in `db/sql_columns.ts`).
|
|
73
73
|
- `auth/role_grant_offer_notifications.ts` — six WS notification specs for the consentful-grant lifecycle.
|
|
74
74
|
|
|
75
75
|
### Queries
|
|
@@ -81,12 +81,30 @@ All take `deps: QueryDeps = {db}` first; `query_validate_api_token` adds `log`.
|
|
|
81
81
|
- `auth/actor_search_queries.ts` — case-insensitive prefix search on `actor.name`, scope-filtered when not admin.
|
|
82
82
|
- `auth/role_grant_queries.ts` — idempotent create, IDOR-guarded revoke (with in-tx supersede), scope-aware lookup, role/account predicates, `query_role_grant_revoke_for_scope` parent-scope cascade.
|
|
83
83
|
- `auth/role_grant_offer_queries.ts` — offer create/decline/retract/list/history/sweep, atomic `query_accept_offer` with sibling supersede; error classes `RoleGrantOfferSelfTargetError` / `_AlreadyTerminalError` / `_ExpiredError` / `_NotFoundError` / `_ActorAccountMismatchError` / `_ActorMismatchError`.
|
|
84
|
-
- `auth/session_queries.ts` — server-side sessions (blake3-hashed), `query_session_revoke_by_hash_unscoped` (logout only), `query_session_enforce_limit` (transaction-required). No touch/renewal query — `expires_at` is an absolute cap set at mint (`AUTH_SESSION_LIFETIME_MS`)
|
|
84
|
+
- `auth/session_queries.ts` — server-side sessions (blake3-hashed), `query_session_revoke_by_hash_unscoped` (logout only), `query_session_enforce_limit` (transaction-required). No touch/renewal query — `expires_at` is an absolute cap set at mint (`AUTH_SESSION_LIFETIME_MS`).
|
|
85
85
|
- `auth/api_token_queries.ts` — token validation with fire-and-forget usage tracking, IDOR-guarded revoke, `query_api_token_enforce_limit` (transaction-required).
|
|
86
86
|
- `auth/invite_queries.ts` — invite create/find/claim/list/delete; `query_invite_claim_unscoped` (scoping enforced upstream by `_find_unclaimed_match_for_update`, which runs inside the signup tx with `FOR UPDATE` so find + claim are atomic).
|
|
87
87
|
- `auth/app_settings_queries.ts` — load/update for the single-row settings table.
|
|
88
88
|
- `auth/audit_log_queries.ts` — `query_audit_log` (in-tx insert), `_list` / `_list_with_usernames` / `_list_role_grant_history` / `_cleanup_before`, drift counters (`get_audit_metadata_validation_failures` / `get_audit_unknown_event_type_failures`).
|
|
89
89
|
|
|
90
|
+
**Named projections** (rationale + helpers: ../../../docs/architecture.md
|
|
91
|
+
§Query Modules). The consts on this side: `ACCOUNT_COLUMNS` + `ACTOR_COLUMNS`
|
|
92
|
+
(`account_queries.ts` owns both tables; its admin listing derives an
|
|
93
|
+
active-grant subset from `ROLE_GRANT_COLUMNS`), `AUTH_SESSION_COLUMNS`,
|
|
94
|
+
`INVITE_COLUMNS`, `AUDIT_LOG_COLUMNS` (shared with `db/cell_audit_queries.ts`),
|
|
95
|
+
`API_TOKEN_COLUMNS` (the client listing derives `minus token_hash`),
|
|
96
|
+
`ROLE_GRANT_COLUMNS`, `ROLE_GRANT_OFFER_COLUMNS` (in `role_grant_offer_ddl.ts`),
|
|
97
|
+
`APP_SETTINGS_COLUMNS` (reads omit the constant singleton `id`; the one const
|
|
98
|
+
without a `satisfies keyof Row` clause, since `AppSettings` deliberately
|
|
99
|
+
doesn't carry `id`). Module direction: `role_grant_offer_queries.ts` imports
|
|
100
|
+
`role_grant_queries.ts` (the accept path writes through
|
|
101
|
+
`query_create_role_grant` / `query_role_grant_by_id`) and not the reverse —
|
|
102
|
+
the revoke cascades in `role_grant_queries.ts` still _write_ offer rows, which
|
|
103
|
+
is exactly why the offer const and the shared CTE tail live in the DDL module.
|
|
104
|
+
Every const is pinned to the live schema by
|
|
105
|
+
`src/test/db/column_projections.db.test.ts`. Mirrors the Rust spine, which
|
|
106
|
+
names columns at every site.
|
|
107
|
+
|
|
90
108
|
`_unscoped` suffix on `query_session_revoke_by_hash_unscoped` and
|
|
91
109
|
`query_invite_claim_unscoped` is the safety signal: SQL only checks row state,
|
|
92
110
|
caller is responsible for scoping. Production scoping for invites is enforced
|
|
@@ -414,9 +432,10 @@ in the HTTP RPC dispatcher (`actions/action_rpc.ts`), the WS dispatcher
|
|
|
414
432
|
|
|
415
433
|
### Migrations
|
|
416
434
|
|
|
417
|
-
Schema migrations live in `auth/migrations.ts` —
|
|
418
|
-
`
|
|
419
|
-
`AUTH_MIGRATION_NAMESPACE = 'fuz_auth'
|
|
435
|
+
Schema migrations live in `auth/migrations.ts` — a frozen, append-only chain
|
|
436
|
+
(`full_auth_schema` first, every later change its own appended entry) under
|
|
437
|
+
the single reserved namespace `AUTH_MIGRATION_NAMESPACE = 'fuz_auth'`, each
|
|
438
|
+
entry twinned byte-for-byte by name on the Rust spine. Consumer namespaces must avoid
|
|
420
439
|
`reserved_migration_namespaces`. Runner contract, error vocabulary, and
|
|
421
440
|
operator recipes (rename, mark applied, reset, baseline) are in
|
|
422
441
|
../../../docs/migrations.md.
|
|
@@ -22,7 +22,6 @@ export declare const SessionListOutput: z.ZodObject<{
|
|
|
22
22
|
account_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
|
|
23
23
|
created_at: z.ZodString;
|
|
24
24
|
expires_at: z.ZodString;
|
|
25
|
-
last_seen_at: z.ZodString;
|
|
26
25
|
}, z.core.$strict>>;
|
|
27
26
|
}, z.core.$strict>;
|
|
28
27
|
export type SessionListOutput = z.infer<typeof SessionListOutput>;
|
|
@@ -149,7 +148,6 @@ export declare const account_session_list_action_spec: {
|
|
|
149
148
|
account_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
|
|
150
149
|
created_at: z.ZodString;
|
|
151
150
|
expires_at: z.ZodString;
|
|
152
|
-
last_seen_at: z.ZodString;
|
|
153
151
|
}, z.core.$strict>>;
|
|
154
152
|
}, z.core.$strict>;
|
|
155
153
|
async: true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account_action_specs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/account_action_specs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAW3E,6EAA6E;AAC7E,eAAO,MAAM,WAAW,WAAW,CAAC;AACpC,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD,uDAAuD;AACvD,eAAO,MAAM,gBAAgB,WAAW,CAAC;AACzC,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE,yCAAyC;AACzC,eAAO,MAAM,iBAAiB
|
|
1
|
+
{"version":3,"file":"account_action_specs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/account_action_specs.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,28 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import type { QueryDeps } from '../db/query_deps.js';
|
|
10
10
|
import { type Account, type Actor, type CreateAccountInput, type AdminAccountEntryJson } from './account_schema.js';
|
|
11
|
+
/**
|
|
12
|
+
* The full `account` column set, named explicitly so a row read fails loud
|
|
13
|
+
* on schema drift.
|
|
14
|
+
*
|
|
15
|
+
* `SELECT *` silently omits a dropped column, which the login lookups then
|
|
16
|
+
* misread: `query_account_by_username_or_email` filters its result with
|
|
17
|
+
* `account.deleted_at === null`, so a missing `deleted_at` column reads back
|
|
18
|
+
* as `undefined`, `undefined === null` is `false`, and *every* login resolves
|
|
19
|
+
* to "not found" (401) — a silent, total auth outage instead of an error.
|
|
20
|
+
* Selecting named columns turns that drift into a hard Postgres
|
|
21
|
+
* `column "..." does not exist`. Mirrors the Rust side
|
|
22
|
+
* (`fuz_auth/src/account_queries.rs`), which selects named columns and
|
|
23
|
+
* decodes them positionally. Keep in sync with `Account` and the `account`
|
|
24
|
+
* DDL in `auth/auth_ddl.ts`.
|
|
25
|
+
*/
|
|
26
|
+
export declare const ACCOUNT_COLUMNS: readonly ["id", "username", "email", "email_verified", "password_hash", "created_at", "created_by", "updated_at", "updated_by", "deleted_at", "deleted_by"];
|
|
27
|
+
/**
|
|
28
|
+
* The full `actor` column set — the same fail-loud discipline as
|
|
29
|
+
* `ACCOUNT_COLUMNS` (this module owns both tables). Keep in sync with
|
|
30
|
+
* `Actor` and the `actor` DDL in `auth/auth_ddl.ts`.
|
|
31
|
+
*/
|
|
32
|
+
export declare const ACTOR_COLUMNS: readonly ["id", "account_id", "name", "created_at", "updated_at", "updated_by", "deleted_at", "deleted_by"];
|
|
11
33
|
/**
|
|
12
34
|
* Create a new account.
|
|
13
35
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/account_queries.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"account_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/account_queries.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,8 +7,10 @@
|
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
9
9
|
import { assert_row } from '../db/assert_row.js';
|
|
10
|
+
import { columns_sql, omit_columns } from '../db/sql_columns.js';
|
|
10
11
|
import { to_admin_account } from './account_schema.js';
|
|
11
12
|
import { ADMIN_ACCOUNT_LIST_DEFAULT_LIMIT } from './admin_action_specs.js';
|
|
13
|
+
import { ROLE_GRANT_COLUMNS } from './role_grant_queries.js';
|
|
12
14
|
/**
|
|
13
15
|
* The full `account` column set, named explicitly so a row read fails loud
|
|
14
16
|
* on schema drift.
|
|
@@ -24,7 +26,34 @@ import { ADMIN_ACCOUNT_LIST_DEFAULT_LIMIT } from './admin_action_specs.js';
|
|
|
24
26
|
* decodes them positionally. Keep in sync with `Account` and the `account`
|
|
25
27
|
* DDL in `auth/auth_ddl.ts`.
|
|
26
28
|
*/
|
|
27
|
-
const ACCOUNT_COLUMNS =
|
|
29
|
+
export const ACCOUNT_COLUMNS = [
|
|
30
|
+
'id',
|
|
31
|
+
'username',
|
|
32
|
+
'email',
|
|
33
|
+
'email_verified',
|
|
34
|
+
'password_hash',
|
|
35
|
+
'created_at',
|
|
36
|
+
'created_by',
|
|
37
|
+
'updated_at',
|
|
38
|
+
'updated_by',
|
|
39
|
+
'deleted_at',
|
|
40
|
+
'deleted_by'
|
|
41
|
+
];
|
|
42
|
+
/**
|
|
43
|
+
* The full `actor` column set — the same fail-loud discipline as
|
|
44
|
+
* `ACCOUNT_COLUMNS` (this module owns both tables). Keep in sync with
|
|
45
|
+
* `Actor` and the `actor` DDL in `auth/auth_ddl.ts`.
|
|
46
|
+
*/
|
|
47
|
+
export const ACTOR_COLUMNS = [
|
|
48
|
+
'id',
|
|
49
|
+
'account_id',
|
|
50
|
+
'name',
|
|
51
|
+
'created_at',
|
|
52
|
+
'updated_at',
|
|
53
|
+
'updated_by',
|
|
54
|
+
'deleted_at',
|
|
55
|
+
'deleted_by'
|
|
56
|
+
];
|
|
28
57
|
/**
|
|
29
58
|
* Create a new account.
|
|
30
59
|
*
|
|
@@ -36,7 +65,7 @@ const ACCOUNT_COLUMNS = 'id, username, email, email_verified, password_hash, cre
|
|
|
36
65
|
export const query_create_account = async (deps, input) => {
|
|
37
66
|
const row = await deps.db.query_one(`INSERT INTO account (username, password_hash, email)
|
|
38
67
|
VALUES ($1, $2, $3)
|
|
39
|
-
RETURNING
|
|
68
|
+
RETURNING ${columns_sql(ACCOUNT_COLUMNS)}`, [input.username, input.password_hash, input.email ?? null]);
|
|
40
69
|
return assert_row(row, 'INSERT INTO account');
|
|
41
70
|
};
|
|
42
71
|
/**
|
|
@@ -49,19 +78,19 @@ export const query_create_account = async (deps, input) => {
|
|
|
49
78
|
* soft-deleted rows too, uses `query_purge_account` directly.
|
|
50
79
|
*/
|
|
51
80
|
export const query_account_by_id = async (deps, id) => {
|
|
52
|
-
return deps.db.query_one(`SELECT ${ACCOUNT_COLUMNS} FROM account WHERE id = $1 AND deleted_at IS NULL`, [id]);
|
|
81
|
+
return deps.db.query_one(`SELECT ${columns_sql(ACCOUNT_COLUMNS)} FROM account WHERE id = $1 AND deleted_at IS NULL`, [id]);
|
|
53
82
|
};
|
|
54
83
|
/**
|
|
55
84
|
* Find an account by username (case-insensitive).
|
|
56
85
|
*/
|
|
57
86
|
export const query_account_by_username = async (deps, username) => {
|
|
58
|
-
return deps.db.query_one(`SELECT ${ACCOUNT_COLUMNS} FROM account WHERE LOWER(username) = LOWER($1)`, [username]);
|
|
87
|
+
return deps.db.query_one(`SELECT ${columns_sql(ACCOUNT_COLUMNS)} FROM account WHERE LOWER(username) = LOWER($1)`, [username]);
|
|
59
88
|
};
|
|
60
89
|
/**
|
|
61
90
|
* Find an account by email (case-insensitive).
|
|
62
91
|
*/
|
|
63
92
|
export const query_account_by_email = async (deps, email) => {
|
|
64
|
-
return deps.db.query_one(`SELECT ${ACCOUNT_COLUMNS} FROM account WHERE LOWER(email) = LOWER($1)`, [email]);
|
|
93
|
+
return deps.db.query_one(`SELECT ${columns_sql(ACCOUNT_COLUMNS)} FROM account WHERE LOWER(email) = LOWER($1)`, [email]);
|
|
65
94
|
};
|
|
66
95
|
/**
|
|
67
96
|
* Find an account by username or email.
|
|
@@ -214,7 +243,7 @@ export const query_account_has_any = async (deps) => {
|
|
|
214
243
|
* @mutates `actor` table - inserts the new row
|
|
215
244
|
*/
|
|
216
245
|
export const query_create_actor = async (deps, account_id, name) => {
|
|
217
|
-
const row = await deps.db.query_one(`INSERT INTO actor (account_id, name) VALUES ($1, $2) RETURNING
|
|
246
|
+
const row = await deps.db.query_one(`INSERT INTO actor (account_id, name) VALUES ($1, $2) RETURNING ${columns_sql(ACTOR_COLUMNS)}`, [account_id, name]);
|
|
218
247
|
return assert_row(row, 'INSERT INTO actor');
|
|
219
248
|
};
|
|
220
249
|
/**
|
|
@@ -229,7 +258,7 @@ export const query_create_actor = async (deps, account_id, name) => {
|
|
|
229
258
|
* `query_actor_by_id` instead.
|
|
230
259
|
*/
|
|
231
260
|
export const query_actors_by_account = async (deps, account_id) => {
|
|
232
|
-
return deps.db.query(`SELECT
|
|
261
|
+
return deps.db.query(`SELECT ${columns_sql(ACTOR_COLUMNS)} FROM actor WHERE account_id = $1 ORDER BY created_at ASC, id ASC`, [account_id]);
|
|
233
262
|
};
|
|
234
263
|
/**
|
|
235
264
|
* List **active** (non-tombstoned) actors on an account, ordered by
|
|
@@ -243,13 +272,15 @@ export const query_actors_by_account = async (deps, account_id) => {
|
|
|
243
272
|
* tombstoned rows stay on the unfiltered `query_actors_by_account`.
|
|
244
273
|
*/
|
|
245
274
|
export const query_active_actors_by_account = async (deps, account_id) => {
|
|
246
|
-
return deps.db.query(`SELECT
|
|
275
|
+
return deps.db.query(`SELECT ${columns_sql(ACTOR_COLUMNS)} FROM actor WHERE account_id = $1 AND deleted_at IS NULL ORDER BY created_at ASC, id ASC`, [account_id]);
|
|
247
276
|
};
|
|
248
277
|
/**
|
|
249
278
|
* Find an actor by id.
|
|
250
279
|
*/
|
|
251
280
|
export const query_actor_by_id = async (deps, id) => {
|
|
252
|
-
return deps.db.query_one(`SELECT
|
|
281
|
+
return deps.db.query_one(`SELECT ${columns_sql(ACTOR_COLUMNS)} FROM actor WHERE id = $1`, [
|
|
282
|
+
id
|
|
283
|
+
]);
|
|
253
284
|
};
|
|
254
285
|
/**
|
|
255
286
|
* Create an account and its actor in a single operation.
|
|
@@ -266,6 +297,11 @@ export const query_create_account_with_actor = async (deps, input) => {
|
|
|
266
297
|
const actor = await query_create_actor(deps, account.id, input.username);
|
|
267
298
|
return { account, actor };
|
|
268
299
|
};
|
|
300
|
+
/**
|
|
301
|
+
* `ROLE_GRANT_COLUMNS` minus the revocation + provenance columns — the
|
|
302
|
+
* active-grant summary the admin listing projects (`RoleGrantWithActorId`).
|
|
303
|
+
*/
|
|
304
|
+
const ADMIN_ROLE_GRANT_COLUMNS = omit_columns(ROLE_GRANT_COLUMNS, 'revoked_at', 'revoked_by', 'revoked_reason', 'source_offer_id');
|
|
269
305
|
/**
|
|
270
306
|
* List accounts with their actors, active role_grants, and pending inbound
|
|
271
307
|
* role_grant offers for admin display.
|
|
@@ -291,17 +327,15 @@ export const query_admin_account_list = async (deps, options) => {
|
|
|
291
327
|
// `include_deleted` to surface tombstoned rows for reactivation.
|
|
292
328
|
const where = options?.include_deleted ? '' : 'WHERE deleted_at IS NULL';
|
|
293
329
|
const account_query = limit == null
|
|
294
|
-
? deps.db.query(`SELECT
|
|
295
|
-
|
|
296
|
-
])
|
|
297
|
-
: deps.db.query(`SELECT * FROM account ${where} ORDER BY created_at LIMIT $1 OFFSET $2`, [limit, offset]);
|
|
330
|
+
? deps.db.query(`SELECT ${columns_sql(ACCOUNT_COLUMNS)} FROM account ${where} ORDER BY created_at OFFSET $1`, [offset])
|
|
331
|
+
: deps.db.query(`SELECT ${columns_sql(ACCOUNT_COLUMNS)} FROM account ${where} ORDER BY created_at LIMIT $1 OFFSET $2`, [limit, offset]);
|
|
298
332
|
const accounts = await account_query;
|
|
299
333
|
if (accounts.length === 0)
|
|
300
334
|
return [];
|
|
301
335
|
const account_ids = accounts.map((a) => a.id);
|
|
302
336
|
const [actors, role_grants, pending_offers] = await Promise.all([
|
|
303
|
-
deps.db.query(`SELECT
|
|
304
|
-
deps.db.query(`SELECT
|
|
337
|
+
deps.db.query(`SELECT ${columns_sql(ACTOR_COLUMNS)} FROM actor WHERE account_id = ANY($1::uuid[])`, [account_ids]),
|
|
338
|
+
deps.db.query(`SELECT ${columns_sql(ADMIN_ROLE_GRANT_COLUMNS)}
|
|
305
339
|
FROM role_grant
|
|
306
340
|
WHERE actor_id IN (SELECT id FROM actor WHERE account_id = ANY($1::uuid[]))
|
|
307
341
|
AND revoked_at IS NULL
|
|
@@ -112,14 +112,13 @@ export declare const is_role_grant_active: (p: {
|
|
|
112
112
|
*/
|
|
113
113
|
export declare const SessionId: z.core.$ZodBranded<z.ZodString, "SessionId", "out">;
|
|
114
114
|
export type SessionId = z.infer<typeof SessionId>;
|
|
115
|
-
/**
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
115
|
+
/**
|
|
116
|
+
* Server-side auth session row, keyed by blake3 hash of the session token.
|
|
117
|
+
* Structurally identical to the wire shape `AuthSessionJson` — kept as the
|
|
118
|
+
* DB-row name so query signatures keep saying which side of the boundary
|
|
119
|
+
* they read.
|
|
120
|
+
*/
|
|
121
|
+
export type AuthSession = AuthSessionJson;
|
|
123
122
|
/** API token for CLI/programmatic access. */
|
|
124
123
|
export interface ApiToken {
|
|
125
124
|
id: string;
|
|
@@ -152,7 +151,6 @@ export declare const AuthSessionJson: z.ZodObject<{
|
|
|
152
151
|
account_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
|
|
153
152
|
created_at: z.ZodString;
|
|
154
153
|
expires_at: z.ZodString;
|
|
155
|
-
last_seen_at: z.ZodString;
|
|
156
154
|
}, z.core.$strict>;
|
|
157
155
|
export type AuthSessionJson = z.infer<typeof AuthSessionJson>;
|
|
158
156
|
/** Zod schema for client-safe API token listing (excludes `token_hash`). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account_schema.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/account_schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAG9C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAI1D,mEAAmE;AACnE,MAAM,WAAW,OAAO;IACvB,EAAE,EAAE,IAAI,CAAC;IACT,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB;;;;OAIG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;;;OAKG;IACH,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;CACxB;AAED,wFAAwF;AACxF,MAAM,WAAW,cAAc;IAC9B,EAAE,EAAE,IAAI,CAAC;IACT,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,4FAA4F;AAC5F,MAAM,WAAW,KAAK;IACrB,EAAE,EAAE,IAAI,CAAC;IACT,UAAU,EAAE,IAAI,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,8EAA8E;IAC9E,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,sEAAsE;IACtE,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;CACxB;AAED;;;;;GAKG;AACH,eAAO,MAAM,oCAAoC,MAAM,CAAC;AAExD,wEAAwE;AACxE,MAAM,WAAW,SAAS;IACzB,EAAE,EAAE,IAAI,CAAC;IACT,QAAQ,EAAE,IAAI,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;OAMG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iGAAiG;IACjG,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,sHAAsH;IACtH,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,mGAAmG;IACnG,eAAe,EAAE,IAAI,GAAG,IAAI,CAAC;CAC7B;AAED,eAAO,MAAM,oBAAoB,GAChC,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EAC5D,MAAK,IAAiB,KACpB,OAA2E,CAAC;AAE/E;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,qDAAgC,CAAC;AACvD,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AAElD
|
|
1
|
+
{"version":3,"file":"account_schema.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/account_schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -52,8 +52,7 @@ export const AuthSessionJson = z.strictObject({
|
|
|
52
52
|
id: SessionId,
|
|
53
53
|
account_id: Uuid,
|
|
54
54
|
created_at: z.string(),
|
|
55
|
-
expires_at: z.string()
|
|
56
|
-
last_seen_at: z.string()
|
|
55
|
+
expires_at: z.string()
|
|
57
56
|
});
|
|
58
57
|
/** Zod schema for client-safe API token listing (excludes `token_hash`). */
|
|
59
58
|
export const ClientApiTokenJson = z.strictObject({
|
|
@@ -83,7 +83,6 @@ export declare const AdminSessionListOutput: z.ZodObject<{
|
|
|
83
83
|
account_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
|
|
84
84
|
created_at: z.ZodString;
|
|
85
85
|
expires_at: z.ZodString;
|
|
86
|
-
last_seen_at: z.ZodString;
|
|
87
86
|
username: z.ZodString;
|
|
88
87
|
}, z.core.$strict>>;
|
|
89
88
|
}, z.core.$strict>;
|
|
@@ -429,7 +428,6 @@ export declare const admin_session_list_action_spec: {
|
|
|
429
428
|
account_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
|
|
430
429
|
created_at: z.ZodString;
|
|
431
430
|
expires_at: z.ZodString;
|
|
432
|
-
last_seen_at: z.ZodString;
|
|
433
431
|
username: z.ZodString;
|
|
434
432
|
}, z.core.$strict>>;
|
|
435
433
|
}, z.core.$strict>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin_action_specs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/admin_action_specs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAiB3E,+BAA+B;AAC/B,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAE5C,8CAA8C;AAC9C,eAAO,MAAM,gCAAgC,KAAK,CAAC;AACnD,0CAA0C;AAC1C,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAIhD,sCAAsC;AACtC,eAAO,MAAM,qBAAqB;;;;;mBAoBrB,CAAC;AACd,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE1E,uCAAuC;AACvC,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAGjC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE5E,sCAAsC;AACtC,eAAO,MAAM,qBAAqB;;mBAIrB,CAAC;AACd,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE1E,mGAAmG;AACnG,eAAO,MAAM,sBAAsB
|
|
1
|
+
{"version":3,"file":"admin_action_specs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/admin_action_specs.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,13 @@ import { type TokenScope } from './token_scope.js';
|
|
|
11
11
|
export interface ApiTokenQueryDeps extends QueryDeps {
|
|
12
12
|
log: Logger;
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* The full `api_token` column set, named explicitly so a row read fails loud
|
|
16
|
+
* on schema drift (see `ACCOUNT_COLUMNS` in `auth/account_queries.ts` for the
|
|
17
|
+
* outage class; the Rust twin names columns at every token site). Keep in
|
|
18
|
+
* sync with `ApiToken` and the migration chain's end state.
|
|
19
|
+
*/
|
|
20
|
+
export declare const API_TOKEN_COLUMNS: readonly ["id", "account_id", "name", "token_hash", "expires_at", "last_used_at", "last_used_ip", "created_at", "scope"];
|
|
14
21
|
/**
|
|
15
22
|
* Store a new API token (the hash, not the raw token).
|
|
16
23
|
*
|
|
@@ -62,10 +69,8 @@ export declare const query_revoke_all_api_tokens_for_account: (deps: QueryDeps,
|
|
|
62
69
|
*/
|
|
63
70
|
export declare const query_revoke_api_token_for_account: (deps: QueryDeps, id: string, account_id: string) => Promise<boolean>;
|
|
64
71
|
/**
|
|
65
|
-
* List all tokens for an account
|
|
66
|
-
*
|
|
67
|
-
* Columns are enumerated explicitly to exclude `token_hash`.
|
|
68
|
-
* Must be updated if the `api_token` table gains new columns.
|
|
72
|
+
* List all tokens for an account, newest first — `API_TOKEN_CLIENT_COLUMNS`,
|
|
73
|
+
* so `token_hash` never rides the listing.
|
|
69
74
|
*/
|
|
70
75
|
export declare const query_api_token_list_for_account: (deps: QueryDeps, account_id: string) => Promise<Array<Omit<ApiToken, "token_hash">>>;
|
|
71
76
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api_token_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/api_token_queries.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"api_token_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/api_token_queries.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,KAAK,UAAU,EAAmD,MAAM,kBAAkB,CAAC;AAEpG,yEAAyE;AACzE,MAAM,WAAW,iBAAkB,SAAQ,SAAS;IACnD,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,0HAUoB,CAAC;AASnD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,SAAS,EACf,IAAI,MAAM,EACV,YAAY,MAAM,EAClB,MAAM,MAAM,EACZ,YAAY,MAAM,EAClB,OAAO,UAAU,EACjB,aAAa,IAAI,GAAG,IAAI,KACtB,OAAO,CAAC,QAAQ,CAelB,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,wBAAwB,GACpC,MAAM,iBAAiB,EACvB,WAAW,MAAM,EACjB,IAAI,MAAM,GAAG,SAAS,EACtB,iBAAiB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,KAC/C,OAAO,CAAC,QAAQ,GAAG,SAAS,CAgC9B,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,uCAAuC,GACnD,MAAM,SAAS,EACf,YAAY,MAAM,KAChB,OAAO,CAAC,MAAM,CAMhB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kCAAkC,GAC9C,MAAM,SAAS,EACf,IAAI,MAAM,EACV,YAAY,MAAM,KAChB,OAAO,CAAC,OAAO,CAMjB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gCAAgC,GAC5C,MAAM,SAAS,EACf,YAAY,MAAM,KAChB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAM7C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,6BAA6B,GACzC,MAAM,SAAS,EACf,YAAY,MAAM,EAClB,YAAY,MAAM,KAChB,OAAO,CAAC,MAAM,CAYhB,CAAC"}
|
|
@@ -4,8 +4,32 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
import { assert_row } from '../db/assert_row.js';
|
|
7
|
+
import { columns_sql, omit_columns } from '../db/sql_columns.js';
|
|
7
8
|
import { hash_api_token } from './api_token.js';
|
|
8
9
|
import { parse_stored_token_scope, serialize_token_scope } from './token_scope.js';
|
|
10
|
+
/**
|
|
11
|
+
* The full `api_token` column set, named explicitly so a row read fails loud
|
|
12
|
+
* on schema drift (see `ACCOUNT_COLUMNS` in `auth/account_queries.ts` for the
|
|
13
|
+
* outage class; the Rust twin names columns at every token site). Keep in
|
|
14
|
+
* sync with `ApiToken` and the migration chain's end state.
|
|
15
|
+
*/
|
|
16
|
+
export const API_TOKEN_COLUMNS = [
|
|
17
|
+
'id',
|
|
18
|
+
'account_id',
|
|
19
|
+
'name',
|
|
20
|
+
'token_hash',
|
|
21
|
+
'expires_at',
|
|
22
|
+
'last_used_at',
|
|
23
|
+
'last_used_ip',
|
|
24
|
+
'created_at',
|
|
25
|
+
'scope'
|
|
26
|
+
];
|
|
27
|
+
/**
|
|
28
|
+
* `API_TOKEN_COLUMNS` minus `token_hash` — the client-safe listing
|
|
29
|
+
* projection, derived so a new column can't land on the wire un-reviewed
|
|
30
|
+
* while the hash stays off it by construction.
|
|
31
|
+
*/
|
|
32
|
+
const API_TOKEN_CLIENT_COLUMNS = omit_columns(API_TOKEN_COLUMNS, 'token_hash');
|
|
9
33
|
/**
|
|
10
34
|
* Store a new API token (the hash, not the raw token).
|
|
11
35
|
*
|
|
@@ -21,7 +45,7 @@ import { parse_stored_token_scope, serialize_token_scope } from './token_scope.j
|
|
|
21
45
|
export const query_create_api_token = async (deps, id, account_id, name, token_hash, scope, expires_at) => {
|
|
22
46
|
const row = await deps.db.query_one(`INSERT INTO api_token (id, account_id, name, token_hash, scope, expires_at)
|
|
23
47
|
VALUES ($1, $2, $3, $4, $5::jsonb, $6)
|
|
24
|
-
RETURNING
|
|
48
|
+
RETURNING ${columns_sql(API_TOKEN_COLUMNS)}`, [
|
|
25
49
|
id,
|
|
26
50
|
account_id,
|
|
27
51
|
name,
|
|
@@ -48,7 +72,7 @@ export const query_create_api_token = async (deps, id, account_id, name, token_h
|
|
|
48
72
|
*/
|
|
49
73
|
export const query_validate_api_token = async (deps, raw_token, ip, pending_effects) => {
|
|
50
74
|
const token_hash = hash_api_token(raw_token);
|
|
51
|
-
const row = await deps.db.query_one(`SELECT
|
|
75
|
+
const row = await deps.db.query_one(`SELECT ${columns_sql(API_TOKEN_COLUMNS)} FROM api_token
|
|
52
76
|
WHERE token_hash = $1
|
|
53
77
|
AND (expires_at IS NULL OR expires_at > NOW())`, [token_hash]);
|
|
54
78
|
if (!row)
|
|
@@ -102,13 +126,11 @@ export const query_revoke_api_token_for_account = async (deps, id, account_id) =
|
|
|
102
126
|
return rows.length > 0;
|
|
103
127
|
};
|
|
104
128
|
/**
|
|
105
|
-
* List all tokens for an account
|
|
106
|
-
*
|
|
107
|
-
* Columns are enumerated explicitly to exclude `token_hash`.
|
|
108
|
-
* Must be updated if the `api_token` table gains new columns.
|
|
129
|
+
* List all tokens for an account, newest first — `API_TOKEN_CLIENT_COLUMNS`,
|
|
130
|
+
* so `token_hash` never rides the listing.
|
|
109
131
|
*/
|
|
110
132
|
export const query_api_token_list_for_account = async (deps, account_id) => {
|
|
111
|
-
return deps.db.query(`SELECT
|
|
133
|
+
return deps.db.query(`SELECT ${columns_sql(API_TOKEN_CLIENT_COLUMNS)}
|
|
112
134
|
FROM api_token WHERE account_id = $1 ORDER BY created_at DESC`, [account_id]);
|
|
113
135
|
};
|
|
114
136
|
/**
|
|
@@ -7,6 +7,14 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { QueryDeps } from '../db/query_deps.js';
|
|
9
9
|
import type { AppSettings, AppSettingsWithUsernameJson } from './app_settings_schema.js';
|
|
10
|
+
/**
|
|
11
|
+
* The full `app_settings` column set — the singleton `id` (always `1`) plus
|
|
12
|
+
* the settings the row type carries — drift-guarded like every other
|
|
13
|
+
* `*_COLUMNS`. Reads project `APP_SETTINGS_ROW_COLUMNS`, which omits the
|
|
14
|
+
* constant `id` since `AppSettings` doesn't carry it. Keep in sync with
|
|
15
|
+
* `AppSettings` and the `app_settings` DDL in `auth/auth_ddl.ts`.
|
|
16
|
+
*/
|
|
17
|
+
export declare const APP_SETTINGS_COLUMNS: readonly ["id", "open_signup", "updated_at", "updated_by"];
|
|
10
18
|
/**
|
|
11
19
|
* Load the current app settings.
|
|
12
20
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app_settings_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/app_settings_queries.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"app_settings_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/app_settings_queries.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,KAAK,EAAE,WAAW,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAEzF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,4DAA6D,CAAC;AAK/F;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,GAAU,MAAM,SAAS,KAAG,OAAO,CAAC,WAAW,CAQlF,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,qCAAqC,GACjD,MAAM,SAAS,KACb,OAAO,CAAC,2BAA2B,CAWrC,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,yBAAyB,GACrC,MAAM,SAAS,EACf,aAAa,OAAO,EACpB,UAAU,MAAM,KACd,OAAO,CAAC,WAAW,CASrB,CAAC"}
|
|
@@ -5,6 +5,17 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module
|
|
7
7
|
*/
|
|
8
|
+
import { columns_sql, omit_columns, qualify_columns } from '../db/sql_columns.js';
|
|
9
|
+
/**
|
|
10
|
+
* The full `app_settings` column set — the singleton `id` (always `1`) plus
|
|
11
|
+
* the settings the row type carries — drift-guarded like every other
|
|
12
|
+
* `*_COLUMNS`. Reads project `APP_SETTINGS_ROW_COLUMNS`, which omits the
|
|
13
|
+
* constant `id` since `AppSettings` doesn't carry it. Keep in sync with
|
|
14
|
+
* `AppSettings` and the `app_settings` DDL in `auth/auth_ddl.ts`.
|
|
15
|
+
*/
|
|
16
|
+
export const APP_SETTINGS_COLUMNS = ['id', 'open_signup', 'updated_at', 'updated_by'];
|
|
17
|
+
/** `APP_SETTINGS_COLUMNS` minus the constant singleton `id` — the `AppSettings` row projection. */
|
|
18
|
+
const APP_SETTINGS_ROW_COLUMNS = omit_columns(APP_SETTINGS_COLUMNS, 'id');
|
|
8
19
|
/**
|
|
9
20
|
* Load the current app settings.
|
|
10
21
|
*
|
|
@@ -13,7 +24,7 @@
|
|
|
13
24
|
* @throws Error if the singleton `app_settings` row is missing (migration drift — should not occur in practice)
|
|
14
25
|
*/
|
|
15
26
|
export const query_app_settings_load = async (deps) => {
|
|
16
|
-
const row = await deps.db.query_one(`SELECT
|
|
27
|
+
const row = await deps.db.query_one(`SELECT ${columns_sql(APP_SETTINGS_ROW_COLUMNS)} FROM app_settings WHERE id = 1`);
|
|
17
28
|
if (!row) {
|
|
18
29
|
throw new Error('app_settings row not found — migration may not have run');
|
|
19
30
|
}
|
|
@@ -27,7 +38,7 @@ export const query_app_settings_load = async (deps) => {
|
|
|
27
38
|
* @throws Error if the singleton `app_settings` row is missing
|
|
28
39
|
*/
|
|
29
40
|
export const query_app_settings_load_with_username = async (deps) => {
|
|
30
|
-
const row = await deps.db.query_one(`SELECT
|
|
41
|
+
const row = await deps.db.query_one(`SELECT ${qualify_columns(APP_SETTINGS_ROW_COLUMNS, 's')}, act.name AS updated_by_username
|
|
31
42
|
FROM app_settings s
|
|
32
43
|
LEFT JOIN actor act ON act.id = s.updated_by
|
|
33
44
|
WHERE s.id = 1`);
|
|
@@ -47,7 +58,7 @@ export const query_app_settings_load_with_username = async (deps) => {
|
|
|
47
58
|
* @throws Error if the singleton `app_settings` row is missing
|
|
48
59
|
*/
|
|
49
60
|
export const query_app_settings_update = async (deps, open_signup, actor_id) => {
|
|
50
|
-
const row = await deps.db.query_one(`UPDATE app_settings SET open_signup = $1, updated_at = NOW(), updated_by = $2 WHERE id = 1 RETURNING
|
|
61
|
+
const row = await deps.db.query_one(`UPDATE app_settings SET open_signup = $1, updated_at = NOW(), updated_by = $2 WHERE id = 1 RETURNING ${columns_sql(APP_SETTINGS_ROW_COLUMNS)}`, [open_signup, actor_id]);
|
|
51
62
|
if (!row) {
|
|
52
63
|
throw new Error('app_settings row not found — migration may not have run');
|
|
53
64
|
}
|
|
@@ -13,6 +13,17 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import type { QueryDeps } from '../db/query_deps.js';
|
|
15
15
|
import { type AuditLogConfig, type AuditLogEvent, type AuditLogInput, type AuditLogListOptions, type AuditLogEventWithUsernamesJson, type RoleGrantHistoryEventJson } from './audit_log_schema.js';
|
|
16
|
+
/**
|
|
17
|
+
* The full `audit_log` column set, named explicitly so a row read fails loud
|
|
18
|
+
* on schema drift — audit rows ride the `audit_log_list` / role-grant-history
|
|
19
|
+
* RPC responses and the SSE broadcast raw, so a `SELECT *` would silently
|
|
20
|
+
* carry a dropped or leftover column into the strict-validated wire shapes
|
|
21
|
+
* (see `ACCOUNT_COLUMNS` in `auth/account_queries.ts` for the outage class;
|
|
22
|
+
* the Rust twin names columns at every audit site). Keep in sync with
|
|
23
|
+
* `AuditLogEvent` and the migration chain's end state. Exported for the
|
|
24
|
+
* per-cell timeline read in `db/cell_audit_queries.ts`.
|
|
25
|
+
*/
|
|
26
|
+
export declare const AUDIT_LOG_COLUMNS: readonly ["id", "seq", "event_type", "outcome", "actor_id", "account_id", "target_account_id", "target_actor_id", "ip", "created_at", "metadata"];
|
|
16
27
|
/** Number of audit metadata validation failures observed since process start. */
|
|
17
28
|
export declare const get_audit_metadata_validation_failures: () => number;
|
|
18
29
|
/** Reset the counter — for tests only. */
|
|
@@ -24,9 +35,10 @@ export declare const reset_audit_unknown_event_type_failures: () => void;
|
|
|
24
35
|
/**
|
|
25
36
|
* Insert an audit log entry.
|
|
26
37
|
*
|
|
27
|
-
* `
|
|
28
|
-
* `created_at`). Validates `metadata` against
|
|
29
|
-
* unknown `event_type` and metadata mismatches
|
|
38
|
+
* Returns the full row (`AUDIT_LOG_COLUMNS`) so callers receive DB-assigned
|
|
39
|
+
* fields (`id`, `seq`, `created_at`). Validates `metadata` against
|
|
40
|
+
* `config.metadata_schemas`; unknown `event_type` and metadata mismatches
|
|
41
|
+
* log + bump their counters
|
|
30
42
|
* but write the row anyway. Consumers extend the recognized set via
|
|
31
43
|
* `create_audit_log_config({extra_events})`.
|
|
32
44
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit_log_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/audit_log_queries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"audit_log_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/audit_log_queries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGrD,OAAO,EAGN,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,8BAA8B,EACnC,KAAK,yBAAyB,EAC9B,MAAM,uBAAuB,CAAC;AAE/B;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,mJAYyB,CAAC;AAaxD,iFAAiF;AACjF,eAAO,MAAM,sCAAsC,QAAO,MACvB,CAAC;AAEpC,0CAA0C;AAC1C,eAAO,MAAM,wCAAwC,QAAO,IAE3D,CAAC;AAYF,gFAAgF;AAChF,eAAO,MAAM,qCAAqC,QAAO,MACvB,CAAC;AAEnC,0CAA0C;AAC1C,eAAO,MAAM,uCAAuC,QAAO,IAE1D,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,eAAe,GAAU,CAAC,SAAS,MAAM,EACrD,MAAM,SAAS,EACf,OAAO,aAAa,CAAC,CAAC,CAAC,EACvB,SAAQ,cAAyC,KAC/C,OAAO,CAAC,aAAa,CAsCvB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAChC,MAAM,SAAS,EACf,UAAU,mBAAmB,KAC3B,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,CA0C9B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,mCAAmC,GAC/C,MAAM,SAAS,EACf,UAAU,mBAAmB,KAC3B,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAwD/C,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,uCAAuC,GACnD,MAAM,SAAS,EACf,cAA+B,EAC/B,eAAU,KACR,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAmB1C,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,8BAA8B,GAC1C,MAAM,SAAS,EACf,QAAQ,IAAI,KACV,OAAO,CAAC,MAAM,CAMhB,CAAC"}
|