@fuzdev/fuz_app 0.1.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/LICENSE +21 -0
- package/README.md +49 -0
- package/dist/actions/action_bridge.d.ts +65 -0
- package/dist/actions/action_bridge.d.ts.map +1 -0
- package/dist/actions/action_bridge.js +76 -0
- package/dist/actions/action_codegen.d.ts +97 -0
- package/dist/actions/action_codegen.d.ts.map +1 -0
- package/dist/actions/action_codegen.js +280 -0
- package/dist/actions/action_registry.d.ts +35 -0
- package/dist/actions/action_registry.d.ts.map +1 -0
- package/dist/actions/action_registry.js +83 -0
- package/dist/actions/action_spec.d.ts +169 -0
- package/dist/actions/action_spec.d.ts.map +1 -0
- package/dist/actions/action_spec.js +76 -0
- package/dist/auth/account_queries.d.ts +96 -0
- package/dist/auth/account_queries.d.ts.map +1 -0
- package/dist/auth/account_queries.js +172 -0
- package/dist/auth/account_routes.d.ts +86 -0
- package/dist/auth/account_routes.d.ts.map +1 -0
- package/dist/auth/account_routes.js +406 -0
- package/dist/auth/account_schema.d.ts +192 -0
- package/dist/auth/account_schema.d.ts.map +1 -0
- package/dist/auth/account_schema.js +105 -0
- package/dist/auth/admin_routes.d.ts +29 -0
- package/dist/auth/admin_routes.d.ts.map +1 -0
- package/dist/auth/admin_routes.js +193 -0
- package/dist/auth/api_token.d.ts +33 -0
- package/dist/auth/api_token.d.ts.map +1 -0
- package/dist/auth/api_token.js +36 -0
- package/dist/auth/api_token_queries.d.ts +80 -0
- package/dist/auth/api_token_queries.d.ts.map +1 -0
- package/dist/auth/api_token_queries.js +116 -0
- package/dist/auth/app_settings_queries.d.ts +33 -0
- package/dist/auth/app_settings_queries.d.ts.map +1 -0
- package/dist/auth/app_settings_queries.js +51 -0
- package/dist/auth/app_settings_routes.d.ts +27 -0
- package/dist/auth/app_settings_routes.d.ts.map +1 -0
- package/dist/auth/app_settings_routes.js +66 -0
- package/dist/auth/app_settings_schema.d.ts +35 -0
- package/dist/auth/app_settings_schema.d.ts.map +1 -0
- package/dist/auth/app_settings_schema.js +22 -0
- package/dist/auth/audit_log_queries.d.ts +90 -0
- package/dist/auth/audit_log_queries.d.ts.map +1 -0
- package/dist/auth/audit_log_queries.js +205 -0
- package/dist/auth/audit_log_routes.d.ts +33 -0
- package/dist/auth/audit_log_routes.d.ts.map +1 -0
- package/dist/auth/audit_log_routes.js +106 -0
- package/dist/auth/audit_log_schema.d.ts +259 -0
- package/dist/auth/audit_log_schema.d.ts.map +1 -0
- package/dist/auth/audit_log_schema.js +123 -0
- package/dist/auth/bearer_auth.d.ts +32 -0
- package/dist/auth/bearer_auth.d.ts.map +1 -0
- package/dist/auth/bearer_auth.js +90 -0
- package/dist/auth/bootstrap_account.d.ts +82 -0
- package/dist/auth/bootstrap_account.d.ts.map +1 -0
- package/dist/auth/bootstrap_account.js +97 -0
- package/dist/auth/bootstrap_routes.d.ts +74 -0
- package/dist/auth/bootstrap_routes.d.ts.map +1 -0
- package/dist/auth/bootstrap_routes.js +154 -0
- package/dist/auth/daemon_token.d.ts +49 -0
- package/dist/auth/daemon_token.d.ts.map +1 -0
- package/dist/auth/daemon_token.js +49 -0
- package/dist/auth/daemon_token_middleware.d.ts +93 -0
- package/dist/auth/daemon_token_middleware.d.ts.map +1 -0
- package/dist/auth/daemon_token_middleware.js +167 -0
- package/dist/auth/ddl.d.ts +27 -0
- package/dist/auth/ddl.d.ts.map +1 -0
- package/dist/auth/ddl.js +111 -0
- package/dist/auth/deps.d.ts +52 -0
- package/dist/auth/deps.d.ts.map +1 -0
- package/dist/auth/deps.js +10 -0
- package/dist/auth/invite_queries.d.ts +68 -0
- package/dist/auth/invite_queries.d.ts.map +1 -0
- package/dist/auth/invite_queries.js +105 -0
- package/dist/auth/invite_routes.d.ts +18 -0
- package/dist/auth/invite_routes.d.ts.map +1 -0
- package/dist/auth/invite_routes.js +129 -0
- package/dist/auth/invite_schema.d.ts +51 -0
- package/dist/auth/invite_schema.d.ts.map +1 -0
- package/dist/auth/invite_schema.js +25 -0
- package/dist/auth/keyring.d.ts +87 -0
- package/dist/auth/keyring.d.ts.map +1 -0
- package/dist/auth/keyring.js +142 -0
- package/dist/auth/middleware.d.ts +40 -0
- package/dist/auth/middleware.d.ts.map +1 -0
- package/dist/auth/middleware.js +64 -0
- package/dist/auth/migrations.d.ts +42 -0
- package/dist/auth/migrations.d.ts.map +1 -0
- package/dist/auth/migrations.js +79 -0
- package/dist/auth/password.d.ts +39 -0
- package/dist/auth/password.d.ts.map +1 -0
- package/dist/auth/password.js +25 -0
- package/dist/auth/password_argon2.d.ts +43 -0
- package/dist/auth/password_argon2.d.ts.map +1 -0
- package/dist/auth/password_argon2.js +76 -0
- package/dist/auth/permit_queries.d.ts +72 -0
- package/dist/auth/permit_queries.d.ts.map +1 -0
- package/dist/auth/permit_queries.js +116 -0
- package/dist/auth/request_context.d.ts +114 -0
- package/dist/auth/request_context.d.ts.map +1 -0
- package/dist/auth/request_context.js +176 -0
- package/dist/auth/require_keeper.d.ts +20 -0
- package/dist/auth/require_keeper.d.ts.map +1 -0
- package/dist/auth/require_keeper.js +35 -0
- package/dist/auth/role_schema.d.ts +69 -0
- package/dist/auth/role_schema.d.ts.map +1 -0
- package/dist/auth/role_schema.js +70 -0
- package/dist/auth/route_guards.d.ts +21 -0
- package/dist/auth/route_guards.d.ts.map +1 -0
- package/dist/auth/route_guards.js +32 -0
- package/dist/auth/session_cookie.d.ts +158 -0
- package/dist/auth/session_cookie.d.ts.map +1 -0
- package/dist/auth/session_cookie.js +135 -0
- package/dist/auth/session_lifecycle.d.ts +35 -0
- package/dist/auth/session_lifecycle.d.ts.map +1 -0
- package/dist/auth/session_lifecycle.js +27 -0
- package/dist/auth/session_middleware.d.ts +33 -0
- package/dist/auth/session_middleware.d.ts.map +1 -0
- package/dist/auth/session_middleware.js +62 -0
- package/dist/auth/session_queries.d.ts +135 -0
- package/dist/auth/session_queries.d.ts.map +1 -0
- package/dist/auth/session_queries.js +186 -0
- package/dist/auth/signup_routes.d.ts +32 -0
- package/dist/auth/signup_routes.d.ts.map +1 -0
- package/dist/auth/signup_routes.js +150 -0
- package/dist/cli/args.d.ts +48 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +76 -0
- package/dist/cli/config.d.ts +48 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +77 -0
- package/dist/cli/daemon.d.ts +82 -0
- package/dist/cli/daemon.d.ts.map +1 -0
- package/dist/cli/daemon.js +149 -0
- package/dist/cli/help.d.ts +85 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +138 -0
- package/dist/cli/logger.d.ts +46 -0
- package/dist/cli/logger.d.ts.map +1 -0
- package/dist/cli/logger.js +48 -0
- package/dist/cli/util.d.ts +36 -0
- package/dist/cli/util.d.ts.map +1 -0
- package/dist/cli/util.js +50 -0
- package/dist/crypto.d.ts +13 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +19 -0
- package/dist/db/assert_row.d.ts +18 -0
- package/dist/db/assert_row.d.ts.map +1 -0
- package/dist/db/assert_row.js +24 -0
- package/dist/db/create_db.d.ts +38 -0
- package/dist/db/create_db.d.ts.map +1 -0
- package/dist/db/create_db.js +57 -0
- package/dist/db/db.d.ts +97 -0
- package/dist/db/db.d.ts.map +1 -0
- package/dist/db/db.js +76 -0
- package/dist/db/db_pg.d.ts +21 -0
- package/dist/db/db_pg.d.ts.map +1 -0
- package/dist/db/db_pg.js +45 -0
- package/dist/db/db_pglite.d.ts +21 -0
- package/dist/db/db_pglite.d.ts.map +1 -0
- package/dist/db/db_pglite.js +28 -0
- package/dist/db/migrate.d.ts +67 -0
- package/dist/db/migrate.d.ts.map +1 -0
- package/dist/db/migrate.js +118 -0
- package/dist/db/pg_error.d.ts +16 -0
- package/dist/db/pg_error.d.ts.map +1 -0
- package/dist/db/pg_error.js +15 -0
- package/dist/db/query_deps.d.ts +14 -0
- package/dist/db/query_deps.d.ts.map +1 -0
- package/dist/db/query_deps.js +9 -0
- package/dist/db/sql_identifier.d.ts +27 -0
- package/dist/db/sql_identifier.d.ts.map +1 -0
- package/dist/db/sql_identifier.js +31 -0
- package/dist/db/status.d.ts +62 -0
- package/dist/db/status.d.ts.map +1 -0
- package/dist/db/status.js +116 -0
- package/dist/dev/setup.d.ts +159 -0
- package/dist/dev/setup.d.ts.map +1 -0
- package/dist/dev/setup.js +265 -0
- package/dist/env/dotenv.d.ts +25 -0
- package/dist/env/dotenv.d.ts.map +1 -0
- package/dist/env/dotenv.js +52 -0
- package/dist/env/load.d.ts +52 -0
- package/dist/env/load.d.ts.map +1 -0
- package/dist/env/load.js +79 -0
- package/dist/env/mask.d.ts +19 -0
- package/dist/env/mask.d.ts.map +1 -0
- package/dist/env/mask.js +26 -0
- package/dist/env/resolve.d.ts +126 -0
- package/dist/env/resolve.d.ts.map +1 -0
- package/dist/env/resolve.js +200 -0
- package/dist/hono_context.d.ts +48 -0
- package/dist/hono_context.d.ts.map +1 -0
- package/dist/hono_context.js +22 -0
- package/dist/http/common_routes.d.ts +52 -0
- package/dist/http/common_routes.d.ts.map +1 -0
- package/dist/http/common_routes.js +65 -0
- package/dist/http/db_routes.d.ts +57 -0
- package/dist/http/db_routes.d.ts.map +1 -0
- package/dist/http/db_routes.js +176 -0
- package/dist/http/error_schemas.d.ts +169 -0
- package/dist/http/error_schemas.d.ts.map +1 -0
- package/dist/http/error_schemas.js +178 -0
- package/dist/http/middleware_spec.d.ts +19 -0
- package/dist/http/middleware_spec.d.ts.map +1 -0
- package/dist/http/middleware_spec.js +9 -0
- package/dist/http/origin.d.ts +57 -0
- package/dist/http/origin.d.ts.map +1 -0
- package/dist/http/origin.js +207 -0
- package/dist/http/proxy.d.ts +112 -0
- package/dist/http/proxy.d.ts.map +1 -0
- package/dist/http/proxy.js +240 -0
- package/dist/http/route_spec.d.ts +197 -0
- package/dist/http/route_spec.d.ts.map +1 -0
- package/dist/http/route_spec.js +243 -0
- package/dist/http/schema_helpers.d.ts +64 -0
- package/dist/http/schema_helpers.d.ts.map +1 -0
- package/dist/http/schema_helpers.js +90 -0
- package/dist/http/surface.d.ts +132 -0
- package/dist/http/surface.d.ts.map +1 -0
- package/dist/http/surface.js +156 -0
- package/dist/http/surface_query.d.ts +77 -0
- package/dist/http/surface_query.d.ts.map +1 -0
- package/dist/http/surface_query.js +86 -0
- package/dist/rate_limiter.d.ts +94 -0
- package/dist/rate_limiter.d.ts.map +1 -0
- package/dist/rate_limiter.js +156 -0
- package/dist/realtime/sse.d.ts +80 -0
- package/dist/realtime/sse.d.ts.map +1 -0
- package/dist/realtime/sse.js +109 -0
- package/dist/realtime/sse_auth_guard.d.ts +93 -0
- package/dist/realtime/sse_auth_guard.d.ts.map +1 -0
- package/dist/realtime/sse_auth_guard.js +111 -0
- package/dist/realtime/subscriber_registry.d.ts +85 -0
- package/dist/realtime/subscriber_registry.d.ts.map +1 -0
- package/dist/realtime/subscriber_registry.js +108 -0
- package/dist/runtime/deno.d.ts +21 -0
- package/dist/runtime/deno.d.ts.map +1 -0
- package/dist/runtime/deno.js +83 -0
- package/dist/runtime/deps.d.ts +113 -0
- package/dist/runtime/deps.d.ts.map +1 -0
- package/dist/runtime/deps.js +10 -0
- package/dist/runtime/fs.d.ts +15 -0
- package/dist/runtime/fs.d.ts.map +1 -0
- package/dist/runtime/fs.js +17 -0
- package/dist/runtime/mock.d.ts +81 -0
- package/dist/runtime/mock.d.ts.map +1 -0
- package/dist/runtime/mock.js +195 -0
- package/dist/runtime/node.d.ts +17 -0
- package/dist/runtime/node.d.ts.map +1 -0
- package/dist/runtime/node.js +117 -0
- package/dist/schema_meta.d.ts +16 -0
- package/dist/schema_meta.d.ts.map +1 -0
- package/dist/schema_meta.js +9 -0
- package/dist/sensitivity.d.ts +15 -0
- package/dist/sensitivity.d.ts.map +1 -0
- package/dist/sensitivity.js +9 -0
- package/dist/server/app_backend.d.ts +74 -0
- package/dist/server/app_backend.d.ts.map +1 -0
- package/dist/server/app_backend.js +39 -0
- package/dist/server/app_server.d.ts +201 -0
- package/dist/server/app_server.d.ts.map +1 -0
- package/dist/server/app_server.js +266 -0
- package/dist/server/env.d.ts +68 -0
- package/dist/server/env.d.ts.map +1 -0
- package/dist/server/env.js +95 -0
- package/dist/server/startup.d.ts +22 -0
- package/dist/server/startup.d.ts.map +1 -0
- package/dist/server/startup.js +48 -0
- package/dist/server/static.d.ts +39 -0
- package/dist/server/static.d.ts.map +1 -0
- package/dist/server/static.js +38 -0
- package/dist/server/validate_nginx.d.ts +34 -0
- package/dist/server/validate_nginx.d.ts.map +1 -0
- package/dist/server/validate_nginx.js +118 -0
- package/dist/testing/CLAUDE.md +3 -0
- package/dist/testing/admin_integration.d.ts +45 -0
- package/dist/testing/admin_integration.d.ts.map +1 -0
- package/dist/testing/admin_integration.js +840 -0
- package/dist/testing/adversarial_404.d.ts +15 -0
- package/dist/testing/adversarial_404.d.ts.map +1 -0
- package/dist/testing/adversarial_404.js +118 -0
- package/dist/testing/adversarial_headers.d.ts +36 -0
- package/dist/testing/adversarial_headers.d.ts.map +1 -0
- package/dist/testing/adversarial_headers.js +128 -0
- package/dist/testing/adversarial_input.d.ts +56 -0
- package/dist/testing/adversarial_input.d.ts.map +1 -0
- package/dist/testing/adversarial_input.js +494 -0
- package/dist/testing/app_server.d.ts +169 -0
- package/dist/testing/app_server.d.ts.map +1 -0
- package/dist/testing/app_server.js +240 -0
- package/dist/testing/assert_dev_env.d.ts +10 -0
- package/dist/testing/assert_dev_env.d.ts.map +1 -0
- package/dist/testing/assert_dev_env.js +13 -0
- package/dist/testing/assertions.d.ts +61 -0
- package/dist/testing/assertions.d.ts.map +1 -0
- package/dist/testing/assertions.js +96 -0
- package/dist/testing/attack_surface.d.ts +63 -0
- package/dist/testing/attack_surface.d.ts.map +1 -0
- package/dist/testing/attack_surface.js +224 -0
- package/dist/testing/audit_completeness.d.ts +29 -0
- package/dist/testing/audit_completeness.d.ts.map +1 -0
- package/dist/testing/audit_completeness.js +410 -0
- package/dist/testing/auth_apps.d.ts +55 -0
- package/dist/testing/auth_apps.d.ts.map +1 -0
- package/dist/testing/auth_apps.js +122 -0
- package/dist/testing/data_exposure.d.ts +62 -0
- package/dist/testing/data_exposure.d.ts.map +1 -0
- package/dist/testing/data_exposure.js +297 -0
- package/dist/testing/db.d.ts +111 -0
- package/dist/testing/db.d.ts.map +1 -0
- package/dist/testing/db.js +258 -0
- package/dist/testing/entities.d.ts +21 -0
- package/dist/testing/entities.d.ts.map +1 -0
- package/dist/testing/entities.js +42 -0
- package/dist/testing/error_coverage.d.ts +78 -0
- package/dist/testing/error_coverage.d.ts.map +1 -0
- package/dist/testing/error_coverage.js +135 -0
- package/dist/testing/integration.d.ts +37 -0
- package/dist/testing/integration.d.ts.map +1 -0
- package/dist/testing/integration.js +1139 -0
- package/dist/testing/integration_helpers.d.ts +107 -0
- package/dist/testing/integration_helpers.d.ts.map +1 -0
- package/dist/testing/integration_helpers.js +246 -0
- package/dist/testing/middleware.d.ts +125 -0
- package/dist/testing/middleware.d.ts.map +1 -0
- package/dist/testing/middleware.js +210 -0
- package/dist/testing/rate_limiting.d.ts +43 -0
- package/dist/testing/rate_limiting.d.ts.map +1 -0
- package/dist/testing/rate_limiting.js +216 -0
- package/dist/testing/round_trip.d.ts +37 -0
- package/dist/testing/round_trip.d.ts.map +1 -0
- package/dist/testing/round_trip.js +128 -0
- package/dist/testing/schema_generators.d.ts +33 -0
- package/dist/testing/schema_generators.d.ts.map +1 -0
- package/dist/testing/schema_generators.js +137 -0
- package/dist/testing/standard.d.ts +49 -0
- package/dist/testing/standard.d.ts.map +1 -0
- package/dist/testing/standard.js +16 -0
- package/dist/testing/stubs.d.ts +96 -0
- package/dist/testing/stubs.d.ts.map +1 -0
- package/dist/testing/stubs.js +192 -0
- package/dist/testing/surface_invariants.d.ts +189 -0
- package/dist/testing/surface_invariants.d.ts.map +1 -0
- package/dist/testing/surface_invariants.js +450 -0
- package/dist/ui/AccountSessions.svelte +75 -0
- package/dist/ui/AccountSessions.svelte.d.ts +19 -0
- package/dist/ui/AccountSessions.svelte.d.ts.map +1 -0
- package/dist/ui/AdminAccounts.svelte +107 -0
- package/dist/ui/AdminAccounts.svelte.d.ts +19 -0
- package/dist/ui/AdminAccounts.svelte.d.ts.map +1 -0
- package/dist/ui/AdminAuditLog.svelte +144 -0
- package/dist/ui/AdminAuditLog.svelte.d.ts +4 -0
- package/dist/ui/AdminAuditLog.svelte.d.ts.map +1 -0
- package/dist/ui/AdminInvites.svelte +142 -0
- package/dist/ui/AdminInvites.svelte.d.ts +4 -0
- package/dist/ui/AdminInvites.svelte.d.ts.map +1 -0
- package/dist/ui/AdminOverview.svelte +337 -0
- package/dist/ui/AdminOverview.svelte.d.ts +4 -0
- package/dist/ui/AdminOverview.svelte.d.ts.map +1 -0
- package/dist/ui/AdminPermitHistory.svelte +61 -0
- package/dist/ui/AdminPermitHistory.svelte.d.ts +19 -0
- package/dist/ui/AdminPermitHistory.svelte.d.ts.map +1 -0
- package/dist/ui/AdminSessions.svelte +85 -0
- package/dist/ui/AdminSessions.svelte.d.ts +19 -0
- package/dist/ui/AdminSessions.svelte.d.ts.map +1 -0
- package/dist/ui/AdminSettings.svelte +32 -0
- package/dist/ui/AdminSettings.svelte.d.ts +19 -0
- package/dist/ui/AdminSettings.svelte.d.ts.map +1 -0
- package/dist/ui/AdminSurface.svelte +42 -0
- package/dist/ui/AdminSurface.svelte.d.ts +4 -0
- package/dist/ui/AdminSurface.svelte.d.ts.map +1 -0
- package/dist/ui/AppShell.svelte +93 -0
- package/dist/ui/AppShell.svelte.d.ts +20 -0
- package/dist/ui/AppShell.svelte.d.ts.map +1 -0
- package/dist/ui/BootstrapForm.svelte +105 -0
- package/dist/ui/BootstrapForm.svelte.d.ts +4 -0
- package/dist/ui/BootstrapForm.svelte.d.ts.map +1 -0
- package/dist/ui/ColumnLayout.svelte +46 -0
- package/dist/ui/ColumnLayout.svelte.d.ts +11 -0
- package/dist/ui/ColumnLayout.svelte.d.ts.map +1 -0
- package/dist/ui/ConfirmButton.svelte +125 -0
- package/dist/ui/ConfirmButton.svelte.d.ts +54 -0
- package/dist/ui/ConfirmButton.svelte.d.ts.map +1 -0
- package/dist/ui/Datatable.svelte +185 -0
- package/dist/ui/Datatable.svelte.d.ts +35 -0
- package/dist/ui/Datatable.svelte.d.ts.map +1 -0
- package/dist/ui/LoginForm.svelte +82 -0
- package/dist/ui/LoginForm.svelte.d.ts +8 -0
- package/dist/ui/LoginForm.svelte.d.ts.map +1 -0
- package/dist/ui/LogoutButton.svelte +36 -0
- package/dist/ui/LogoutButton.svelte.d.ts +10 -0
- package/dist/ui/LogoutButton.svelte.d.ts.map +1 -0
- package/dist/ui/MenuLink.svelte +35 -0
- package/dist/ui/MenuLink.svelte.d.ts +12 -0
- package/dist/ui/MenuLink.svelte.d.ts.map +1 -0
- package/dist/ui/OpenSignupToggle.svelte +36 -0
- package/dist/ui/OpenSignupToggle.svelte.d.ts +19 -0
- package/dist/ui/OpenSignupToggle.svelte.d.ts.map +1 -0
- package/dist/ui/PopoverButton.svelte +136 -0
- package/dist/ui/PopoverButton.svelte.d.ts +63 -0
- package/dist/ui/PopoverButton.svelte.d.ts.map +1 -0
- package/dist/ui/SignupForm.svelte +117 -0
- package/dist/ui/SignupForm.svelte.d.ts +7 -0
- package/dist/ui/SignupForm.svelte.d.ts.map +1 -0
- package/dist/ui/SurfaceExplorer.svelte +287 -0
- package/dist/ui/SurfaceExplorer.svelte.d.ts +8 -0
- package/dist/ui/SurfaceExplorer.svelte.d.ts.map +1 -0
- package/dist/ui/account_sessions_state.svelte.d.ts +15 -0
- package/dist/ui/account_sessions_state.svelte.d.ts.map +1 -0
- package/dist/ui/account_sessions_state.svelte.js +45 -0
- package/dist/ui/admin_accounts_state.svelte.d.ts +19 -0
- package/dist/ui/admin_accounts_state.svelte.d.ts.map +1 -0
- package/dist/ui/admin_accounts_state.svelte.js +65 -0
- package/dist/ui/admin_invites_state.svelte.d.ts +19 -0
- package/dist/ui/admin_invites_state.svelte.d.ts.map +1 -0
- package/dist/ui/admin_invites_state.svelte.js +71 -0
- package/dist/ui/admin_sessions_state.svelte.d.ts +18 -0
- package/dist/ui/admin_sessions_state.svelte.d.ts.map +1 -0
- package/dist/ui/admin_sessions_state.svelte.js +62 -0
- package/dist/ui/app_settings_state.svelte.d.ts +14 -0
- package/dist/ui/app_settings_state.svelte.d.ts.map +1 -0
- package/dist/ui/app_settings_state.svelte.js +44 -0
- package/dist/ui/audit_log_state.svelte.d.ts +40 -0
- package/dist/ui/audit_log_state.svelte.d.ts.map +1 -0
- package/dist/ui/audit_log_state.svelte.js +153 -0
- package/dist/ui/auth_state.svelte.d.ts +85 -0
- package/dist/ui/auth_state.svelte.d.ts.map +1 -0
- package/dist/ui/auth_state.svelte.js +238 -0
- package/dist/ui/datatable.d.ts +25 -0
- package/dist/ui/datatable.d.ts.map +1 -0
- package/dist/ui/datatable.js +9 -0
- package/dist/ui/enter_advance.d.ts +13 -0
- package/dist/ui/enter_advance.d.ts.map +1 -0
- package/dist/ui/enter_advance.js +30 -0
- package/dist/ui/loadable.svelte.d.ts +55 -0
- package/dist/ui/loadable.svelte.d.ts.map +1 -0
- package/dist/ui/loadable.svelte.js +75 -0
- package/dist/ui/popover.svelte.d.ts +137 -0
- package/dist/ui/popover.svelte.d.ts.map +1 -0
- package/dist/ui/popover.svelte.js +288 -0
- package/dist/ui/position_helpers.d.ts +27 -0
- package/dist/ui/position_helpers.d.ts.map +1 -0
- package/dist/ui/position_helpers.js +81 -0
- package/dist/ui/sidebar_state.svelte.d.ts +30 -0
- package/dist/ui/sidebar_state.svelte.d.ts.map +1 -0
- package/dist/ui/sidebar_state.svelte.js +39 -0
- package/dist/ui/table_state.svelte.d.ts +63 -0
- package/dist/ui/table_state.svelte.d.ts.map +1 -0
- package/dist/ui/table_state.svelte.js +117 -0
- package/dist/ui/ui_fetch.d.ts +29 -0
- package/dist/ui/ui_fetch.d.ts.map +1 -0
- package/dist/ui/ui_fetch.js +37 -0
- package/dist/ui/ui_format.d.ts +63 -0
- package/dist/ui/ui_format.d.ts.map +1 -0
- package/dist/ui/ui_format.js +196 -0
- package/package.json +121 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import './assert_dev_env.js';
|
|
2
|
+
/**
|
|
3
|
+
* Integration test helpers — route lookup, response validation, and cookie utilities.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import type { RouteSpec, RouteMethod } from '../http/route_spec.js';
|
|
8
|
+
import type { Keyring } from '../auth/keyring.js';
|
|
9
|
+
import { type SessionOptions } from '../auth/session_cookie.js';
|
|
10
|
+
/**
|
|
11
|
+
* Find a route spec matching the given method and path.
|
|
12
|
+
*
|
|
13
|
+
* Supports both exact matches and parameterized paths (`:param` segments).
|
|
14
|
+
*
|
|
15
|
+
* @param specs - route specs to search
|
|
16
|
+
* @param method - HTTP method
|
|
17
|
+
* @param path - request path (exact or with concrete param values)
|
|
18
|
+
* @returns matching route spec, or `undefined`
|
|
19
|
+
*/
|
|
20
|
+
export declare const find_route_spec: (specs: Array<RouteSpec>, method: string, path: string) => RouteSpec | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Find an auth route by suffix and method.
|
|
23
|
+
*
|
|
24
|
+
* Useful for discovering login/logout/verify/revoke paths regardless
|
|
25
|
+
* of consumer prefix (`/api/account/login`, `/api/auth/login`, etc.).
|
|
26
|
+
*
|
|
27
|
+
* @param specs - route specs to search
|
|
28
|
+
* @param suffix - path suffix to match (e.g. `'/login'`)
|
|
29
|
+
* @param method - HTTP method
|
|
30
|
+
* @returns matching route spec, or `undefined`
|
|
31
|
+
*/
|
|
32
|
+
export declare const find_auth_route: (specs: Array<RouteSpec>, suffix: string, method: RouteMethod) => RouteSpec | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Validate a response body against the route spec's declared schemas.
|
|
35
|
+
*
|
|
36
|
+
* For 2xx responses, validates against `spec.output`.
|
|
37
|
+
* For error responses, validates against the merged error schema for that status code.
|
|
38
|
+
* Throws with details on mismatch.
|
|
39
|
+
*
|
|
40
|
+
* @param route_specs - route specs for schema lookup
|
|
41
|
+
* @param method - HTTP method of the request
|
|
42
|
+
* @param path - path of the request
|
|
43
|
+
* @param response - the Response to validate
|
|
44
|
+
*/
|
|
45
|
+
export declare const assert_response_matches_spec: (route_specs: Array<RouteSpec>, method: string, path: string, response: Response) => Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Create an expired test cookie — validly signed but with an expiry timestamp in 1970.
|
|
48
|
+
*
|
|
49
|
+
* @param keyring - keyring for signing
|
|
50
|
+
* @param session_options - session config
|
|
51
|
+
* @returns signed cookie value with long-past expiry
|
|
52
|
+
*/
|
|
53
|
+
export declare const create_expired_test_cookie: (keyring: Keyring, session_options: SessionOptions<string>) => Promise<string>;
|
|
54
|
+
/**
|
|
55
|
+
* Assert that an error response body contains no unexpected fields.
|
|
56
|
+
*
|
|
57
|
+
* Error schemas use `z.looseObject` (intentional — multiple producers), but
|
|
58
|
+
* test responses should be checked for fields that could leak information.
|
|
59
|
+
* Flags any field not in the known-safe set.
|
|
60
|
+
*
|
|
61
|
+
* @param body - parsed error response JSON
|
|
62
|
+
* @param context - description for error messages (e.g., `'POST /api/login 401'`)
|
|
63
|
+
* @returns array of unexpected field names (empty = clean)
|
|
64
|
+
*/
|
|
65
|
+
export declare const check_error_response_fields: (body: Record<string, unknown>) => Array<string>;
|
|
66
|
+
/**
|
|
67
|
+
* Assert that an error response contains no leaky field values.
|
|
68
|
+
*
|
|
69
|
+
* Checks both field names and string values for patterns indicating
|
|
70
|
+
* stack traces, SQL, or internal paths.
|
|
71
|
+
*
|
|
72
|
+
* @param body - parsed error response JSON
|
|
73
|
+
* @param context - description for error messages
|
|
74
|
+
*/
|
|
75
|
+
export declare const assert_no_error_info_leakage: (body: Record<string, unknown>, context: string) => void;
|
|
76
|
+
/**
|
|
77
|
+
* Assert that a 429 response includes a valid `Retry-After` header
|
|
78
|
+
* matching the JSON body's `retry_after` field.
|
|
79
|
+
*
|
|
80
|
+
* @param response - the 429 response
|
|
81
|
+
* @param body - parsed JSON body with `retry_after` field
|
|
82
|
+
*/
|
|
83
|
+
export declare const assert_rate_limit_retry_after_header: (response: Response, body: {
|
|
84
|
+
retry_after: number;
|
|
85
|
+
}) => void;
|
|
86
|
+
/** Field names that must never appear in any HTTP response body. */
|
|
87
|
+
export declare const SENSITIVE_FIELD_BLOCKLIST: ReadonlyArray<string>;
|
|
88
|
+
/** Field names that must not appear in non-admin HTTP response bodies. */
|
|
89
|
+
export declare const ADMIN_ONLY_FIELD_BLOCKLIST: ReadonlyArray<string>;
|
|
90
|
+
/**
|
|
91
|
+
* Recursively collect all key names from a parsed JSON value.
|
|
92
|
+
*
|
|
93
|
+
* Walks objects and arrays to find every property name at any nesting depth.
|
|
94
|
+
*
|
|
95
|
+
* @param value - parsed JSON value
|
|
96
|
+
* @returns set of all key names found
|
|
97
|
+
*/
|
|
98
|
+
export declare const collect_json_keys_recursive: (value: unknown) => Set<string>;
|
|
99
|
+
/**
|
|
100
|
+
* Assert that a parsed JSON body contains no fields from the given blocklist.
|
|
101
|
+
*
|
|
102
|
+
* @param body - parsed response JSON
|
|
103
|
+
* @param blocklist - field names to check for
|
|
104
|
+
* @param context - description for error messages
|
|
105
|
+
*/
|
|
106
|
+
export declare const assert_no_sensitive_fields_in_json: (body: unknown, blocklist: ReadonlyArray<string>, context: string) => void;
|
|
107
|
+
//# sourceMappingURL=integration_helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/integration_helpers.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAE7B;;;;GAIG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAE,WAAW,EAAC,MAAM,uBAAuB,CAAC;AAIlE,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAA8B,KAAK,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAE3F;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,GAC3B,OAAO,KAAK,CAAC,SAAS,CAAC,EACvB,QAAQ,MAAM,EACd,MAAM,MAAM,KACV,SAAS,GAAG,SAad,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,GAC3B,OAAO,KAAK,CAAC,SAAS,CAAC,EACvB,QAAQ,MAAM,EACd,QAAQ,WAAW,KACjB,SAAS,GAAG,SAEd,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,4BAA4B,GACxC,aAAa,KAAK,CAAC,SAAS,CAAC,EAC7B,QAAQ,MAAM,EACd,MAAM,MAAM,EACZ,UAAU,QAAQ,KAChB,OAAO,CAAC,IAAI,CAmDd,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,GACtC,SAAS,OAAO,EAChB,iBAAiB,cAAc,CAAC,MAAM,CAAC,KACrC,OAAO,CAAC,MAAM,CAGhB,CAAC;AAuCF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,2BAA2B,GAAI,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,KAAK,CAAC,MAAM,CAQvF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,4BAA4B,GACxC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,SAAS,MAAM,KACb,IAkBF,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,oCAAoC,GAChD,UAAU,QAAQ,EAClB,MAAM;IAAC,WAAW,EAAE,MAAM,CAAA;CAAC,KACzB,IAUF,CAAC;AAIF,oEAAoE;AACpE,eAAO,MAAM,yBAAyB,EAAE,aAAa,CAAC,MAAM,CAAmC,CAAC;AAEhG,0EAA0E;AAC1E,eAAO,MAAM,0BAA0B,EAAE,aAAa,CAAC,MAAM,CAAgC,CAAC;AAE9F;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,GAAI,OAAO,OAAO,KAAG,GAAG,CAAC,MAAM,CAetE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,kCAAkC,GAC9C,MAAM,OAAO,EACb,WAAW,aAAa,CAAC,MAAM,CAAC,EAChC,SAAS,MAAM,KACb,IAKF,CAAC"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import './assert_dev_env.js';
|
|
2
|
+
import { is_null_schema, merge_error_schemas } from '../http/schema_helpers.js';
|
|
3
|
+
import { assert } from 'vitest';
|
|
4
|
+
import { create_session_cookie_value } from '../auth/session_cookie.js';
|
|
5
|
+
/**
|
|
6
|
+
* Find a route spec matching the given method and path.
|
|
7
|
+
*
|
|
8
|
+
* Supports both exact matches and parameterized paths (`:param` segments).
|
|
9
|
+
*
|
|
10
|
+
* @param specs - route specs to search
|
|
11
|
+
* @param method - HTTP method
|
|
12
|
+
* @param path - request path (exact or with concrete param values)
|
|
13
|
+
* @returns matching route spec, or `undefined`
|
|
14
|
+
*/
|
|
15
|
+
export const find_route_spec = (specs, method, path) => {
|
|
16
|
+
// exact match first
|
|
17
|
+
const exact = specs.find((s) => s.method === method && s.path === path);
|
|
18
|
+
if (exact)
|
|
19
|
+
return exact;
|
|
20
|
+
// parameterized match — `:param` segments match any value
|
|
21
|
+
return specs.find((s) => {
|
|
22
|
+
if (s.method !== method)
|
|
23
|
+
return false;
|
|
24
|
+
const spec_parts = s.path.split('/');
|
|
25
|
+
const path_parts = path.split('/');
|
|
26
|
+
if (spec_parts.length !== path_parts.length)
|
|
27
|
+
return false;
|
|
28
|
+
return spec_parts.every((sp, i) => sp.startsWith(':') || sp === path_parts[i]);
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Find an auth route by suffix and method.
|
|
33
|
+
*
|
|
34
|
+
* Useful for discovering login/logout/verify/revoke paths regardless
|
|
35
|
+
* of consumer prefix (`/api/account/login`, `/api/auth/login`, etc.).
|
|
36
|
+
*
|
|
37
|
+
* @param specs - route specs to search
|
|
38
|
+
* @param suffix - path suffix to match (e.g. `'/login'`)
|
|
39
|
+
* @param method - HTTP method
|
|
40
|
+
* @returns matching route spec, or `undefined`
|
|
41
|
+
*/
|
|
42
|
+
export const find_auth_route = (specs, suffix, method) => {
|
|
43
|
+
return specs.find((s) => s.method === method && s.path.endsWith(suffix));
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Validate a response body against the route spec's declared schemas.
|
|
47
|
+
*
|
|
48
|
+
* For 2xx responses, validates against `spec.output`.
|
|
49
|
+
* For error responses, validates against the merged error schema for that status code.
|
|
50
|
+
* Throws with details on mismatch.
|
|
51
|
+
*
|
|
52
|
+
* @param route_specs - route specs for schema lookup
|
|
53
|
+
* @param method - HTTP method of the request
|
|
54
|
+
* @param path - path of the request
|
|
55
|
+
* @param response - the Response to validate
|
|
56
|
+
*/
|
|
57
|
+
export const assert_response_matches_spec = async (route_specs, method, path, response) => {
|
|
58
|
+
const spec = find_route_spec(route_specs, method, path);
|
|
59
|
+
if (!spec) {
|
|
60
|
+
throw new Error(`No route spec found for ${method} ${path}`);
|
|
61
|
+
}
|
|
62
|
+
const cloned = response.clone();
|
|
63
|
+
let body;
|
|
64
|
+
try {
|
|
65
|
+
body = await cloned.json();
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// Non-JSON response — only acceptable when no schema applies.
|
|
69
|
+
// If the spec declares an output or error schema for this status,
|
|
70
|
+
// getting non-JSON is a real bug.
|
|
71
|
+
if (response.ok && !is_null_schema(spec.output)) {
|
|
72
|
+
throw new Error(`${method} ${path} (${response.status}) returned non-JSON but has output schema`);
|
|
73
|
+
}
|
|
74
|
+
if (!response.ok) {
|
|
75
|
+
const merged = merge_error_schemas(spec);
|
|
76
|
+
if (merged?.[response.status]) {
|
|
77
|
+
throw new Error(`${method} ${path} (${response.status}) returned non-JSON but has error schema for status ${response.status}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (response.ok) {
|
|
83
|
+
const result = spec.output.safeParse(body);
|
|
84
|
+
if (!result.success) {
|
|
85
|
+
throw new Error(`Output schema mismatch for ${method} ${path} (${response.status}): ${JSON.stringify(result.error.issues)}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
const merged = merge_error_schemas(spec);
|
|
90
|
+
if (merged) {
|
|
91
|
+
const status_schema = merged[response.status];
|
|
92
|
+
if (status_schema) {
|
|
93
|
+
const result = status_schema.safeParse(body);
|
|
94
|
+
if (!result.success) {
|
|
95
|
+
throw new Error(`Error schema mismatch for ${method} ${path} (${response.status}): ${JSON.stringify(result.error.issues)}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Create an expired test cookie — validly signed but with an expiry timestamp in 1970.
|
|
103
|
+
*
|
|
104
|
+
* @param keyring - keyring for signing
|
|
105
|
+
* @param session_options - session config
|
|
106
|
+
* @returns signed cookie value with long-past expiry
|
|
107
|
+
*/
|
|
108
|
+
export const create_expired_test_cookie = async (keyring, session_options) => {
|
|
109
|
+
// now_seconds=1 puts the expiry at 1 + max_age seconds past epoch — still in 1970
|
|
110
|
+
return create_session_cookie_value(keyring, 'expired_test_token', session_options, 1);
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Assert that a 429 response includes a valid `Retry-After` header
|
|
114
|
+
* matching the JSON body's `retry_after` field.
|
|
115
|
+
*
|
|
116
|
+
* @param response - the 429 response
|
|
117
|
+
* @param body - parsed JSON body with `retry_after` field
|
|
118
|
+
*/
|
|
119
|
+
/**
|
|
120
|
+
* Known safe fields that may appear in any error response.
|
|
121
|
+
*
|
|
122
|
+
* Error schemas use `z.looseObject` so extra context fields are allowed in production,
|
|
123
|
+
* but test responses should not contain fields that leak internal details (stack traces,
|
|
124
|
+
* SQL, file paths). This set lists the fields that are safe to appear.
|
|
125
|
+
*/
|
|
126
|
+
const KNOWN_SAFE_ERROR_FIELDS = new Set([
|
|
127
|
+
'error',
|
|
128
|
+
'issues',
|
|
129
|
+
'required_role',
|
|
130
|
+
'retry_after',
|
|
131
|
+
'credential_type',
|
|
132
|
+
'has_references',
|
|
133
|
+
'ok',
|
|
134
|
+
]);
|
|
135
|
+
/** Fields in error responses that indicate information leakage. */
|
|
136
|
+
const LEAKY_FIELD_PATTERNS = [
|
|
137
|
+
'stack',
|
|
138
|
+
'trace',
|
|
139
|
+
'sql',
|
|
140
|
+
'query',
|
|
141
|
+
'internal',
|
|
142
|
+
'password',
|
|
143
|
+
'hash',
|
|
144
|
+
'secret',
|
|
145
|
+
'token',
|
|
146
|
+
];
|
|
147
|
+
/**
|
|
148
|
+
* Assert that an error response body contains no unexpected fields.
|
|
149
|
+
*
|
|
150
|
+
* Error schemas use `z.looseObject` (intentional — multiple producers), but
|
|
151
|
+
* test responses should be checked for fields that could leak information.
|
|
152
|
+
* Flags any field not in the known-safe set.
|
|
153
|
+
*
|
|
154
|
+
* @param body - parsed error response JSON
|
|
155
|
+
* @param context - description for error messages (e.g., `'POST /api/login 401'`)
|
|
156
|
+
* @returns array of unexpected field names (empty = clean)
|
|
157
|
+
*/
|
|
158
|
+
export const check_error_response_fields = (body) => {
|
|
159
|
+
const unexpected = [];
|
|
160
|
+
for (const key of Object.keys(body)) {
|
|
161
|
+
if (!KNOWN_SAFE_ERROR_FIELDS.has(key)) {
|
|
162
|
+
unexpected.push(key);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return unexpected;
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* Assert that an error response contains no leaky field values.
|
|
169
|
+
*
|
|
170
|
+
* Checks both field names and string values for patterns indicating
|
|
171
|
+
* stack traces, SQL, or internal paths.
|
|
172
|
+
*
|
|
173
|
+
* @param body - parsed error response JSON
|
|
174
|
+
* @param context - description for error messages
|
|
175
|
+
*/
|
|
176
|
+
export const assert_no_error_info_leakage = (body, context) => {
|
|
177
|
+
const body_str = JSON.stringify(body);
|
|
178
|
+
for (const pattern of LEAKY_FIELD_PATTERNS) {
|
|
179
|
+
// check field names (not values — 'error' legitimately contains error codes)
|
|
180
|
+
for (const key of Object.keys(body)) {
|
|
181
|
+
assert.ok(!key.toLowerCase().includes(pattern), `${context}: error response field '${key}' matches leaky pattern '${pattern}'`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// check for stack traces and file paths in values
|
|
185
|
+
assert.ok(!body_str.includes('node_modules'), `${context}: error response contains node_modules path`);
|
|
186
|
+
assert.ok(!body_str.includes('at '), `${context}: error response contains stack trace`);
|
|
187
|
+
assert.ok(!/\.ts:\d+/.test(body_str), `${context}: error response contains .ts file reference`);
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* Assert that a 429 response includes a valid `Retry-After` header
|
|
191
|
+
* matching the JSON body's `retry_after` field.
|
|
192
|
+
*
|
|
193
|
+
* @param response - the 429 response
|
|
194
|
+
* @param body - parsed JSON body with `retry_after` field
|
|
195
|
+
*/
|
|
196
|
+
export const assert_rate_limit_retry_after_header = (response, body) => {
|
|
197
|
+
const header = response.headers.get('Retry-After');
|
|
198
|
+
assert.ok(header, 'Missing Retry-After header on 429 response');
|
|
199
|
+
const header_value = Number(header);
|
|
200
|
+
assert.ok(!Number.isNaN(header_value), `Retry-After header is not a number: ${header}`);
|
|
201
|
+
assert.strictEqual(header_value, Math.ceil(body.retry_after), `Retry-After header (${header_value}) should equal ceil(retry_after) (${Math.ceil(body.retry_after)})`);
|
|
202
|
+
};
|
|
203
|
+
// --- Data exposure helpers ---
|
|
204
|
+
/** Field names that must never appear in any HTTP response body. */
|
|
205
|
+
export const SENSITIVE_FIELD_BLOCKLIST = ['password_hash', 'token_hash'];
|
|
206
|
+
/** Field names that must not appear in non-admin HTTP response bodies. */
|
|
207
|
+
export const ADMIN_ONLY_FIELD_BLOCKLIST = ['updated_by', 'created_by'];
|
|
208
|
+
/**
|
|
209
|
+
* Recursively collect all key names from a parsed JSON value.
|
|
210
|
+
*
|
|
211
|
+
* Walks objects and arrays to find every property name at any nesting depth.
|
|
212
|
+
*
|
|
213
|
+
* @param value - parsed JSON value
|
|
214
|
+
* @returns set of all key names found
|
|
215
|
+
*/
|
|
216
|
+
export const collect_json_keys_recursive = (value) => {
|
|
217
|
+
const keys = new Set();
|
|
218
|
+
const walk = (v) => {
|
|
219
|
+
if (v === null || v === undefined || typeof v !== 'object')
|
|
220
|
+
return;
|
|
221
|
+
if (Array.isArray(v)) {
|
|
222
|
+
for (const item of v)
|
|
223
|
+
walk(item);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
for (const [key, val] of Object.entries(v)) {
|
|
227
|
+
keys.add(key);
|
|
228
|
+
walk(val);
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
walk(value);
|
|
232
|
+
return keys;
|
|
233
|
+
};
|
|
234
|
+
/**
|
|
235
|
+
* Assert that a parsed JSON body contains no fields from the given blocklist.
|
|
236
|
+
*
|
|
237
|
+
* @param body - parsed response JSON
|
|
238
|
+
* @param blocklist - field names to check for
|
|
239
|
+
* @param context - description for error messages
|
|
240
|
+
*/
|
|
241
|
+
export const assert_no_sensitive_fields_in_json = (body, blocklist, context) => {
|
|
242
|
+
const keys = collect_json_keys_recursive(body);
|
|
243
|
+
for (const field of blocklist) {
|
|
244
|
+
assert.ok(!keys.has(field), `${context}: response contains blocklisted field '${field}'`);
|
|
245
|
+
}
|
|
246
|
+
};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import './assert_dev_env.js';
|
|
2
|
+
/**
|
|
3
|
+
* Table-driven middleware test helpers.
|
|
4
|
+
*
|
|
5
|
+
* Provides mock builders for bearer auth middleware dependencies,
|
|
6
|
+
* a generic test runner that iterates case tables, and a reusable
|
|
7
|
+
* middleware stack factory for integration testing.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import { vi } from 'vitest';
|
|
12
|
+
import { Hono } from 'hono';
|
|
13
|
+
import type { z } from 'zod';
|
|
14
|
+
import type { RateLimiter } from '../rate_limiter.js';
|
|
15
|
+
import { type RequestContext } from '../auth/request_context.js';
|
|
16
|
+
/** Mock configuration for bearer auth middleware test setup. */
|
|
17
|
+
export interface BearerAuthTestOptions {
|
|
18
|
+
/** Test description. */
|
|
19
|
+
name: string;
|
|
20
|
+
/** Request headers. */
|
|
21
|
+
headers?: Record<string, string>;
|
|
22
|
+
/** Pre-set request context (simulates session already resolved). */
|
|
23
|
+
pre_context?: RequestContext;
|
|
24
|
+
/** What `query_validate_api_token()` returns. */
|
|
25
|
+
mock_validate_result?: unknown;
|
|
26
|
+
/** What `query_account_by_id()` returns. */
|
|
27
|
+
mock_find_by_id_result?: unknown;
|
|
28
|
+
/** What `query_actor_by_account()` returns. */
|
|
29
|
+
mock_find_by_account_result?: unknown;
|
|
30
|
+
/** What `query_permit_find_active_for_actor()` returns. */
|
|
31
|
+
mock_permits_result?: unknown;
|
|
32
|
+
/** Expected HTTP status, or `'next'` if the middleware should call `next()`. */
|
|
33
|
+
expected_status: number | 'next';
|
|
34
|
+
/** Expected `error` field in JSON response body. */
|
|
35
|
+
expected_error?: string;
|
|
36
|
+
/** Zod schema to validate error response body against. Defaults to `ApiError` when `expected_error` is set. */
|
|
37
|
+
expected_error_schema?: z.ZodType;
|
|
38
|
+
}
|
|
39
|
+
/** A full test case for the table-driven bearer auth runner. */
|
|
40
|
+
export interface BearerAuthTestCase extends BearerAuthTestOptions {
|
|
41
|
+
/** Whether the request should reach token validation or be short-circuited. */
|
|
42
|
+
validate_expectation: 'called' | 'not_called';
|
|
43
|
+
/** If true, assert `REQUEST_CONTEXT_KEY` and `CREDENTIAL_TYPE_KEY` were set to api_token values. */
|
|
44
|
+
assert_context_set?: boolean;
|
|
45
|
+
/** If true, assert the pre-existing session context and credential type are preserved. */
|
|
46
|
+
assert_context_preserved?: boolean;
|
|
47
|
+
/** Optional callback for custom spy assertions on the mocks bundle. */
|
|
48
|
+
assert_mocks?: (mocks: BearerAuthMocks) => void;
|
|
49
|
+
}
|
|
50
|
+
/** Mocks bundle returned by `create_bearer_auth_mocks`. */
|
|
51
|
+
export interface BearerAuthMocks {
|
|
52
|
+
mock_validate: ReturnType<typeof vi.fn>;
|
|
53
|
+
mock_find_by_id: ReturnType<typeof vi.fn>;
|
|
54
|
+
mock_find_by_account: ReturnType<typeof vi.fn>;
|
|
55
|
+
mock_find_active_for_actor: ReturnType<typeof vi.fn>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Create mock dependencies for `create_bearer_auth_middleware`, configured per test case.
|
|
59
|
+
*
|
|
60
|
+
* Configures the module-level mocks for `query_validate_api_token`,
|
|
61
|
+
* `query_account_by_id`, `query_actor_by_account`, and `query_permit_find_active_for_actor`
|
|
62
|
+
* so each test case controls return values independently.
|
|
63
|
+
*
|
|
64
|
+
* @param tc - the test config providing mock return values
|
|
65
|
+
* @returns mocks bundle with spy references
|
|
66
|
+
*/
|
|
67
|
+
export declare const create_bearer_auth_mocks: (tc: BearerAuthTestOptions) => BearerAuthMocks;
|
|
68
|
+
/** Default client IP set by the proxy stub in test apps. */
|
|
69
|
+
export declare const TEST_CLIENT_IP = "127.0.0.1";
|
|
70
|
+
/**
|
|
71
|
+
* Create a Hono app wired with `create_bearer_auth_middleware` using mocked deps.
|
|
72
|
+
*
|
|
73
|
+
* The route handler at `/api/test` returns the resolved context in the response body,
|
|
74
|
+
* enabling assertions on `REQUEST_CONTEXT_KEY` and `CREDENTIAL_TYPE_KEY`.
|
|
75
|
+
*
|
|
76
|
+
* @param tc - the test config providing mock behavior
|
|
77
|
+
* @param ip_rate_limiter - optional rate limiter (null to disable)
|
|
78
|
+
* @returns the app and mocks bundle
|
|
79
|
+
*/
|
|
80
|
+
export declare const create_bearer_auth_test_app: (tc: BearerAuthTestOptions, ip_rate_limiter?: RateLimiter | null) => {
|
|
81
|
+
app: Hono;
|
|
82
|
+
mocks: BearerAuthMocks;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Run a table of bearer auth middleware test cases.
|
|
86
|
+
*
|
|
87
|
+
* Generates one `test()` per case inside a `describe()` block.
|
|
88
|
+
*
|
|
89
|
+
* @param suite_name - the describe block name
|
|
90
|
+
* @param cases - the test case table
|
|
91
|
+
* @param ip_rate_limiter - optional rate limiter shared across cases
|
|
92
|
+
*/
|
|
93
|
+
export declare const describe_bearer_auth_cases: (suite_name: string, cases: Array<BearerAuthTestCase>, ip_rate_limiter?: RateLimiter | null) => void;
|
|
94
|
+
/** Path used by the echo route in `create_test_middleware_stack_app`. */
|
|
95
|
+
export declare const TEST_MIDDLEWARE_PATH = "/api/test";
|
|
96
|
+
/** Options for `create_test_middleware_stack_app`. */
|
|
97
|
+
export interface TestMiddlewareStackOptions {
|
|
98
|
+
/** Trusted proxy IPs. @default `['10.0.0.1']` */
|
|
99
|
+
trusted_proxies?: Array<string>;
|
|
100
|
+
/** Comma-separated allowed origin patterns. @default `'https://app.example.com'` */
|
|
101
|
+
allowed_origins?: string;
|
|
102
|
+
/** Connection IP or factory. @default first trusted proxy */
|
|
103
|
+
connection_ip?: string | (() => string | undefined);
|
|
104
|
+
/** Rate limiter for bearer auth. @default `null` */
|
|
105
|
+
ip_rate_limiter?: RateLimiter | null;
|
|
106
|
+
}
|
|
107
|
+
/** Return type of `create_test_middleware_stack_app`. */
|
|
108
|
+
export interface TestMiddlewareStackApp {
|
|
109
|
+
app: Hono;
|
|
110
|
+
mock_validate: ReturnType<typeof vi.fn>;
|
|
111
|
+
mock_find_by_id: ReturnType<typeof vi.fn>;
|
|
112
|
+
mock_find_by_account: ReturnType<typeof vi.fn>;
|
|
113
|
+
mock_find_active_for_actor: ReturnType<typeof vi.fn>;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Create a Hono app with real proxy + origin + bearer middleware for integration testing.
|
|
117
|
+
*
|
|
118
|
+
* All DB queries return undefined (no real database needed).
|
|
119
|
+
* The echo route at `TEST_MIDDLEWARE_PATH` returns `{ok, client_ip, has_context}`.
|
|
120
|
+
*
|
|
121
|
+
* @param options - middleware stack configuration
|
|
122
|
+
* @returns the app and mock spies (reconfigure via `mockImplementation` for valid-token paths)
|
|
123
|
+
*/
|
|
124
|
+
export declare const create_test_middleware_stack_app: (options?: TestMiddlewareStackOptions) => TestMiddlewareStackApp;
|
|
125
|
+
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/middleware.ts"],"names":[],"mappings":"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"}
|