@fuzdev/fuz_app 0.55.0 → 0.57.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 +72 -39
- package/dist/http/error_schemas.d.ts.map +1 -1
- package/dist/http/error_schemas.js +81 -33
- 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 +14 -6
- package/dist/testing/surface_invariants.d.ts.map +1 -1
- package/dist/testing/surface_invariants.js +119 -43
- 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
package/dist/auth/cleanup.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Periodic auth cleanup — sweeps expired sessions and
|
|
2
|
+
* Periodic auth cleanup — sweeps expired sessions and role_grant offers.
|
|
3
3
|
*
|
|
4
4
|
* Single entry point for consumers scheduling auth maintenance. Internally
|
|
5
5
|
* runs every known sweep and emits the corresponding audit events so
|
|
6
6
|
* consumer code only manages cadence, not per-task wiring.
|
|
7
7
|
*
|
|
8
8
|
* The per-task primitives remain exported from their home modules
|
|
9
|
-
* (`query_session_cleanup_expired`, `
|
|
10
|
-
* `
|
|
11
|
-
* `
|
|
9
|
+
* (`query_session_cleanup_expired`, `query_role_grant_offer_sweep_expired`);
|
|
10
|
+
* `cleanup_expired_role_grant_offers` here wraps the latter with the required
|
|
11
|
+
* `role_grant_offer_expire` audit emission and is the piece most likely to be
|
|
12
12
|
* reused in a consumer's bespoke scheduler.
|
|
13
13
|
*
|
|
14
|
-
* Idempotency: the audit log has no tombstone on `
|
|
14
|
+
* Idempotency: the audit log has no tombstone on `role_grant_offer_expire`, so
|
|
15
15
|
* concurrent sweep runs double-audit. The expected deployment pattern is a
|
|
16
16
|
* single scheduled invocation per instance — matching
|
|
17
17
|
* `query_session_cleanup_expired`.
|
|
@@ -19,73 +19,59 @@
|
|
|
19
19
|
* @module
|
|
20
20
|
*/
|
|
21
21
|
import { query_session_cleanup_expired } from './session_queries.js';
|
|
22
|
-
import {
|
|
23
|
-
import { query_audit_log } from './audit_log_queries.js';
|
|
22
|
+
import { query_role_grant_offer_sweep_expired } from './role_grant_offer_queries.js';
|
|
24
23
|
/**
|
|
25
|
-
* Sweep expired
|
|
24
|
+
* Sweep expired role_grant offers and emit one `role_grant_offer_expire` audit
|
|
26
25
|
* event per row.
|
|
27
26
|
*
|
|
28
27
|
* Returns the count of offers audit-stamped. The offer rows themselves are
|
|
29
28
|
* preserved — offers carry audit value for the history view even after
|
|
30
|
-
* expiry, and accepted rows are the provenance for the resulting
|
|
29
|
+
* expiry, and accepted rows are the provenance for the resulting role_grant
|
|
31
30
|
* (deleting expired rows would not threaten that, but keeping them uniform
|
|
32
31
|
* with the retention policy for terminal rows is simpler).
|
|
33
32
|
*
|
|
34
|
-
* @mutates `audit_log` table - inserts one `
|
|
33
|
+
* @mutates `audit_log` table - inserts one `role_grant_offer_expire` row per swept offer
|
|
35
34
|
*/
|
|
36
|
-
export const
|
|
37
|
-
const expired = await
|
|
38
|
-
const { on_audit_event, audit_log_config } = deps;
|
|
35
|
+
export const cleanup_expired_role_grant_offers = async (deps) => {
|
|
36
|
+
const expired = await query_role_grant_offer_sweep_expired(deps);
|
|
39
37
|
for (const offer of expired) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
},
|
|
57
|
-
|
|
58
|
-
try {
|
|
59
|
-
on_audit_event(event);
|
|
60
|
-
}
|
|
61
|
-
catch (callback_err) {
|
|
62
|
-
deps.log.error('on_audit_event callback failed:', callback_err);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
catch (err) {
|
|
67
|
-
// One failed audit write must not starve siblings — log and continue.
|
|
68
|
-
deps.log.error('permit_offer_expire audit write failed:', err);
|
|
69
|
-
}
|
|
38
|
+
// `role_grant_offer_expire` populates `target_actor_id` only when the
|
|
39
|
+
// offer was actor-targeted (`to_actor_id` set at create time).
|
|
40
|
+
// Account-grain offers (no `to_actor_id`) never bound to a
|
|
41
|
+
// specific actor and leave the field null.
|
|
42
|
+
// `emit_pool` swallows + logs both write errors and per-listener
|
|
43
|
+
// throws, so a single bad row never starves the rest of the sweep.
|
|
44
|
+
await deps.audit.emit_pool({
|
|
45
|
+
event_type: 'role_grant_offer_expire',
|
|
46
|
+
actor_id: offer.from_actor_id,
|
|
47
|
+
target_account_id: offer.to_account_id,
|
|
48
|
+
target_actor_id: offer.to_actor_id,
|
|
49
|
+
ip: null,
|
|
50
|
+
metadata: {
|
|
51
|
+
offer_id: offer.id,
|
|
52
|
+
role: offer.role,
|
|
53
|
+
scope_id: offer.scope_id,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
70
56
|
}
|
|
71
57
|
return expired.length;
|
|
72
58
|
};
|
|
73
59
|
/**
|
|
74
|
-
* Run every auth cleanup sweep — expired sessions and expired
|
|
60
|
+
* Run every auth cleanup sweep — expired sessions and expired role_grant
|
|
75
61
|
* offers — and return the counts.
|
|
76
62
|
*
|
|
77
63
|
* Consumers call this from a scheduled task (setInterval, cron, etc.)
|
|
78
64
|
* alongside their own domain cleanup. Errors from individual sweeps are
|
|
79
65
|
* re-thrown so the caller's scheduler can log/alert; use the per-task
|
|
80
|
-
* helpers (`query_session_cleanup_expired`, `
|
|
66
|
+
* helpers (`query_session_cleanup_expired`, `cleanup_expired_role_grant_offers`)
|
|
81
67
|
* directly if you need finer error isolation.
|
|
82
68
|
*
|
|
83
69
|
* @mutates `auth_session` table - deletes expired sessions
|
|
84
|
-
* @mutates `audit_log` table - emits `
|
|
70
|
+
* @mutates `audit_log` table - emits `role_grant_offer_expire` rows for expired offers
|
|
85
71
|
* @throws Error re-thrown from any sweep that fails (no per-sweep isolation here)
|
|
86
72
|
*/
|
|
87
73
|
export const run_auth_cleanup = async (deps) => {
|
|
88
74
|
const expired_sessions = await query_session_cleanup_expired(deps);
|
|
89
|
-
const expired_offers = await
|
|
75
|
+
const expired_offers = await cleanup_expired_role_grant_offers(deps);
|
|
90
76
|
return { expired_sessions, expired_offers };
|
|
91
77
|
};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential-type registry — how a request was authenticated.
|
|
3
|
+
*
|
|
4
|
+
* Three builtins: `session` (cookie-based), `api_token` (HTTP Bearer
|
|
5
|
+
* token), `daemon_token` (filesystem proof for the keeper account).
|
|
6
|
+
* Open-string registry on top so consumers can declare additional
|
|
7
|
+
* credential types (e.g. `'sso_assertion'`, `'agent_token'`) without an
|
|
8
|
+
* upstream release. `RoleSpec.required_credential_types` references
|
|
9
|
+
* entries from this registry; v1 keeps the field informative-only
|
|
10
|
+
* (consumed by `auth/middleware.ts` and the dispatcher). Mirrors the
|
|
11
|
+
* open-registry pattern used for `RoleName`, `ScopeKindName`,
|
|
12
|
+
* `GrantPathName`, and `AuditEventTypeName`.
|
|
13
|
+
*
|
|
14
|
+
* The Hono-side wire-validated `CredentialType` Zod enum (in
|
|
15
|
+
* `hono_context.ts`) is the closed-set narrow type middleware sets on
|
|
16
|
+
* the context; the constants below are the source of truth for those
|
|
17
|
+
* three string values. Future builtin credential types added here
|
|
18
|
+
* propagate to the wire enum by editing the import list.
|
|
19
|
+
*
|
|
20
|
+
* @module
|
|
21
|
+
*/
|
|
22
|
+
import { z } from 'zod';
|
|
23
|
+
/**
|
|
24
|
+
* Letter (lowercase a-z) start and end (or single letter), with letters
|
|
25
|
+
* and underscores in between. Mirrors `RoleName`, `ScopeKindName`,
|
|
26
|
+
* `GrantPathName`. Rejects empty strings, leading or trailing
|
|
27
|
+
* underscores, uppercase, and digits.
|
|
28
|
+
*/
|
|
29
|
+
export declare const CREDENTIAL_TYPE_NAME_REGEX: RegExp;
|
|
30
|
+
/** Zod schema for valid credential-type name strings. */
|
|
31
|
+
export declare const CredentialTypeName: z.ZodString;
|
|
32
|
+
export type CredentialTypeName = z.infer<typeof CredentialTypeName>;
|
|
33
|
+
/** Cookie-based session credential. */
|
|
34
|
+
export declare const CREDENTIAL_TYPE_SESSION = "session";
|
|
35
|
+
/**
|
|
36
|
+
* HTTP `Authorization: Bearer` API token credential. The wire literal
|
|
37
|
+
* `'api_token'` aligns with the `api_token` storage table name; the
|
|
38
|
+
* constant is named `_API_TOKEN` (not `_BEARER`) to keep wire and
|
|
39
|
+
* storage nomenclature in lockstep.
|
|
40
|
+
*/
|
|
41
|
+
export declare const CREDENTIAL_TYPE_API_TOKEN = "api_token";
|
|
42
|
+
/** Daemon-token credential — filesystem proof for the keeper account. */
|
|
43
|
+
export declare const CREDENTIAL_TYPE_DAEMON_TOKEN = "daemon_token";
|
|
44
|
+
/** The builtin credential-type names as a const tuple. */
|
|
45
|
+
export declare const BUILTIN_CREDENTIAL_TYPES: readonly ["session", "api_token", "daemon_token"];
|
|
46
|
+
/** Zod enum for builtin credential types only. */
|
|
47
|
+
export declare const BuiltinCredentialType: z.ZodEnum<{
|
|
48
|
+
daemon_token: "daemon_token";
|
|
49
|
+
session: "session";
|
|
50
|
+
api_token: "api_token";
|
|
51
|
+
}>;
|
|
52
|
+
export type BuiltinCredentialType = z.infer<typeof BuiltinCredentialType>;
|
|
53
|
+
/**
|
|
54
|
+
* Per-credential-type metadata. `description` is admin-UI-facing copy
|
|
55
|
+
* (mirrors `RoleSpec.description` and `ScopeKindMeta.description`).
|
|
56
|
+
* Open shape so v2 can extend without a breaking change.
|
|
57
|
+
*/
|
|
58
|
+
export interface CredentialTypeMeta {
|
|
59
|
+
description?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Builtin credential-type metadata. Not overridable by consumers.
|
|
63
|
+
*
|
|
64
|
+
* Typed `ReadonlyMap` for the contract — but JS Maps don't honor
|
|
65
|
+
* `Object.freeze` for `.set` / `.delete` / `.clear` (they mutate
|
|
66
|
+
* internal slots, not own properties), so freeze adds no runtime guard
|
|
67
|
+
* here. Read once at startup by `create_credential_type_schema`;
|
|
68
|
+
* runtime mutation has no effect on already-built schemas.
|
|
69
|
+
*/
|
|
70
|
+
export declare const BUILTIN_CREDENTIAL_TYPE_META: ReadonlyMap<string, CredentialTypeMeta>;
|
|
71
|
+
/** The result of `create_credential_type_schema` — a Zod schema and metadata map. */
|
|
72
|
+
export interface CredentialTypeSchemaResult {
|
|
73
|
+
/**
|
|
74
|
+
* Zod schema that validates credential-type name strings against the
|
|
75
|
+
* registered set (builtins + consumer-declared). Use at I/O
|
|
76
|
+
* boundaries (admin UIs, codegen) and as the construction-time check
|
|
77
|
+
* inside `create_role_schema` for every
|
|
78
|
+
* `RoleSpec.required_credential_types` entry.
|
|
79
|
+
*/
|
|
80
|
+
CredentialType: z.ZodType<string>;
|
|
81
|
+
/**
|
|
82
|
+
* Map of every registered credential-type to its metadata. Keyed by
|
|
83
|
+
* name. Read at startup by admin / codegen surfaces.
|
|
84
|
+
*/
|
|
85
|
+
credential_types: ReadonlyMap<string, CredentialTypeMeta>;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Create a credential-type schema from the builtin set plus optional
|
|
89
|
+
* consumer-declared additions.
|
|
90
|
+
*
|
|
91
|
+
* Builtins (`session`, `api_token`, `daemon_token`) are always present;
|
|
92
|
+
* consumer entries that collide with a builtin name throw at
|
|
93
|
+
* construction. Pass the result into `create_role_schema`'s optional
|
|
94
|
+
* `credential_types` parameter so each role's
|
|
95
|
+
* `required_credential_types` entries are validated against this set
|
|
96
|
+
* at construction time.
|
|
97
|
+
*
|
|
98
|
+
* @param consumer_types - optional consumer-declared credential-type set with optional metadata
|
|
99
|
+
* @returns `{CredentialType, credential_types}` — Zod schema and metadata map
|
|
100
|
+
*
|
|
101
|
+
* @throws Error if any `consumer_types` key fails the `CredentialTypeName` regex, collides with a builtin name, or appears more than once
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```ts
|
|
105
|
+
* // simple — builtins only
|
|
106
|
+
* const {CredentialType, credential_types} = create_credential_type_schema();
|
|
107
|
+
*
|
|
108
|
+
* // with consumer extensions
|
|
109
|
+
* const {CredentialType} = create_credential_type_schema({
|
|
110
|
+
* sso_assertion: {description: 'OIDC SSO assertion bound to an IdP-asserted account.'},
|
|
111
|
+
* });
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
export declare const create_credential_type_schema: (consumer_types?: Record<string, CredentialTypeMeta>) => CredentialTypeSchemaResult;
|
|
115
|
+
//# sourceMappingURL=credential_type_schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential_type_schema.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/credential_type_schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,QAAgC,CAAC;AAExE,yDAAyD;AACzD,eAAO,MAAM,kBAAkB,aAK7B,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAIpE,uCAAuC;AACvC,eAAO,MAAM,uBAAuB,YAAY,CAAC;AAEjD;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,cAAc,CAAC;AAErD,yEAAyE;AACzE,eAAO,MAAM,4BAA4B,iBAAiB,CAAC;AAE3D,0DAA0D;AAC1D,eAAO,MAAM,wBAAwB,mDAI3B,CAAC;AAEX,kDAAkD;AAClD,eAAO,MAAM,qBAAqB;;;;EAAmC,CAAC;AACtE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE1E;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,4BAA4B,EAAE,WAAW,CAAC,MAAM,EAAE,kBAAkB,CAa/E,CAAC;AAEH,qFAAqF;AACrF,MAAM,WAAW,0BAA0B;IAC1C;;;;;;OAMG;IACH,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC;;;OAGG;IACH,gBAAgB,EAAE,WAAW,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;CAC1D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,6BAA6B,GACzC,iBAAgB,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAM,KACrD,0BA2BF,CAAC"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential-type registry — how a request was authenticated.
|
|
3
|
+
*
|
|
4
|
+
* Three builtins: `session` (cookie-based), `api_token` (HTTP Bearer
|
|
5
|
+
* token), `daemon_token` (filesystem proof for the keeper account).
|
|
6
|
+
* Open-string registry on top so consumers can declare additional
|
|
7
|
+
* credential types (e.g. `'sso_assertion'`, `'agent_token'`) without an
|
|
8
|
+
* upstream release. `RoleSpec.required_credential_types` references
|
|
9
|
+
* entries from this registry; v1 keeps the field informative-only
|
|
10
|
+
* (consumed by `auth/middleware.ts` and the dispatcher). Mirrors the
|
|
11
|
+
* open-registry pattern used for `RoleName`, `ScopeKindName`,
|
|
12
|
+
* `GrantPathName`, and `AuditEventTypeName`.
|
|
13
|
+
*
|
|
14
|
+
* The Hono-side wire-validated `CredentialType` Zod enum (in
|
|
15
|
+
* `hono_context.ts`) is the closed-set narrow type middleware sets on
|
|
16
|
+
* the context; the constants below are the source of truth for those
|
|
17
|
+
* three string values. Future builtin credential types added here
|
|
18
|
+
* propagate to the wire enum by editing the import list.
|
|
19
|
+
*
|
|
20
|
+
* @module
|
|
21
|
+
*/
|
|
22
|
+
import { z } from 'zod';
|
|
23
|
+
/**
|
|
24
|
+
* Letter (lowercase a-z) start and end (or single letter), with letters
|
|
25
|
+
* and underscores in between. Mirrors `RoleName`, `ScopeKindName`,
|
|
26
|
+
* `GrantPathName`. Rejects empty strings, leading or trailing
|
|
27
|
+
* underscores, uppercase, and digits.
|
|
28
|
+
*/
|
|
29
|
+
export const CREDENTIAL_TYPE_NAME_REGEX = /^[a-z][a-z_]*[a-z]$|^[a-z]$/;
|
|
30
|
+
/** Zod schema for valid credential-type name strings. */
|
|
31
|
+
export const CredentialTypeName = z
|
|
32
|
+
.string()
|
|
33
|
+
.regex(CREDENTIAL_TYPE_NAME_REGEX, 'Credential-type names must be lowercase letters and underscores (a-z_), no leading/trailing underscore');
|
|
34
|
+
// Builtin credential types — provided by fuz_app, always available.
|
|
35
|
+
/** Cookie-based session credential. */
|
|
36
|
+
export const CREDENTIAL_TYPE_SESSION = 'session';
|
|
37
|
+
/**
|
|
38
|
+
* HTTP `Authorization: Bearer` API token credential. The wire literal
|
|
39
|
+
* `'api_token'` aligns with the `api_token` storage table name; the
|
|
40
|
+
* constant is named `_API_TOKEN` (not `_BEARER`) to keep wire and
|
|
41
|
+
* storage nomenclature in lockstep.
|
|
42
|
+
*/
|
|
43
|
+
export const CREDENTIAL_TYPE_API_TOKEN = 'api_token';
|
|
44
|
+
/** Daemon-token credential — filesystem proof for the keeper account. */
|
|
45
|
+
export const CREDENTIAL_TYPE_DAEMON_TOKEN = 'daemon_token';
|
|
46
|
+
/** The builtin credential-type names as a const tuple. */
|
|
47
|
+
export const BUILTIN_CREDENTIAL_TYPES = [
|
|
48
|
+
CREDENTIAL_TYPE_SESSION,
|
|
49
|
+
CREDENTIAL_TYPE_API_TOKEN,
|
|
50
|
+
CREDENTIAL_TYPE_DAEMON_TOKEN,
|
|
51
|
+
];
|
|
52
|
+
/** Zod enum for builtin credential types only. */
|
|
53
|
+
export const BuiltinCredentialType = z.enum(BUILTIN_CREDENTIAL_TYPES);
|
|
54
|
+
/**
|
|
55
|
+
* Builtin credential-type metadata. Not overridable by consumers.
|
|
56
|
+
*
|
|
57
|
+
* Typed `ReadonlyMap` for the contract — but JS Maps don't honor
|
|
58
|
+
* `Object.freeze` for `.set` / `.delete` / `.clear` (they mutate
|
|
59
|
+
* internal slots, not own properties), so freeze adds no runtime guard
|
|
60
|
+
* here. Read once at startup by `create_credential_type_schema`;
|
|
61
|
+
* runtime mutation has no effect on already-built schemas.
|
|
62
|
+
*/
|
|
63
|
+
export const BUILTIN_CREDENTIAL_TYPE_META = new Map([
|
|
64
|
+
[
|
|
65
|
+
CREDENTIAL_TYPE_SESSION,
|
|
66
|
+
{ description: 'Cookie-based session credential, signed and validated server-side.' },
|
|
67
|
+
],
|
|
68
|
+
[
|
|
69
|
+
CREDENTIAL_TYPE_API_TOKEN,
|
|
70
|
+
{ description: 'HTTP Authorization: Bearer API token credential, hashed at rest.' },
|
|
71
|
+
],
|
|
72
|
+
[
|
|
73
|
+
CREDENTIAL_TYPE_DAEMON_TOKEN,
|
|
74
|
+
{ description: 'Filesystem-proof daemon-token credential, scoped to the keeper account.' },
|
|
75
|
+
],
|
|
76
|
+
]);
|
|
77
|
+
/**
|
|
78
|
+
* Create a credential-type schema from the builtin set plus optional
|
|
79
|
+
* consumer-declared additions.
|
|
80
|
+
*
|
|
81
|
+
* Builtins (`session`, `api_token`, `daemon_token`) are always present;
|
|
82
|
+
* consumer entries that collide with a builtin name throw at
|
|
83
|
+
* construction. Pass the result into `create_role_schema`'s optional
|
|
84
|
+
* `credential_types` parameter so each role's
|
|
85
|
+
* `required_credential_types` entries are validated against this set
|
|
86
|
+
* at construction time.
|
|
87
|
+
*
|
|
88
|
+
* @param consumer_types - optional consumer-declared credential-type set with optional metadata
|
|
89
|
+
* @returns `{CredentialType, credential_types}` — Zod schema and metadata map
|
|
90
|
+
*
|
|
91
|
+
* @throws Error if any `consumer_types` key fails the `CredentialTypeName` regex, collides with a builtin name, or appears more than once
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```ts
|
|
95
|
+
* // simple — builtins only
|
|
96
|
+
* const {CredentialType, credential_types} = create_credential_type_schema();
|
|
97
|
+
*
|
|
98
|
+
* // with consumer extensions
|
|
99
|
+
* const {CredentialType} = create_credential_type_schema({
|
|
100
|
+
* sso_assertion: {description: 'OIDC SSO assertion bound to an IdP-asserted account.'},
|
|
101
|
+
* });
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
export const create_credential_type_schema = (consumer_types = {}) => {
|
|
105
|
+
const consumer_names = Object.keys(consumer_types);
|
|
106
|
+
const seen = new Set();
|
|
107
|
+
for (const name of consumer_names) {
|
|
108
|
+
const parsed = CredentialTypeName.safeParse(name);
|
|
109
|
+
if (!parsed.success) {
|
|
110
|
+
throw new Error(`Invalid credential-type name "${name}": ${parsed.error.issues[0].message}`);
|
|
111
|
+
}
|
|
112
|
+
if (BUILTIN_CREDENTIAL_TYPE_META.has(name)) {
|
|
113
|
+
throw new Error(`Consumer credential-type "${name}" collides with builtin credential-type`);
|
|
114
|
+
}
|
|
115
|
+
if (seen.has(name)) {
|
|
116
|
+
throw new Error(`Duplicate credential-type name "${name}"`);
|
|
117
|
+
}
|
|
118
|
+
seen.add(name);
|
|
119
|
+
}
|
|
120
|
+
const all_names = [...BUILTIN_CREDENTIAL_TYPES, ...consumer_names];
|
|
121
|
+
const CredentialType = z.enum(all_names);
|
|
122
|
+
const credential_types = new Map(BUILTIN_CREDENTIAL_TYPE_META);
|
|
123
|
+
for (const name of consumer_names) {
|
|
124
|
+
credential_types.set(name, consumer_types[name]);
|
|
125
|
+
}
|
|
126
|
+
return { CredentialType, credential_types };
|
|
127
|
+
};
|
|
@@ -42,7 +42,7 @@ export declare const get_daemon_token_path: (runtime: Pick<EnvDeps, "env_get">,
|
|
|
42
42
|
export declare const write_daemon_token: (runtime: DaemonTokenWriteDeps, token_path: string, token: string) => Promise<void>;
|
|
43
43
|
/**
|
|
44
44
|
* Resolve the keeper account ID by querying for the account with an active
|
|
45
|
-
* keeper
|
|
45
|
+
* keeper role_grant.
|
|
46
46
|
*
|
|
47
47
|
* There is exactly one keeper account (the bootstrap account). Runs once
|
|
48
48
|
* at server startup — the result is cached in
|
|
@@ -14,7 +14,7 @@ import { write_file_atomic } from '../runtime/fs.js';
|
|
|
14
14
|
import { get_app_dir } from '../cli/config.js';
|
|
15
15
|
import { ACCOUNT_ID_KEY, AUTH_API_TOKEN_ID_KEY, CREDENTIAL_TYPE_KEY } from '../hono_context.js';
|
|
16
16
|
import { ERROR_INVALID_DAEMON_TOKEN, ERROR_KEEPER_ACCOUNT_NOT_CONFIGURED, } from '../http/error_schemas.js';
|
|
17
|
-
import {
|
|
17
|
+
import { query_role_grant_find_account_id_for_role } from './role_grant_queries.js';
|
|
18
18
|
import { ROLE_KEEPER } from './role_schema.js';
|
|
19
19
|
import { DaemonToken, DAEMON_TOKEN_HEADER, generate_daemon_token, validate_daemon_token, } from './daemon_token.js';
|
|
20
20
|
/** Default rotation interval in milliseconds (30 seconds). */
|
|
@@ -48,7 +48,7 @@ export const write_daemon_token = async (runtime, token_path, token) => {
|
|
|
48
48
|
};
|
|
49
49
|
/**
|
|
50
50
|
* Resolve the keeper account ID by querying for the account with an active
|
|
51
|
-
* keeper
|
|
51
|
+
* keeper role_grant.
|
|
52
52
|
*
|
|
53
53
|
* There is exactly one keeper account (the bootstrap account). Runs once
|
|
54
54
|
* at server startup — the result is cached in
|
|
@@ -62,7 +62,7 @@ export const write_daemon_token = async (runtime, token_path, token) => {
|
|
|
62
62
|
* @returns the keeper account ID, or `null` if no keeper exists yet (pre-bootstrap)
|
|
63
63
|
*/
|
|
64
64
|
export const resolve_keeper_account_id = async (deps) => {
|
|
65
|
-
return
|
|
65
|
+
return query_role_grant_find_account_id_for_role(deps, ROLE_KEEPER);
|
|
66
66
|
};
|
|
67
67
|
/**
|
|
68
68
|
* Start daemon token rotation.
|
package/dist/auth/ddl.d.ts
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
export declare const ACCOUNT_SCHEMA = "\nCREATE TABLE IF NOT EXISTS account (\n id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n username TEXT UNIQUE NOT NULL,\n email TEXT,\n email_verified BOOLEAN NOT NULL DEFAULT false,\n password_hash TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n created_by UUID,\n updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n updated_by UUID\n)";
|
|
10
10
|
export declare const ACTOR_SCHEMA = "\nCREATE TABLE IF NOT EXISTS actor (\n id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n account_id UUID NOT NULL REFERENCES account(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMPTZ,\n updated_by UUID REFERENCES actor(id) ON DELETE SET NULL\n)";
|
|
11
11
|
export declare const ACTOR_INDEX = "\nCREATE INDEX IF NOT EXISTS idx_actor_account ON actor(account_id)";
|
|
12
|
-
export declare const
|
|
13
|
-
export declare const
|
|
12
|
+
export declare const ROLE_GRANT_SCHEMA = "\nCREATE TABLE IF NOT EXISTS role_grant (\n id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n actor_id UUID NOT NULL REFERENCES actor(id) ON DELETE CASCADE,\n role TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n expires_at TIMESTAMPTZ,\n revoked_at TIMESTAMPTZ,\n revoked_by UUID REFERENCES actor(id) ON DELETE SET NULL,\n granted_by UUID REFERENCES actor(id) ON DELETE SET NULL\n)";
|
|
13
|
+
export declare const ROLE_GRANT_INDEXES: string[];
|
|
14
14
|
export declare const AUTH_SESSION_SCHEMA = "\nCREATE TABLE IF NOT EXISTS auth_session (\n id TEXT PRIMARY KEY,\n account_id UUID NOT NULL REFERENCES account(id) ON DELETE CASCADE,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n expires_at TIMESTAMPTZ NOT NULL,\n last_seen_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\n)";
|
|
15
15
|
export declare const AUTH_SESSION_INDEXES: string[];
|
|
16
16
|
export declare const API_TOKEN_SCHEMA = "\nCREATE TABLE IF NOT EXISTS api_token (\n id TEXT PRIMARY KEY,\n account_id UUID NOT NULL REFERENCES account(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n token_hash TEXT NOT NULL,\n expires_at TIMESTAMPTZ,\n last_used_at TIMESTAMPTZ,\n last_used_ip TEXT,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\n)";
|
package/dist/auth/ddl.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ddl.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/ddl.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,eAAO,MAAM,cAAc,8WAWzB,CAAC;AAEH,eAAO,MAAM,YAAY,mUAQvB,CAAC;AAEH,eAAO,MAAM,WAAW,wEAC0C,CAAC;AAEnE,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"ddl.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/ddl.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,eAAO,MAAM,cAAc,8WAWzB,CAAC;AAEH,eAAO,MAAM,YAAY,mUAQvB,CAAC;AAEH,eAAO,MAAM,WAAW,wEAC0C,CAAC;AAEnE,eAAO,MAAM,iBAAiB,2ZAU5B,CAAC;AAEH,eAAO,MAAM,kBAAkB,UAI9B,CAAC;AAEF,eAAO,MAAM,mBAAmB,0RAO9B,CAAC;AAEH,eAAO,MAAM,oBAAoB,UAGhC,CAAC;AAEF,eAAO,MAAM,gBAAgB,iUAU3B,CAAC;AAEH,eAAO,MAAM,mBAAmB,4GACsE,CAAC;AAEvG,eAAO,MAAM,yBAAyB,6FACiD,CAAC;AAExF,eAAO,MAAM,eAAe,gFAC8C,CAAC;AAE3E,eAAO,MAAM,qBAAqB,wJAIhC,CAAC;AAEH,6FAA6F;AAC7F,eAAO,MAAM,mBAAmB,yHAGP,CAAC;AAE1B,eAAO,MAAM,aAAa,6ZAUxB,CAAC;AAEH,eAAO,MAAM,cAAc,UAI1B,CAAC;AAEF,eAAO,MAAM,mBAAmB,oMAM9B,CAAC;AAEH,eAAO,MAAM,iBAAiB,sEACkC,CAAC"}
|
package/dist/auth/ddl.js
CHANGED
|
@@ -29,8 +29,8 @@ CREATE TABLE IF NOT EXISTS actor (
|
|
|
29
29
|
)`;
|
|
30
30
|
export const ACTOR_INDEX = `
|
|
31
31
|
CREATE INDEX IF NOT EXISTS idx_actor_account ON actor(account_id)`;
|
|
32
|
-
export const
|
|
33
|
-
CREATE TABLE IF NOT EXISTS
|
|
32
|
+
export const ROLE_GRANT_SCHEMA = `
|
|
33
|
+
CREATE TABLE IF NOT EXISTS role_grant (
|
|
34
34
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
35
35
|
actor_id UUID NOT NULL REFERENCES actor(id) ON DELETE CASCADE,
|
|
36
36
|
role TEXT NOT NULL,
|
|
@@ -40,10 +40,10 @@ CREATE TABLE IF NOT EXISTS permit (
|
|
|
40
40
|
revoked_by UUID REFERENCES actor(id) ON DELETE SET NULL,
|
|
41
41
|
granted_by UUID REFERENCES actor(id) ON DELETE SET NULL
|
|
42
42
|
)`;
|
|
43
|
-
export const
|
|
44
|
-
`CREATE INDEX IF NOT EXISTS
|
|
45
|
-
`CREATE UNIQUE INDEX IF NOT EXISTS
|
|
46
|
-
ON
|
|
43
|
+
export const ROLE_GRANT_INDEXES = [
|
|
44
|
+
`CREATE INDEX IF NOT EXISTS idx_role_grant_actor ON role_grant(actor_id)`,
|
|
45
|
+
`CREATE UNIQUE INDEX IF NOT EXISTS role_grant_actor_role_active_unique
|
|
46
|
+
ON role_grant (actor_id, role) WHERE revoked_at IS NULL`,
|
|
47
47
|
];
|
|
48
48
|
export const AUTH_SESSION_SCHEMA = `
|
|
49
49
|
CREATE TABLE IF NOT EXISTS auth_session (
|
package/dist/auth/deps.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ import type { Keyring } from './keyring.js';
|
|
|
12
12
|
import type { PasswordHashDeps } from './password.js';
|
|
13
13
|
import type { Db } from '../db/db.js';
|
|
14
14
|
import type { StatResult } from '../runtime/deps.js';
|
|
15
|
-
import type {
|
|
15
|
+
import type { AuditEmitter } from './audit_emitter.js';
|
|
16
16
|
/**
|
|
17
17
|
* Stateless capabilities bundle for fuz_app backends.
|
|
18
18
|
*
|
|
@@ -35,24 +35,13 @@ export interface AppDeps {
|
|
|
35
35
|
/** Structured logger instance. */
|
|
36
36
|
log: Logger;
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
38
|
+
* Bound audit emitter. Closes over the pool, the `on_audit_event`
|
|
39
|
+
* subscriber chain, and the optional `AuditLogConfig`. Built once at
|
|
40
|
+
* backend assembly via `create_audit_emitter` so handlers can never
|
|
41
|
+
* accidentally write audits against the request transaction — there
|
|
42
|
+
* is no pool slot on the handler context.
|
|
42
43
|
*/
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Audit-log config for `audit_log_fire_and_forget` and `query_audit_log`.
|
|
46
|
-
* Built once at startup via `create_audit_log_config({extra_events})` to
|
|
47
|
-
* register consumer event types. Optional — defaults to
|
|
48
|
-
* `BUILTIN_AUDIT_LOG_CONFIG` when absent.
|
|
49
|
-
*
|
|
50
|
-
* Threaded through `AppDeps` (instead of a per-call positional arg) so
|
|
51
|
-
* consumer handlers cannot silently fall back to the builtin config by
|
|
52
|
-
* forgetting to pass theirs — the deps bundle carries it everywhere
|
|
53
|
-
* fuz_app emits an audit event.
|
|
54
|
-
*/
|
|
55
|
-
audit_log_config?: AuditLogConfig;
|
|
44
|
+
audit: AuditEmitter;
|
|
56
45
|
}
|
|
57
46
|
/**
|
|
58
47
|
* Capabilities for route spec factories.
|
|
@@ -61,18 +50,4 @@ export interface AppDeps {
|
|
|
61
50
|
* via `RouteContext`, so factories don't capture a pool-level `Db`.
|
|
62
51
|
*/
|
|
63
52
|
export type RouteFactoryDeps = Omit<AppDeps, 'db'>;
|
|
64
|
-
/**
|
|
65
|
-
* Capabilities required by anything that emits audit events.
|
|
66
|
-
*
|
|
67
|
-
* The slice every audit-emitting site needs: `log` for sibling failure
|
|
68
|
-
* reporting, `on_audit_event` for SSE/WS fan-out, and the optional
|
|
69
|
-
* `audit_log_config` for consumer-extended event-type validation. Used
|
|
70
|
-
* by `audit_log_fire_and_forget` / `emit_permit_target_event` (the
|
|
71
|
-
* primitives) and by every action-factory deps type in `auth/`
|
|
72
|
-
* (`AdminActionDeps`, `AccountActionDeps`, `PermitOfferActionDeps`,
|
|
73
|
-
* `SelfServiceRoleActionDeps`) that runs through them. Lifted here so
|
|
74
|
-
* the five factory deps stop spelling the same `Pick<RouteFactoryDeps,
|
|
75
|
-
* 'log' | 'on_audit_event' | 'audit_log_config'>` independently.
|
|
76
|
-
*/
|
|
77
|
-
export type AuditEmitDeps = Pick<AppDeps, 'log' | 'on_audit_event' | 'audit_log_config'>;
|
|
78
53
|
//# sourceMappingURL=deps.d.ts.map
|
package/dist/auth/deps.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deps.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/deps.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAC,
|
|
1
|
+
{"version":3,"file":"deps.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/deps.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAErD;;;;;GAKG;AACH,MAAM,WAAW,OAAO;IACvB,+DAA+D;IAC/D,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACnD,2BAA2B;IAC3B,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,qBAAqB;IACrB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,0CAA0C;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,6EAA6E;IAC7E,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,yBAAyB;IACzB,EAAE,EAAE,EAAE,CAAC;IACP,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;OAMG;IACH,KAAK,EAAE,YAAY,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grant-path registry — the surfaces through which a role can be
|
|
3
|
+
* granted to an actor.
|
|
4
|
+
*
|
|
5
|
+
* Four builtins:
|
|
6
|
+
*
|
|
7
|
+
* - `admin` — granted by an admin via `role_grant_offer_create` (subject to
|
|
8
|
+
* the consumer's `authorize` callback) or admin-side direct grant.
|
|
9
|
+
* - `self_service` — toggled by the holder themselves via
|
|
10
|
+
* `self_service_role_set` (allowlisted by `eligible_roles`).
|
|
11
|
+
* - `system` — granted by system code paths (signup, automation, etc.)
|
|
12
|
+
* that don't fit either of the above.
|
|
13
|
+
* - `bootstrap` — granted exactly once during the bootstrap flow
|
|
14
|
+
* (`keeper`, `admin` on a fresh install).
|
|
15
|
+
*
|
|
16
|
+
* Open registry on top so consumers can declare additional paths
|
|
17
|
+
* (e.g. `'invite_only'`, `'sso_assertion'`) without an upstream release.
|
|
18
|
+
* `RoleSpec.grant_paths` references entries from this registry; the
|
|
19
|
+
* default for `admin_actions.grantable_roles` is `grant_paths.includes('admin')`,
|
|
20
|
+
* the default for `self_service_role_actions` eligibility is
|
|
21
|
+
* `grant_paths.includes('self_service')`. Mirrors the open-registry
|
|
22
|
+
* pattern used for `RoleName`, `ScopeKindName`, `CredentialTypeName`,
|
|
23
|
+
* and `AuditEventTypeName`.
|
|
24
|
+
*
|
|
25
|
+
* @module
|
|
26
|
+
*/
|
|
27
|
+
import { z } from 'zod';
|
|
28
|
+
/**
|
|
29
|
+
* Letter (lowercase a-z) start and end (or single letter), with letters
|
|
30
|
+
* and underscores in between. Mirrors `RoleName`, `ScopeKindName`,
|
|
31
|
+
* `CredentialTypeName`. Rejects empty strings, leading or trailing
|
|
32
|
+
* underscores, uppercase, and digits.
|
|
33
|
+
*/
|
|
34
|
+
export declare const GRANT_PATH_NAME_REGEX: RegExp;
|
|
35
|
+
/** Zod schema for valid grant-path name strings. */
|
|
36
|
+
export declare const GrantPathName: z.ZodString;
|
|
37
|
+
export type GrantPathName = z.infer<typeof GrantPathName>;
|
|
38
|
+
/** Admin-mediated grant — `role_grant_offer_create` plus admin-direct flows. */
|
|
39
|
+
export declare const GRANT_PATH_ADMIN = "admin";
|
|
40
|
+
/** Self-service grant — caller toggles their own role_grant via `self_service_role_set`. */
|
|
41
|
+
export declare const GRANT_PATH_SELF_SERVICE = "self_service";
|
|
42
|
+
/** System-mediated grant — signup hooks, automation, internal service flows. */
|
|
43
|
+
export declare const GRANT_PATH_SYSTEM = "system";
|
|
44
|
+
/** Bootstrap grant — one-shot flow during the keep's first-run bootstrap. */
|
|
45
|
+
export declare const GRANT_PATH_BOOTSTRAP = "bootstrap";
|
|
46
|
+
/** The builtin grant-path names as a const tuple. */
|
|
47
|
+
export declare const BUILTIN_GRANT_PATHS: readonly ["admin", "self_service", "system", "bootstrap"];
|
|
48
|
+
/** Zod enum for builtin grant paths only. */
|
|
49
|
+
export declare const BuiltinGrantPath: z.ZodEnum<{
|
|
50
|
+
admin: "admin";
|
|
51
|
+
self_service: "self_service";
|
|
52
|
+
system: "system";
|
|
53
|
+
bootstrap: "bootstrap";
|
|
54
|
+
}>;
|
|
55
|
+
export type BuiltinGrantPath = z.infer<typeof BuiltinGrantPath>;
|
|
56
|
+
/**
|
|
57
|
+
* Per-grant-path metadata. `description` is admin-UI-facing copy
|
|
58
|
+
* (mirrors `RoleSpec.description` and `ScopeKindMeta.description`).
|
|
59
|
+
* Open shape so v2 can extend without a breaking change.
|
|
60
|
+
*/
|
|
61
|
+
export interface GrantPathMeta {
|
|
62
|
+
description?: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Builtin grant-path metadata. Not overridable by consumers.
|
|
66
|
+
*
|
|
67
|
+
* Typed `ReadonlyMap` for the contract — but JS Maps don't honor
|
|
68
|
+
* `Object.freeze` for `.set` / `.delete` / `.clear` (they mutate
|
|
69
|
+
* internal slots, not own properties), so freeze adds no runtime guard
|
|
70
|
+
* here. Read once at startup by `create_grant_path_schema`; runtime
|
|
71
|
+
* mutation has no effect on already-built schemas.
|
|
72
|
+
*/
|
|
73
|
+
export declare const BUILTIN_GRANT_PATH_META: ReadonlyMap<string, GrantPathMeta>;
|
|
74
|
+
/** The result of `create_grant_path_schema` — a Zod schema and metadata map. */
|
|
75
|
+
export interface GrantPathSchemaResult {
|
|
76
|
+
/**
|
|
77
|
+
* Zod schema that validates grant-path name strings against the
|
|
78
|
+
* registered set (builtins + consumer-declared). Use at I/O
|
|
79
|
+
* boundaries (admin UIs, codegen) and as the construction-time check
|
|
80
|
+
* inside `create_role_schema` for every `RoleSpec.grant_paths`
|
|
81
|
+
* entry.
|
|
82
|
+
*/
|
|
83
|
+
GrantPath: z.ZodType<string>;
|
|
84
|
+
/**
|
|
85
|
+
* Map of every registered grant-path to its metadata. Keyed by
|
|
86
|
+
* name. Read at startup by admin / codegen surfaces.
|
|
87
|
+
*/
|
|
88
|
+
grant_paths: ReadonlyMap<string, GrantPathMeta>;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Create a grant-path schema from the builtin set plus optional
|
|
92
|
+
* consumer-declared additions.
|
|
93
|
+
*
|
|
94
|
+
* Builtins (`admin`, `self_service`, `system`, `bootstrap`) are always
|
|
95
|
+
* present; consumer entries that collide with a builtin name throw at
|
|
96
|
+
* construction. Pass the result into `create_role_schema`'s optional
|
|
97
|
+
* `grant_paths` parameter so each role's `grant_paths` entries are
|
|
98
|
+
* validated against this set at construction time.
|
|
99
|
+
*
|
|
100
|
+
* @param consumer_paths - optional consumer-declared grant-path set with optional metadata
|
|
101
|
+
* @returns `{GrantPath, grant_paths}` — Zod schema and metadata map
|
|
102
|
+
*
|
|
103
|
+
* @throws Error if any `consumer_paths` key fails the `GrantPathName` regex, collides with a builtin name, or appears more than once
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```ts
|
|
107
|
+
* // simple — builtins only
|
|
108
|
+
* const {GrantPath, grant_paths} = create_grant_path_schema();
|
|
109
|
+
*
|
|
110
|
+
* // with consumer extensions
|
|
111
|
+
* const {GrantPath} = create_grant_path_schema({
|
|
112
|
+
* invite_only: {description: 'Granted by claiming a consumer-issued invite.'},
|
|
113
|
+
* });
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
export declare const create_grant_path_schema: (consumer_paths?: Record<string, GrantPathMeta>) => GrantPathSchemaResult;
|
|
117
|
+
//# sourceMappingURL=grant_path_schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grant_path_schema.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/grant_path_schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,QAAgC,CAAC;AAEnE,oDAAoD;AACpD,eAAO,MAAM,aAAa,aAKxB,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAI1D,gFAAgF;AAChF,eAAO,MAAM,gBAAgB,UAAU,CAAC;AAExC,4FAA4F;AAC5F,eAAO,MAAM,uBAAuB,iBAAiB,CAAC;AAEtD,gFAAgF;AAChF,eAAO,MAAM,iBAAiB,WAAW,CAAC;AAE1C,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,cAAc,CAAC;AAEhD,qDAAqD;AACrD,eAAO,MAAM,mBAAmB,2DAKtB,CAAC;AAEX,6CAA6C;AAC7C,eAAO,MAAM,gBAAgB;;;;;EAA8B,CAAC;AAC5D,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAuBrE,CAAC;AAEH,gFAAgF;AAChF,MAAM,WAAW,qBAAqB;IACrC;;;;;;OAMG;IACH,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7B;;;OAGG;IACH,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CAChD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,wBAAwB,GACpC,iBAAgB,MAAM,CAAC,MAAM,EAAE,aAAa,CAAM,KAChD,qBA2BF,CAAC"}
|