@fuzdev/fuz_app 0.62.0 → 0.63.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/CLAUDE.md +15 -13
- package/dist/actions/action_rpc.d.ts +10 -0
- package/dist/actions/action_rpc.d.ts.map +1 -1
- package/dist/actions/action_rpc.js +1 -1
- package/dist/actions/action_spec.d.ts +1 -1
- package/dist/actions/action_spec.js +1 -1
- package/dist/actions/perform_action.d.ts.map +1 -1
- package/dist/actions/perform_action.js +1 -0
- package/dist/auth/CLAUDE.md +45 -24
- package/dist/auth/account_action_specs.d.ts +6 -0
- package/dist/auth/account_action_specs.d.ts.map +1 -1
- package/dist/auth/account_action_specs.js +11 -4
- package/dist/auth/account_actions.d.ts.map +1 -1
- package/dist/auth/account_actions.js +9 -4
- package/dist/auth/account_routes.d.ts.map +1 -1
- package/dist/auth/account_routes.js +8 -4
- package/dist/auth/account_schema.d.ts +2 -2
- package/dist/auth/account_schema.js +2 -2
- package/dist/auth/actor_lookup_actions.d.ts +1 -1
- package/dist/auth/actor_lookup_actions.js +1 -1
- package/dist/auth/actor_lookup_queries.d.ts +1 -1
- package/dist/auth/actor_lookup_queries.js +1 -1
- package/dist/auth/actor_search_action_specs.d.ts +1 -1
- package/dist/auth/actor_search_action_specs.js +1 -1
- package/dist/auth/actor_search_actions.d.ts +1 -1
- package/dist/auth/actor_search_actions.js +1 -1
- package/dist/auth/actor_search_queries.d.ts +1 -1
- package/dist/auth/actor_search_queries.js +1 -1
- package/dist/auth/all_action_spec_registries.d.ts +2 -2
- package/dist/auth/all_action_spec_registries.js +2 -2
- package/dist/auth/audit_log_routes.d.ts +1 -1
- package/dist/auth/audit_log_routes.js +1 -1
- package/dist/auth/audit_log_schema.d.ts +25 -0
- package/dist/auth/audit_log_schema.d.ts.map +1 -1
- package/dist/auth/audit_log_schema.js +16 -0
- package/dist/auth/request_context.d.ts +1 -1
- package/dist/env/update_env_variable.js +1 -1
- package/dist/http/CLAUDE.md +15 -15
- package/dist/testing/CLAUDE.md +28 -44
- package/dist/testing/audit_completeness.d.ts.map +1 -1
- package/dist/testing/audit_completeness.js +17 -1
- package/dist/ui/CLAUDE.md +13 -18
- package/dist/ui/keyed_async_slot.svelte.d.ts +1 -1
- package/dist/ui/keyed_async_slot.svelte.js +1 -1
- package/package.json +1 -1
package/dist/actions/CLAUDE.md
CHANGED
|
@@ -12,12 +12,13 @@ server-authoritative dispatch, role-grant-offer UI integration) see
|
|
|
12
12
|
../../docs/usage.md §Deriving Route/Event Specs, §Single JSON-RPC 2.0 Endpoint,
|
|
13
13
|
§WebSocket Endpoint. For DEV-only output validation semantics see
|
|
14
14
|
../../docs/architecture.md §DEV-only Output Validation. For the SAES
|
|
15
|
-
binding matrix and middleware ordering see the root
|
|
15
|
+
binding matrix and middleware ordering see the root ../../CLAUDE.md
|
|
16
16
|
§Action Spec System (SAES) and §Middleware Ordering.
|
|
17
17
|
|
|
18
18
|
IMPORTANT: Every exported Zod schema is paired with a same-named `z.infer`
|
|
19
|
-
type export
|
|
20
|
-
|
|
19
|
+
type export — the convention callers rely on for type imports. When adding
|
|
20
|
+
new schemas, keep the pair invariant (ecosystem-wide rule; see
|
|
21
|
+
Skill(fuz-stack) zod-schemas).
|
|
21
22
|
|
|
22
23
|
NOTE: `ActionRegistry` keeps a few pre-built getters (auth filters,
|
|
23
24
|
initiator-direction filters) that codegen doesn't consume today — kept
|
|
@@ -53,10 +54,10 @@ declarative metadata for consumers (codegen, UI form-state matching, docs)
|
|
|
53
54
|
to read off the spec instead of scanning handler code. No runtime
|
|
54
55
|
enforcement — drift between declared reasons and what handlers actually
|
|
55
56
|
throw is caught per-module by source-scanning unit tests (see
|
|
56
|
-
|
|
57
|
+
../../test/auth/role*grant_offer_actions.error_reasons.test.ts). Reuses
|
|
57
58
|
the same `as const` string constants the handler throws (e.g.
|
|
58
|
-
`
|
|
59
|
-
`ERROR_ROLE_GRANT_NOT_FOUND`
|
|
59
|
+
`ERROR_ROLE_GRANT_OFFER*\*`from`auth/role_grant_offer_action_specs.ts`,
|
|
60
|
+
`ERROR_ROLE_GRANT_NOT_FOUND`from`http/error_schemas.ts`) so call
|
|
60
61
|
sites can import either side. Standard transport errors (validation,
|
|
61
62
|
auth, rate-limit) stay implicit.
|
|
62
63
|
|
|
@@ -119,7 +120,7 @@ The remaining asymmetry today is runtime: there is no
|
|
|
119
120
|
`Promise<Result<{value}, {error}>>` shape `FrontendActionsApi` methods
|
|
120
121
|
return. Closing those gaps is on the deferred follow-up set in the
|
|
121
122
|
[SAES RPC closeout](https://github.com/ryanatkn/grimoire/blob/main/quests/HISTORY.md#saes-rpc-direction-2026-04)
|
|
122
|
-
(grimoire `lore/fuz_app/TODO.md` §
|
|
123
|
+
(grimoire `lore/fuz_app/TODO.md` §Future Directions tracks the symmetric
|
|
123
124
|
backend signature, backend RPC client, and local-call symmetry items) —
|
|
124
125
|
wait for a second backend runtime case.
|
|
125
126
|
|
|
@@ -217,7 +218,7 @@ and `FrontendActionHandlers`.
|
|
|
217
218
|
- `generate_action_event_datas(specs, imports, {same_file?, collections_path?, include_protocol_actions?})` — `ActionEventDatas` interface; per-spec variant by kind (`ActionEventRequestResponseData` / `ActionEventRemoteNotificationData` / `ActionEventLocalCallData`). `same_file` (default `true`) is the file-layout switch: when `true`, assumes `ActionInputs` / `ActionOutputs` are in the same module and adds no import (the zzz pattern); when `false`, adds the type imports from `collections_path` (default `'./action_collections.js'`). `collections_path` alone is a no-op — the surprising omit-vs-default behavior of earlier versions has been replaced.
|
|
218
219
|
- `generate_frontend_actions_api(specs, imports, {interface_name?, method_filter?, collections_path?, sync_returns_value?, include_protocol_actions?})` — emits the typed `FrontendActionsApi` interface (configurable via `interface_name`, default `'FrontendActionsApi'`). One method signature per spec via `generate_actions_api_method_signature`. Protocol actions filtered by default; `method_filter: (spec) => boolean` runs after the protocol-action filter. Renamed from `generate_actions_api` in API review III to make the side-of-the-wire intent visible at every consumer site.
|
|
219
220
|
- `generate_frontend_action_handlers(specs, imports, {collections_path?, include_protocol_actions?})` — `FrontendActionHandlers` interface (Tier 2 only — wraps `generate_phase_handlers` with `action_event_type: 'TypedActionEvent'`). Pair with `generate_typed_action_event_alias`.
|
|
220
|
-
- `generate_backend_actions_api(specs, imports, {interface_name?, spec_array_name?, specs_module?, collections_path?, qualify_spec?, include_protocol_actions?})` — `BackendActionsApi` interface AND `broadcast_action_specs: ReadonlyArray<ActionSpecUnion>` array (both names configurable). Filter: `kind === 'remote_notification' && initiator !== 'frontend'`, with `streams`-target methods (request-scoped progress notifications invoked via `ctx.notify`) excluded — the discriminator is `ActionSpec.streams`, not a manual list. Adds `ActionInputs` (from `collections_path`) + `ActionSpecUnion`, plus `* as specs` from `specs_module` unless `qualify_spec` is set. Method shape today is `(input) => Promise<void>` (matches `create_broadcast_api`'s fire-and-forget runtime); generalizing to per-kind shapes via `generate_actions_api_method_signature` is deferred until a second backend runtime constructor lands (tracked in grimoire `lore/fuz_app/TODO.md` §
|
|
221
|
+
- `generate_backend_actions_api(specs, imports, {interface_name?, spec_array_name?, specs_module?, collections_path?, qualify_spec?, include_protocol_actions?})` — `BackendActionsApi` interface AND `broadcast_action_specs: ReadonlyArray<ActionSpecUnion>` array (both names configurable). Filter: `kind === 'remote_notification' && initiator !== 'frontend'`, with `streams`-target methods (request-scoped progress notifications invoked via `ctx.notify`) excluded — the discriminator is `ActionSpec.streams`, not a manual list. Adds `ActionInputs` (from `collections_path`) + `ActionSpecUnion`, plus `* as specs` from `specs_module` unless `qualify_spec` is set. Method shape today is `(input) => Promise<void>` (matches `create_broadcast_api`'s fire-and-forget runtime); generalizing to per-kind shapes via `generate_actions_api_method_signature` is deferred until a second backend runtime constructor lands (tracked in grimoire `lore/fuz_app/TODO.md` §Future Directions, _Symmetric backend signature shape_).
|
|
221
222
|
- `generate_backend_action_handlers_map(imports, options?)` — emits the `BackendActionHandlers` mapped type (`{[K in BackendRequestResponseMethod]: (input: ActionInputs[K], ctx: BackendHandlerContext) => ActionOutputs[K] | Promise<ActionOutputs[K]>}`). Replaces the hand-maintained `Exclude<>` + parallel mapped-type pattern (zzz had this at `zzz/src/lib/server/zzz_action_handlers.ts:42-66`). Configurable type name, method enum name, and context type name; configurable `collections_path` / `metatypes_path` for the type imports.
|
|
222
223
|
|
|
223
224
|
### Wrapper + multi-source helper
|
|
@@ -319,6 +320,7 @@ interface ActionContext {
|
|
|
319
320
|
pending_effects: Array<Promise<void>>; // eager pool writes already in flight — see http/CLAUDE.md §Pending Effects
|
|
320
321
|
post_commit_effects: Array<() => void | Promise<void>>; // deferred — push via `emit_after_commit`
|
|
321
322
|
client_ip: string;
|
|
323
|
+
credential_type: CredentialType | null; // session | api_token | daemon_token (or null for anonymous) — same value the credential_types gate consumed
|
|
322
324
|
log: Logger;
|
|
323
325
|
notify: (method, params) => void; // HTTP: DEV-mode warn + drop (no streaming channel); WS: socket-scoped
|
|
324
326
|
signal: AbortSignal; // HTTP: client-disconnect; WS: AbortSignal.any([socket_close, request_cancel])
|
|
@@ -458,7 +460,7 @@ Fan-out:
|
|
|
458
460
|
|
|
459
461
|
- `send(notification)` — broadcasts to every connection (current `send(request)` returns an internal_error "not yet implemented" — backend cannot initiate request-response).
|
|
460
462
|
- `broadcast_filtered(message, predicate)` — per-connection predicate over `ConnectionIdentity`; skips non-matching. Returns count.
|
|
461
|
-
- `send_to_account(account_id, message)` — targeted wrapper over `broadcast_filtered`. Mirrors `close_sockets_for_account` on the send side (every connection for the account). Structurally satisfies the `NotificationSender` interface from `auth/role_grant_offer_notifications.ts` (see
|
|
463
|
+
- `send_to_account(account_id, message)` — targeted wrapper over `broadcast_filtered`. Mirrors `close_sockets_for_account` on the send side (every connection for the account). Structurally satisfies the `NotificationSender` interface from `auth/role_grant_offer_notifications.ts` (see `auth/CLAUDE.md` §WS notifications).
|
|
462
464
|
- `get_connection_count()` — telemetry counter over the connection map.
|
|
463
465
|
|
|
464
466
|
Return values are bookkeeping, not delivery receipts — `0` means no live
|
|
@@ -527,7 +529,7 @@ and optional `required_role: RoleName`. Returns `{transport}`. Note:
|
|
|
527
529
|
`required_role` is a **coarse upgrade-time gate** — per-action `auth` in
|
|
528
530
|
each spec still applies at dispatch time via `perform_action`.
|
|
529
531
|
(`verify_request_source` and `require_auth` / `require_role` are from
|
|
530
|
-
|
|
532
|
+
`auth/`; see `auth/CLAUDE.md` §Middleware for their semantics.)
|
|
531
533
|
|
|
532
534
|
### `register_action_ws` (`register_action_ws.ts`) — lower-level
|
|
533
535
|
|
|
@@ -584,7 +586,7 @@ Per-message side-effect queues: `pending_effects: Array<Promise<void>>`
|
|
|
584
586
|
`flush_post_commit_effects`. Both flush in the same `try/finally` that
|
|
585
587
|
releases the request controller, so fire-and-forget audit / notification
|
|
586
588
|
effects pushed by the handler complete (or reject visibly) before the
|
|
587
|
-
next message dispatches. See
|
|
589
|
+
next message dispatches. See `http/CLAUDE.md` §Pending Effects.
|
|
588
590
|
|
|
589
591
|
Lifecycle hooks on `RegisterActionWsOptions`:
|
|
590
592
|
|
|
@@ -950,9 +952,9 @@ wiring (zzz-style reactive Cells observing `ActionEvent` lifecycle)
|
|
|
950
952
|
don't have to drop down to manual `create_rpc_client` construction
|
|
951
953
|
(which forfeits the bundled `api` / `api_result` pair).
|
|
952
954
|
|
|
953
|
-
`all_standard_action_specs` (in
|
|
955
|
+
`all_standard_action_specs` (in `auth/standard_action_specs.ts`) is
|
|
954
956
|
the matching aggregate spec list mirroring `create_standard_rpc_actions`
|
|
955
|
-
on the backend — see
|
|
957
|
+
on the backend — see `auth/CLAUDE.md` §`standard_rpc_actions.ts`.
|
|
956
958
|
|
|
957
959
|
## Broadcast API (`broadcast_api.ts`)
|
|
958
960
|
|
|
@@ -17,6 +17,7 @@ import type { Uuid } from '@fuzdev/fuz_util/id.js';
|
|
|
17
17
|
import type { RequestResponseActionSpec } from './action_spec.js';
|
|
18
18
|
import { type RouteSpec } from '../http/route_spec.js';
|
|
19
19
|
import { type RequestActorContext, type RequestContext } from '../auth/request_context.js';
|
|
20
|
+
import { type CredentialType } from '../hono_context.js';
|
|
20
21
|
import type { Db } from '../db/db.js';
|
|
21
22
|
import { type JsonrpcRequestId } from '../http/jsonrpc.js';
|
|
22
23
|
import type { RateLimiter } from '../rate_limiter.js';
|
|
@@ -72,6 +73,15 @@ export interface ActionContext {
|
|
|
72
73
|
* `role_grant_offer_expire` cleanup sweep in `auth/cleanup.ts`).
|
|
73
74
|
*/
|
|
74
75
|
client_ip: string;
|
|
76
|
+
/**
|
|
77
|
+
* Credential channel the request arrived on (`'session'` | `'api_token'` |
|
|
78
|
+
* `'daemon_token'`), or `null` for anonymous requests. Same value the
|
|
79
|
+
* dispatcher's `credential_types` gate consumed at step 4 — exposed here
|
|
80
|
+
* so handlers can record it in audit metadata (defense in depth: the
|
|
81
|
+
* gate may be loosened or bypassed in a future refactor, but the audit
|
|
82
|
+
* row preserves what actually authenticated the request).
|
|
83
|
+
*/
|
|
84
|
+
credential_type: CredentialType | null;
|
|
75
85
|
/** Logger instance. */
|
|
76
86
|
log: Logger;
|
|
77
87
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action_rpc.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_rpc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,wBAAwB,CAAC;AAEjD,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAoB,KAAK,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAExE,OAAO,EAEN,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"action_rpc.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_rpc.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,7 +16,7 @@ import { DEV } from 'esm-env';
|
|
|
16
16
|
import {} from '../http/route_spec.js';
|
|
17
17
|
import { get_client_ip } from '../http/proxy.js';
|
|
18
18
|
import { get_request_context, } from '../auth/request_context.js';
|
|
19
|
-
import { ACCOUNT_ID_KEY, CREDENTIAL_TYPE_KEY, TEST_CONTEXT_PRESET_KEY } from '../hono_context.js';
|
|
19
|
+
import { ACCOUNT_ID_KEY, CREDENTIAL_TYPE_KEY, TEST_CONTEXT_PRESET_KEY, } from '../hono_context.js';
|
|
20
20
|
import { compile_action_registry } from './compile_action_registry.js';
|
|
21
21
|
import { JSONRPC_VERSION, JsonrpcRequest, } from '../http/jsonrpc.js';
|
|
22
22
|
import { jsonrpc_error_messages, jsonrpc_error_code_to_http_status, JSONRPC_ERROR_CODES, } from '../http/jsonrpc_errors.js';
|
|
@@ -42,7 +42,7 @@ export declare const ActionSpec: z.ZodObject<{
|
|
|
42
42
|
* `null` for `remote_notification` and `local_call` — those don't
|
|
43
43
|
* dispatch through the request/response auth gate.
|
|
44
44
|
*
|
|
45
|
-
* See
|
|
45
|
+
* See `http/auth_shape.ts` for the design rationale (orthogonal
|
|
46
46
|
* authentication / account-resolution / actor-resolution / role-and-
|
|
47
47
|
* credential authorization axes).
|
|
48
48
|
*/
|
|
@@ -25,7 +25,7 @@ export const ActionSpec = z.strictObject({
|
|
|
25
25
|
* `null` for `remote_notification` and `local_call` — those don't
|
|
26
26
|
* dispatch through the request/response auth gate.
|
|
27
27
|
*
|
|
28
|
-
* See
|
|
28
|
+
* See `http/auth_shape.ts` for the design rationale (orthogonal
|
|
29
29
|
* authentication / account-resolution / actor-resolution / role-and-
|
|
30
30
|
* credential authorization axes).
|
|
31
31
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"perform_action.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/perform_action.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAGH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAGN,KAAK,cAAc,EACnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAC,KAAK,cAAc,EAAC,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AAEpC,OAAO,EAEN,KAAK,gBAAgB,EAErB,KAAK,kBAAkB,EACvB,MAAM,oBAAoB,CAAC;AAW5B,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAEpD,OAAO,KAAK,EAA+B,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAE7E;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IAClC,kEAAkE;IAClE,MAAM,EAAE,SAAS,CAAC;IAClB,mGAAmG;IACnG,UAAU,EAAE,OAAO,CAAC;IACpB,sDAAsD;IACtD,UAAU,EAAE,gBAAgB,CAAC;IAC7B,yDAAyD;IACzD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,uEAAuE;IACvE,eAAe,EAAE,cAAc,GAAG,IAAI,CAAC;IACvC,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB,oGAAoG;IACpG,MAAM,EAAE,WAAW,CAAC;IACpB,sFAAsF;IACtF,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,uDAAuD;IACvD,aAAa,CAAC,EAAE,IAAI,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE;QAAC,eAAe,EAAE,cAAc,GAAG,IAAI,CAAA;KAAC,CAAC;CAClD;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IACjC,gGAAgG;IAChG,EAAE,EAAE,EAAE,CAAC;IACP;;;OAGG;IACH,eAAe,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACtC;;;OAGG;IACH,mBAAmB,EAAE,KAAK,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACvD,gDAAgD;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,kEAAkE;IAClE,sBAAsB,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3C,uEAAuE;IACvE,2BAA2B,EAAE,WAAW,GAAG,IAAI,CAAC;CAChD;AAED;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAC5B;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAC,GAC7B;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC,CAAC;AAE9D;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,GAC1B,OAAO,kBAAkB,EACzB,MAAM,iBAAiB,KACrB,OAAO,CAAC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"perform_action.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/perform_action.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAGH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAGN,KAAK,cAAc,EACnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAC,KAAK,cAAc,EAAC,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AAEpC,OAAO,EAEN,KAAK,gBAAgB,EAErB,KAAK,kBAAkB,EACvB,MAAM,oBAAoB,CAAC;AAW5B,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAEpD,OAAO,KAAK,EAA+B,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAE7E;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IAClC,kEAAkE;IAClE,MAAM,EAAE,SAAS,CAAC;IAClB,mGAAmG;IACnG,UAAU,EAAE,OAAO,CAAC;IACpB,sDAAsD;IACtD,UAAU,EAAE,gBAAgB,CAAC;IAC7B,yDAAyD;IACzD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,uEAAuE;IACvE,eAAe,EAAE,cAAc,GAAG,IAAI,CAAC;IACvC,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB,oGAAoG;IACpG,MAAM,EAAE,WAAW,CAAC;IACpB,sFAAsF;IACtF,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,uDAAuD;IACvD,aAAa,CAAC,EAAE,IAAI,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE;QAAC,eAAe,EAAE,cAAc,GAAG,IAAI,CAAA;KAAC,CAAC;CAClD;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IACjC,gGAAgG;IAChG,EAAE,EAAE,EAAE,CAAC;IACP;;;OAGG;IACH,eAAe,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACtC;;;OAGG;IACH,mBAAmB,EAAE,KAAK,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACvD,gDAAgD;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,kEAAkE;IAClE,sBAAsB,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3C,uEAAuE;IACvE,2BAA2B,EAAE,WAAW,GAAG,IAAI,CAAC;CAChD;AAED;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAC5B;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAC,GAC7B;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC,CAAC;AAE9D;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,GAC1B,OAAO,kBAAkB,EACzB,MAAM,iBAAiB,KACrB,OAAO,CAAC,mBAAmB,CAwJ7B,CAAC;AA4EF;;;GAGG;AACH,eAAO,MAAM,iCAAiC,GAC7C,IAAI,gBAAgB,EACpB,QAAQ,mBAAmB,KACzB;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,gBAAgB,CAAA;CAAC,GAAG,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAC,GAAG;IAAC,KAAK,EAAE,kBAAkB,CAAA;CAAC,CAK5F,CAAC"}
|
package/dist/auth/CLAUDE.md
CHANGED
|
@@ -2,16 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
> Auth domain: identity, crypto primitives, schema + DDL, queries, middleware, routes, RPC actions, cleanup.
|
|
4
4
|
|
|
5
|
-
Grouped below by theme. For design rationale and threat
|
|
6
|
-
|
|
5
|
+
Grouped below by theme. For design rationale and threat model, see
|
|
6
|
+
../../../docs/identity.md and ../../../docs/security.md. For the
|
|
7
7
|
subsystem's place in server assembly and middleware ordering, see
|
|
8
|
-
|
|
8
|
+
../../../docs/architecture.md and the root ../../../CLAUDE.md. For
|
|
9
|
+
the workspace-wide DI vocabulary (capabilities / options / runtime
|
|
10
|
+
state), see Skill(fuz-stack) dependency-injection.
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
`
|
|
12
|
-
(
|
|
13
|
-
inline, never in `deps`. All `query_*` functions take
|
|
14
|
-
as their first arg.
|
|
12
|
+
Auth-specific instances: stateless capabilities in `AppDeps` /
|
|
13
|
+
`RouteFactoryDeps`; static config in `*Options`; runtime state
|
|
14
|
+
(`DaemonTokenState`, mutable `AppSettings` ref, `BootstrapStatus`) is
|
|
15
|
+
inline, never in `deps`. All `query_*` functions take
|
|
16
|
+
`deps: QueryDeps = {db}` as their first arg.
|
|
15
17
|
|
|
16
18
|
## Crypto primitives
|
|
17
19
|
|
|
@@ -789,7 +791,7 @@ Per-call `ctx` shape:
|
|
|
789
791
|
- `emit` requires `{pending_effects: Array<Promise<void>>}` — the eager
|
|
790
792
|
queue only. Both `RouteContext` and `ActionContext` satisfy this
|
|
791
793
|
structurally; `audit.emit` pushes its in-flight pool-write promise
|
|
792
|
-
onto the eager queue. See
|
|
794
|
+
onto the eager queue. See `http/CLAUDE.md` §Pending Effects for
|
|
793
795
|
the eager / deferred split.
|
|
794
796
|
- `emit_role_grant_target` adds `client_ip: string` (also on `ActionContext`;
|
|
795
797
|
REST handlers pass `{pending_effects, client_ip: get_client_ip(c)}`).
|
|
@@ -919,7 +921,7 @@ consciously violate the contract.
|
|
|
919
921
|
|
|
920
922
|
## Middleware
|
|
921
923
|
|
|
922
|
-
See the root
|
|
924
|
+
See the root ../../../CLAUDE.md §Middleware Ordering for the canonical
|
|
923
925
|
assembly order. Two-phase identity:
|
|
924
926
|
|
|
925
927
|
- **Authentication** runs in middleware (session / bearer / daemon
|
|
@@ -974,7 +976,7 @@ assembly order. Two-phase identity:
|
|
|
974
976
|
actor row was deleted between credential validation and the
|
|
975
977
|
follow-up read). The named per-error shape `AuthorizationFailureBody`
|
|
976
978
|
is still exported for callers that want to bind the failure body
|
|
977
|
-
by type. See the root
|
|
979
|
+
by type. See the root ../../../CLAUDE.md §Cleanest architecture
|
|
978
980
|
takes priority for the rationale.
|
|
979
981
|
|
|
980
982
|
Session parsing is separate from auth enforcement — login / bootstrap
|
|
@@ -1141,6 +1143,8 @@ Session-based auth route specs. Factory: `create_account_route_specs(deps, optio
|
|
|
1141
1143
|
- `POST /logout` — revokes session by hash, clears cookie.
|
|
1142
1144
|
- **`POST /password`** — `current_password: PasswordProvided` +
|
|
1143
1145
|
`new_password: Password`. Per-IP + per-account rate limited.
|
|
1146
|
+
Declares `credential_types: ['session']` (see
|
|
1147
|
+
`docs/security.md` §Credential-channel gating).
|
|
1144
1148
|
**Revokes all sessions + all API tokens** (force re-auth everywhere);
|
|
1145
1149
|
clears cookie.
|
|
1146
1150
|
- **`GET /verify`** — empty-body session-validity probe for nginx
|
|
@@ -1212,7 +1216,7 @@ gets `require_auth` when `account === 'required'` or `actor === 'required'`;
|
|
|
1212
1216
|
`post_authorization` gets `require_credential_types(types)` when
|
|
1213
1217
|
`credential_types?.length` and `require_role(roles)` when `roles?.length`.
|
|
1214
1218
|
Injected into `apply_route_specs` so the generic HTTP framework stays
|
|
1215
|
-
auth-agnostic (see
|
|
1219
|
+
auth-agnostic (see `http/CLAUDE.md` §Validation pipeline for where it plugs in).
|
|
1216
1220
|
|
|
1217
1221
|
### `audit_log_routes.ts`
|
|
1218
1222
|
|
|
@@ -1232,7 +1236,7 @@ module produces is now just the optional SSE stream:
|
|
|
1232
1236
|
## RPC actions (SAES)
|
|
1233
1237
|
|
|
1234
1238
|
Three action surfaces that mount on a consumer's JSON-RPC endpoint via
|
|
1235
|
-
`create_rpc_endpoint` (see
|
|
1239
|
+
`create_rpc_endpoint` (see `actions/CLAUDE.md` §Single JSON-RPC 2.0 endpoint).
|
|
1236
1240
|
Each surface is split across two files:
|
|
1237
1241
|
|
|
1238
1242
|
- `*_action_specs.ts` — Input/Output Zod schemas (paired with `z.infer` type
|
|
@@ -1413,16 +1417,16 @@ Error reason constants (exported as `as const` literals):
|
|
|
1413
1417
|
- `ERROR_ROLE_GRANT_OFFER_ACTOR_MISMATCH` (`'role_grant_offer_actor_mismatch'` —
|
|
1414
1418
|
actor-targeted offer was accepted by an actor other than `to_actor_id`)
|
|
1415
1419
|
|
|
1416
|
-
Plus re-uses from
|
|
1420
|
+
Plus re-uses from `http/error_schemas.ts`: `ERROR_ROLE_GRANT_NOT_FOUND`,
|
|
1417
1421
|
`ERROR_ROLE_NOT_WEB_GRANTABLE`, `ERROR_INSUFFICIENT_PERMISSIONS`,
|
|
1418
1422
|
`ERROR_ACCOUNT_NOT_FOUND`.
|
|
1419
1423
|
|
|
1420
1424
|
Each spec declares the reason codes its handler may surface (see
|
|
1421
|
-
|
|
1425
|
+
`actions/CLAUDE.md` §Action specs for the field semantics). Only
|
|
1422
1426
|
domain reasons returned via `error.data.reason` are listed; standard
|
|
1423
1427
|
transport errors (validation, auth, rate-limit) stay implicit. Drift
|
|
1424
1428
|
between declared reasons and handler throws is caught by
|
|
1425
|
-
|
|
1429
|
+
../../test/auth/role_grant_offer_actions.error_reasons.test.ts.
|
|
1426
1430
|
|
|
1427
1431
|
Failure-outcome audit events emitted (success and failure rows both carry
|
|
1428
1432
|
`ip: ctx.client_ip` — uniform with the admin and self-service surfaces):
|
|
@@ -1442,8 +1446,8 @@ Failure-outcome audit events emitted (success and failure rows both carry
|
|
|
1442
1446
|
role_grant).
|
|
1443
1447
|
|
|
1444
1448
|
WS notifications (post-commit via `emit_after_commit` from
|
|
1445
|
-
|
|
1446
|
-
can't starve others; see
|
|
1449
|
+
`http/pending_effects.js` — swallows exceptions so one failed send
|
|
1450
|
+
can't starve others; see `http/CLAUDE.md` §Pending Effects):
|
|
1447
1451
|
|
|
1448
1452
|
- Create → `role_grant_offer_received` to recipient.
|
|
1449
1453
|
- Retract → `role_grant_offer_retracted` to recipient.
|
|
@@ -1506,7 +1510,7 @@ Pair this with `create_app_server`'s `rpc_endpoints` factory form
|
|
|
1506
1510
|
(`(ctx) => Array<RpcEndpointSpec>`) so the combined action list gets
|
|
1507
1511
|
`ctx.deps` + `ctx.app_settings` — `create_app_server` auto-mounts the
|
|
1508
1512
|
endpoint via `create_rpc_endpoint`, so consumers don't need to mount it
|
|
1509
|
-
again in `create_route_specs`. See
|
|
1513
|
+
again in `create_route_specs`. See ../../../docs/usage.md §Server
|
|
1510
1514
|
Assembly.
|
|
1511
1515
|
|
|
1512
1516
|
Pre-bundle consumers spread `create_admin_actions` and
|
|
@@ -1519,7 +1523,7 @@ consumer wiring the admin surface without account actions will hit
|
|
|
1519
1523
|
`method not found` on first admin-suite run.
|
|
1520
1524
|
|
|
1521
1525
|
Frontend mirror: `all_standard_action_specs` (in
|
|
1522
|
-
|
|
1526
|
+
`auth/standard_action_specs.ts`) bundles `all_admin_action_specs +
|
|
1523
1527
|
all_role_grant_offer_action_specs + all_account_action_specs` into one
|
|
1524
1528
|
`ReadonlyArray<RequestResponseActionSpec>` for typed-client codegen
|
|
1525
1529
|
and `create_frontend_rpc_client({specs})` wiring. Self-service role
|
|
@@ -1532,7 +1536,7 @@ spread `all_self_service_role_action_specs` separately when needed.
|
|
|
1532
1536
|
fuz-auth action-spec bundle (`admin`, `role_grant_offer`, `account`,
|
|
1533
1537
|
`self_service_role`, `actor_lookup`, `actor_search`). Not a mounting
|
|
1534
1538
|
surface; protocol specs are excluded. Iterated by registry-wide
|
|
1535
|
-
invariant tests in
|
|
1539
|
+
invariant tests in ../../test/auth/.
|
|
1536
1540
|
|
|
1537
1541
|
### `account_action_specs.ts` + `account_actions.ts` — seven self-service RPC actions
|
|
1538
1542
|
|
|
@@ -1553,6 +1557,18 @@ operations are account-scoped via `query_session_revoke_for_account` /
|
|
|
1553
1557
|
or token id returns `revoked: false` rather than revealing whether the id
|
|
1554
1558
|
exists.
|
|
1555
1559
|
|
|
1560
|
+
**Credential-channel gating** — `account_token_create`,
|
|
1561
|
+
`account_token_revoke`, `account_session_revoke`, and
|
|
1562
|
+
`account_session_revoke_all` declare `credential_types: ['session']`
|
|
1563
|
+
on their `auth` axis (same gate as REST `POST /password`).
|
|
1564
|
+
`account_session_revoke` is gated alongside `_revoke_all` because a
|
|
1565
|
+
leaked bearer can otherwise compose `account_session_list` + N×revoke
|
|
1566
|
+
to reach the same lockout. Admin token/session revoke specs in
|
|
1567
|
+
`admin_action_specs.ts` deliberately stay unrestricted (admin
|
|
1568
|
+
scripting from CLI/bearer is legitimate operator workflow). For the
|
|
1569
|
+
threat model, the trust-bar rationale, and the defense-in-depth audit
|
|
1570
|
+
metadata see `docs/security.md` §Credential-channel gating.
|
|
1571
|
+
|
|
1556
1572
|
| Spec | Side effects | Rate limit | Input | Output |
|
|
1557
1573
|
| ---------------------------------------- | ------------ | ----------- | -------------- | ----------------------- |
|
|
1558
1574
|
| `account_verify_action_spec` | false | | `z.void()` | `SessionAccountJson` |
|
|
@@ -1577,7 +1593,12 @@ vector, so rate caps are symmetry-only and skipped.
|
|
|
1577
1593
|
Audit events emitted (via `deps.audit.emit` with `ip: ctx.client_ip`):
|
|
1578
1594
|
`session_revoke`, `session_revoke_all`, `token_create`, `token_revoke`. The
|
|
1579
1595
|
IP is the resolved trusted-proxy value from `ActionContext.client_ip`,
|
|
1580
|
-
matching the REST handler convention.
|
|
1596
|
+
matching the REST handler convention. Every gated event additionally
|
|
1597
|
+
records `credential_type` (read from `ActionContext.credential_type`)
|
|
1598
|
+
in metadata — defense in depth so forensics survive if the
|
|
1599
|
+
`credential_types: ['session']` spec gate is ever loosened or bypassed.
|
|
1600
|
+
The REST `password_change` audit row mirrors the same field on all
|
|
1601
|
+
three outcomes (success, wrong-password, concurrent-change).
|
|
1581
1602
|
|
|
1582
1603
|
Deps: `Pick<RouteFactoryDeps, 'log' | 'audit'>`.
|
|
1583
1604
|
Options: `{max_tokens?: number | null}` — defaults to `DEFAULT_MAX_TOKENS`
|
|
@@ -1698,7 +1719,7 @@ One static `request_response` action — `actor_search({query, scope_ids?, limit
|
|
|
1698
1719
|
powers person-target pickers. Sibling to `actor_lookup`: that resolves a
|
|
1699
1720
|
batch of known ids to labels; this resolves a partial name to candidate
|
|
1700
1721
|
actors. Reuses `ActorLookupEntryJson` from
|
|
1701
|
-
|
|
1722
|
+
`auth/actor_lookup_action_specs.ts` so the labels arc on the consumer side
|
|
1702
1723
|
stays uniform. Default limit `ACTOR_SEARCH_LIMIT_DEFAULT = 20`, hard cap
|
|
1703
1724
|
`ACTOR_SEARCH_LIMIT_MAX = 50`. Query string capped at
|
|
1704
1725
|
`ACTOR_SEARCH_QUERY_LENGTH_MAX = 50`.
|
|
@@ -1805,5 +1826,5 @@ resulting role_grant.
|
|
|
1805
1826
|
Action factories take `Pick<RouteFactoryDeps, 'log' | 'audit'>` directly
|
|
1806
1827
|
(role-grant-offer adds `notification_sender?` inline).
|
|
1807
1828
|
|
|
1808
|
-
See root
|
|
1829
|
+
See root ../../../CLAUDE.md §AppDeps Vocabulary for the
|
|
1809
1830
|
capability / options / runtime-state split across the whole project.
|
|
@@ -135,6 +135,7 @@ export declare const account_session_revoke_action_spec: {
|
|
|
135
135
|
auth: {
|
|
136
136
|
account: "required";
|
|
137
137
|
actor: "none";
|
|
138
|
+
credential_types: string[];
|
|
138
139
|
};
|
|
139
140
|
side_effects: true;
|
|
140
141
|
input: z.ZodObject<{
|
|
@@ -154,6 +155,7 @@ export declare const account_session_revoke_all_action_spec: {
|
|
|
154
155
|
auth: {
|
|
155
156
|
account: "required";
|
|
156
157
|
actor: "none";
|
|
158
|
+
credential_types: string[];
|
|
157
159
|
};
|
|
158
160
|
side_effects: true;
|
|
159
161
|
input: z.ZodVoid;
|
|
@@ -165,6 +167,8 @@ export declare const account_session_revoke_all_action_spec: {
|
|
|
165
167
|
description: string;
|
|
166
168
|
};
|
|
167
169
|
/**
|
|
170
|
+
* `credential_types: ['session']` — see `docs/security.md` §Credential-channel gating.
|
|
171
|
+
*
|
|
168
172
|
* `rate_limit: 'account'` bounds the burn rate of API-token creates. The
|
|
169
173
|
* outstanding-token count is already capped by `max_tokens` (via
|
|
170
174
|
* `query_api_token_enforce_limit`), but the per-account *rate* of churn
|
|
@@ -179,6 +183,7 @@ export declare const account_token_create_action_spec: {
|
|
|
179
183
|
auth: {
|
|
180
184
|
account: "required";
|
|
181
185
|
actor: "none";
|
|
186
|
+
credential_types: string[];
|
|
182
187
|
};
|
|
183
188
|
side_effects: true;
|
|
184
189
|
input: z.ZodPrefault<z.ZodObject<{
|
|
@@ -225,6 +230,7 @@ export declare const account_token_revoke_action_spec: {
|
|
|
225
230
|
auth: {
|
|
226
231
|
account: "required";
|
|
227
232
|
actor: "none";
|
|
233
|
+
credential_types: string[];
|
|
228
234
|
};
|
|
229
235
|
side_effects: true;
|
|
230
236
|
input: z.ZodObject<{
|
|
@@ -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,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAGtB,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,2BAA2B,CAAC;AAMzE,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;;;;;;;;kBAE5B,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB;;kBAE7B,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEpE,iFAAiF;AACjF,eAAO,MAAM,mBAAmB;;;kBAG9B,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE,6DAA6D;AAC7D,eAAO,MAAM,qBAAqB,WAAW,CAAC;AAC9C,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE1E,+CAA+C;AAC/C,eAAO,MAAM,sBAAsB;;;kBAGjC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE5E,wCAAwC;AACxC,eAAO,MAAM,gBAAgB;;mBAOf,CAAC;AACf,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE,2EAA2E;AAC3E,eAAO,MAAM,iBAAiB;;;;;kBAK5B,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE,qDAAqD;AACrD,eAAO,MAAM,cAAc,WAAW,CAAC;AACvC,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D,4DAA4D;AAC5D,eAAO,MAAM,eAAe;;;;;;;;;;kBAE1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,wCAAwC;AACxC,eAAO,MAAM,gBAAgB;;kBAE3B,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE,+EAA+E;AAC/E,eAAO,MAAM,iBAAiB;;;kBAG5B,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAIlE,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;CAUF,CAAC;AAEtC,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;;;CAUR,CAAC;
|
|
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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"}
|
|
@@ -90,22 +90,26 @@ export const account_session_list_action_spec = {
|
|
|
90
90
|
async: true,
|
|
91
91
|
description: 'List auth sessions for the current account.',
|
|
92
92
|
};
|
|
93
|
+
// `credential_types: ['session']` — see `docs/security.md` §Credential-channel gating.
|
|
94
|
+
// A leaked bearer can otherwise compose `account_session_list` + N×revoke to
|
|
95
|
+
// reach the same effect as `account_session_revoke_all`.
|
|
93
96
|
export const account_session_revoke_action_spec = {
|
|
94
97
|
method: 'account_session_revoke',
|
|
95
98
|
kind: 'request_response',
|
|
96
99
|
initiator: 'frontend',
|
|
97
|
-
auth: { account: 'required', actor: 'none' },
|
|
100
|
+
auth: { account: 'required', actor: 'none', credential_types: ['session'] },
|
|
98
101
|
side_effects: true,
|
|
99
102
|
input: SessionRevokeInput,
|
|
100
103
|
output: SessionRevokeOutput,
|
|
101
104
|
async: true,
|
|
102
105
|
description: 'Revoke a single auth session for the current account (IDOR-guarded).',
|
|
103
106
|
};
|
|
107
|
+
// `credential_types: ['session']` — see `docs/security.md` §Credential-channel gating.
|
|
104
108
|
export const account_session_revoke_all_action_spec = {
|
|
105
109
|
method: 'account_session_revoke_all',
|
|
106
110
|
kind: 'request_response',
|
|
107
111
|
initiator: 'frontend',
|
|
108
|
-
auth: { account: 'required', actor: 'none' },
|
|
112
|
+
auth: { account: 'required', actor: 'none', credential_types: ['session'] },
|
|
109
113
|
side_effects: true,
|
|
110
114
|
input: SessionRevokeAllInput,
|
|
111
115
|
output: SessionRevokeAllOutput,
|
|
@@ -113,6 +117,8 @@ export const account_session_revoke_all_action_spec = {
|
|
|
113
117
|
description: 'Revoke every auth session for the current account.',
|
|
114
118
|
};
|
|
115
119
|
/**
|
|
120
|
+
* `credential_types: ['session']` — see `docs/security.md` §Credential-channel gating.
|
|
121
|
+
*
|
|
116
122
|
* `rate_limit: 'account'` bounds the burn rate of API-token creates. The
|
|
117
123
|
* outstanding-token count is already capped by `max_tokens` (via
|
|
118
124
|
* `query_api_token_enforce_limit`), but the per-account *rate* of churn
|
|
@@ -124,7 +130,7 @@ export const account_token_create_action_spec = {
|
|
|
124
130
|
method: 'account_token_create',
|
|
125
131
|
kind: 'request_response',
|
|
126
132
|
initiator: 'frontend',
|
|
127
|
-
auth: { account: 'required', actor: 'none' },
|
|
133
|
+
auth: { account: 'required', actor: 'none', credential_types: ['session'] },
|
|
128
134
|
side_effects: true,
|
|
129
135
|
input: TokenCreateInput,
|
|
130
136
|
output: TokenCreateOutput,
|
|
@@ -143,11 +149,12 @@ export const account_token_list_action_spec = {
|
|
|
143
149
|
async: true,
|
|
144
150
|
description: 'List API tokens for the current account. Hashes are never returned.',
|
|
145
151
|
};
|
|
152
|
+
// `credential_types: ['session']` — see `docs/security.md` §Credential-channel gating.
|
|
146
153
|
export const account_token_revoke_action_spec = {
|
|
147
154
|
method: 'account_token_revoke',
|
|
148
155
|
kind: 'request_response',
|
|
149
156
|
initiator: 'frontend',
|
|
150
|
-
auth: { account: 'required', actor: 'none' },
|
|
157
|
+
auth: { account: 'required', actor: 'none', credential_types: ['session'] },
|
|
151
158
|
side_effects: true,
|
|
152
159
|
input: TokenRevokeInput,
|
|
153
160
|
output: TokenRevokeOutput,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/account_actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAqC,KAAK,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAe5F,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAwBhD,4CAA4C;AAC5C,MAAM,WAAW,oBAAoB;IACpC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,OAAO,CAAC,EAC7C,UAAS,oBAAyB,KAChC,KAAK,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"account_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/account_actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAqC,KAAK,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAe5F,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAwBhD,4CAA4C;AAC5C,MAAM,WAAW,oBAAoB;IACpC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,OAAO,CAAC,EAC7C,UAAS,oBAAyB,KAChC,KAAK,CAAC,SAAS,CA2GjB,CAAC"}
|
|
@@ -54,7 +54,8 @@ export const create_account_actions = (deps, options = {}) => {
|
|
|
54
54
|
outcome: revoked ? 'success' : 'failure',
|
|
55
55
|
account_id: ctx.auth.account.id,
|
|
56
56
|
ip: ctx.client_ip,
|
|
57
|
-
|
|
57
|
+
// `credential_type` defense in depth — see `docs/security.md` §Credential-channel gating.
|
|
58
|
+
metadata: { session_id: input.session_id, credential_type: ctx.credential_type ?? undefined },
|
|
58
59
|
});
|
|
59
60
|
return { ok: true, revoked };
|
|
60
61
|
};
|
|
@@ -64,7 +65,7 @@ export const create_account_actions = (deps, options = {}) => {
|
|
|
64
65
|
event_type: 'session_revoke_all',
|
|
65
66
|
account_id: ctx.auth.account.id,
|
|
66
67
|
ip: ctx.client_ip,
|
|
67
|
-
metadata: { count },
|
|
68
|
+
metadata: { count, credential_type: ctx.credential_type ?? undefined },
|
|
68
69
|
});
|
|
69
70
|
return { ok: true, count };
|
|
70
71
|
};
|
|
@@ -78,7 +79,11 @@ export const create_account_actions = (deps, options = {}) => {
|
|
|
78
79
|
event_type: 'token_create',
|
|
79
80
|
account_id: ctx.auth.account.id,
|
|
80
81
|
ip: ctx.client_ip,
|
|
81
|
-
metadata: {
|
|
82
|
+
metadata: {
|
|
83
|
+
token_id: id,
|
|
84
|
+
name: input.name,
|
|
85
|
+
credential_type: ctx.credential_type ?? undefined,
|
|
86
|
+
},
|
|
82
87
|
});
|
|
83
88
|
return { ok: true, token, id, name: input.name };
|
|
84
89
|
};
|
|
@@ -93,7 +98,7 @@ export const create_account_actions = (deps, options = {}) => {
|
|
|
93
98
|
outcome: revoked ? 'success' : 'failure',
|
|
94
99
|
account_id: ctx.auth.account.id,
|
|
95
100
|
ip: ctx.client_ip,
|
|
96
|
-
metadata: { token_id: input.token_id },
|
|
101
|
+
metadata: { token_id: input.token_id, credential_type: ctx.credential_type ?? undefined },
|
|
97
102
|
});
|
|
98
103
|
return { ok: true, revoked };
|
|
99
104
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account_routes.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/account_routes.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"account_routes.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/account_routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,7 +29,7 @@ import { hash_session_token, query_session_revoke_all_for_account, query_session
|
|
|
29
29
|
import { query_account_by_username_or_email, query_update_account_password, } from './account_queries.js';
|
|
30
30
|
import { query_revoke_all_api_tokens_for_account } from './api_token_queries.js';
|
|
31
31
|
import { build_account_context, build_request_context, get_request_context, require_request_context, resolve_acting_actor, } from './request_context.js';
|
|
32
|
-
import { ACCOUNT_ID_KEY } from '../hono_context.js';
|
|
32
|
+
import { ACCOUNT_ID_KEY, CREDENTIAL_TYPE_KEY } from '../hono_context.js';
|
|
33
33
|
import { get_route_input } from '../http/route_spec.js';
|
|
34
34
|
import { get_client_ip } from '../http/proxy.js';
|
|
35
35
|
import { rate_limit_exceeded_response } from '../rate_limiter.js';
|
|
@@ -355,7 +355,8 @@ export const create_account_route_specs = (deps, options) => {
|
|
|
355
355
|
{
|
|
356
356
|
method: 'POST',
|
|
357
357
|
path: '/password',
|
|
358
|
-
|
|
358
|
+
// `credential_types: ['session']` — see `docs/security.md` §Credential-channel gating.
|
|
359
|
+
auth: { account: 'required', actor: 'none', credential_types: ['session'] },
|
|
359
360
|
description: 'Change password (revokes all sessions and API tokens)',
|
|
360
361
|
input: PasswordChangeInput,
|
|
361
362
|
output: PasswordChangeOutput,
|
|
@@ -376,6 +377,8 @@ export const create_account_route_specs = (deps, options) => {
|
|
|
376
377
|
}
|
|
377
378
|
const ctx = require_request_context(c);
|
|
378
379
|
const { current_password, new_password } = get_route_input(c);
|
|
380
|
+
// Defense in depth — see `docs/security.md` §Credential-channel gating.
|
|
381
|
+
const credential_type = c.get(CREDENTIAL_TYPE_KEY) ?? undefined;
|
|
379
382
|
// per-account rate limit check (after context resolution, before argon2 work)
|
|
380
383
|
if (login_account_rate_limiter) {
|
|
381
384
|
const check = login_account_rate_limiter.check(ctx.account.id);
|
|
@@ -394,6 +397,7 @@ export const create_account_route_specs = (deps, options) => {
|
|
|
394
397
|
outcome: 'failure',
|
|
395
398
|
account_id: ctx.account.id,
|
|
396
399
|
ip: get_client_ip(c),
|
|
400
|
+
metadata: { credential_type },
|
|
397
401
|
});
|
|
398
402
|
return c.json({ error: ERROR_INVALID_CREDENTIALS }, 401);
|
|
399
403
|
}
|
|
@@ -426,7 +430,7 @@ export const create_account_route_specs = (deps, options) => {
|
|
|
426
430
|
outcome: 'failure',
|
|
427
431
|
account_id: ctx.account.id,
|
|
428
432
|
ip: get_client_ip(c),
|
|
429
|
-
metadata: { reason: 'concurrent_change' },
|
|
433
|
+
metadata: { reason: 'concurrent_change', credential_type },
|
|
430
434
|
});
|
|
431
435
|
return c.json({ error: ERROR_INVALID_CREDENTIALS }, 401);
|
|
432
436
|
}
|
|
@@ -442,7 +446,7 @@ export const create_account_route_specs = (deps, options) => {
|
|
|
442
446
|
event_type: 'password_change',
|
|
443
447
|
account_id: ctx.account.id,
|
|
444
448
|
ip: get_client_ip(c),
|
|
445
|
-
metadata: { sessions_revoked, tokens_revoked },
|
|
449
|
+
metadata: { sessions_revoked, tokens_revoked, credential_type },
|
|
446
450
|
});
|
|
447
451
|
return c.json({ ok: true, sessions_revoked, tokens_revoked });
|
|
448
452
|
},
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* `Account`, `Actor`, `RoleGrant`, `AuthSession`, and `ApiToken`.
|
|
6
6
|
*
|
|
7
7
|
* Identifier primitives (`Username`, `UsernameProvided`, `Email`) live
|
|
8
|
-
* in
|
|
8
|
+
* in `primitive_schemas.ts` — they're general validator shapes that
|
|
9
9
|
* don't depend on the auth domain. The auth-shape request-contract
|
|
10
|
-
* primitive `ActingActor` lives in
|
|
10
|
+
* primitive `ActingActor` lives in `http/auth_shape.ts` next to
|
|
11
11
|
* `RouteAuth` (the two pair: `auth.actor !== 'none'` ⟺ input declares
|
|
12
12
|
* `acting?: ActingActor`).
|
|
13
13
|
*
|