@fuzdev/fuz_app 0.54.0 → 0.56.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 +214 -103
- package/dist/actions/action_bridge.d.ts +8 -5
- package/dist/actions/action_bridge.d.ts.map +1 -1
- package/dist/actions/action_bridge.js +1 -11
- package/dist/actions/action_codegen.d.ts +32 -0
- package/dist/actions/action_codegen.d.ts.map +1 -1
- package/dist/actions/action_codegen.js +35 -15
- package/dist/actions/action_registry.d.ts.map +1 -1
- package/dist/actions/action_registry.js +5 -2
- package/dist/actions/action_rpc.d.ts +141 -22
- package/dist/actions/action_rpc.d.ts.map +1 -1
- package/dist/actions/action_rpc.js +106 -187
- package/dist/actions/action_spec.d.ts +55 -16
- package/dist/actions/action_spec.d.ts.map +1 -1
- package/dist/actions/action_spec.js +16 -11
- package/dist/actions/action_types.d.ts +28 -60
- package/dist/actions/action_types.d.ts.map +1 -1
- package/dist/actions/action_types.js +13 -5
- package/dist/actions/broadcast_api.d.ts +2 -2
- package/dist/actions/broadcast_api.js +2 -2
- package/dist/actions/compile_action_registry.d.ts +50 -0
- package/dist/actions/compile_action_registry.d.ts.map +1 -0
- package/dist/actions/compile_action_registry.js +69 -0
- package/dist/actions/heartbeat.d.ts +8 -4
- package/dist/actions/heartbeat.d.ts.map +1 -1
- package/dist/actions/heartbeat.js +5 -4
- package/dist/actions/perform_action.d.ts +145 -0
- package/dist/actions/perform_action.d.ts.map +1 -0
- package/dist/actions/perform_action.js +258 -0
- package/dist/actions/register_action_ws.d.ts +46 -40
- package/dist/actions/register_action_ws.d.ts.map +1 -1
- package/dist/actions/register_action_ws.js +101 -159
- package/dist/actions/register_ws_endpoint.d.ts +15 -10
- package/dist/actions/register_ws_endpoint.d.ts.map +1 -1
- package/dist/actions/register_ws_endpoint.js +54 -7
- package/dist/actions/transports.d.ts.map +1 -1
- package/dist/actions/transports.js +0 -4
- package/dist/actions/transports_ws_auth_guard.d.ts +1 -1
- package/dist/actions/transports_ws_auth_guard.js +1 -1
- package/dist/actions/transports_ws_backend.d.ts +1 -1
- package/dist/actions/transports_ws_backend.js +1 -1
- package/dist/auth/CLAUDE.md +794 -410
- package/dist/auth/account_action_specs.d.ts +28 -7
- package/dist/auth/account_action_specs.d.ts.map +1 -1
- package/dist/auth/account_action_specs.js +7 -7
- package/dist/auth/account_actions.d.ts +7 -13
- package/dist/auth/account_actions.d.ts.map +1 -1
- package/dist/auth/account_actions.js +26 -35
- package/dist/auth/account_queries.d.ts +52 -16
- package/dist/auth/account_queries.d.ts.map +1 -1
- package/dist/auth/account_queries.js +87 -38
- package/dist/auth/account_routes.d.ts +9 -11
- package/dist/auth/account_routes.d.ts.map +1 -1
- package/dist/auth/account_routes.js +118 -46
- package/dist/auth/account_schema.d.ts +46 -35
- package/dist/auth/account_schema.d.ts.map +1 -1
- package/dist/auth/account_schema.js +21 -28
- package/dist/auth/admin_action_specs.d.ts +100 -32
- package/dist/auth/admin_action_specs.d.ts.map +1 -1
- package/dist/auth/admin_action_specs.js +64 -33
- package/dist/auth/admin_actions.d.ts +13 -19
- package/dist/auth/admin_actions.d.ts.map +1 -1
- package/dist/auth/admin_actions.js +37 -41
- package/dist/auth/audit_emitter.d.ts +160 -0
- package/dist/auth/audit_emitter.d.ts.map +1 -0
- package/dist/auth/audit_emitter.js +83 -0
- package/dist/auth/audit_log_queries.d.ts +17 -48
- package/dist/auth/audit_log_queries.d.ts.map +1 -1
- package/dist/auth/audit_log_queries.js +20 -56
- package/dist/auth/audit_log_routes.d.ts +1 -1
- package/dist/auth/audit_log_routes.d.ts.map +1 -1
- package/dist/auth/audit_log_routes.js +7 -3
- package/dist/auth/audit_log_schema.d.ts +92 -32
- package/dist/auth/audit_log_schema.d.ts.map +1 -1
- package/dist/auth/audit_log_schema.js +75 -46
- package/dist/auth/auth_guard_resolver.d.ts +44 -0
- package/dist/auth/auth_guard_resolver.d.ts.map +1 -0
- package/dist/auth/auth_guard_resolver.js +56 -0
- package/dist/auth/bearer_auth.d.ts +9 -7
- package/dist/auth/bearer_auth.d.ts.map +1 -1
- package/dist/auth/bearer_auth.js +13 -21
- package/dist/auth/bootstrap_account.d.ts +7 -7
- package/dist/auth/bootstrap_account.d.ts.map +1 -1
- package/dist/auth/bootstrap_account.js +7 -7
- package/dist/auth/bootstrap_routes.d.ts.map +1 -1
- package/dist/auth/bootstrap_routes.js +11 -10
- package/dist/auth/cleanup.d.ts +20 -26
- package/dist/auth/cleanup.d.ts.map +1 -1
- package/dist/auth/cleanup.js +33 -42
- package/dist/auth/credential_type_schema.d.ts +115 -0
- package/dist/auth/credential_type_schema.d.ts.map +1 -0
- package/dist/auth/credential_type_schema.js +127 -0
- package/dist/auth/daemon_token_middleware.d.ts +23 -11
- package/dist/auth/daemon_token_middleware.d.ts.map +1 -1
- package/dist/auth/daemon_token_middleware.js +28 -22
- package/dist/auth/ddl.d.ts +2 -2
- package/dist/auth/ddl.d.ts.map +1 -1
- package/dist/auth/ddl.js +6 -6
- package/dist/auth/deps.d.ts +7 -18
- package/dist/auth/deps.d.ts.map +1 -1
- package/dist/auth/grant_path_schema.d.ts +117 -0
- package/dist/auth/grant_path_schema.d.ts.map +1 -0
- package/dist/auth/grant_path_schema.js +137 -0
- package/dist/auth/invite_queries.d.ts +12 -1
- package/dist/auth/invite_queries.d.ts.map +1 -1
- package/dist/auth/invite_queries.js +12 -1
- package/dist/auth/invite_schema.d.ts +1 -1
- package/dist/auth/invite_schema.d.ts.map +1 -1
- package/dist/auth/invite_schema.js +1 -1
- package/dist/auth/middleware.d.ts.map +1 -1
- package/dist/auth/middleware.js +9 -4
- package/dist/auth/migrations.d.ts +37 -14
- package/dist/auth/migrations.d.ts.map +1 -1
- package/dist/auth/migrations.js +79 -32
- package/dist/auth/request_context.d.ts +331 -61
- package/dist/auth/request_context.d.ts.map +1 -1
- package/dist/auth/request_context.js +378 -95
- package/dist/auth/{permit_offer_action_specs.d.ts → role_grant_offer_action_specs.d.ts} +163 -94
- package/dist/auth/role_grant_offer_action_specs.d.ts.map +1 -0
- package/dist/auth/role_grant_offer_action_specs.js +262 -0
- package/dist/auth/role_grant_offer_actions.d.ts +104 -0
- package/dist/auth/role_grant_offer_actions.d.ts.map +1 -0
- package/dist/auth/role_grant_offer_actions.js +473 -0
- package/dist/auth/{permit_offer_notifications.d.ts → role_grant_offer_notifications.d.ts} +90 -70
- package/dist/auth/role_grant_offer_notifications.d.ts.map +1 -0
- package/dist/auth/role_grant_offer_notifications.js +182 -0
- package/dist/auth/role_grant_offer_queries.d.ts +242 -0
- package/dist/auth/role_grant_offer_queries.d.ts.map +1 -0
- package/dist/auth/role_grant_offer_queries.js +533 -0
- package/dist/auth/role_grant_offer_schema.d.ts +150 -0
- package/dist/auth/role_grant_offer_schema.d.ts.map +1 -0
- package/dist/auth/{permit_offer_schema.js → role_grant_offer_schema.js} +60 -36
- package/dist/auth/role_grant_queries.d.ts +231 -0
- package/dist/auth/role_grant_queries.d.ts.map +1 -0
- package/dist/auth/role_grant_queries.js +320 -0
- package/dist/auth/role_schema.d.ts +150 -40
- package/dist/auth/role_schema.d.ts.map +1 -1
- package/dist/auth/role_schema.js +144 -45
- package/dist/auth/scope_kind_schema.d.ts +96 -0
- package/dist/auth/scope_kind_schema.d.ts.map +1 -0
- package/dist/auth/scope_kind_schema.js +94 -0
- package/dist/auth/self_service_role_action_specs.d.ts +6 -1
- package/dist/auth/self_service_role_action_specs.d.ts.map +1 -1
- package/dist/auth/self_service_role_action_specs.js +3 -1
- package/dist/auth/self_service_role_actions.d.ts +34 -27
- package/dist/auth/self_service_role_actions.d.ts.map +1 -1
- package/dist/auth/self_service_role_actions.js +68 -48
- package/dist/auth/session_cookie.d.ts +43 -6
- package/dist/auth/session_cookie.d.ts.map +1 -1
- package/dist/auth/session_cookie.js +31 -5
- package/dist/auth/session_middleware.d.ts +37 -3
- package/dist/auth/session_middleware.d.ts.map +1 -1
- package/dist/auth/session_middleware.js +33 -7
- package/dist/auth/signup_routes.d.ts.map +1 -1
- package/dist/auth/signup_routes.js +48 -19
- package/dist/auth/standard_action_specs.d.ts +2 -2
- package/dist/auth/standard_action_specs.js +4 -4
- package/dist/auth/standard_rpc_actions.d.ts +23 -19
- package/dist/auth/standard_rpc_actions.d.ts.map +1 -1
- package/dist/auth/standard_rpc_actions.js +12 -12
- package/dist/db/migrate.d.ts +12 -8
- package/dist/db/migrate.d.ts.map +1 -1
- package/dist/db/migrate.js +10 -7
- package/dist/dev/setup.d.ts +2 -2
- package/dist/dev/setup.d.ts.map +1 -1
- package/dist/dev/setup.js +9 -7
- package/dist/env/load.d.ts +1 -1
- package/dist/env/load.js +1 -1
- package/dist/hono_context.d.ts +64 -5
- package/dist/hono_context.d.ts.map +1 -1
- package/dist/hono_context.js +38 -2
- package/dist/http/CLAUDE.md +264 -87
- package/dist/http/auth_shape.d.ts +191 -0
- package/dist/http/auth_shape.d.ts.map +1 -0
- package/dist/http/auth_shape.js +237 -0
- package/dist/http/common_routes.js +3 -3
- package/dist/http/db_routes.d.ts +4 -0
- package/dist/http/db_routes.d.ts.map +1 -1
- package/dist/http/db_routes.js +44 -7
- package/dist/http/error_schemas.d.ts +132 -19
- package/dist/http/error_schemas.d.ts.map +1 -1
- package/dist/http/error_schemas.js +132 -40
- package/dist/http/jsonrpc_errors.d.ts +27 -2
- package/dist/http/jsonrpc_errors.d.ts.map +1 -1
- package/dist/http/jsonrpc_errors.js +26 -2
- package/dist/http/pending_effects.d.ts +71 -18
- package/dist/http/pending_effects.d.ts.map +1 -1
- package/dist/http/pending_effects.js +87 -18
- package/dist/http/proxy.d.ts +52 -5
- package/dist/http/proxy.d.ts.map +1 -1
- package/dist/http/proxy.js +92 -14
- package/dist/http/route_spec.d.ts +113 -41
- package/dist/http/route_spec.d.ts.map +1 -1
- package/dist/http/route_spec.js +130 -52
- package/dist/http/schema_helpers.d.ts +3 -2
- package/dist/http/schema_helpers.d.ts.map +1 -1
- package/dist/http/schema_helpers.js +9 -2
- package/dist/http/surface.d.ts +2 -1
- package/dist/http/surface.d.ts.map +1 -1
- package/dist/http/surface.js +1 -2
- package/dist/http/surface_query.d.ts +39 -35
- package/dist/http/surface_query.d.ts.map +1 -1
- package/dist/http/surface_query.js +79 -36
- package/dist/primitive_schemas.d.ts +39 -0
- package/dist/primitive_schemas.d.ts.map +1 -0
- package/dist/primitive_schemas.js +40 -0
- package/dist/realtime/sse_auth_guard.d.ts +5 -5
- package/dist/realtime/sse_auth_guard.js +9 -9
- package/dist/runtime/mock.d.ts +1 -1
- package/dist/runtime/mock.js +1 -1
- package/dist/server/app_backend.d.ts +14 -11
- package/dist/server/app_backend.d.ts.map +1 -1
- package/dist/server/app_backend.js +12 -8
- package/dist/server/app_server.d.ts +7 -7
- package/dist/server/app_server.d.ts.map +1 -1
- package/dist/server/app_server.js +36 -31
- package/dist/server/validate_nginx.d.ts +1 -1
- package/dist/server/validate_nginx.js +1 -1
- package/dist/testing/CLAUDE.md +73 -55
- package/dist/testing/admin_integration.d.ts +5 -6
- package/dist/testing/admin_integration.d.ts.map +1 -1
- package/dist/testing/admin_integration.js +100 -96
- package/dist/testing/adversarial_headers.js +1 -1
- package/dist/testing/app_server.d.ts +11 -14
- package/dist/testing/app_server.d.ts.map +1 -1
- package/dist/testing/app_server.js +18 -17
- package/dist/testing/assertions.d.ts.map +1 -1
- package/dist/testing/assertions.js +2 -1
- package/dist/testing/attack_surface.d.ts.map +1 -1
- package/dist/testing/attack_surface.js +15 -9
- package/dist/testing/audit_completeness.d.ts +2 -2
- package/dist/testing/audit_completeness.d.ts.map +1 -1
- package/dist/testing/audit_completeness.js +53 -39
- package/dist/testing/auth_apps.d.ts +5 -4
- package/dist/testing/auth_apps.d.ts.map +1 -1
- package/dist/testing/auth_apps.js +28 -22
- package/dist/testing/data_exposure.d.ts.map +1 -1
- package/dist/testing/data_exposure.js +5 -5
- package/dist/testing/db.d.ts +1 -1
- package/dist/testing/db.d.ts.map +1 -1
- package/dist/testing/db.js +4 -4
- package/dist/testing/db_entities.d.ts +22 -0
- package/dist/testing/db_entities.d.ts.map +1 -0
- package/dist/testing/db_entities.js +28 -0
- package/dist/testing/entities.d.ts +10 -8
- package/dist/testing/entities.d.ts.map +1 -1
- package/dist/testing/entities.js +22 -18
- package/dist/testing/integration.d.ts.map +1 -1
- package/dist/testing/integration.js +13 -14
- package/dist/testing/integration_helpers.d.ts +8 -6
- package/dist/testing/integration_helpers.d.ts.map +1 -1
- package/dist/testing/integration_helpers.js +29 -23
- package/dist/testing/middleware.d.ts +15 -11
- package/dist/testing/middleware.d.ts.map +1 -1
- package/dist/testing/middleware.js +75 -32
- package/dist/testing/rpc_attack_surface.d.ts.map +1 -1
- package/dist/testing/rpc_attack_surface.js +40 -24
- package/dist/testing/rpc_helpers.d.ts.map +1 -1
- package/dist/testing/rpc_helpers.js +3 -1
- package/dist/testing/rpc_round_trip.d.ts +1 -1
- package/dist/testing/rpc_round_trip.d.ts.map +1 -1
- package/dist/testing/rpc_round_trip.js +14 -13
- package/dist/testing/sse_round_trip.d.ts +3 -4
- package/dist/testing/sse_round_trip.d.ts.map +1 -1
- package/dist/testing/sse_round_trip.js +7 -11
- package/dist/testing/standard.d.ts +1 -1
- package/dist/testing/stubs.d.ts +25 -0
- package/dist/testing/stubs.d.ts.map +1 -1
- package/dist/testing/stubs.js +43 -2
- package/dist/testing/surface_invariants.d.ts +2 -2
- package/dist/testing/ws_round_trip.d.ts +12 -13
- package/dist/testing/ws_round_trip.d.ts.map +1 -1
- package/dist/testing/ws_round_trip.js +24 -12
- package/dist/ui/AdminAccounts.svelte +23 -20
- package/dist/ui/AdminOverview.svelte +15 -13
- package/dist/ui/AdminOverview.svelte.d.ts.map +1 -1
- package/dist/ui/{AdminPermitHistory.svelte → AdminRoleGrantHistory.svelte} +12 -12
- package/dist/ui/AdminRoleGrantHistory.svelte.d.ts +4 -0
- package/dist/ui/AdminRoleGrantHistory.svelte.d.ts.map +1 -0
- package/dist/ui/BootstrapForm.svelte +1 -1
- package/dist/ui/CLAUDE.md +65 -59
- package/dist/ui/{PermitOfferForm.svelte → RoleGrantOfferForm.svelte} +37 -22
- package/dist/ui/RoleGrantOfferForm.svelte.d.ts +20 -0
- package/dist/ui/RoleGrantOfferForm.svelte.d.ts.map +1 -0
- package/dist/ui/{PermitOfferHistory.svelte → RoleGrantOfferHistory.svelte} +12 -12
- package/dist/ui/{PermitOfferHistory.svelte.d.ts → RoleGrantOfferHistory.svelte.d.ts} +4 -4
- package/dist/ui/RoleGrantOfferHistory.svelte.d.ts.map +1 -0
- package/dist/ui/{PermitOfferInbox.svelte → RoleGrantOfferInbox.svelte} +14 -14
- package/dist/ui/{PermitOfferInbox.svelte.d.ts → RoleGrantOfferInbox.svelte.d.ts} +4 -4
- package/dist/ui/RoleGrantOfferInbox.svelte.d.ts.map +1 -0
- package/dist/ui/SignupForm.svelte +1 -1
- package/dist/ui/SurfaceExplorer.svelte +35 -15
- package/dist/ui/SurfaceExplorer.svelte.d.ts.map +1 -1
- package/dist/ui/account_sessions_state.svelte.d.ts +2 -3
- package/dist/ui/account_sessions_state.svelte.d.ts.map +1 -1
- package/dist/ui/account_sessions_state.svelte.js +2 -3
- package/dist/ui/admin_accounts_state.svelte.d.ts +25 -18
- package/dist/ui/admin_accounts_state.svelte.d.ts.map +1 -1
- package/dist/ui/admin_accounts_state.svelte.js +28 -17
- package/dist/ui/admin_rpc_adapters.d.ts +20 -20
- package/dist/ui/admin_rpc_adapters.d.ts.map +1 -1
- package/dist/ui/admin_rpc_adapters.js +17 -17
- package/dist/ui/admin_sessions_state.svelte.d.ts +2 -2
- package/dist/ui/admin_sessions_state.svelte.js +2 -2
- package/dist/ui/audit_log_state.svelte.d.ts +7 -7
- package/dist/ui/audit_log_state.svelte.d.ts.map +1 -1
- package/dist/ui/audit_log_state.svelte.js +6 -6
- package/dist/ui/auth_state.svelte.d.ts +3 -3
- package/dist/ui/auth_state.svelte.d.ts.map +1 -1
- package/dist/ui/auth_state.svelte.js +6 -6
- package/dist/ui/format_scope.d.ts +2 -2
- package/dist/ui/format_scope.js +2 -2
- package/dist/ui/{permit_offers_state.svelte.d.ts → role_grant_offers_state.svelte.d.ts} +39 -31
- package/dist/ui/role_grant_offers_state.svelte.d.ts.map +1 -0
- package/dist/ui/{permit_offers_state.svelte.js → role_grant_offers_state.svelte.js} +25 -19
- package/dist/ui/ui_format.js +2 -2
- package/package.json +3 -3
- package/dist/auth/permit_offer_action_specs.d.ts.map +0 -1
- package/dist/auth/permit_offer_action_specs.js +0 -227
- package/dist/auth/permit_offer_actions.d.ts +0 -110
- package/dist/auth/permit_offer_actions.d.ts.map +0 -1
- package/dist/auth/permit_offer_actions.js +0 -452
- package/dist/auth/permit_offer_notifications.d.ts.map +0 -1
- package/dist/auth/permit_offer_notifications.js +0 -182
- package/dist/auth/permit_offer_queries.d.ts +0 -183
- package/dist/auth/permit_offer_queries.d.ts.map +0 -1
- package/dist/auth/permit_offer_queries.js +0 -408
- package/dist/auth/permit_offer_schema.d.ts +0 -103
- package/dist/auth/permit_offer_schema.d.ts.map +0 -1
- package/dist/auth/permit_queries.d.ts +0 -210
- package/dist/auth/permit_queries.d.ts.map +0 -1
- package/dist/auth/permit_queries.js +0 -294
- package/dist/auth/require_keeper.d.ts +0 -20
- package/dist/auth/require_keeper.d.ts.map +0 -1
- package/dist/auth/require_keeper.js +0 -35
- package/dist/auth/route_guards.d.ts +0 -21
- package/dist/auth/route_guards.d.ts.map +0 -1
- package/dist/auth/route_guards.js +0 -32
- package/dist/auth/session_lifecycle.d.ts +0 -37
- package/dist/auth/session_lifecycle.d.ts.map +0 -1
- package/dist/auth/session_lifecycle.js +0 -29
- package/dist/ui/AdminPermitHistory.svelte.d.ts +0 -4
- package/dist/ui/AdminPermitHistory.svelte.d.ts.map +0 -1
- package/dist/ui/PermitOfferForm.svelte.d.ts +0 -14
- package/dist/ui/PermitOfferForm.svelte.d.ts.map +0 -1
- package/dist/ui/PermitOfferHistory.svelte.d.ts.map +0 -1
- package/dist/ui/PermitOfferInbox.svelte.d.ts.map +0 -1
- package/dist/ui/permit_offers_state.svelte.d.ts.map +0 -1
|
@@ -32,14 +32,11 @@ export type AccountStatusInput = z.infer<typeof AccountStatusInput>;
|
|
|
32
32
|
/**
|
|
33
33
|
* Output for `GET /api/account/status` on the authenticated path.
|
|
34
34
|
*
|
|
35
|
-
* `account`
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* `revoked_reason` are never populated here, so `PermitSummaryJson`
|
|
41
|
-
* carries the fields a client actually needs (including `scope_id` for
|
|
42
|
-
* per-scope auth decisions).
|
|
35
|
+
* `account` is always populated for authenticated callers. `actor` and
|
|
36
|
+
* `role_grants` are populated when the caller's account has a unique actor or
|
|
37
|
+
* the request supplies `?acting=<actor_id>`; on multi-actor accounts
|
|
38
|
+
* without an `acting` query, `actor` is `null` and `role_grants` is empty so
|
|
39
|
+
* the frontend can show a persona picker without a separate roundtrip.
|
|
43
40
|
*/
|
|
44
41
|
export declare const AccountStatusOutput: z.ZodObject<{
|
|
45
42
|
account: z.ZodObject<{
|
|
@@ -49,13 +46,14 @@ export declare const AccountStatusOutput: z.ZodObject<{
|
|
|
49
46
|
email_verified: z.ZodBoolean;
|
|
50
47
|
created_at: z.ZodString;
|
|
51
48
|
}, z.core.$strict>;
|
|
52
|
-
actor: z.ZodObject<{
|
|
49
|
+
actor: z.ZodNullable<z.ZodObject<{
|
|
53
50
|
id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
|
|
54
51
|
name: z.ZodString;
|
|
55
|
-
}, z.core.$strict
|
|
56
|
-
|
|
52
|
+
}, z.core.$strict>>;
|
|
53
|
+
role_grants: z.ZodArray<z.ZodObject<{
|
|
57
54
|
id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
|
|
58
55
|
role: z.ZodString;
|
|
56
|
+
scope_kind: z.ZodNullable<z.ZodString>;
|
|
59
57
|
scope_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
|
|
60
58
|
created_at: z.ZodString;
|
|
61
59
|
expires_at: z.ZodNullable<z.ZodString>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account_routes.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/account_routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"account_routes.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/account_routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,14 +22,14 @@
|
|
|
22
22
|
* @module
|
|
23
23
|
*/
|
|
24
24
|
import { z } from 'zod';
|
|
25
|
-
import { clear_session_cookie } from './session_middleware.js';
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
25
|
+
import { clear_session_cookie, create_session_and_set_cookie } from './session_middleware.js';
|
|
26
|
+
import { ActorSummaryJson, RoleGrantSummaryJson, SessionAccountJson, to_session_account, } from './account_schema.js';
|
|
27
|
+
import { UsernameProvided } from '../primitive_schemas.js';
|
|
28
28
|
import { hash_session_token, query_session_revoke_all_for_account, query_session_revoke_by_hash_unscoped, } from './session_queries.js';
|
|
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
|
-
import {
|
|
32
|
-
import {
|
|
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';
|
|
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';
|
|
@@ -40,19 +40,16 @@ export const AccountStatusInput = z.null();
|
|
|
40
40
|
/**
|
|
41
41
|
* Output for `GET /api/account/status` on the authenticated path.
|
|
42
42
|
*
|
|
43
|
-
* `account`
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* `revoked_reason` are never populated here, so `PermitSummaryJson`
|
|
49
|
-
* carries the fields a client actually needs (including `scope_id` for
|
|
50
|
-
* per-scope auth decisions).
|
|
43
|
+
* `account` is always populated for authenticated callers. `actor` and
|
|
44
|
+
* `role_grants` are populated when the caller's account has a unique actor or
|
|
45
|
+
* the request supplies `?acting=<actor_id>`; on multi-actor accounts
|
|
46
|
+
* without an `acting` query, `actor` is `null` and `role_grants` is empty so
|
|
47
|
+
* the frontend can show a persona picker without a separate roundtrip.
|
|
51
48
|
*/
|
|
52
49
|
export const AccountStatusOutput = z.strictObject({
|
|
53
50
|
account: SessionAccountJson,
|
|
54
|
-
actor: ActorSummaryJson,
|
|
55
|
-
|
|
51
|
+
actor: ActorSummaryJson.nullable(),
|
|
52
|
+
role_grants: z.array(RoleGrantSummaryJson),
|
|
56
53
|
});
|
|
57
54
|
/** Error body for `GET /api/account/status` on the unauthenticated path. */
|
|
58
55
|
export const AccountStatusUnauthenticatedError = z.looseObject({
|
|
@@ -75,34 +72,79 @@ export const AccountStatusUnauthenticatedError = z.looseObject({
|
|
|
75
72
|
export const create_account_status_route_spec = (options) => ({
|
|
76
73
|
method: 'GET',
|
|
77
74
|
path: options?.path ?? '/api/account/status',
|
|
78
|
-
auth: {
|
|
75
|
+
auth: { account: 'none', actor: 'none' },
|
|
79
76
|
description: 'Current account info (unauthenticated: 401 with bootstrap status)',
|
|
80
77
|
input: AccountStatusInput,
|
|
81
78
|
output: AccountStatusOutput,
|
|
82
79
|
errors: {
|
|
83
80
|
401: AccountStatusUnauthenticatedError,
|
|
84
81
|
},
|
|
85
|
-
handler: (c) => {
|
|
86
|
-
const
|
|
87
|
-
if (
|
|
88
|
-
|
|
82
|
+
handler: async (c, route) => {
|
|
83
|
+
const account_id = c.get(ACCOUNT_ID_KEY) ?? null;
|
|
84
|
+
if (!account_id) {
|
|
85
|
+
return c.json({
|
|
86
|
+
error: ERROR_AUTHENTICATION_REQUIRED,
|
|
87
|
+
...(options?.bootstrap_status?.available ? { bootstrap_available: true } : {}),
|
|
88
|
+
}, 401);
|
|
89
|
+
}
|
|
90
|
+
// Honor a pre-populated request context. The dispatcher's authorization
|
|
91
|
+
// phase doesn't run for `auth: 'none'` routes, but a caller (test
|
|
92
|
+
// harness, or future middleware) may still populate the context — use
|
|
93
|
+
// it directly to avoid redundant lookups.
|
|
94
|
+
const existing = get_request_context(c);
|
|
95
|
+
if (existing && existing.account.id === account_id) {
|
|
96
|
+
const role_grants = existing.role_grants.map((p) => ({
|
|
89
97
|
id: p.id,
|
|
90
98
|
role: p.role,
|
|
99
|
+
scope_kind: p.scope_kind,
|
|
91
100
|
scope_id: p.scope_id,
|
|
92
101
|
created_at: p.created_at,
|
|
93
102
|
expires_at: p.expires_at,
|
|
94
103
|
granted_by: p.granted_by,
|
|
95
104
|
}));
|
|
96
105
|
return c.json({
|
|
97
|
-
account: to_session_account(
|
|
98
|
-
actor: { id:
|
|
99
|
-
|
|
106
|
+
account: to_session_account(existing.account),
|
|
107
|
+
actor: existing.actor ? { id: existing.actor.id, name: existing.actor.name } : null,
|
|
108
|
+
role_grants,
|
|
100
109
|
});
|
|
101
110
|
}
|
|
111
|
+
// Resolve actor + role_grants when the caller is unambiguous (single-actor
|
|
112
|
+
// account, or supplied `?acting=<uuid>`). On multi-actor accounts
|
|
113
|
+
// without `acting`, fall back to account-only so the frontend can
|
|
114
|
+
// surface a persona picker.
|
|
115
|
+
const acting = c.req.query('acting') ?? undefined;
|
|
116
|
+
const acting_result = await resolve_acting_actor(route, account_id, acting);
|
|
117
|
+
if (acting_result.ok) {
|
|
118
|
+
const ctx = await build_request_context(route, account_id, acting_result.actor_id);
|
|
119
|
+
if (ctx) {
|
|
120
|
+
const role_grants = ctx.role_grants.map((p) => ({
|
|
121
|
+
id: p.id,
|
|
122
|
+
role: p.role,
|
|
123
|
+
scope_kind: p.scope_kind,
|
|
124
|
+
scope_id: p.scope_id,
|
|
125
|
+
created_at: p.created_at,
|
|
126
|
+
expires_at: p.expires_at,
|
|
127
|
+
granted_by: p.granted_by,
|
|
128
|
+
}));
|
|
129
|
+
return c.json({
|
|
130
|
+
account: to_session_account(ctx.account),
|
|
131
|
+
actor: { id: ctx.actor.id, name: ctx.actor.name },
|
|
132
|
+
role_grants,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const account_ctx = await build_account_context(route, account_id);
|
|
137
|
+
if (!account_ctx) {
|
|
138
|
+
return c.json({
|
|
139
|
+
error: ERROR_AUTHENTICATION_REQUIRED,
|
|
140
|
+
...(options?.bootstrap_status?.available ? { bootstrap_available: true } : {}),
|
|
141
|
+
}, 401);
|
|
142
|
+
}
|
|
102
143
|
return c.json({
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
144
|
+
account: to_session_account(account_ctx.account),
|
|
145
|
+
actor: null,
|
|
146
|
+
role_grants: [],
|
|
147
|
+
});
|
|
106
148
|
},
|
|
107
149
|
});
|
|
108
150
|
/** Default maximum sessions per account. */
|
|
@@ -180,7 +222,7 @@ export const create_account_route_specs = (deps, options) => {
|
|
|
180
222
|
{
|
|
181
223
|
method: 'GET',
|
|
182
224
|
path: '/verify',
|
|
183
|
-
auth: {
|
|
225
|
+
auth: { account: 'required', actor: 'none' },
|
|
184
226
|
description: 'Session-validity probe for nginx auth_request (empty body, 200 or 401)',
|
|
185
227
|
input: z.null(),
|
|
186
228
|
output: z.null(),
|
|
@@ -192,7 +234,7 @@ export const create_account_route_specs = (deps, options) => {
|
|
|
192
234
|
{
|
|
193
235
|
method: 'POST',
|
|
194
236
|
path: '/login',
|
|
195
|
-
auth: {
|
|
237
|
+
auth: { account: 'none', actor: 'none' },
|
|
196
238
|
description: 'Exchange credentials for session',
|
|
197
239
|
input: LoginInput,
|
|
198
240
|
output: LoginOutput,
|
|
@@ -238,12 +280,12 @@ export const create_account_route_specs = (deps, options) => {
|
|
|
238
280
|
ip_rate_limiter.record(ip);
|
|
239
281
|
if (login_account_rate_limiter)
|
|
240
282
|
login_account_rate_limiter.record(account_rate_key);
|
|
241
|
-
|
|
283
|
+
deps.audit.emit(route, {
|
|
242
284
|
event_type: 'login',
|
|
243
285
|
outcome: 'failure',
|
|
244
286
|
ip: get_client_ip(c),
|
|
245
287
|
metadata: { username },
|
|
246
|
-
}
|
|
288
|
+
});
|
|
247
289
|
await delay;
|
|
248
290
|
return c.json({ error: ERROR_INVALID_CREDENTIALS }, 401);
|
|
249
291
|
}
|
|
@@ -253,13 +295,13 @@ export const create_account_route_specs = (deps, options) => {
|
|
|
253
295
|
ip_rate_limiter.record(ip);
|
|
254
296
|
if (login_account_rate_limiter)
|
|
255
297
|
login_account_rate_limiter.record(account_rate_key);
|
|
256
|
-
|
|
298
|
+
deps.audit.emit(route, {
|
|
257
299
|
event_type: 'login',
|
|
258
300
|
outcome: 'failure',
|
|
259
301
|
account_id: account.id,
|
|
260
302
|
ip: get_client_ip(c),
|
|
261
303
|
metadata: { username },
|
|
262
|
-
}
|
|
304
|
+
});
|
|
263
305
|
await delay;
|
|
264
306
|
return c.json({ error: ERROR_INVALID_CREDENTIALS }, 401);
|
|
265
307
|
}
|
|
@@ -276,18 +318,18 @@ export const create_account_route_specs = (deps, options) => {
|
|
|
276
318
|
session_options,
|
|
277
319
|
max_sessions,
|
|
278
320
|
});
|
|
279
|
-
|
|
321
|
+
deps.audit.emit(route, {
|
|
280
322
|
event_type: 'login',
|
|
281
323
|
account_id: account.id,
|
|
282
324
|
ip: get_client_ip(c),
|
|
283
|
-
}
|
|
325
|
+
});
|
|
284
326
|
return c.json({ ok: true });
|
|
285
327
|
},
|
|
286
328
|
},
|
|
287
329
|
{
|
|
288
330
|
method: 'POST',
|
|
289
331
|
path: '/logout',
|
|
290
|
-
auth: {
|
|
332
|
+
auth: { account: 'required', actor: 'none' },
|
|
291
333
|
description: 'Revoke current session and clear cookie',
|
|
292
334
|
input: LogoutInput,
|
|
293
335
|
output: LogoutOutput,
|
|
@@ -299,19 +341,21 @@ export const create_account_route_specs = (deps, options) => {
|
|
|
299
341
|
await query_session_revoke_by_hash_unscoped(route, token_hash);
|
|
300
342
|
}
|
|
301
343
|
clear_session_cookie(c, session_options);
|
|
302
|
-
|
|
344
|
+
// Account-grain operation — no `actor_id` (which actor was
|
|
345
|
+
// resolved per-request is incidental to "this account ended
|
|
346
|
+
// its session"). Mirrors `login`.
|
|
347
|
+
deps.audit.emit(route, {
|
|
303
348
|
event_type: 'logout',
|
|
304
|
-
actor_id: ctx.actor.id,
|
|
305
349
|
account_id: ctx.account.id,
|
|
306
350
|
ip: get_client_ip(c),
|
|
307
|
-
}
|
|
351
|
+
});
|
|
308
352
|
return c.json({ ok: true, username: ctx.account.username });
|
|
309
353
|
},
|
|
310
354
|
},
|
|
311
355
|
{
|
|
312
356
|
method: 'POST',
|
|
313
357
|
path: '/password',
|
|
314
|
-
auth: {
|
|
358
|
+
auth: { account: 'required', actor: 'none' },
|
|
315
359
|
description: 'Change password (revokes all sessions and API tokens)',
|
|
316
360
|
input: PasswordChangeInput,
|
|
317
361
|
output: PasswordChangeOutput,
|
|
@@ -345,13 +389,12 @@ export const create_account_route_specs = (deps, options) => {
|
|
|
345
389
|
ip_rate_limiter.record(ip);
|
|
346
390
|
if (login_account_rate_limiter)
|
|
347
391
|
login_account_rate_limiter.record(ctx.account.id);
|
|
348
|
-
|
|
392
|
+
deps.audit.emit(route, {
|
|
349
393
|
event_type: 'password_change',
|
|
350
394
|
outcome: 'failure',
|
|
351
|
-
actor_id: ctx.actor.id,
|
|
352
395
|
account_id: ctx.account.id,
|
|
353
396
|
ip: get_client_ip(c),
|
|
354
|
-
}
|
|
397
|
+
});
|
|
355
398
|
return c.json({ error: ERROR_INVALID_CREDENTIALS }, 401);
|
|
356
399
|
}
|
|
357
400
|
// successful verification — reset rate limiters
|
|
@@ -360,18 +403,47 @@ export const create_account_route_specs = (deps, options) => {
|
|
|
360
403
|
if (login_account_rate_limiter)
|
|
361
404
|
login_account_rate_limiter.reset(ctx.account.id);
|
|
362
405
|
const new_hash = await password.hash_password(new_password);
|
|
363
|
-
|
|
406
|
+
// Conditional UPDATE keyed on the verified hash: closes the
|
|
407
|
+
// verify-write race with a concurrent password change that
|
|
408
|
+
// already committed against the same starting hash. Account-grain
|
|
409
|
+
// operation — `updated_by` stays null (the per-request actor is
|
|
410
|
+
// incidental; password is account-level state).
|
|
411
|
+
const updated = await query_update_account_password(route, ctx.account.id, new_hash, null, ctx.account.password_hash);
|
|
412
|
+
if (!updated) {
|
|
413
|
+
// A concurrent password change committed first — our
|
|
414
|
+
// `current_password` was correct at read-time but the row's
|
|
415
|
+
// `password_hash` no longer matches. Mirrors the wrong-password
|
|
416
|
+
// 401 shape; tag the failure metadata so admins reading the
|
|
417
|
+
// audit log can distinguish "user typoed" from "two clients
|
|
418
|
+
// raced." Sessions/tokens were already revoked by the winner;
|
|
419
|
+
// no cookie clear here either.
|
|
420
|
+
if (ip_rate_limiter && ip)
|
|
421
|
+
ip_rate_limiter.record(ip);
|
|
422
|
+
if (login_account_rate_limiter)
|
|
423
|
+
login_account_rate_limiter.record(ctx.account.id);
|
|
424
|
+
deps.audit.emit(route, {
|
|
425
|
+
event_type: 'password_change',
|
|
426
|
+
outcome: 'failure',
|
|
427
|
+
account_id: ctx.account.id,
|
|
428
|
+
ip: get_client_ip(c),
|
|
429
|
+
metadata: { reason: 'concurrent_change' },
|
|
430
|
+
});
|
|
431
|
+
return c.json({ error: ERROR_INVALID_CREDENTIALS }, 401);
|
|
432
|
+
}
|
|
364
433
|
// revoke all sessions and API tokens (force re-auth everywhere)
|
|
365
434
|
const sessions_revoked = await query_session_revoke_all_for_account(route, ctx.account.id);
|
|
366
435
|
const tokens_revoked = await query_revoke_all_api_tokens_for_account(route, ctx.account.id);
|
|
367
436
|
clear_session_cookie(c, session_options);
|
|
368
|
-
|
|
437
|
+
// Account-grain operation — no `actor_id`. The password is
|
|
438
|
+
// account-level state; which per-request actor was resolved
|
|
439
|
+
// has no semantic bearing on "this account changed its
|
|
440
|
+
// password". Mirrors `login`/`logout`.
|
|
441
|
+
deps.audit.emit(route, {
|
|
369
442
|
event_type: 'password_change',
|
|
370
|
-
actor_id: ctx.actor.id,
|
|
371
443
|
account_id: ctx.account.id,
|
|
372
444
|
ip: get_client_ip(c),
|
|
373
445
|
metadata: { sessions_revoked, tokens_revoked },
|
|
374
|
-
}
|
|
446
|
+
});
|
|
375
447
|
return c.json({ ok: true, sessions_revoked, tokens_revoked });
|
|
376
448
|
},
|
|
377
449
|
},
|
|
@@ -2,7 +2,14 @@
|
|
|
2
2
|
* Auth entity types and client-safe schemas.
|
|
3
3
|
*
|
|
4
4
|
* Defines the runtime types for the fuz identity system:
|
|
5
|
-
* `Account`, `Actor`, `
|
|
5
|
+
* `Account`, `Actor`, `RoleGrant`, `AuthSession`, and `ApiToken`.
|
|
6
|
+
*
|
|
7
|
+
* Identifier primitives (`Username`, `UsernameProvided`, `Email`) live
|
|
8
|
+
* in `../primitive_schemas.ts` — they're general validator shapes that
|
|
9
|
+
* don't depend on the auth domain. The auth-shape request-contract
|
|
10
|
+
* primitive `ActingActor` lives in `../http/auth_shape.ts` next to
|
|
11
|
+
* `RouteAuth` (the two pair: `auth.actor !== 'none'` ⟺ input declares
|
|
12
|
+
* `acting?: ActingActor`).
|
|
6
13
|
*
|
|
7
14
|
* DDL lives in `auth/ddl.ts`; role system in `auth/role_schema.ts`.
|
|
8
15
|
* See docs/identity.md for design rationale.
|
|
@@ -11,21 +18,7 @@
|
|
|
11
18
|
*/
|
|
12
19
|
import { z } from 'zod';
|
|
13
20
|
import { Uuid } from '@fuzdev/fuz_util/id.js';
|
|
14
|
-
|
|
15
|
-
export declare const USERNAME_LENGTH_MIN = 3;
|
|
16
|
-
/** Maximum username length (matches GitHub's limit). */
|
|
17
|
-
export declare const USERNAME_LENGTH_MAX = 39;
|
|
18
|
-
/** Maximum length for username input on login/lookup — more permissive than `USERNAME_LENGTH_MAX` for forward-compatibility if the creation limit is raised. */
|
|
19
|
-
export declare const USERNAME_PROVIDED_LENGTH_MAX = 255;
|
|
20
|
-
/** Username for account creation — starts with letter, alphanumeric/dash/underscore middle, ends with alphanumeric. No @ or . allowed. */
|
|
21
|
-
export declare const Username: z.ZodString;
|
|
22
|
-
export type Username = z.infer<typeof Username>;
|
|
23
|
-
/** Username submitted for login or lookup — minimal validation for forward-compatibility if format rules change. */
|
|
24
|
-
export declare const UsernameProvided: z.ZodString;
|
|
25
|
-
export type UsernameProvided = z.infer<typeof UsernameProvided>;
|
|
26
|
-
/** Email validation. */
|
|
27
|
-
export declare const Email: z.ZodEmail;
|
|
28
|
-
export type Email = z.infer<typeof Email>;
|
|
21
|
+
import { Username, Email } from '../primitive_schemas.js';
|
|
29
22
|
/** Account — authentication identity. You log in as an account. */
|
|
30
23
|
export interface Account {
|
|
31
24
|
id: Uuid;
|
|
@@ -46,7 +39,7 @@ export interface SessionAccount {
|
|
|
46
39
|
email_verified: boolean;
|
|
47
40
|
created_at: string;
|
|
48
41
|
}
|
|
49
|
-
/** Actor — the entity that acts. Owns cells, holds
|
|
42
|
+
/** Actor — the entity that acts. Owns cells, holds role_grants, appears in audit trails. */
|
|
50
43
|
export interface Actor {
|
|
51
44
|
id: Uuid;
|
|
52
45
|
account_id: Uuid;
|
|
@@ -57,17 +50,25 @@ export interface Actor {
|
|
|
57
50
|
}
|
|
58
51
|
/**
|
|
59
52
|
* Maximum length of the optional free-form `revoked_reason` attached to a
|
|
60
|
-
* revoked
|
|
53
|
+
* revoked role_grant. Bounds the value at the schema layer so both the admin
|
|
61
54
|
* input (when the route surfaces a reason field) and the revokee-facing
|
|
62
|
-
* `
|
|
55
|
+
* `role_grant_revoke` WS notification validate against the same ceiling.
|
|
63
56
|
*/
|
|
64
|
-
export declare const
|
|
65
|
-
/**
|
|
66
|
-
export interface
|
|
57
|
+
export declare const ROLE_GRANT_REVOKED_REASON_LENGTH_MAX = 500;
|
|
58
|
+
/** Role grant — time-bounded, revocable grant of a role to an actor. */
|
|
59
|
+
export interface RoleGrant {
|
|
67
60
|
id: Uuid;
|
|
68
61
|
actor_id: Uuid;
|
|
69
62
|
role: string;
|
|
70
|
-
/**
|
|
63
|
+
/**
|
|
64
|
+
* Machine-readable kind tag for the polymorphic `scope_id`. Paired-null
|
|
65
|
+
* with `scope_id` per the `role_grant_scope_kind_paired` CHECK: both null
|
|
66
|
+
* (global) or both non-null (scoped). Consumer-declared via
|
|
67
|
+
* `create_scope_kind_schema(...)`; v1 keeps validation registry-membership
|
|
68
|
+
* only, with no INSERT-time `(role, scope_kind)` enforcement.
|
|
69
|
+
*/
|
|
70
|
+
scope_kind: string | null;
|
|
71
|
+
/** Resource scope this grant applies to (e.g. a classroom id). `null` for global role_grants. */
|
|
71
72
|
scope_id: Uuid | null;
|
|
72
73
|
created_at: string;
|
|
73
74
|
expires_at: string | null;
|
|
@@ -76,10 +77,10 @@ export interface Permit {
|
|
|
76
77
|
/** Optional free-form reason attached on revoke (surfaced in the revokee WS notification once it lands). */
|
|
77
78
|
revoked_reason: string | null;
|
|
78
79
|
granted_by: Uuid | null;
|
|
79
|
-
/** Offer that produced this
|
|
80
|
+
/** Offer that produced this role_grant (set by `query_accept_offer`). `null` for direct grants. */
|
|
80
81
|
source_offer_id: Uuid | null;
|
|
81
82
|
}
|
|
82
|
-
export declare const
|
|
83
|
+
export declare const is_role_grant_active: (p: {
|
|
83
84
|
revoked_at?: string | null;
|
|
84
85
|
expires_at: string | null;
|
|
85
86
|
}, now?: Date) => boolean;
|
|
@@ -131,16 +132,17 @@ export declare const ClientApiTokenJson: z.ZodObject<{
|
|
|
131
132
|
created_at: z.ZodString;
|
|
132
133
|
}, z.core.$strict>;
|
|
133
134
|
export type ClientApiTokenJson = z.infer<typeof ClientApiTokenJson>;
|
|
134
|
-
/** Zod schema for the
|
|
135
|
-
export declare const
|
|
135
|
+
/** Zod schema for the role_grant summary returned in admin account listings. */
|
|
136
|
+
export declare const RoleGrantSummaryJson: z.ZodObject<{
|
|
136
137
|
id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
|
|
137
138
|
role: z.ZodString;
|
|
139
|
+
scope_kind: z.ZodNullable<z.ZodString>;
|
|
138
140
|
scope_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
|
|
139
141
|
created_at: z.ZodString;
|
|
140
142
|
expires_at: z.ZodNullable<z.ZodString>;
|
|
141
143
|
granted_by: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
|
|
142
144
|
}, z.core.$strict>;
|
|
143
|
-
export type
|
|
145
|
+
export type RoleGrantSummaryJson = z.infer<typeof RoleGrantSummaryJson>;
|
|
144
146
|
/** Zod schema for the actor summary returned in admin account listings. */
|
|
145
147
|
export declare const ActorSummaryJson: z.ZodObject<{
|
|
146
148
|
id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
|
|
@@ -159,9 +161,9 @@ export declare const AdminAccountJson: z.ZodObject<{
|
|
|
159
161
|
}, z.core.$strict>;
|
|
160
162
|
export type AdminAccountJson = z.infer<typeof AdminAccountJson>;
|
|
161
163
|
/**
|
|
162
|
-
* Zod schema for a pending
|
|
164
|
+
* Zod schema for a pending role_grant offer surfaced in admin account listings.
|
|
163
165
|
*
|
|
164
|
-
* Deliberately narrower than `
|
|
166
|
+
* Deliberately narrower than `RoleGrantOfferJson`: omits `message` and
|
|
165
167
|
* `decline_reason` so cross-admin visibility of the listing does not expose
|
|
166
168
|
* grantor-authored text that the audit log also withholds. Full offer
|
|
167
169
|
* payloads remain available through the offer-specific RPC surface and the
|
|
@@ -174,6 +176,7 @@ export type AdminAccountJson = z.infer<typeof AdminAccountJson>;
|
|
|
174
176
|
export declare const PendingOfferSummaryJson: z.ZodObject<{
|
|
175
177
|
id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
|
|
176
178
|
role: z.ZodString;
|
|
179
|
+
scope_kind: z.ZodNullable<z.ZodString>;
|
|
177
180
|
scope_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
|
|
178
181
|
from_actor_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
|
|
179
182
|
from_username: z.ZodString;
|
|
@@ -181,7 +184,7 @@ export declare const PendingOfferSummaryJson: z.ZodObject<{
|
|
|
181
184
|
expires_at: z.ZodString;
|
|
182
185
|
}, z.core.$strict>;
|
|
183
186
|
export type PendingOfferSummaryJson = z.infer<typeof PendingOfferSummaryJson>;
|
|
184
|
-
/** Zod schema for an admin account listing entry (account + actor +
|
|
187
|
+
/** Zod schema for an admin account listing entry (account + actor + role_grants + pending offers). */
|
|
185
188
|
export declare const AdminAccountEntryJson: z.ZodObject<{
|
|
186
189
|
account: z.ZodObject<{
|
|
187
190
|
id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
|
|
@@ -196,9 +199,10 @@ export declare const AdminAccountEntryJson: z.ZodObject<{
|
|
|
196
199
|
id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
|
|
197
200
|
name: z.ZodString;
|
|
198
201
|
}, z.core.$strict>>;
|
|
199
|
-
|
|
202
|
+
role_grants: z.ZodArray<z.ZodObject<{
|
|
200
203
|
id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
|
|
201
204
|
role: z.ZodString;
|
|
205
|
+
scope_kind: z.ZodNullable<z.ZodString>;
|
|
202
206
|
scope_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
|
|
203
207
|
created_at: z.ZodString;
|
|
204
208
|
expires_at: z.ZodNullable<z.ZodString>;
|
|
@@ -207,6 +211,7 @@ export declare const AdminAccountEntryJson: z.ZodObject<{
|
|
|
207
211
|
pending_offers: z.ZodArray<z.ZodObject<{
|
|
208
212
|
id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
|
|
209
213
|
role: z.ZodString;
|
|
214
|
+
scope_kind: z.ZodNullable<z.ZodString>;
|
|
210
215
|
scope_id: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
|
|
211
216
|
from_actor_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
|
|
212
217
|
from_username: z.ZodString;
|
|
@@ -220,14 +225,20 @@ export interface CreateAccountInput {
|
|
|
220
225
|
password_hash: string;
|
|
221
226
|
email?: Email | null;
|
|
222
227
|
}
|
|
223
|
-
export interface
|
|
228
|
+
export interface CreateRoleGrantInput {
|
|
224
229
|
actor_id: Uuid;
|
|
225
230
|
role: string;
|
|
226
|
-
/**
|
|
231
|
+
/**
|
|
232
|
+
* Machine-readable kind for the `scope_id`. Required iff `scope_id` is
|
|
233
|
+
* set; must be null/omitted when `scope_id` is null. The DB-level
|
|
234
|
+
* `role_grant_scope_kind_paired` CHECK rejects mismatched pairs.
|
|
235
|
+
*/
|
|
236
|
+
scope_kind?: string | null;
|
|
237
|
+
/** Scope the grant applies to. `null` / omitted grants a global role_grant. */
|
|
227
238
|
scope_id?: Uuid | null;
|
|
228
239
|
expires_at?: Date | null;
|
|
229
240
|
granted_by: Uuid | null;
|
|
230
|
-
/** Offer id that produced this
|
|
241
|
+
/** Offer id that produced this role_grant. Set by `query_accept_offer`; leave unset for direct grants. */
|
|
231
242
|
source_offer_id?: Uuid | null;
|
|
232
243
|
}
|
|
233
244
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account_schema.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/account_schema.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"account_schema.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/account_schema.ts"],"names":[],"mappings":"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"}
|