@fuzdev/fuz_app 0.55.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 +211 -155
- 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 +19 -0
- package/dist/actions/action_codegen.d.ts.map +1 -1
- package/dist/actions/action_codegen.js +20 -14
- 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 +110 -44
- package/dist/actions/action_rpc.d.ts.map +1 -1
- package/dist/actions/action_rpc.js +92 -287
- 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 +44 -38
- 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 +2 -10
- package/dist/actions/register_ws_endpoint.d.ts.map +1 -1
- package/dist/actions/register_ws_endpoint.js +32 -10
- 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 +673 -442
- 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 +8 -14
- package/dist/auth/account_actions.d.ts.map +1 -1
- package/dist/auth/account_actions.js +26 -32
- package/dist/auth/account_queries.d.ts +46 -13
- package/dist/auth/account_queries.d.ts.map +1 -1
- package/dist/auth/account_queries.js +73 -33
- package/dist/auth/account_routes.d.ts +4 -3
- package/dist/auth/account_routes.d.ts.map +1 -1
- package/dist/auth/account_routes.js +58 -33
- package/dist/auth/account_schema.d.ts +46 -54
- package/dist/auth/account_schema.d.ts.map +1 -1
- package/dist/auth/account_schema.js +21 -48
- package/dist/auth/admin_action_specs.d.ts +55 -21
- package/dist/auth/admin_action_specs.d.ts.map +1 -1
- package/dist/auth/admin_action_specs.js +42 -26
- package/dist/auth/admin_actions.d.ts +14 -21
- package/dist/auth/admin_actions.d.ts.map +1 -1
- package/dist/auth/admin_actions.js +47 -44
- 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 -87
- package/dist/auth/audit_log_queries.d.ts.map +1 -1
- package/dist/auth/audit_log_queries.js +17 -96
- 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 +48 -42
- package/dist/auth/audit_log_schema.d.ts.map +1 -1
- package/dist/auth/audit_log_schema.js +56 -43
- 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/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 -47
- 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 +1 -1
- package/dist/auth/daemon_token_middleware.js +3 -3
- 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 -32
- 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 +5 -2
- package/dist/auth/migrations.d.ts +22 -7
- package/dist/auth/migrations.d.ts.map +1 -1
- package/dist/auth/migrations.js +64 -25
- package/dist/auth/request_context.d.ts +157 -170
- package/dist/auth/request_context.d.ts.map +1 -1
- package/dist/auth/request_context.js +224 -268
- package/dist/auth/{permit_offer_action_specs.d.ts → role_grant_offer_action_specs.d.ts} +130 -100
- 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/{permit_offer_actions.js → role_grant_offer_actions.js} +153 -140
- package/dist/auth/{permit_offer_notifications.d.ts → role_grant_offer_notifications.d.ts} +80 -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/{permit_offer_queries.d.ts → role_grant_offer_queries.d.ts} +64 -64
- package/dist/auth/role_grant_offer_queries.d.ts.map +1 -0
- package/dist/auth/{permit_offer_queries.js → role_grant_offer_queries.js} +136 -123
- 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} +55 -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 +4 -1
- package/dist/auth/self_service_role_action_specs.d.ts.map +1 -1
- package/dist/auth/self_service_role_action_specs.js +2 -2
- package/dist/auth/self_service_role_actions.d.ts +35 -29
- package/dist/auth/self_service_role_actions.d.ts.map +1 -1
- package/dist/auth/self_service_role_actions.js +58 -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 +1 -1
- package/dist/db/migrate.js +1 -1
- package/dist/dev/setup.d.ts +2 -2
- package/dist/dev/setup.d.ts.map +1 -1
- package/dist/dev/setup.js +4 -4
- package/dist/env/load.d.ts +1 -1
- package/dist/env/load.js +1 -1
- package/dist/hono_context.d.ts +27 -45
- package/dist/hono_context.d.ts.map +1 -1
- package/dist/hono_context.js +14 -28
- package/dist/http/CLAUDE.md +235 -121
- 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 +56 -34
- package/dist/http/error_schemas.d.ts.map +1 -1
- package/dist/http/error_schemas.js +63 -28
- 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 +89 -75
- package/dist/http/route_spec.d.ts.map +1 -1
- package/dist/http/route_spec.js +54 -72
- package/dist/http/schema_helpers.d.ts +3 -14
- package/dist/http/schema_helpers.d.ts.map +1 -1
- package/dist/http/schema_helpers.js +2 -14
- package/dist/http/surface.d.ts +2 -10
- package/dist/http/surface.d.ts.map +1 -1
- package/dist/http/surface.js +3 -4
- 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 +35 -40
- package/dist/server/validate_nginx.d.ts +1 -1
- package/dist/server/validate_nginx.js +1 -1
- package/dist/testing/CLAUDE.md +50 -38
- 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 +87 -85
- 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 +16 -15
- 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 +36 -36
- 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 +22 -19
- 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 +8 -7
- package/dist/testing/entities.d.ts.map +1 -1
- package/dist/testing/entities.js +21 -18
- package/dist/testing/integration.d.ts.map +1 -1
- package/dist/testing/integration.js +13 -14
- package/dist/testing/integration_helpers.d.ts +4 -4
- package/dist/testing/integration_helpers.d.ts.map +1 -1
- package/dist/testing/integration_helpers.js +20 -18
- package/dist/testing/middleware.d.ts +4 -4
- package/dist/testing/middleware.d.ts.map +1 -1
- package/dist/testing/middleware.js +12 -11
- package/dist/testing/rpc_attack_surface.d.ts.map +1 -1
- package/dist/testing/rpc_attack_surface.js +40 -24
- 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 +19 -11
- 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 +60 -60
- package/dist/ui/{PermitOfferForm.svelte → RoleGrantOfferForm.svelte} +27 -26
- package/dist/ui/{PermitOfferForm.svelte.d.ts → RoleGrantOfferForm.svelte.d.ts} +7 -7
- 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 +18 -18
- package/dist/ui/admin_accounts_state.svelte.d.ts.map +1 -1
- package/dist/ui/admin_accounts_state.svelte.js +16 -16
- 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} +30 -30
- 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} +18 -18
- 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 -258
- 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_notifications.d.ts.map +0 -1
- package/dist/auth/permit_offer_notifications.js +0 -182
- package/dist/auth/permit_offer_queries.d.ts.map +0 -1
- package/dist/auth/permit_offer_schema.d.ts +0 -125
- package/dist/auth/permit_offer_schema.d.ts.map +0 -1
- package/dist/auth/permit_queries.d.ts +0 -222
- package/dist/auth/permit_queries.d.ts.map +0 -1
- package/dist/auth/permit_queries.js +0 -305
- 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 -27
- package/dist/auth/route_guards.d.ts.map +0 -1
- package/dist/auth/route_guards.js +0 -38
- 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.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
|
@@ -23,7 +23,7 @@ import { assert_surface_matches_snapshot, assert_surface_deterministic, assert_o
|
|
|
23
23
|
import { merge_error_schemas } from '../http/schema_helpers.js';
|
|
24
24
|
import { collect_middleware_errors } from '../http/surface.js';
|
|
25
25
|
import { filter_protected_routes, filter_role_routes, filter_keeper_routes, } from '../http/surface_query.js';
|
|
26
|
-
import { ERROR_AUTHENTICATION_REQUIRED, ERROR_INSUFFICIENT_PERMISSIONS,
|
|
26
|
+
import { ERROR_AUTHENTICATION_REQUIRED, ERROR_INSUFFICIENT_PERMISSIONS, ERROR_CREDENTIAL_TYPE_REQUIRED, } from '../http/error_schemas.js';
|
|
27
27
|
// --- Adversarial test runner ---
|
|
28
28
|
/**
|
|
29
29
|
* Build a lookup from `"METHOD /path"` to merged error schemas (auto-derived + middleware + explicit).
|
|
@@ -79,12 +79,17 @@ export const describe_adversarial_auth = (options) => {
|
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
81
|
});
|
|
82
|
-
|
|
82
|
+
// Role-only routes (no credential gate). Keeper routes have a credential
|
|
83
|
+
// gate that fires before the role gate, so they get tested separately
|
|
84
|
+
// in the keeper block below.
|
|
85
|
+
const role_only_routes = role_routes.filter((r) => !(r.auth.credential_types?.length ?? 0));
|
|
86
|
+
if (role_only_routes.length > 0) {
|
|
83
87
|
describe('wrong role → 403', () => {
|
|
84
|
-
for (const route of
|
|
85
|
-
const
|
|
88
|
+
for (const route of role_only_routes) {
|
|
89
|
+
const required_roles = route.auth.roles ?? [];
|
|
90
|
+
const wrong_roles = roles.filter((r) => !required_roles.includes(r));
|
|
86
91
|
for (const wrong_role of wrong_roles) {
|
|
87
|
-
test(`${route.method} ${route.path} (${wrong_role} instead of ${
|
|
92
|
+
test(`${route.method} ${route.path} (${wrong_role} instead of ${required_roles.join('|')})`, async () => {
|
|
88
93
|
const app = apps.by_role.get(wrong_role);
|
|
89
94
|
if (!app)
|
|
90
95
|
throw new Error(`No test app for role '${wrong_role}'`);
|
|
@@ -94,14 +99,14 @@ export const describe_adversarial_auth = (options) => {
|
|
|
94
99
|
assert.strictEqual(res.status, 403, `${route.method} ${route.path}`);
|
|
95
100
|
const body = await res.json();
|
|
96
101
|
assert.strictEqual(body.error, ERROR_INSUFFICIENT_PERMISSIONS);
|
|
97
|
-
assert.
|
|
102
|
+
assert.deepStrictEqual(body.required_roles, required_roles);
|
|
98
103
|
assert_error_schema_valid(error_schema_lookup, route, 403, body);
|
|
99
104
|
});
|
|
100
105
|
}
|
|
101
106
|
}
|
|
102
107
|
});
|
|
103
108
|
describe('authenticated without role → 403', () => {
|
|
104
|
-
for (const route of
|
|
109
|
+
for (const route of role_only_routes) {
|
|
105
110
|
test(`${route.method} ${route.path}`, async () => {
|
|
106
111
|
const res = await apps.authed.request(resolve_test_path(route.path), {
|
|
107
112
|
method: route.method,
|
|
@@ -109,7 +114,7 @@ export const describe_adversarial_auth = (options) => {
|
|
|
109
114
|
assert.strictEqual(res.status, 403, `${route.method} ${route.path}`);
|
|
110
115
|
const body = await res.json();
|
|
111
116
|
assert.strictEqual(body.error, ERROR_INSUFFICIENT_PERMISSIONS);
|
|
112
|
-
assert.
|
|
117
|
+
assert.deepStrictEqual(body.required_roles, route.auth.roles ?? []);
|
|
113
118
|
assert_error_schema_valid(error_schema_lookup, route, 403, body);
|
|
114
119
|
});
|
|
115
120
|
}
|
|
@@ -126,7 +131,8 @@ export const describe_adversarial_auth = (options) => {
|
|
|
126
131
|
});
|
|
127
132
|
assert.strictEqual(res.status, 403, `${route.method} ${route.path}`);
|
|
128
133
|
const body = await res.json();
|
|
129
|
-
assert.strictEqual(body.error,
|
|
134
|
+
assert.strictEqual(body.error, ERROR_CREDENTIAL_TYPE_REQUIRED);
|
|
135
|
+
assert.deepStrictEqual(body.required_credential_types, route.auth.credential_types ?? []);
|
|
130
136
|
assert_error_schema_valid(error_schema_lookup, route, 403, body);
|
|
131
137
|
});
|
|
132
138
|
}
|
|
@@ -15,7 +15,7 @@ export interface AuditCompletenessTestOptions {
|
|
|
15
15
|
create_route_specs: (ctx: AppServerContext) => Array<RouteSpec>;
|
|
16
16
|
/**
|
|
17
17
|
* RPC endpoint specs — the source `RpcAction` arrays. Required; the
|
|
18
|
-
* admin
|
|
18
|
+
* admin role_grant flow is RPC-only and the suite hard-fails without it.
|
|
19
19
|
*
|
|
20
20
|
* Accepts either an array (eager) or a factory
|
|
21
21
|
* `(ctx: AppServerContext) => Array<RpcEndpointSpec>` — the factory form
|
|
@@ -39,7 +39,7 @@ export interface AuditCompletenessTestOptions {
|
|
|
39
39
|
* database, then queries the `audit_log` table to verify events.
|
|
40
40
|
*
|
|
41
41
|
* @throws Error at setup time when `options.rpc_endpoints` is empty — the
|
|
42
|
-
* mutation-audit tests drive
|
|
42
|
+
* mutation-audit tests drive role_grant flow, session/token revoke-all, and
|
|
43
43
|
* invite create/delete through their RPC action specs. Hard-fails via
|
|
44
44
|
* `require_rpc_endpoint_path`.
|
|
45
45
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit_completeness.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/audit_completeness.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAkB7B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAIrD,OAAO,EAGN,KAAK,eAAe,EAEpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,SAAS,CAAC;AAKjB,OAAO,EAIN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAqB1B;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC5C,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;;;;;;;;;;;OAWG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC,iDAAiD;IACjD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,qEAAqE;IACrE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;CAChC;AAoDD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,iCAAiC,GAAI,SAAS,4BAA4B,KAAG,
|
|
1
|
+
{"version":3,"file":"audit_completeness.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/audit_completeness.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAkB7B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAIrD,OAAO,EAGN,KAAK,eAAe,EAEpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,SAAS,CAAC;AAKjB,OAAO,EAIN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAqB1B;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC5C,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;;;;;;;;;;;OAWG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC,iDAAiD;IACjD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,qEAAqE;IACrE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;CAChC;AAoDD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,iCAAiC,GAAI,SAAS,4BAA4B,KAAG,IAkgBzF,CAAC"}
|
|
@@ -20,9 +20,9 @@ import { create_test_app, } from './app_server.js';
|
|
|
20
20
|
import { create_pglite_factory, create_describe_db, AUTH_INTEGRATION_TRUNCATE_TABLES, } from './db.js';
|
|
21
21
|
import { find_auth_route } from './integration_helpers.js';
|
|
22
22
|
import { run_migrations } from '../db/migrate.js';
|
|
23
|
-
import { query_accept_offer } from '../auth/
|
|
23
|
+
import { query_accept_offer } from '../auth/role_grant_offer_queries.js';
|
|
24
24
|
import { rpc_call_for_spec, require_rpc_endpoint_path, resolve_rpc_endpoints_for_setup, } from './rpc_helpers.js';
|
|
25
|
-
import {
|
|
25
|
+
import { role_grant_offer_create_action_spec, role_grant_revoke_action_spec, } from '../auth/role_grant_offer_action_specs.js';
|
|
26
26
|
import { admin_session_revoke_all_action_spec, admin_token_revoke_all_action_spec, app_settings_update_action_spec, invite_create_action_spec, invite_delete_action_spec, } from '../auth/admin_action_specs.js';
|
|
27
27
|
import { account_session_list_action_spec, account_session_revoke_action_spec, account_session_revoke_all_action_spec, account_token_create_action_spec, account_token_list_action_spec, account_token_revoke_action_spec, } from '../auth/account_action_specs.js';
|
|
28
28
|
/** Query audit log events from the database. */
|
|
@@ -63,7 +63,7 @@ const json_session_headers = (test_app, extra) => test_app.create_session_header
|
|
|
63
63
|
* database, then queries the `audit_log` table to verify events.
|
|
64
64
|
*
|
|
65
65
|
* @throws Error at setup time when `options.rpc_endpoints` is empty — the
|
|
66
|
-
* mutation-audit tests drive
|
|
66
|
+
* mutation-audit tests drive role_grant flow, session/token revoke-all, and
|
|
67
67
|
* invite create/delete through their RPC action specs. Hard-fails via
|
|
68
68
|
* `require_rpc_endpoint_path`.
|
|
69
69
|
*/
|
|
@@ -231,23 +231,23 @@ export const describe_audit_completeness_tests = (options) => {
|
|
|
231
231
|
});
|
|
232
232
|
// --- Admin routes ---
|
|
233
233
|
describe('admin mutation audit events', () => {
|
|
234
|
-
test('admin offer (RPC) + accept produces
|
|
234
|
+
test('admin offer (RPC) + accept produces role_grant_offer_create and role_grant_create events', async () => {
|
|
235
235
|
const test_app = await create_test_app(build_options(options, get_db()));
|
|
236
236
|
const target = await test_app.create_account({ username: 'audit_target' });
|
|
237
237
|
const offer_res = await rpc_call_for_spec({
|
|
238
238
|
app: test_app.app,
|
|
239
239
|
path: rpc_path,
|
|
240
|
-
spec:
|
|
240
|
+
spec: role_grant_offer_create_action_spec,
|
|
241
241
|
params: { to_account_id: target.account.id, role: ROLE_ADMIN },
|
|
242
242
|
headers: test_app.create_session_headers(),
|
|
243
243
|
});
|
|
244
|
-
assert.ok(offer_res.ok, `
|
|
244
|
+
assert.ok(offer_res.ok, `role_grant_offer_create failed: ${offer_res.ok ? '' : JSON.stringify(offer_res.error)}`);
|
|
245
245
|
const { offer } = offer_res.result;
|
|
246
|
-
// Admin offer emits `
|
|
247
|
-
// exist yet. Drive the accept to confirm `
|
|
246
|
+
// Admin offer emits `role_grant_offer_create` only — the role_grant doesn't
|
|
247
|
+
// exist yet. Drive the accept to confirm `role_grant_create` fires on the
|
|
248
248
|
// downstream consent transition.
|
|
249
249
|
const events_after_offer = await query_audit_events(test_app.backend.deps.db);
|
|
250
|
-
assert_has_event(events_after_offer, '
|
|
250
|
+
assert_has_event(events_after_offer, 'role_grant_offer_create', 'role_grant_offer_create RPC');
|
|
251
251
|
await get_db().transaction(async (tx) => {
|
|
252
252
|
await query_accept_offer({ db: tx }, {
|
|
253
253
|
offer_id: offer.id,
|
|
@@ -257,20 +257,20 @@ export const describe_audit_completeness_tests = (options) => {
|
|
|
257
257
|
});
|
|
258
258
|
});
|
|
259
259
|
const events_after_accept = await query_audit_events(test_app.backend.deps.db);
|
|
260
|
-
assert_has_event(events_after_accept, '
|
|
260
|
+
assert_has_event(events_after_accept, 'role_grant_create', 'offer accept');
|
|
261
261
|
});
|
|
262
|
-
test('
|
|
262
|
+
test('role_grant revoke (RPC) produces role_grant_revoke event with both target columns', async () => {
|
|
263
263
|
const test_app = await create_test_app(build_options(options, get_db()));
|
|
264
264
|
const target = await test_app.create_account({ username: 'audit_revoke_target' });
|
|
265
|
-
// Offer + accept to materialize a
|
|
265
|
+
// Offer + accept to materialize a role_grant we can revoke.
|
|
266
266
|
const offer_res = await rpc_call_for_spec({
|
|
267
267
|
app: test_app.app,
|
|
268
268
|
path: rpc_path,
|
|
269
|
-
spec:
|
|
269
|
+
spec: role_grant_offer_create_action_spec,
|
|
270
270
|
params: { to_account_id: target.account.id, role: ROLE_ADMIN },
|
|
271
271
|
headers: test_app.create_session_headers(),
|
|
272
272
|
});
|
|
273
|
-
assert.ok(offer_res.ok, `
|
|
273
|
+
assert.ok(offer_res.ok, `role_grant_offer_create failed: ${offer_res.ok ? '' : JSON.stringify(offer_res.error)}`);
|
|
274
274
|
const { offer } = offer_res.result;
|
|
275
275
|
const accept_result = await get_db().transaction(async (tx) => {
|
|
276
276
|
return query_accept_offer({ db: tx }, {
|
|
@@ -284,17 +284,17 @@ export const describe_audit_completeness_tests = (options) => {
|
|
|
284
284
|
const revoke_res = await rpc_call_for_spec({
|
|
285
285
|
app: test_app.app,
|
|
286
286
|
path: rpc_path,
|
|
287
|
-
spec:
|
|
288
|
-
params: { actor_id: target.actor.id,
|
|
287
|
+
spec: role_grant_revoke_action_spec,
|
|
288
|
+
params: { actor_id: target.actor.id, role_grant_id: accept_result.role_grant.id },
|
|
289
289
|
headers: test_app.create_session_headers(),
|
|
290
290
|
});
|
|
291
|
-
assert.ok(revoke_res.ok, `
|
|
291
|
+
assert.ok(revoke_res.ok, `role_grant_revoke failed: ${revoke_res.ok ? '' : JSON.stringify(revoke_res.error)}`);
|
|
292
292
|
const events = await query_audit_events(test_app.backend.deps.db);
|
|
293
|
-
assert_has_event(events, '
|
|
293
|
+
assert_has_event(events, 'role_grant_revoke', 'role_grant_revoke RPC');
|
|
294
294
|
// Audit envelope must populate both target columns —
|
|
295
|
-
// `
|
|
295
|
+
// `role_grant_revoke` is the canonical actor-bound-subject event.
|
|
296
296
|
const revoke_rows = await test_app.backend.deps.db.query(`SELECT target_account_id, target_actor_id FROM audit_log
|
|
297
|
-
WHERE event_type = '
|
|
297
|
+
WHERE event_type = 'role_grant_revoke' ORDER BY seq DESC LIMIT 1`);
|
|
298
298
|
const row = revoke_rows[0];
|
|
299
299
|
assert.strictEqual(row.target_account_id, target.account.id);
|
|
300
300
|
assert.strictEqual(row.target_actor_id, target.actor.id);
|
|
@@ -416,9 +416,9 @@ export const describe_audit_completeness_tests = (options) => {
|
|
|
416
416
|
'token_create',
|
|
417
417
|
'token_revoke',
|
|
418
418
|
'token_revoke_all',
|
|
419
|
-
'
|
|
420
|
-
'
|
|
421
|
-
'
|
|
419
|
+
'role_grant_offer_create',
|
|
420
|
+
'role_grant_create',
|
|
421
|
+
'role_grant_revoke',
|
|
422
422
|
'invite_create',
|
|
423
423
|
'invite_delete',
|
|
424
424
|
'app_settings_update',
|
|
@@ -426,20 +426,20 @@ export const describe_audit_completeness_tests = (options) => {
|
|
|
426
426
|
/** Event types excluded with justification. */
|
|
427
427
|
const EXCLUDED_EVENT_TYPES = new Set([
|
|
428
428
|
'bootstrap', // requires filesystem token — tested in bootstrap_account.db.test.ts
|
|
429
|
-
// The remaining `
|
|
430
|
-
// endpoint or via downstream effects of `
|
|
431
|
-
// coverage lives in `
|
|
432
|
-
// `
|
|
433
|
-
// `
|
|
434
|
-
// `
|
|
435
|
-
// `
|
|
436
|
-
// (`
|
|
429
|
+
// The remaining `role_grant_offer_*` events fire only via the RPC
|
|
430
|
+
// endpoint or via downstream effects of `role_grant_revoke`. Direct
|
|
431
|
+
// coverage lives in `role_grant_offer_queries.db.test.ts`,
|
|
432
|
+
// `role_grant_offer_actions.db.test.ts`,
|
|
433
|
+
// `role_grant_offer_actions.notifications.db.test.ts`, and
|
|
434
|
+
// `role_grant_offer_actions.notifications.revoke.db.test.ts`.
|
|
435
|
+
// `role_grant_offer_expire` fires from the cleanup sweep
|
|
436
|
+
// (`cleanup_expired_role_grant_offers` in `auth/cleanup.ts`) —
|
|
437
437
|
// covered in `cleanup.db.test.ts`.
|
|
438
|
-
'
|
|
439
|
-
'
|
|
440
|
-
'
|
|
441
|
-
'
|
|
442
|
-
'
|
|
438
|
+
'role_grant_offer_accept',
|
|
439
|
+
'role_grant_offer_decline',
|
|
440
|
+
'role_grant_offer_retract',
|
|
441
|
+
'role_grant_offer_expire',
|
|
442
|
+
'role_grant_offer_supersede',
|
|
443
443
|
]);
|
|
444
444
|
test('all audit event types are covered or explicitly excluded', () => {
|
|
445
445
|
const all_covered = new Set([...COVERED_EVENT_TYPES, ...EXCLUDED_EVENT_TYPES]);
|
|
@@ -8,11 +8,12 @@ import './assert_dev_env.js';
|
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
10
10
|
import { Hono } from 'hono';
|
|
11
|
-
import { type RouteSpec
|
|
11
|
+
import { type RouteSpec } from '../http/route_spec.js';
|
|
12
|
+
import { type RouteAuth } from '../http/auth_shape.js';
|
|
12
13
|
import { type RequestContext } from '../auth/request_context.js';
|
|
13
14
|
import { type CredentialType } from '../hono_context.js';
|
|
14
15
|
/**
|
|
15
|
-
* Create a mock `RequestContext` with optional role
|
|
16
|
+
* Create a mock `RequestContext` with optional role role_grant.
|
|
16
17
|
*/
|
|
17
18
|
export declare const create_test_request_context: (role?: string) => RequestContext;
|
|
18
19
|
/**
|
|
@@ -40,8 +41,8 @@ export declare const create_auth_test_apps: (route_specs: Array<RouteSpec>, role
|
|
|
40
41
|
/**
|
|
41
42
|
* Select the Hono test app with correct auth for a route.
|
|
42
43
|
*
|
|
43
|
-
* @throws Error if `auth.
|
|
44
|
-
*
|
|
44
|
+
* @throws Error if `auth.roles` names a role not present in `apps.by_role` —
|
|
45
|
+
* surfaces a missing entry in the `roles` array passed to
|
|
45
46
|
* `create_auth_test_apps`.
|
|
46
47
|
*/
|
|
47
48
|
export declare const select_auth_app: (apps: AuthTestApps, auth: RouteAuth) => Hono;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth_apps.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/auth_apps.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAE7B;;;;;;;GAOG;AAEH,OAAO,EAAC,IAAI,EAAC,MAAM,MAAM,CAAC;AAG1B,OAAO,EAAoB,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"auth_apps.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/auth_apps.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAE7B;;;;;;;GAOG;AAEH,OAAO,EAAC,IAAI,EAAC,MAAM,MAAM,CAAC;AAG1B,OAAO,EAAoB,KAAK,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAiB,KAAK,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAErE,OAAO,EAGN,KAAK,cAAc,EACnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAIN,KAAK,cAAc,EACnB,MAAM,oBAAoB,CAAC;AAI5B;;GAEG;AACH,eAAO,MAAM,2BAA2B,GAAI,OAAO,MAAM,KAAG,cAI1D,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,GACtC,aAAa,KAAK,CAAC,SAAS,CAAC,EAC7B,WAAW,cAAc,EACzB,kBAAkB,cAAc,KAC9B,IAuBF,CAAC;AAEF,sFAAsF;AACtF,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,IAAI,CAAC;IACb,MAAM,EAAE,IAAI,CAAC;IACb,MAAM,EAAE,IAAI,CAAC;IACb,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;CAC3B;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GACjC,aAAa,KAAK,CAAC,SAAS,CAAC,EAC7B,OAAO,KAAK,CAAC,MAAM,CAAC,KAClB,YAeF,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAAI,MAAM,YAAY,EAAE,MAAM,SAAS,KAAG,IAarE,CAAC;AAEF,6EAA6E;AAC7E,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,KAAG,MAA4C,CAAC"}
|
|
@@ -10,18 +10,19 @@ import './assert_dev_env.js';
|
|
|
10
10
|
import { Hono } from 'hono';
|
|
11
11
|
import { Logger } from '@fuzdev/fuz_util/log.js';
|
|
12
12
|
import { apply_route_specs } from '../http/route_spec.js';
|
|
13
|
-
import {
|
|
13
|
+
import { is_public_auth } from '../http/auth_shape.js';
|
|
14
|
+
import { fuz_auth_guard_resolver } from '../auth/auth_guard_resolver.js';
|
|
14
15
|
import { REQUEST_CONTEXT_KEY, create_fuz_authorization_handler, } from '../auth/request_context.js';
|
|
15
16
|
import { ACCOUNT_ID_KEY, CREDENTIAL_TYPE_KEY, TEST_CONTEXT_PRESET_KEY, } from '../hono_context.js';
|
|
16
17
|
import { create_stub_db } from './stubs.js';
|
|
17
|
-
import { create_test_account, create_test_actor,
|
|
18
|
+
import { create_test_account, create_test_actor, create_test_role_grant } from './entities.js';
|
|
18
19
|
/**
|
|
19
|
-
* Create a mock `RequestContext` with optional role
|
|
20
|
+
* Create a mock `RequestContext` with optional role role_grant.
|
|
20
21
|
*/
|
|
21
22
|
export const create_test_request_context = (role) => ({
|
|
22
23
|
account: create_test_account({ id: 'acc_1', username: 'testuser' }),
|
|
23
24
|
actor: create_test_actor({ id: 'act_1', account_id: 'acc_1', name: 'testuser' }),
|
|
24
|
-
|
|
25
|
+
role_grants: role ? [create_test_role_grant({ id: 'perm_1', actor_id: 'act_1', role })] : [],
|
|
25
26
|
});
|
|
26
27
|
/**
|
|
27
28
|
* Create a Hono test app from route specs with optional auth context.
|
|
@@ -35,6 +36,7 @@ export const create_test_app_from_specs = (route_specs, auth_ctx, credential_typ
|
|
|
35
36
|
const db = create_stub_db();
|
|
36
37
|
app.use('/*', async (c, next) => {
|
|
37
38
|
c.set('pending_effects', []);
|
|
39
|
+
c.set('post_commit_effects', []);
|
|
38
40
|
if (auth_ctx) {
|
|
39
41
|
c.set(ACCOUNT_ID_KEY, auth_ctx.account.id);
|
|
40
42
|
c.set(REQUEST_CONTEXT_KEY, auth_ctx);
|
|
@@ -67,25 +69,26 @@ export const create_auth_test_apps = (route_specs, roles) => {
|
|
|
67
69
|
/**
|
|
68
70
|
* Select the Hono test app with correct auth for a route.
|
|
69
71
|
*
|
|
70
|
-
* @throws Error if `auth.
|
|
71
|
-
*
|
|
72
|
+
* @throws Error if `auth.roles` names a role not present in `apps.by_role` —
|
|
73
|
+
* surfaces a missing entry in the `roles` array passed to
|
|
72
74
|
* `create_auth_test_apps`.
|
|
73
75
|
*/
|
|
74
76
|
export const select_auth_app = (apps, auth) => {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
77
|
+
if (is_public_auth(auth))
|
|
78
|
+
return apps.public;
|
|
79
|
+
if (auth.credential_types?.includes('daemon_token'))
|
|
80
|
+
return apps.keeper;
|
|
81
|
+
if (auth.roles?.length) {
|
|
82
|
+
// Multi-role disjunction: any of the named roles admits the caller.
|
|
83
|
+
// Tests pick the first role's app; consumers wanting per-role coverage
|
|
84
|
+
// should hit each role's app explicitly.
|
|
85
|
+
const role = auth.roles[0];
|
|
86
|
+
const app = apps.by_role.get(role);
|
|
87
|
+
if (!app)
|
|
88
|
+
throw new Error(`No test app for role '${role}' — is it in the roles array?`);
|
|
89
|
+
return app;
|
|
88
90
|
}
|
|
91
|
+
return apps.authed;
|
|
89
92
|
};
|
|
90
93
|
/** Replace Hono route params (`:foo`) with dummy values for HTTP testing. */
|
|
91
94
|
export const resolve_test_path = (path) => path.replace(/:(\w+)/g, 'test_$1');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data_exposure.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/data_exposure.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAgB7B,OAAO,KAAK,EAAC,UAAU,EAAE,cAAc,EAAC,MAAM,oBAAoB,CAAC;AACnE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAC,gBAAgB,EAAE,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAChF,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAG9D,OAAO,EAAwB,KAAK,SAAS,EAAC,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"data_exposure.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/data_exposure.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAgB7B,OAAO,KAAK,EAAC,UAAU,EAAE,cAAc,EAAC,MAAM,oBAAoB,CAAC;AACnE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAC,gBAAgB,EAAE,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAChF,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAG9D,OAAO,EAAwB,KAAK,SAAS,EAAC,MAAM,SAAS,CAAC;AAgB9D;;;;;GAKG;AACH,eAAO,MAAM,kCAAkC,GAAI,QAAQ,OAAO,KAAG,GAAG,CAAC,MAAM,CAuB9E,CAAC;AAIF;;GAEG;AACH,eAAO,MAAM,yCAAyC,GACrD,SAAS,UAAU,EACnB,mBAAkB,aAAa,CAAC,MAAM,CAA6B,KACjE,IAWF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,wCAAwC,GACpD,SAAS,UAAU,EACnB,oBAAmB,aAAa,CAAC,MAAM,CAA8B,KACnE,IAcF,CAAC;AAIF,kDAAkD;AAClD,MAAM,WAAW,uBAAuB;IACvC,4DAA4D;IAC5D,KAAK,EAAE,MAAM,cAAc,CAAC;IAC5B,wCAAwC;IACxC,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,4CAA4C;IAC5C,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE,2FAA2F;IAC3F,gBAAgB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,iGAAiG;IACjG,iBAAiB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC1C,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CACpB,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,iBAAiB,GAAG,oBAAoB,CAAC,CAC5E,CAAC;IACF,qEAAqE;IACrE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC,kDAAkD;IAClD,WAAW,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CAC5B;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,4BAA4B,GAAI,SAAS,uBAAuB,KAAG,IAmC/E,CAAC"}
|
|
@@ -18,6 +18,7 @@ import { resolve_valid_path, generate_valid_body } from './schema_generators.js'
|
|
|
18
18
|
import { run_migrations } from '../db/migrate.js';
|
|
19
19
|
import { AUTH_MIGRATION_NS } from '../auth/migrations.js';
|
|
20
20
|
import { is_null_schema, is_strict_object_schema } from '../http/schema_helpers.js';
|
|
21
|
+
import { is_keeper_auth, is_public_auth } from '../http/auth_shape.js';
|
|
21
22
|
import { SENSITIVE_FIELD_BLOCKLIST, ADMIN_ONLY_FIELD_BLOCKLIST, assert_no_sensitive_fields_in_json, pick_auth_headers, } from './integration_helpers.js';
|
|
22
23
|
// --- Schema introspection ---
|
|
23
24
|
/**
|
|
@@ -71,7 +72,7 @@ export const assert_output_schemas_no_sensitive_fields = (surface, sensitive_fie
|
|
|
71
72
|
* Assert that non-admin route output schemas don't contain admin-only fields.
|
|
72
73
|
*/
|
|
73
74
|
export const assert_non_admin_schemas_no_admin_fields = (surface, admin_only_fields = ADMIN_ONLY_FIELD_BLOCKLIST) => {
|
|
74
|
-
const non_admin = surface.routes.filter((r) => r.auth
|
|
75
|
+
const non_admin = surface.routes.filter((r) => !is_keeper_auth(r.auth) && !(r.auth.roles?.includes('admin') ?? false));
|
|
75
76
|
for (const route of non_admin) {
|
|
76
77
|
if (route.output_schema === null)
|
|
77
78
|
continue;
|
|
@@ -154,7 +155,7 @@ const describe_data_exposure_runtime_tests = (options) => {
|
|
|
154
155
|
// Tests that don't fire authenticated requests run first — they don't
|
|
155
156
|
// invalidate sessions and are independent of test order.
|
|
156
157
|
test('unauthenticated error responses contain no sensitive fields', async () => {
|
|
157
|
-
const protected_specs = test_app.route_specs.filter((s) => s.auth
|
|
158
|
+
const protected_specs = test_app.route_specs.filter((s) => !is_public_auth(s.auth));
|
|
158
159
|
for (const spec of protected_specs) {
|
|
159
160
|
const route_key = `${spec.method} ${spec.path}`;
|
|
160
161
|
if (skip_set.has(route_key))
|
|
@@ -181,7 +182,7 @@ const describe_data_exposure_runtime_tests = (options) => {
|
|
|
181
182
|
// Cross-privilege test runs before 2xx tests — admin routes reject
|
|
182
183
|
// without calling handlers, so sessions stay intact.
|
|
183
184
|
test('admin routes return 403 for non-admin user', async () => {
|
|
184
|
-
const admin_specs = test_app.route_specs.filter((s) => s.auth.
|
|
185
|
+
const admin_specs = test_app.route_specs.filter((s) => s.auth.roles?.includes('admin') ?? false);
|
|
185
186
|
for (const spec of admin_specs) {
|
|
186
187
|
const route_key = `${spec.method} ${spec.path}`;
|
|
187
188
|
if (skip_set.has(route_key))
|
|
@@ -221,8 +222,7 @@ const describe_data_exposure_runtime_tests = (options) => {
|
|
|
221
222
|
if (skip_set.has(route_key))
|
|
222
223
|
continue;
|
|
223
224
|
// keeper auth (daemon token) is strictly more privileged than admin
|
|
224
|
-
const is_elevated = spec.auth
|
|
225
|
-
(spec.auth.type === 'role' && spec.auth.role === 'admin');
|
|
225
|
+
const is_elevated = is_keeper_auth(spec.auth) || (spec.auth.roles?.includes('admin') ?? false);
|
|
226
226
|
const url = resolve_valid_path(spec.path, spec.params);
|
|
227
227
|
const body = generate_valid_body(spec.input);
|
|
228
228
|
const headers = pick_auth_headers(spec, test_app, authed_account, admin_account);
|
package/dist/testing/db.d.ts
CHANGED
|
@@ -79,7 +79,7 @@ export declare const AUTH_INTEGRATION_TRUNCATE_TABLES: string[];
|
|
|
79
79
|
*
|
|
80
80
|
* When adding tables to `AUTH_MIGRATIONS`, add them here too.
|
|
81
81
|
*/
|
|
82
|
-
export declare const AUTH_DROP_TABLES: readonly ["app_settings", "invite", "audit_log", "api_token", "auth_session", "
|
|
82
|
+
export declare const AUTH_DROP_TABLES: readonly ["app_settings", "invite", "audit_log", "api_token", "auth_session", "role_grant", "role_grant_offer", "actor", "account", "bootstrap_lock"];
|
|
83
83
|
/**
|
|
84
84
|
* Drop all auth tables and schema version tracking for a clean slate.
|
|
85
85
|
*
|
package/dist/testing/db.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/db.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AA6B7B,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AAKpC;;GAEG;AACH,eAAO,MAAM,KAAK,SAA4B,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1B,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,GAAU,IAAI,EAAE,KAAG,OAAO,CAAC,IAAI,CAGvD,CAAC;AAMF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,GAAI,aAAa,CAAC,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,KAAG,SAkB7E,CAAC;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,iBAAiB,GAC7B,aAAa,CAAC,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,EACtC,WAAW,MAAM,KACf,SA2DF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,UAQhC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,gCAAgC,UAAyC,CAAC;AAEvF;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/db.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AA6B7B,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AAKpC;;GAEG;AACH,eAAO,MAAM,KAAK,SAA4B,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1B,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,GAAU,IAAI,EAAE,KAAG,OAAO,CAAC,IAAI,CAGvD,CAAC;AAMF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,GAAI,aAAa,CAAC,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,KAAG,SAkB7E,CAAC;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,iBAAiB,GAC7B,aAAa,CAAC,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,EACtC,WAAW,MAAM,KACf,SA2DF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,UAQhC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,gCAAgC,UAAyC,CAAC;AAEvF;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,uJAWnB,CAAC;AAEX;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,GAAU,IAAI,EAAE,KAAG,OAAO,CAAC,IAAI,CAK3D,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kBAAkB,GAC9B,WAAW,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,EACvC,iBAAiB,KAAK,CAAC,MAAM,CAAC,KAC5B,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,KAAK,IAAI,CAwBzD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,GAAI,WAAW,KAAK,CAAC,SAAS,CAAC,KAAG,IAMnE,CAAC"}
|
package/dist/testing/db.js
CHANGED
|
@@ -164,8 +164,8 @@ export const AUTH_TRUNCATE_TABLES = [
|
|
|
164
164
|
'invite',
|
|
165
165
|
'api_token',
|
|
166
166
|
'auth_session',
|
|
167
|
-
'
|
|
168
|
-
'
|
|
167
|
+
'role_grant',
|
|
168
|
+
'role_grant_offer',
|
|
169
169
|
'actor',
|
|
170
170
|
'account',
|
|
171
171
|
];
|
|
@@ -192,8 +192,8 @@ export const AUTH_DROP_TABLES = [
|
|
|
192
192
|
'audit_log',
|
|
193
193
|
'api_token',
|
|
194
194
|
'auth_session',
|
|
195
|
-
'
|
|
196
|
-
'
|
|
195
|
+
'role_grant',
|
|
196
|
+
'role_grant_offer',
|
|
197
197
|
'actor',
|
|
198
198
|
'account',
|
|
199
199
|
'bootstrap_lock',
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import './assert_dev_env.js';
|
|
2
|
+
import type { Account, Actor } from '../auth/account_schema.js';
|
|
3
|
+
import type { Db } from '../db/db.js';
|
|
4
|
+
/** The `{account, actor}` row pair returned by `create_test_account_with_actor`. */
|
|
5
|
+
export interface TestAccountWithActor {
|
|
6
|
+
account: Account;
|
|
7
|
+
actor: Actor;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Create an `account` + `actor` row pair in the database for tests.
|
|
11
|
+
*
|
|
12
|
+
* Wraps `query_create_account_with_actor` with a default `password_hash`
|
|
13
|
+
* so suites that don't exercise password verification can stay terse.
|
|
14
|
+
* Replaces the per-file `create_user` / `create_test_actor` /
|
|
15
|
+
* `create_test_account` helpers that had accumulated across the auth
|
|
16
|
+
* test suite.
|
|
17
|
+
*/
|
|
18
|
+
export declare const create_test_account_with_actor: (db: Db, options: {
|
|
19
|
+
username: string;
|
|
20
|
+
password_hash?: string;
|
|
21
|
+
}) => Promise<TestAccountWithActor>;
|
|
22
|
+
//# sourceMappingURL=db_entities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db_entities.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/db_entities.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAoB7B,OAAO,KAAK,EAAC,OAAO,EAAE,KAAK,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AAEpC,oFAAoF;AACpF,MAAM,WAAW,oBAAoB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;CACb;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,8BAA8B,GAC1C,IAAI,EAAE,EACN,SAAS;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAC,KACjD,OAAO,CAAC,oBAAoB,CAI7B,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import './assert_dev_env.js';
|
|
2
|
+
/**
|
|
3
|
+
* DB-backed entity factories for tests that need real `account` + `actor`
|
|
4
|
+
* rows in the database.
|
|
5
|
+
*
|
|
6
|
+
* Companion to `entities.ts` — that file ships in-memory factories
|
|
7
|
+
* (`create_test_account`, `create_test_actor`) for tests that mock the
|
|
8
|
+
* DB; this file ships factories that hit a real `Db` so query-level
|
|
9
|
+
* tests don't reimplement the same `query_create_account_with_actor`
|
|
10
|
+
* wrapper in every file.
|
|
11
|
+
*
|
|
12
|
+
* For full-fledged test accounts that also need an API token + signed
|
|
13
|
+
* session cookie + role_grants, use `bootstrap_test_account` from
|
|
14
|
+
* `app_server.ts` instead.
|
|
15
|
+
*
|
|
16
|
+
* @module
|
|
17
|
+
*/
|
|
18
|
+
import { query_create_account_with_actor } from '../auth/account_queries.js';
|
|
19
|
+
/**
|
|
20
|
+
* Create an `account` + `actor` row pair in the database for tests.
|
|
21
|
+
*
|
|
22
|
+
* Wraps `query_create_account_with_actor` with a default `password_hash`
|
|
23
|
+
* so suites that don't exercise password verification can stay terse.
|
|
24
|
+
* Replaces the per-file `create_user` / `create_test_actor` /
|
|
25
|
+
* `create_test_account` helpers that had accumulated across the auth
|
|
26
|
+
* test suite.
|
|
27
|
+
*/
|
|
28
|
+
export const create_test_account_with_actor = async (db, options) => query_create_account_with_actor({ db }, { username: options.username, password_hash: options.password_hash ?? 'hash' });
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import './assert_dev_env.js';
|
|
2
|
-
import type { Account, Actor,
|
|
2
|
+
import type { Account, Actor, RoleGrant } from '../auth/account_schema.js';
|
|
3
3
|
import type { AuditLogEvent } from '../auth/audit_log_schema.js';
|
|
4
4
|
import type { RequestContext } from '../auth/request_context.js';
|
|
5
5
|
/** Override type for `create_test_account` — id-like fields accept plain `string`. */
|
|
@@ -18,19 +18,20 @@ export type TestActorOverrides = Partial<Omit<Actor, 'id' | 'account_id' | 'upda
|
|
|
18
18
|
};
|
|
19
19
|
/** Create a test `Actor` with sensible defaults. */
|
|
20
20
|
export declare const create_test_actor: (overrides?: TestActorOverrides) => Actor;
|
|
21
|
-
/** Override type for `
|
|
22
|
-
export type
|
|
21
|
+
/** Override type for `create_test_role_grant` — id-like fields accept plain `string`. */
|
|
22
|
+
export type TestRoleGrantOverrides = Partial<Omit<RoleGrant, 'id' | 'actor_id' | 'scope_kind' | 'scope_id' | 'revoked_by' | 'granted_by' | 'source_offer_id'>> & {
|
|
23
23
|
id?: string;
|
|
24
24
|
actor_id?: string;
|
|
25
|
+
scope_kind?: string | null;
|
|
25
26
|
scope_id?: string | null;
|
|
26
27
|
revoked_by?: string | null;
|
|
27
28
|
granted_by?: string | null;
|
|
28
29
|
source_offer_id?: string | null;
|
|
29
30
|
};
|
|
30
|
-
/** Create a test `
|
|
31
|
-
export declare const
|
|
32
|
-
/** Create a test `RequestContext` with
|
|
33
|
-
export declare const create_test_context: (
|
|
31
|
+
/** Create a test `RoleGrant` with sensible defaults. */
|
|
32
|
+
export declare const create_test_role_grant: (overrides?: TestRoleGrantOverrides) => RoleGrant;
|
|
33
|
+
/** Create a test `RequestContext` with role_grants from partial overrides. */
|
|
34
|
+
export declare const create_test_context: (role_grants?: Array<TestRoleGrantOverrides>) => RequestContext;
|
|
34
35
|
/** Override type for `create_test_audit_event` — id-like fields accept plain `string`. */
|
|
35
36
|
export type TestAuditEventOverrides = Partial<Omit<AuditLogEvent, 'id' | 'actor_id' | 'account_id' | 'target_account_id' | 'target_actor_id'>> & {
|
|
36
37
|
id?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entities.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/entities.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAiB7B,OAAO,KAAK,EAAC,OAAO,EAAE,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"entities.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/entities.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAiB7B,OAAO,KAAK,EAAC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAC,MAAM,2BAA2B,CAAC;AACzE,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,4BAA4B,CAAC;AAE/D,sFAAsF;AACtF,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,YAAY,GAAG,YAAY,CAAC,CAAC,GAAG;IAC/F,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,mBAAmB,GAAI,YAAY,oBAAoB,KAAG,OAWrE,CAAC;AAEH,oFAAoF;AACpF,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,GAAG,YAAY,GAAG,YAAY,CAAC,CAAC,GAAG;IAC3F,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC;AAEF,oDAAoD;AACpD,eAAO,MAAM,iBAAiB,GAAI,YAAY,kBAAkB,KAAG,KAQjE,CAAC;AAEH,yFAAyF;AACzF,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAC3C,IAAI,CACH,SAAS,EACT,IAAI,GAAG,UAAU,GAAG,YAAY,GAAG,UAAU,GAAG,YAAY,GAAG,YAAY,GAAG,iBAAiB,CAC/F,CACD,GAAG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,wDAAwD;AACxD,eAAO,MAAM,sBAAsB,GAAI,YAAY,sBAAsB,KAAG,SAgB3E,CAAC;AAEF,8EAA8E;AAC9E,eAAO,MAAM,mBAAmB,GAC/B,cAAa,KAAK,CAAC,sBAAsB,CAAQ,KAC/C,cAID,CAAC;AAEH,0FAA0F;AAC1F,MAAM,MAAM,uBAAuB,GAAG,OAAO,CAC5C,IAAI,CAAC,aAAa,EAAE,IAAI,GAAG,UAAU,GAAG,YAAY,GAAG,mBAAmB,GAAG,iBAAiB,CAAC,CAC/F,GAAG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,4DAA4D;AAC5D,eAAO,MAAM,uBAAuB,GAAI,YAAY,uBAAuB,KAAG,aAa5E,CAAC"}
|
package/dist/testing/entities.js
CHANGED
|
@@ -22,26 +22,29 @@ export const create_test_actor = (overrides) => ({
|
|
|
22
22
|
updated_by: null,
|
|
23
23
|
...overrides,
|
|
24
24
|
});
|
|
25
|
-
/** Create a test `
|
|
26
|
-
export const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
25
|
+
/** Create a test `RoleGrant` with sensible defaults. */
|
|
26
|
+
export const create_test_role_grant = (overrides) => {
|
|
27
|
+
const base = {
|
|
28
|
+
id: 'role-grant-test',
|
|
29
|
+
actor_id: 'actor-test',
|
|
30
|
+
role: 'admin',
|
|
31
|
+
scope_kind: null,
|
|
32
|
+
scope_id: null,
|
|
33
|
+
created_at: '2024-01-01T00:00:00Z',
|
|
34
|
+
expires_at: null,
|
|
35
|
+
revoked_at: null,
|
|
36
|
+
revoked_by: null,
|
|
37
|
+
revoked_reason: null,
|
|
38
|
+
granted_by: null,
|
|
39
|
+
source_offer_id: null,
|
|
40
|
+
};
|
|
41
|
+
return overrides ? { ...base, ...overrides } : base;
|
|
42
|
+
};
|
|
43
|
+
/** Create a test `RequestContext` with role_grants from partial overrides. */
|
|
44
|
+
export const create_test_context = (role_grants = [{}]) => ({
|
|
42
45
|
account: create_test_account(),
|
|
43
46
|
actor: create_test_actor(),
|
|
44
|
-
|
|
47
|
+
role_grants: role_grants.map((p) => create_test_role_grant(p)),
|
|
45
48
|
});
|
|
46
49
|
/** Create a test `AuditLogEvent` with sensible defaults. */
|
|
47
50
|
export const create_test_audit_event = (overrides) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/integration.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAsB7B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAA6C,KAAK,eAAe,EAAC,MAAM,iBAAiB,CAAC;AACjG,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,SAAS,CAAC;AAOjB,OAAO,EAKN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"integration.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/integration.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAsB7B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAA6C,KAAK,eAAe,EAAC,MAAM,iBAAiB,CAAC;AACjG,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,SAAS,CAAC;AAOjB,OAAO,EAKN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAsB1B;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC9C,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,iDAAiD;IACjD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B;;;OAGG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC;;;;;;;;;;;;;;;;OAgBG;IACH,aAAa,EAAE,uBAAuB,CAAC;CACvC;AAsBD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,mCAAmC,GAC/C,SAAS,8BAA8B,KACrC,IA87CF,CAAC"}
|