@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
|
@@ -13,12 +13,12 @@ import { Hono } from 'hono';
|
|
|
13
13
|
import { Logger } from '@fuzdev/fuz_util/log.js';
|
|
14
14
|
import { create_bearer_auth_middleware } from '../auth/bearer_auth.js';
|
|
15
15
|
import { query_validate_api_token } from '../auth/api_token_queries.js';
|
|
16
|
-
import { query_account_by_id,
|
|
17
|
-
import {
|
|
16
|
+
import { query_account_by_id, query_actor_by_id, query_actors_by_account, } from '../auth/account_queries.js';
|
|
17
|
+
import { query_role_grant_find_active_for_actor } from '../auth/role_grant_queries.js';
|
|
18
18
|
import { create_proxy_middleware, get_client_ip } from '../http/proxy.js';
|
|
19
19
|
import { verify_request_source, parse_allowed_origins } from '../http/origin.js';
|
|
20
20
|
import { REQUEST_CONTEXT_KEY } from '../auth/request_context.js';
|
|
21
|
-
import { AUTH_API_TOKEN_ID_KEY, CREDENTIAL_TYPE_KEY } from '../hono_context.js';
|
|
21
|
+
import { ACCOUNT_ID_KEY, AUTH_API_TOKEN_ID_KEY, CREDENTIAL_TYPE_KEY, TEST_CONTEXT_PRESET_KEY, } from '../hono_context.js';
|
|
22
22
|
import { ApiError } from '../http/error_schemas.js';
|
|
23
23
|
// Mock the query modules so test cases can control return values.
|
|
24
24
|
// vi.mock() is hoisted by vitest, so these run before any imports resolve.
|
|
@@ -27,10 +27,11 @@ vi.mock('../auth/api_token_queries.js', () => ({
|
|
|
27
27
|
}));
|
|
28
28
|
vi.mock('../auth/account_queries.js', () => ({
|
|
29
29
|
query_account_by_id: vi.fn(),
|
|
30
|
-
|
|
30
|
+
query_actor_by_id: vi.fn(),
|
|
31
|
+
query_actors_by_account: vi.fn(),
|
|
31
32
|
}));
|
|
32
|
-
vi.mock('../auth/
|
|
33
|
-
|
|
33
|
+
vi.mock('../auth/role_grant_queries.js', () => ({
|
|
34
|
+
query_role_grant_find_active_for_actor: vi.fn(),
|
|
34
35
|
}));
|
|
35
36
|
/** Stub `QueryDeps` for bearer auth tests (no real DB needed). */
|
|
36
37
|
const STUB_DEPS = { db: {} };
|
|
@@ -38,32 +39,48 @@ const STUB_DEPS = { db: {} };
|
|
|
38
39
|
* Create mock dependencies for `create_bearer_auth_middleware`, configured per test case.
|
|
39
40
|
*
|
|
40
41
|
* Configures the module-level mocks for `query_validate_api_token`,
|
|
41
|
-
* `query_account_by_id`, `
|
|
42
|
+
* `query_account_by_id`, `query_actor_by_id`, and `query_role_grant_find_active_for_actor`
|
|
42
43
|
* so each test case controls return values independently.
|
|
43
44
|
*
|
|
44
45
|
* @returns mocks bundle with spy references
|
|
45
46
|
* @mutates module-level `vi.mock` registrations for `api_token_queries`,
|
|
46
|
-
* `account_queries`, and `
|
|
47
|
+
* `account_queries`, and `role_grant_queries` — each call resets and re-binds
|
|
47
48
|
* the four spies, so cases run in sequence without bleeding state.
|
|
48
49
|
*/
|
|
49
50
|
export const create_bearer_auth_mocks = (tc) => {
|
|
50
51
|
const mock_validate = vi.mocked(query_validate_api_token);
|
|
51
52
|
const mock_find_by_id = vi.mocked(query_account_by_id);
|
|
52
|
-
const
|
|
53
|
-
const
|
|
53
|
+
const mock_find_actor_by_id = vi.mocked(query_actor_by_id);
|
|
54
|
+
const mock_find_actors_by_account = vi.mocked(query_actors_by_account);
|
|
55
|
+
const mock_find_active_for_actor = vi.mocked(query_role_grant_find_active_for_actor);
|
|
54
56
|
mock_validate
|
|
55
57
|
.mockReset()
|
|
56
58
|
.mockImplementation(() => Promise.resolve(tc.mock_validate_result));
|
|
57
59
|
mock_find_by_id
|
|
58
60
|
.mockReset()
|
|
59
61
|
.mockImplementation(() => Promise.resolve(tc.mock_find_by_id_result));
|
|
60
|
-
|
|
62
|
+
mock_find_actor_by_id
|
|
61
63
|
.mockReset()
|
|
62
|
-
.mockImplementation(() => Promise.resolve(tc.
|
|
64
|
+
.mockImplementation(() => Promise.resolve(tc.mock_find_actor_by_id_result));
|
|
65
|
+
// `resolve_acting_actor` enumerates actors. Default: wrap the
|
|
66
|
+
// `mock_find_actor_by_id_result` in a single-element array so
|
|
67
|
+
// single-actor account scenarios resolve transparently; empty when
|
|
68
|
+
// the actor mock is undefined/null. Multi-actor scenarios should
|
|
69
|
+
// override this directly via `mockResolvedValue`.
|
|
70
|
+
mock_find_actors_by_account.mockReset().mockImplementation(() => {
|
|
71
|
+
const actor = tc.mock_find_actor_by_id_result;
|
|
72
|
+
return Promise.resolve(actor ? [actor] : []);
|
|
73
|
+
});
|
|
63
74
|
mock_find_active_for_actor
|
|
64
75
|
.mockReset()
|
|
65
|
-
.mockImplementation(() => Promise.resolve(tc.
|
|
66
|
-
return {
|
|
76
|
+
.mockImplementation(() => Promise.resolve(tc.mock_role_grants_result ?? []));
|
|
77
|
+
return {
|
|
78
|
+
mock_validate,
|
|
79
|
+
mock_find_by_id,
|
|
80
|
+
mock_find_actor_by_id,
|
|
81
|
+
mock_find_actors_by_account,
|
|
82
|
+
mock_find_active_for_actor,
|
|
83
|
+
};
|
|
67
84
|
};
|
|
68
85
|
/** Default client IP set by the proxy stub in test apps. */
|
|
69
86
|
export const TEST_CLIENT_IP = '127.0.0.1';
|
|
@@ -77,11 +94,20 @@ export const create_bearer_auth_test_app = (tc, ip_rate_limiter = null) => {
|
|
|
77
94
|
const mocks = create_bearer_auth_mocks(tc);
|
|
78
95
|
const bearer_middleware = create_bearer_auth_middleware(STUB_DEPS, ip_rate_limiter, new Logger('test', { level: 'off' }));
|
|
79
96
|
const app = new Hono();
|
|
80
|
-
// inject pre-existing
|
|
97
|
+
// inject pre-existing session identity if the test case specifies one.
|
|
98
|
+
// `pre_context` simulates the session middleware having authenticated
|
|
99
|
+
// the caller — sets `ACCOUNT_ID_KEY` (the account-grain identity bearer
|
|
100
|
+
// auth checks) and pre-populates `REQUEST_CONTEXT_KEY` as a test
|
|
101
|
+
// escape-hatch (production bearer middleware is account-only and never
|
|
102
|
+
// sets this key — see `auth/CLAUDE.md` Production-middleware invariant)
|
|
103
|
+
// so consumer expectations on the full context shape stay testable.
|
|
81
104
|
if (tc.pre_context) {
|
|
105
|
+
const pre_context = tc.pre_context;
|
|
82
106
|
app.use('*', async (c, next) => {
|
|
83
|
-
c.set(
|
|
107
|
+
c.set(ACCOUNT_ID_KEY, pre_context.account.id);
|
|
108
|
+
c.set(REQUEST_CONTEXT_KEY, pre_context);
|
|
84
109
|
c.set(CREDENTIAL_TYPE_KEY, 'session');
|
|
110
|
+
c.set(TEST_CONTEXT_PRESET_KEY, true);
|
|
85
111
|
await next();
|
|
86
112
|
});
|
|
87
113
|
}
|
|
@@ -91,19 +117,22 @@ export const create_bearer_auth_test_app = (tc, ip_rate_limiter = null) => {
|
|
|
91
117
|
await next();
|
|
92
118
|
});
|
|
93
119
|
app.use('/api/*', bearer_middleware);
|
|
94
|
-
// route handler echoes
|
|
120
|
+
// route handler echoes the account-grain identity the middleware writes
|
|
121
|
+
// (bearer auth sets `ACCOUNT_ID_KEY` + `CREDENTIAL_TYPE_KEY` +
|
|
122
|
+
// `AUTH_API_TOKEN_ID_KEY`; it never builds the full request context —
|
|
123
|
+
// that is the dispatcher's authorization phase). `request_context_set`
|
|
124
|
+
// is only true when a test pre-populates it via `pre_context`.
|
|
95
125
|
app.get('/api/test', (c) => {
|
|
96
|
-
const
|
|
126
|
+
const account_id = c.get(ACCOUNT_ID_KEY);
|
|
97
127
|
const cred = c.get(CREDENTIAL_TYPE_KEY);
|
|
98
128
|
const api_token_id = c.get(AUTH_API_TOKEN_ID_KEY);
|
|
129
|
+
const ctx = c.get(REQUEST_CONTEXT_KEY);
|
|
99
130
|
return c.json({
|
|
100
131
|
ok: true,
|
|
101
|
-
|
|
132
|
+
account_id: account_id ?? null,
|
|
102
133
|
credential_type: cred ?? null,
|
|
103
|
-
account_id: ctx?.account.id ?? null,
|
|
104
|
-
actor_id: ctx?.actor.id ?? null,
|
|
105
|
-
permit_count: ctx?.permits.length ?? 0,
|
|
106
134
|
api_token_id: api_token_id ?? null,
|
|
135
|
+
request_context_set: ctx != null,
|
|
107
136
|
});
|
|
108
137
|
});
|
|
109
138
|
return { app, mocks };
|
|
@@ -141,15 +170,18 @@ export const describe_bearer_auth_cases = (suite_name, cases, ip_rate_limiter =
|
|
|
141
170
|
else {
|
|
142
171
|
assert.ok(mocks.mock_validate.mock.calls.length > 0, 'validate should have been called');
|
|
143
172
|
}
|
|
144
|
-
if (tc.
|
|
145
|
-
assert.
|
|
173
|
+
if (tc.assert_account_set) {
|
|
174
|
+
assert.ok(body.account_id, 'ACCOUNT_ID_KEY should be set');
|
|
175
|
+
if (tc.expected_account_id !== undefined) {
|
|
176
|
+
assert.strictEqual(body.account_id, tc.expected_account_id, 'ACCOUNT_ID_KEY should match the validated api_token.account_id');
|
|
177
|
+
}
|
|
146
178
|
assert.strictEqual(body.credential_type, 'api_token', 'CREDENTIAL_TYPE_KEY should be api_token');
|
|
147
179
|
}
|
|
148
180
|
if (tc.expected_api_token_id !== undefined) {
|
|
149
181
|
assert.strictEqual(body.api_token_id, tc.expected_api_token_id, 'AUTH_API_TOKEN_ID_KEY should match the validated api_token.id');
|
|
150
182
|
}
|
|
151
183
|
if (tc.assert_context_preserved) {
|
|
152
|
-
assert.
|
|
184
|
+
assert.ok(body.account_id, 'pre-existing account_id should be preserved');
|
|
153
185
|
assert.strictEqual(body.credential_type, 'session', 'credential type should remain session');
|
|
154
186
|
}
|
|
155
187
|
if (tc.assert_mocks) {
|
|
@@ -177,11 +209,13 @@ export const create_test_middleware_stack_app = (options) => {
|
|
|
177
209
|
const allowed_origins_str = options?.allowed_origins ?? 'https://app.example.com';
|
|
178
210
|
const mock_validate = vi.mocked(query_validate_api_token);
|
|
179
211
|
const mock_find_by_id = vi.mocked(query_account_by_id);
|
|
180
|
-
const
|
|
181
|
-
const
|
|
212
|
+
const mock_find_actor_by_id = vi.mocked(query_actor_by_id);
|
|
213
|
+
const mock_find_actors_by_account = vi.mocked(query_actors_by_account);
|
|
214
|
+
const mock_find_active_for_actor = vi.mocked(query_role_grant_find_active_for_actor);
|
|
182
215
|
mock_validate.mockReset().mockImplementation(() => Promise.resolve(undefined));
|
|
183
216
|
mock_find_by_id.mockReset().mockImplementation(() => Promise.resolve(undefined));
|
|
184
|
-
|
|
217
|
+
mock_find_actor_by_id.mockReset().mockImplementation(() => Promise.resolve(undefined));
|
|
218
|
+
mock_find_actors_by_account.mockReset().mockImplementation(() => Promise.resolve([]));
|
|
185
219
|
mock_find_active_for_actor.mockReset().mockImplementation(() => Promise.resolve([]));
|
|
186
220
|
const get_connection_ip = typeof options?.connection_ip === 'function'
|
|
187
221
|
? options.connection_ip
|
|
@@ -197,14 +231,23 @@ export const create_test_middleware_stack_app = (options) => {
|
|
|
197
231
|
app.use('*', proxy_mw);
|
|
198
232
|
app.use('/api/*', origin_mw);
|
|
199
233
|
app.use('/api/*', bearer_mw);
|
|
200
|
-
// echo route for assertions
|
|
234
|
+
// echo route for assertions — exposes the account-grain identity bearer
|
|
235
|
+
// auth writes (`ACCOUNT_ID_KEY`); the full request context is the
|
|
236
|
+
// dispatcher's authorization phase concern, not middleware.
|
|
201
237
|
app.get(TEST_MIDDLEWARE_PATH, (c) => {
|
|
202
|
-
const
|
|
238
|
+
const account_id = c.get(ACCOUNT_ID_KEY);
|
|
203
239
|
return c.json({
|
|
204
240
|
ok: true,
|
|
205
241
|
client_ip: get_client_ip(c),
|
|
206
|
-
|
|
242
|
+
account_id: account_id ?? null,
|
|
207
243
|
});
|
|
208
244
|
});
|
|
209
|
-
return {
|
|
245
|
+
return {
|
|
246
|
+
app,
|
|
247
|
+
mock_validate,
|
|
248
|
+
mock_find_by_id,
|
|
249
|
+
mock_find_actor_by_id,
|
|
250
|
+
mock_find_actors_by_account,
|
|
251
|
+
mock_find_active_for_actor,
|
|
252
|
+
};
|
|
210
253
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc_attack_surface.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rpc_attack_surface.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAkB7B,OAAO,KAAK,EAA6C,cAAc,EAAC,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"rpc_attack_surface.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rpc_attack_surface.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAkB7B,OAAO,KAAK,EAA6C,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAqBnG,uDAAuD;AACvD,MAAM,WAAW,uBAAuB;IACvC,+FAA+F;IAC/F,KAAK,EAAE,MAAM,cAAc,CAAC;IAC5B,yDAAyD;IACzD,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CACrB;AA0dD;;;;;;;;;GASG;AACH,eAAO,MAAM,iCAAiC,GAAI,SAAS,uBAAuB,KAAG,IAOpF,CAAC"}
|
|
@@ -13,18 +13,23 @@ import './assert_dev_env.js';
|
|
|
13
13
|
* @module
|
|
14
14
|
*/
|
|
15
15
|
import { test, assert, describe } from 'vitest';
|
|
16
|
+
import { is_keeper_auth, is_public_auth, is_role_auth } from '../http/auth_shape.js';
|
|
16
17
|
import { JSONRPC_ERROR_CODES } from '../http/jsonrpc_errors.js';
|
|
17
18
|
import { create_auth_test_apps, create_test_app_from_specs, create_test_request_context, select_auth_app, } from './auth_apps.js';
|
|
18
19
|
import { generate_input_test_cases } from './adversarial_input.js';
|
|
20
|
+
import { generate_valid_body } from './schema_generators.js';
|
|
19
21
|
import { ERROR_INVALID_JSON_BODY } from '../http/error_schemas.js';
|
|
20
22
|
import { create_rpc_post_init, create_rpc_get_url, assert_jsonrpc_error_response, } from './rpc_helpers.js';
|
|
21
23
|
// --- Helpers ---
|
|
22
24
|
/** Filter RPC methods that require any form of authentication. */
|
|
23
|
-
const filter_protected_rpc_methods = (endpoint) => endpoint.methods.filter((m) => m.auth
|
|
24
|
-
/** Filter RPC methods that
|
|
25
|
-
const filter_role_rpc_methods = (endpoint) => endpoint.methods.filter((m) => m.auth
|
|
26
|
-
/**
|
|
27
|
-
|
|
25
|
+
const filter_protected_rpc_methods = (endpoint) => endpoint.methods.filter((m) => !is_public_auth(m.auth));
|
|
26
|
+
/** Filter RPC methods that declare a role gate (`auth.roles?.length`). */
|
|
27
|
+
const filter_role_rpc_methods = (endpoint) => endpoint.methods.filter((m) => is_role_auth(m.auth));
|
|
28
|
+
/**
|
|
29
|
+
* Filter RPC methods that require daemon-token credentials. Today this
|
|
30
|
+
* is the keeper bucket; future credential gates will widen the filter.
|
|
31
|
+
*/
|
|
32
|
+
const filter_keeper_rpc_methods = (endpoint) => endpoint.methods.filter((m) => is_keeper_auth(m.auth));
|
|
28
33
|
/** Find the `RpcAction` source spec for a surface method. */
|
|
29
34
|
const find_rpc_action = (rpc_endpoint_specs, endpoint_path, method_name) => {
|
|
30
35
|
const ep = rpc_endpoint_specs.find((e) => e.path === endpoint_path);
|
|
@@ -47,7 +52,7 @@ const find_rpc_action = (rpc_endpoint_specs, endpoint_path, method_name) => {
|
|
|
47
52
|
*/
|
|
48
53
|
const describe_rpc_auth = (options) => {
|
|
49
54
|
const { build, roles } = options;
|
|
50
|
-
const { surface, route_specs } = build();
|
|
55
|
+
const { surface, route_specs, rpc_endpoints: rpc_endpoint_specs } = build();
|
|
51
56
|
if (surface.rpc_endpoints.length === 0)
|
|
52
57
|
return;
|
|
53
58
|
const apps = create_auth_test_apps(route_specs, roles);
|
|
@@ -71,13 +76,18 @@ const describe_rpc_auth = (options) => {
|
|
|
71
76
|
if (role_methods.length > 0) {
|
|
72
77
|
describe('wrong role → forbidden', () => {
|
|
73
78
|
for (const method of role_methods) {
|
|
74
|
-
const
|
|
79
|
+
const required_roles = method.auth.roles ?? [];
|
|
80
|
+
const wrong_roles = roles.filter((r) => !required_roles.includes(r));
|
|
75
81
|
for (const wrong_role of wrong_roles) {
|
|
76
|
-
test(`${method.name} (${wrong_role} instead of ${
|
|
82
|
+
test(`${method.name} (${wrong_role} instead of ${required_roles.join('|')})`, async () => {
|
|
77
83
|
const app = apps.by_role.get(wrong_role);
|
|
78
84
|
if (!app)
|
|
79
85
|
throw new Error(`No test app for role '${wrong_role}'`);
|
|
80
|
-
|
|
86
|
+
// Send valid params so we trip the role gate (403), not input
|
|
87
|
+
// validation (400). Dispatcher ordering: 401 → 400 → 403.
|
|
88
|
+
const action = find_rpc_action(rpc_endpoint_specs, endpoint.path, method.name);
|
|
89
|
+
const params = action ? generate_valid_body(action.spec.input) : undefined;
|
|
90
|
+
const res = await app.request(endpoint.path, create_rpc_post_init(method.name, params));
|
|
81
91
|
assert.strictEqual(res.status, 403, `${method.name} should return 403`);
|
|
82
92
|
const body = await res.json();
|
|
83
93
|
assert_jsonrpc_error_response(body, JSONRPC_ERROR_CODES.forbidden);
|
|
@@ -87,8 +97,12 @@ const describe_rpc_auth = (options) => {
|
|
|
87
97
|
});
|
|
88
98
|
describe('authenticated without role → forbidden', () => {
|
|
89
99
|
for (const method of role_methods) {
|
|
90
|
-
test(`${method.name} (${method.auth.
|
|
91
|
-
|
|
100
|
+
test(`${method.name} (${(method.auth.roles ?? []).join('|')})`, async () => {
|
|
101
|
+
// Send valid params so we trip the role gate (403), not input
|
|
102
|
+
// validation (400).
|
|
103
|
+
const action = find_rpc_action(rpc_endpoint_specs, endpoint.path, method.name);
|
|
104
|
+
const params = action ? generate_valid_body(action.spec.input) : undefined;
|
|
105
|
+
const res = await apps.authed.request(endpoint.path, create_rpc_post_init(method.name, params));
|
|
92
106
|
assert.strictEqual(res.status, 403, `${method.name} should return 403`);
|
|
93
107
|
const body = await res.json();
|
|
94
108
|
assert_jsonrpc_error_response(body, JSONRPC_ERROR_CODES.forbidden);
|
|
@@ -102,14 +116,16 @@ const describe_rpc_auth = (options) => {
|
|
|
102
116
|
const session_app = create_test_app_from_specs(route_specs, create_test_request_context('keeper'), 'session');
|
|
103
117
|
const api_token_app = create_test_app_from_specs(route_specs, create_test_request_context('keeper'), 'api_token');
|
|
104
118
|
for (const method of keeper_methods) {
|
|
119
|
+
const action = find_rpc_action(rpc_endpoint_specs, endpoint.path, method.name);
|
|
120
|
+
const valid_params = action ? generate_valid_body(action.spec.input) : undefined;
|
|
105
121
|
test(`${method.name} rejects session credential`, async () => {
|
|
106
|
-
const res = await session_app.request(endpoint.path, create_rpc_post_init(method.name));
|
|
122
|
+
const res = await session_app.request(endpoint.path, create_rpc_post_init(method.name, valid_params));
|
|
107
123
|
assert.strictEqual(res.status, 403, `${method.name} should reject session credential`);
|
|
108
124
|
const body = await res.json();
|
|
109
125
|
assert_jsonrpc_error_response(body, JSONRPC_ERROR_CODES.forbidden);
|
|
110
126
|
});
|
|
111
127
|
test(`${method.name} rejects api_token credential`, async () => {
|
|
112
|
-
const res = await api_token_app.request(endpoint.path, create_rpc_post_init(method.name));
|
|
128
|
+
const res = await api_token_app.request(endpoint.path, create_rpc_post_init(method.name, valid_params));
|
|
113
129
|
assert.strictEqual(res.status, 403, `${method.name} should reject api_token credential`);
|
|
114
130
|
const body = await res.json();
|
|
115
131
|
assert_jsonrpc_error_response(body, JSONRPC_ERROR_CODES.forbidden);
|
|
@@ -279,7 +295,7 @@ const describe_rpc_adversarial_envelopes = (options) => {
|
|
|
279
295
|
return;
|
|
280
296
|
// valid JSON but not an object — hits dispatcher's params validation
|
|
281
297
|
const res = await apps.public.request(`${endpoint.path}?method=${read_method.name}&id=test¶ms=42`);
|
|
282
|
-
// should reject: either invalid_params (
|
|
298
|
+
// should reject: either invalid_params (validation) or auth error
|
|
283
299
|
assert.ok(res.status >= 400, `expected error status for non-object params, got ${res.status}`);
|
|
284
300
|
const body = await res.json();
|
|
285
301
|
assert_jsonrpc_error_response(body);
|
|
@@ -362,16 +378,16 @@ const describe_rpc_adversarial_params = (options) => {
|
|
|
362
378
|
// --- Helpers (formatting) ---
|
|
363
379
|
/** Format a `RouteAuth` as a human-readable label. */
|
|
364
380
|
const format_auth = (auth) => {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
381
|
+
if (is_public_auth(auth))
|
|
382
|
+
return 'public';
|
|
383
|
+
const parts = [];
|
|
384
|
+
parts.push(`account:${auth.account}`);
|
|
385
|
+
parts.push(`actor:${auth.actor}`);
|
|
386
|
+
if (auth.roles?.length)
|
|
387
|
+
parts.push(`roles:${auth.roles.join('|')}`);
|
|
388
|
+
if (auth.credential_types?.length)
|
|
389
|
+
parts.push(`creds:${auth.credential_types.join('|')}`);
|
|
390
|
+
return parts.join(' ');
|
|
375
391
|
};
|
|
376
392
|
// --- Public API ---
|
|
377
393
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rpc_helpers.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAa7B,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,EAIN,KAAK,gBAAgB,EACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,2BAA2B,CAAC;AACzE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,0BAA0B,CAAC;AACxD,OAAO,KAAK,EAAC,qBAAqB,EAAE,mBAAmB,EAAE,eAAe,EAAC,MAAM,oBAAoB,CAAC;AACpG,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAG9D;;;;;;;;GAQG;AACH,MAAM,MAAM,uBAAuB,GAChC,KAAK,CAAC,eAAe,CAAC,GACtB,CAAC,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,+BAA+B,GAC3C,eAAe,uBAAuB,EACtC,iBAAiB,cAAc,CAAC,MAAM,CAAC,KACrC,KAAK,CAAC,eAAe,CAuBvB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,GAChC,QAAQ,MAAM,EACd,SAAS,OAAO,EAChB,KAAI,MAAM,GAAG,MAAe,KAC1B,WAQF,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,GAC9B,eAAe,MAAM,EACrB,QAAQ,MAAM,EACd,SAAS,OAAO,EAChB,KAAI,MAAM,GAAG,MAAe,KAC1B,MAMF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,6BAA6B,GACzC,MAAM,OAAO,EACb,gBAAgB,gBAAgB,KAC9B,IAUF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,+BAA+B,GAAI,MAAM,OAAO,EAAE,gBAAgB,CAAC,CAAC,OAAO,KAAG,
|
|
1
|
+
{"version":3,"file":"rpc_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rpc_helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -119,7 +119,9 @@ export const assert_jsonrpc_success_response = (body, output_schema) => {
|
|
|
119
119
|
assert.ok(result.success, `not a valid JSON-RPC success response: ${JSON.stringify(body)}`);
|
|
120
120
|
if (output_schema) {
|
|
121
121
|
const output_result = output_schema.safeParse(result.data.result);
|
|
122
|
-
|
|
122
|
+
if (!output_result.success) {
|
|
123
|
+
assert.fail(`JSON-RPC result does not match output schema: ${JSON.stringify(output_result.error.issues)}`);
|
|
124
|
+
}
|
|
123
125
|
}
|
|
124
126
|
};
|
|
125
127
|
/** Adapt a `Hono`-style app into an `RpcTestTransport`. */
|
|
@@ -27,7 +27,7 @@ export interface RpcRoundTripTestOptions {
|
|
|
27
27
|
app_options?: SuiteAppOptions;
|
|
28
28
|
/** Database factories to run tests against. Default: pglite only. */
|
|
29
29
|
db_factories?: Array<DbFactory>;
|
|
30
|
-
/** Methods to skip, by name (e.g., `'
|
|
30
|
+
/** Methods to skip, by name (e.g., `'zap_plan'`). */
|
|
31
31
|
skip_methods?: Array<string>;
|
|
32
32
|
/** Override generated params for specific methods (method name → params). */
|
|
33
33
|
input_overrides?: Map<string, Record<string, unknown>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc_round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rpc_round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAe7B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAE9D,OAAO,EAEN,KAAK,eAAe,EAGpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAwB,KAAK,SAAS,EAAC,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"rpc_round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rpc_round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAe7B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAE9D,OAAO,EAEN,KAAK,eAAe,EAGpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAwB,KAAK,SAAS,EAAC,MAAM,SAAS,CAAC;AAO9D,OAAO,EAMN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAE1B,mDAAmD;AACnD,MAAM,WAAW,uBAAuB;IACvC,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,wDAAwD;IACxD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE;;;;;;;;;;OAUG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC,iDAAiD;IACjD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,qEAAqE;IACrE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC,qDAAqD;IACrD,YAAY,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B,6EAA6E;IAC7E,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACvD;AA2BD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,6BAA6B,GAAI,SAAS,uBAAuB,KAAG,IA8IhF,CAAC"}
|
|
@@ -16,25 +16,26 @@ import { create_pglite_factory } from './db.js';
|
|
|
16
16
|
import { generate_valid_body } from './schema_generators.js';
|
|
17
17
|
import { run_migrations } from '../db/migrate.js';
|
|
18
18
|
import { AUTH_MIGRATION_NS } from '../auth/migrations.js';
|
|
19
|
+
import { is_public_auth } from '../http/auth_shape.js';
|
|
19
20
|
import { create_rpc_post_init, create_rpc_get_url, assert_jsonrpc_error_response, assert_jsonrpc_success_response, resolve_rpc_endpoints_for_setup, } from './rpc_helpers.js';
|
|
20
21
|
/**
|
|
21
22
|
* Pick auth headers matching an RPC method's auth requirement.
|
|
22
23
|
*/
|
|
23
24
|
const pick_rpc_auth_headers = (method, test_app, authed_account, admin_account) => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
case 'authenticated':
|
|
28
|
-
return authed_account.create_session_headers();
|
|
29
|
-
case 'role':
|
|
30
|
-
if (method.auth.role === ROLE_ADMIN) {
|
|
31
|
-
return admin_account.create_session_headers();
|
|
32
|
-
}
|
|
33
|
-
// keeper role uses the bootstrapped account
|
|
34
|
-
return test_app.create_session_headers();
|
|
35
|
-
case 'keeper':
|
|
36
|
-
return test_app.create_daemon_token_headers();
|
|
25
|
+
const { auth } = method;
|
|
26
|
+
if (is_public_auth(auth)) {
|
|
27
|
+
return { host: 'localhost', origin: 'http://localhost:5173' };
|
|
37
28
|
}
|
|
29
|
+
if (auth.credential_types?.includes('daemon_token')) {
|
|
30
|
+
return test_app.create_daemon_token_headers();
|
|
31
|
+
}
|
|
32
|
+
if (auth.roles?.length) {
|
|
33
|
+
if (auth.roles.includes(ROLE_ADMIN)) {
|
|
34
|
+
return admin_account.create_session_headers();
|
|
35
|
+
}
|
|
36
|
+
return test_app.create_session_headers();
|
|
37
|
+
}
|
|
38
|
+
return authed_account.create_session_headers();
|
|
38
39
|
};
|
|
39
40
|
/**
|
|
40
41
|
* Run schema-driven round-trip validation for RPC endpoints.
|
|
@@ -9,7 +9,7 @@ import { type DbFactory } from './db.js';
|
|
|
9
9
|
import { type RpcEndpointsSuiteOption } from './rpc_helpers.js';
|
|
10
10
|
/** Config for a single SSE route under test. */
|
|
11
11
|
export interface SseRouteTestSpec {
|
|
12
|
-
/** Full HTTP path of the SSE endpoint (e.g., `'/api/
|
|
12
|
+
/** Full HTTP path of the SSE endpoint (e.g., `'/api/zap/subscribe'`). */
|
|
13
13
|
path: string;
|
|
14
14
|
/**
|
|
15
15
|
* Fire an event matching one of the declared `event_specs` that should
|
|
@@ -51,9 +51,8 @@ export interface SseRouteTestOptions {
|
|
|
51
51
|
on_audit_event?: (event: AuditLogEvent) => void;
|
|
52
52
|
/**
|
|
53
53
|
* RPC endpoint specs — required so the close-on-revoke assertion can
|
|
54
|
-
* dispatch `account_session_revoke_all` via RPC (
|
|
55
|
-
*
|
|
56
|
-
* migration). Hard-fails via `require_rpc_endpoint_path` on setup.
|
|
54
|
+
* dispatch `account_session_revoke_all` via RPC (there is no REST
|
|
55
|
+
* equivalent). Hard-fails via `require_rpc_endpoint_path` on setup.
|
|
57
56
|
*
|
|
58
57
|
* Accepts either an array (eager) or a factory
|
|
59
58
|
* `(ctx: AppServerContext) => Array<RpcEndpointSpec>` — the factory form
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sse_round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/sse_round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAmB7B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAwB,KAAK,SAAS,EAAuB,MAAM,oBAAoB,CAAC;AAE/F,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAEN,KAAK,eAAe,EACpB,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAwB,KAAK,SAAS,EAAC,MAAM,SAAS,CAAC;AAE9D,OAAO,EAIN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAM1B,gDAAgD;AAChD,MAAM,WAAW,gBAAgB;IAChC,
|
|
1
|
+
{"version":3,"file":"sse_round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/sse_round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAmB7B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAwB,KAAK,SAAS,EAAuB,MAAM,oBAAoB,CAAC;AAE/F,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAEN,KAAK,eAAe,EACpB,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAwB,KAAK,SAAS,EAAC,MAAM,SAAS,CAAC;AAE9D,OAAO,EAIN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAM1B,gDAAgD;AAChD,MAAM,WAAW,gBAAgB;IAChC,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,EAAE,CAAC,GAAG,EAAE;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,WAAW,CAAA;KAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E;;;OAGG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/B;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,8CAA8C;AAC9C,MAAM,WAAW,mBAAmB;IACnC,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,qDAAqD;IACrD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE,iDAAiD;IACjD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,qEAAqE;IACrE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAChD;;;;;;;;;;;;OAYG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC,8BAA8B;IAC9B,MAAM,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;CAChC;AAyHD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,GAAI,SAAS,mBAAmB,KAAG,IA2HvE,CAAC"}
|
|
@@ -229,18 +229,14 @@ export const describe_sse_route_tests = (options) => {
|
|
|
229
229
|
* (keeper, other roles) uses the bootstrapped keeper account.
|
|
230
230
|
*/
|
|
231
231
|
const pick_account_for_auth = (spec, test_app, authed_account, admin_account) => {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
return admin_account;
|
|
238
|
-
// keeper role — bootstrapped account is the keeper; model it as a TestAccount
|
|
239
|
-
return bootstrap_as_account(test_app);
|
|
240
|
-
case 'keeper':
|
|
241
|
-
case 'none':
|
|
242
|
-
return bootstrap_as_account(test_app);
|
|
232
|
+
const { auth } = spec;
|
|
233
|
+
if (auth.roles?.includes(ROLE_ADMIN))
|
|
234
|
+
return admin_account;
|
|
235
|
+
if (auth.account === 'required' && !auth.roles?.length && !auth.credential_types?.length) {
|
|
236
|
+
return authed_account;
|
|
243
237
|
}
|
|
238
|
+
// keeper / other-role / public — bootstrapped account
|
|
239
|
+
return bootstrap_as_account(test_app);
|
|
244
240
|
};
|
|
245
241
|
/**
|
|
246
242
|
* Treat the bootstrapped `TestApp` account as a `TestAccount` for revocation.
|
|
@@ -36,7 +36,7 @@ export interface StandardTestOptions {
|
|
|
36
36
|
/**
|
|
37
37
|
* RPC endpoint specs — required. The standard integration tests drive
|
|
38
38
|
* `account_verify`, `account_session_*`, `account_token_*` through the
|
|
39
|
-
* RPC surface (and admin tests, when wired, drive
|
|
39
|
+
* RPC surface (and admin tests, when wired, drive role_grant grant/revoke
|
|
40
40
|
* through it too).
|
|
41
41
|
*
|
|
42
42
|
* Accepts either an array (eager) or a factory
|
package/dist/testing/stubs.d.ts
CHANGED
|
@@ -3,11 +3,13 @@ import type { z } from 'zod';
|
|
|
3
3
|
import type { SessionOptions } from '../auth/session_cookie.js';
|
|
4
4
|
import type { MiddlewareSpec } from '../http/middleware_spec.js';
|
|
5
5
|
import type { AppDeps } from '../auth/deps.js';
|
|
6
|
+
import type { AuditEmitter } from '../auth/audit_emitter.js';
|
|
6
7
|
import type { AppServerContext } from '../server/app_server.js';
|
|
7
8
|
import { Db } from '../db/db.js';
|
|
8
9
|
import { type RouteSpec } from '../http/route_spec.js';
|
|
9
10
|
import { type AppSurfaceSpec, type RpcEndpointSpec } from '../http/surface.js';
|
|
10
11
|
import type { EventSpec } from '../realtime/sse.js';
|
|
12
|
+
import { type AuditLogSse } from '../realtime/sse_auth_guard.js';
|
|
11
13
|
/**
|
|
12
14
|
* Create a Proxy that throws descriptive errors on any property access or method call.
|
|
13
15
|
*
|
|
@@ -51,6 +53,29 @@ export declare const create_stub_db: () => Db;
|
|
|
51
53
|
export declare const stub_handler: () => Response;
|
|
52
54
|
/** Stub middleware that passes through. */
|
|
53
55
|
export declare const stub_mw: (_c: any, next: any) => Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Build a no-op `AuditEmitter` for tests that don't assert on audit fan-out.
|
|
58
|
+
*
|
|
59
|
+
* `emit` / `emit_role_grant_target` are no-ops; `emit_pool` resolves
|
|
60
|
+
* immediately; `notify` is a no-op; `on_event_chain` is a frozen empty
|
|
61
|
+
* array — pushing onto it throws at runtime, so a test that wires a
|
|
62
|
+
* listener fails loudly instead of silently never firing. Tests asserting
|
|
63
|
+
* on real audit-row persistence (or on listener fan-out) build a real
|
|
64
|
+
* emitter via `create_audit_emitter` against a stub or real DB —
|
|
65
|
+
* `create_test_app` already does this on the test backend.
|
|
66
|
+
*/
|
|
67
|
+
export declare const create_test_audit_emitter: () => AuditEmitter;
|
|
68
|
+
/**
|
|
69
|
+
* Build a no-op `AuditLogSse` for tests that wire `audit_sse` into the
|
|
70
|
+
* surface helper but don't assert on SSE fan-out or subscriber state.
|
|
71
|
+
*
|
|
72
|
+
* `subscribe` returns a no-op cleanup; `on_audit_event` is a no-op; the
|
|
73
|
+
* `registry` is a fresh `SubscriberRegistry` instance (call sites that
|
|
74
|
+
* inspect `.size` or call `.close_*` see a real registry, so writes are
|
|
75
|
+
* isolated per test). Tests that need real SSE plumbing build it via
|
|
76
|
+
* `create_audit_log_sse` against `create_test_app`.
|
|
77
|
+
*/
|
|
78
|
+
export declare const create_stub_audit_sse: () => AuditLogSse;
|
|
54
79
|
/** Stub `AppDeps` for auth surface tests — throws on any method access. */
|
|
55
80
|
export declare const stub_app_deps: AppDeps;
|
|
56
81
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stubs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/stubs.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAa7B,OAAO,KAAK,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAE3B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,4BAA4B,CAAC;AAE/D,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AAC/B,OAAO,EAAqB,KAAK,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAGzE,OAAO,EAEN,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"stubs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/stubs.ts"],"names":[],"mappings":"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"}
|