@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
package/dist/ui/CLAUDE.md
CHANGED
|
@@ -7,7 +7,7 @@ hold `$state` fields exclusively via runes. Shared dependencies flow
|
|
|
7
7
|
through Svelte context, never through props — RPC adapters in particular
|
|
8
8
|
are provisioned once at the admin shell and read by every `Admin*.svelte`.
|
|
9
9
|
|
|
10
|
-
See ../../docs/usage.md for end-to-end wiring examples (sections "
|
|
10
|
+
See ../../docs/usage.md for end-to-end wiring examples (sections "Role grant
|
|
11
11
|
offer UI" and "Admin UI"). This file is a reference, not a tutorial.
|
|
12
12
|
|
|
13
13
|
## Key patterns
|
|
@@ -19,8 +19,8 @@ Five narrow RPC adapter contexts — `admin_accounts_rpc_context`,
|
|
|
19
19
|
`app_settings_rpc_context`, `account_sessions_rpc_context` — carry a
|
|
20
20
|
reactive `() => Rpc | null` accessor. All five declare a `() => () => null`
|
|
21
21
|
default so components mounted without a provisioner render the "rpc adapter
|
|
22
|
-
not wired" state instead of crashing. (`
|
|
23
|
-
a `
|
|
22
|
+
not wired" state instead of crashing. (`role_grant_offers_state_context` carries
|
|
23
|
+
a `RoleGrantOffersState` directly, not an RPC accessor, and isn't counted
|
|
24
24
|
here.) The standard consumer shape:
|
|
25
25
|
|
|
26
26
|
```ts
|
|
@@ -43,14 +43,13 @@ context — RPC adapters are never threaded through props.
|
|
|
43
43
|
|
|
44
44
|
Every state class backed by a narrow RPC interface exposes a `has_rpc`
|
|
45
45
|
getter. When `false`, `fetch()`, mutations, and `subscribe` no-op and
|
|
46
|
-
set `error` to `'rpc adapter not wired'`.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
surface.
|
|
46
|
+
set `error` to `'rpc adapter not wired'`. `AdminSessionsState`'s listing
|
|
47
|
+
plus mutations all run through the shared `AdminAccountsRpc`, so
|
|
48
|
+
`has_rpc` gates the whole surface.
|
|
50
49
|
|
|
51
50
|
### `$state.raw` Map keyed by id + `$derived` views
|
|
52
51
|
|
|
53
|
-
`
|
|
52
|
+
`RoleGrantOffersState` maintains a single `Map<string, RoleGrantOfferJson>` in
|
|
54
53
|
`$state.raw`, keyed by offer id, and exposes `incoming` / `outgoing` /
|
|
55
54
|
`history` as `$derived.by` arrays. Writes go through `#merge_offers`
|
|
56
55
|
(clone-and-replace) / `#remove_offer` — never mutate the Map in place
|
|
@@ -58,13 +57,13 @@ because `$state.raw` expects reference swaps.
|
|
|
58
57
|
|
|
59
58
|
### Reducer pattern for WS notifications
|
|
60
59
|
|
|
61
|
-
`
|
|
60
|
+
`RoleGrantOffersState.apply_notification(notification)` is the single
|
|
62
61
|
reducer — `subscribe(subscribe_fn)` is a thin subscription adapter over
|
|
63
|
-
it. Six methods land on the reducer: `
|
|
62
|
+
it. Six methods land on the reducer: `role_grant_offer_received` /
|
|
64
63
|
`_retracted` / `_accepted` / `_declined` / `_supersede` all merge a
|
|
65
|
-
`{offer}` payload; `
|
|
66
|
-
lifecycle lives in auth/
|
|
67
|
-
their payload shapes are defined in `../auth/
|
|
64
|
+
`{offer}` payload; `role_grant_revoke` is ignored at this layer (role_grant
|
|
65
|
+
lifecycle lives in auth/role_grants state). The six notification specs and
|
|
66
|
+
their payload shapes are defined in `../auth/role_grant_offer_notifications.ts`
|
|
68
67
|
(see `../auth/CLAUDE.md` §WS notifications).
|
|
69
68
|
|
|
70
69
|
### Svelte 5 inline `$props` shape
|
|
@@ -76,7 +75,7 @@ conventions.
|
|
|
76
75
|
|
|
77
76
|
### Context over props for shared deps
|
|
78
77
|
|
|
79
|
-
Auth, RPC adapters, sidebar, and
|
|
78
|
+
Auth, RPC adapters, sidebar, and role_grant offers all flow through
|
|
80
79
|
`create_context` from `@fuzdev/fuz_ui/context_helpers.js`. Components
|
|
81
80
|
consume with `const x = x_context.get()` (or a `get_rpc`/`$derived`
|
|
82
81
|
pair when the value may change reactively). New shared state joins the
|
|
@@ -126,9 +125,9 @@ Every admin component below consumes its RPC adapter via the matching
|
|
|
126
125
|
context and delegates rendering to `Datatable` + `ConfirmButton` for
|
|
127
126
|
destructive actions.
|
|
128
127
|
|
|
129
|
-
- `AdminAccounts.svelte` — accounts +
|
|
128
|
+
- `AdminAccounts.svelte` — accounts + role_grants + pending offers.
|
|
130
129
|
Consumes `admin_accounts_rpc_context`. Per-row actions: grant (+role
|
|
131
|
-
chip with `ConfirmButton`), revoke (`actor_id` + `
|
|
130
|
+
chip with `ConfirmButton`), revoke (`actor_id` + `role_grant_id`),
|
|
132
131
|
retract pending offer. Tracks `granting_keys` / `revoking_ids` /
|
|
133
132
|
`retracting_ids` for per-action spinners.
|
|
134
133
|
- `AdminAuditLog.svelte` — audit event stream. Consumes
|
|
@@ -140,11 +139,11 @@ destructive actions.
|
|
|
140
139
|
- `AdminOverview.svelte` — dashboard panels (accounts / sessions /
|
|
141
140
|
invites / recent activity / security / system). Consumes all four
|
|
142
141
|
RPC contexts plus `auth_state_context`; fetches in parallel on mount.
|
|
143
|
-
Derives `role_counts`, `failed_logins`, `
|
|
142
|
+
Derives `role_counts`, `failed_logins`, `role_grant_changes` from
|
|
144
143
|
the audit log.
|
|
145
|
-
- `
|
|
144
|
+
- `AdminRoleGrantHistory.svelte` — role-grant-create/revoke history table.
|
|
146
145
|
Consumes `audit_log_rpc_context`, calls
|
|
147
|
-
`audit_log.
|
|
146
|
+
`audit_log.fetch_role_grant_history()` once on mount.
|
|
148
147
|
- `AdminSessions.svelte` — cross-account active sessions.
|
|
149
148
|
Both listing (`admin_session_list` RPC) and the two revoke-all
|
|
150
149
|
mutations go through `admin_accounts_rpc_context` (reused).
|
|
@@ -161,41 +160,42 @@ destructive actions.
|
|
|
161
160
|
dump `params`/`query`/`input`/`output`/`errors` schemas as JSON.
|
|
162
161
|
Also tables middleware, env, events, and diagnostics.
|
|
163
162
|
|
|
164
|
-
##
|
|
163
|
+
## Role grant offers
|
|
165
164
|
|
|
166
|
-
- `
|
|
167
|
-
`
|
|
165
|
+
- `RoleGrantOfferInbox.svelte` — recipient-side pending inbox; renders
|
|
166
|
+
`RoleGrantOffersState.incoming`. Props: `format_actor?`, `format_scope?`,
|
|
168
167
|
`format_role?` — consumers plug in display names for actor/scope ids.
|
|
169
168
|
Accept is a `PendingButton`; decline is a `ConfirmButton` whose
|
|
170
|
-
popover contains a textarea (max `
|
|
171
|
-
- `
|
|
169
|
+
popover contains a textarea (max `ROLE_GRANT_OFFER_MESSAGE_LENGTH_MAX`).
|
|
170
|
+
- `RoleGrantOfferForm.svelte` — grantor-side create form. Props:
|
|
172
171
|
`to_account_id`, `to_actor_id = null` (optional — narrows the offer
|
|
173
172
|
to a specific actor on the recipient account; default account-grain),
|
|
174
|
-
`roles: Array<string>` (pre-filtered upstream by
|
|
173
|
+
`roles: Array<string>` (pre-filtered upstream by admin-grant-path —
|
|
174
|
+
`RoleSpec.grant_paths` includes `'admin'`),
|
|
175
175
|
`scope_id = null`, `on_created?`, `format_role?`. Surfaces five
|
|
176
|
-
reason codes with friendly copy: `
|
|
177
|
-
`
|
|
178
|
-
`
|
|
179
|
-
— imported from `../auth/
|
|
180
|
-
`../auth/CLAUDE.md` for `
|
|
181
|
-
`
|
|
182
|
-
- `
|
|
176
|
+
reason codes with friendly copy: `ERROR_ROLE_GRANT_OFFER_SELF_TARGET`,
|
|
177
|
+
`ERROR_ROLE_GRANT_OFFER_ROLE_NOT_GRANTABLE`, `ERROR_ROLE_GRANT_OFFER_NOT_AUTHORIZED`,
|
|
178
|
+
`ERROR_ROLE_GRANT_OFFER_ACTOR_ACCOUNT_MISMATCH`, `ERROR_ROLE_GRANT_OFFER_ACTOR_MISMATCH`
|
|
179
|
+
— imported from `../auth/role_grant_offer_action_specs.js` (see
|
|
180
|
+
`../auth/CLAUDE.md` for `role_grant_offer_action_specs.ts` +
|
|
181
|
+
`role_grant_offer_actions.ts`).
|
|
182
|
+
- `RoleGrantOfferHistory.svelte` — both-directions history (recipient +
|
|
183
183
|
grantor, including terminal). Props: `current_actor_id: string | null`
|
|
184
184
|
(classifies row as "sent" vs "received"), `format_actor?`,
|
|
185
185
|
`format_scope?`, `format_role?`. Consumes
|
|
186
|
-
`
|
|
187
|
-
`
|
|
188
|
-
- `
|
|
189
|
-
`Loadable`) + `
|
|
190
|
-
`rpc:
|
|
191
|
-
`actor_id: () => string | null`. The narrow `
|
|
186
|
+
`role_grant_offers_state_context`; caller seeds via
|
|
187
|
+
`RoleGrantOffersState.fetch_history()`.
|
|
188
|
+
- `role_grant_offers_state.svelte.ts` — `RoleGrantOffersState` (extends
|
|
189
|
+
`Loadable`) + `role_grant_offers_state_context`. Options:
|
|
190
|
+
`rpc: RoleGrantOffersRpc`, `account_id: () => string | null`,
|
|
191
|
+
`actor_id: () => string | null`. The narrow `RoleGrantOffersRpc`
|
|
192
192
|
interface has six methods: `list`, `history`, `create`, `accept`,
|
|
193
193
|
`decline`, `retract`. `$state.raw` Map keyed by offer id;
|
|
194
194
|
`$derived.by` views: `incoming` (recipient-side pending, soonest-
|
|
195
195
|
expiry first), `outgoing` (grantor-side pending, newest-created
|
|
196
196
|
first), `history` (all known, newest-created first). Reducer
|
|
197
|
-
`apply_notification` handles the six
|
|
198
|
-
methods; `
|
|
197
|
+
`apply_notification` handles the six role-grant-offer notification
|
|
198
|
+
methods; `role_grant_revoke` is deliberately ignored here (auth/role_grants
|
|
199
199
|
concern). `reset()` clears the Map.
|
|
200
200
|
|
|
201
201
|
## State primitives
|
|
@@ -209,8 +209,8 @@ destructive actions.
|
|
|
209
209
|
- `auth_state.svelte.ts` — `AuthState`, `auth_state_context`.
|
|
210
210
|
Fields: `verifying`, `verified`, `verify_error`, `account`, `actor`
|
|
211
211
|
(the caller's own `ActorSummaryJson` — surfaced directly so consumers
|
|
212
|
-
don't derive `actor_id` from the
|
|
213
|
-
`
|
|
212
|
+
don't derive `actor_id` from the role_grant list), `role_grants`,
|
|
213
|
+
`active_role_grants` (derived via `is_role_grant_active`), `roles` (derived),
|
|
214
214
|
`needs_bootstrap`. Methods: `check_session()`
|
|
215
215
|
(GET `/api/account/status`), `login`, `bootstrap`, `signup`,
|
|
216
216
|
`logout`. Handles 401/403/409/429 translations inline.
|
|
@@ -238,24 +238,24 @@ destructive actions.
|
|
|
238
238
|
`account_session_revoke_all` RPC actions. Derived `active_count`.
|
|
239
239
|
- `audit_log_state.svelte.ts` — `AuditLogState` extends `Loadable`
|
|
240
240
|
- `audit_log_rpc_context` + narrow `AuditLogRpc` (`list` +
|
|
241
|
-
`
|
|
241
|
+
`role_grant_history`). Fields: `events`, `role_grant_history_events`,
|
|
242
242
|
`connected`. Internal `#last_seq` for SSE gap fill on reconnect.
|
|
243
|
-
Methods: `fetch(options?)` (RPC), `
|
|
243
|
+
Methods: `fetch(options?)` (RPC), `fetch_role_grant_history`,
|
|
244
244
|
`subscribe()` (opens `EventSource` at `#stream_url`, default
|
|
245
245
|
`/api/admin/audit/stream`; prepends new events; refills gap
|
|
246
246
|
via `since_seq`), `disconnect()`. SSE stays on `EventSource` —
|
|
247
247
|
streaming is not an RPC concern.
|
|
248
248
|
- `admin_accounts_state.svelte.ts` — `AdminAccountsState` extends
|
|
249
249
|
`Loadable` + `admin_accounts_rpc_context` + narrow
|
|
250
|
-
`AdminAccountsRpc` (six methods: `list_accounts`, `
|
|
251
|
-
`
|
|
250
|
+
`AdminAccountsRpc` (six methods: `list_accounts`, `create_role_grant`,
|
|
251
|
+
`revoke_role_grant`, `retract_offer`, `session_revoke_all`,
|
|
252
252
|
`token_revoke_all` — the last two are also reused by
|
|
253
253
|
`AdminSessionsState`). `SvelteSet`s for in-flight tracking:
|
|
254
254
|
`granting_keys` (`${account_id}:${role}` for the account-grain
|
|
255
|
-
default; `${account_id}:${role}:${to_actor_id}` when `
|
|
256
|
-
is called with an actor-targeted offer), `revoking_ids` (
|
|
257
|
-
`retracting_ids` (offer id). `
|
|
258
|
-
(
|
|
255
|
+
default; `${account_id}:${role}:${to_actor_id}` when `create_role_grant`
|
|
256
|
+
is called with an actor-targeted offer), `revoking_ids` (role_grant id),
|
|
257
|
+
`retracting_ids` (offer id). `revoke_role_grant` keys on `actor_id`
|
|
258
|
+
(role_grants are actor-scoped — matches `row.actor.id` straight from the
|
|
259
259
|
listing) with optional `reason`.
|
|
260
260
|
- `admin_invites_state.svelte.ts` — `AdminInvitesState` extends
|
|
261
261
|
`Loadable` + `admin_invites_rpc_context` + narrow
|
|
@@ -280,8 +280,8 @@ destructive actions.
|
|
|
280
280
|
objects. `provide_admin_rpc_contexts(adapters)` calls `set` on all
|
|
281
281
|
four contexts in one shot. One line at the admin shell layout:
|
|
282
282
|
`provide_admin_rpc_contexts(create_admin_rpc_adapters(api))`.
|
|
283
|
-
Method-name mapping is in the module TSDoc (`
|
|
284
|
-
`
|
|
283
|
+
Method-name mapping is in the module TSDoc (`create_role_grant` →
|
|
284
|
+
`role_grant_offer_create`, `retract_offer` → `role_grant_offer_retract`, etc.)
|
|
285
285
|
and the `admin_rpc_adapters.test.ts` fixtures.
|
|
286
286
|
|
|
287
287
|
## RPC adapter contexts
|
|
@@ -299,24 +299,24 @@ provisioner pattern.
|
|
|
299
299
|
- `admin_invites_rpc_context` — `() => AdminInvitesRpc | null`.
|
|
300
300
|
Consumed by `AdminInvites`, `AdminOverview`.
|
|
301
301
|
- `audit_log_rpc_context` — `() => AuditLogRpc | null`. Consumed by
|
|
302
|
-
`AdminAuditLog`, `
|
|
302
|
+
`AdminAuditLog`, `AdminRoleGrantHistory`, `AdminOverview`.
|
|
303
303
|
- `app_settings_rpc_context` — `() => AppSettingsRpc | null`.
|
|
304
304
|
Consumed by `OpenSignupToggle`, `AdminOverview`.
|
|
305
305
|
- `account_sessions_rpc_context` — `() => AccountSessionsRpc | null`.
|
|
306
306
|
Consumed by `AccountSessions`.
|
|
307
|
-
- `
|
|
308
|
-
directly. Consumed by `
|
|
309
|
-
`
|
|
310
|
-
getters), so there's no separate `
|
|
307
|
+
- `role_grant_offers_state_context` — carries `RoleGrantOffersState`
|
|
308
|
+
directly. Consumed by `RoleGrantOfferInbox`, `RoleGrantOfferForm`,
|
|
309
|
+
`RoleGrantOfferHistory`. Wiring is ctor-bound (RPC + account/actor
|
|
310
|
+
getters), so there's no separate `role_grant_offers_rpc_context`.
|
|
311
311
|
- `format_scope_context` — `() => FormatScope` (getter shape, matching
|
|
312
312
|
the RPC contexts above). `FormatScope = ({scope_id, role}) => string |
|
|
313
313
|
null`; default returns `null` so callers fall back to the raw uuid.
|
|
314
314
|
Provisioned by `provide_admin_rpc_contexts(adapters, {format_scope})`.
|
|
315
|
-
Consumed by `AdminAccounts`, `
|
|
316
|
-
`
|
|
315
|
+
Consumed by `AdminAccounts`, `AdminRoleGrantHistory`, `RoleGrantOfferInbox`,
|
|
316
|
+
`RoleGrantOfferHistory` via the `resolve_scope_label(scope_id, role,
|
|
317
317
|
format_scope, global_label)` helper — `global_label = null` renders no
|
|
318
318
|
chip (admin tables); `'global'` renders an explicit label (offer
|
|
319
|
-
surfaces). `
|
|
319
|
+
surfaces). `RoleGrantOfferInbox` / `RoleGrantOfferHistory` accept a
|
|
320
320
|
`format_scope?: FormatScope` prop — same shape as the context, prop
|
|
321
321
|
wins when supplied.
|
|
322
322
|
- `sidebar_state_context` — `() => SidebarState`. Provisioned by
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
/**
|
|
3
|
-
* Grantor-side
|
|
3
|
+
* Grantor-side role_grant offer form.
|
|
4
4
|
*
|
|
5
5
|
* Caller supplies `to_account_id`, the subset of roles the grantor may
|
|
6
|
-
* offer (typically filtered by
|
|
6
|
+
* offer (typically filtered by admin-grant-path — `RoleSpec.grant_paths`
|
|
7
|
+
* includes `'admin'`), an optional `scope_id`,
|
|
7
8
|
* and an optional `on_created` callback for post-submit UX. Errors from
|
|
8
9
|
* the RPC surface the three distinct reason codes — self-target,
|
|
9
10
|
* role-not-grantable, not-authorized — so consumers can render them
|
|
@@ -12,19 +13,19 @@
|
|
|
12
13
|
|
|
13
14
|
import PendingButton from '@fuzdev/fuz_ui/PendingButton.svelte';
|
|
14
15
|
|
|
15
|
-
import {
|
|
16
|
+
import {role_grant_offers_state_context} from './role_grant_offers_state.svelte.js';
|
|
16
17
|
import {FormState} from './form_state.svelte.js';
|
|
17
18
|
import {
|
|
18
|
-
|
|
19
|
-
type
|
|
20
|
-
} from '../auth/
|
|
19
|
+
ROLE_GRANT_OFFER_MESSAGE_LENGTH_MAX,
|
|
20
|
+
type RoleGrantOfferJson,
|
|
21
|
+
} from '../auth/role_grant_offer_schema.js';
|
|
21
22
|
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
} from '../auth/
|
|
23
|
+
ERROR_ROLE_GRANT_OFFER_ACTOR_ACCOUNT_MISMATCH,
|
|
24
|
+
ERROR_ROLE_GRANT_OFFER_ACTOR_MISMATCH,
|
|
25
|
+
ERROR_ROLE_GRANT_OFFER_NOT_AUTHORIZED,
|
|
26
|
+
ERROR_ROLE_GRANT_OFFER_ROLE_NOT_GRANTABLE,
|
|
27
|
+
ERROR_ROLE_GRANT_OFFER_SELF_TARGET,
|
|
28
|
+
} from '../auth/role_grant_offer_action_specs.js';
|
|
28
29
|
|
|
29
30
|
const {
|
|
30
31
|
to_account_id,
|
|
@@ -41,15 +42,15 @@
|
|
|
41
42
|
* actor on the recipient account may accept.
|
|
42
43
|
*/
|
|
43
44
|
to_actor_id?: string | null;
|
|
44
|
-
/** Roles the caller may offer — caller filters
|
|
45
|
+
/** Roles the caller may offer — caller filters upstream (default: admin-grant-path). */
|
|
45
46
|
roles: Array<string>;
|
|
46
47
|
/** Resource scope for the offer; `null` (default) yields a global offer. */
|
|
47
48
|
scope_id?: string | null;
|
|
48
|
-
on_created?: (offer:
|
|
49
|
+
on_created?: (offer: RoleGrantOfferJson) => void;
|
|
49
50
|
format_role?: (role: string) => string;
|
|
50
51
|
} = $props();
|
|
51
52
|
|
|
52
|
-
const
|
|
53
|
+
const role_grant_offers = role_grant_offers_state_context.get();
|
|
53
54
|
const form_state = new FormState();
|
|
54
55
|
|
|
55
56
|
let role: string | undefined = $state.raw();
|
|
@@ -57,19 +58,19 @@
|
|
|
57
58
|
let message = $state.raw('');
|
|
58
59
|
let local_error: string | null = $state.raw(null);
|
|
59
60
|
|
|
60
|
-
const submitting = $derived(
|
|
61
|
+
const submitting = $derived(role_grant_offers.loading);
|
|
61
62
|
|
|
62
63
|
const surface_error = (reason: string | null): string | null => {
|
|
63
64
|
switch (reason) {
|
|
64
|
-
case
|
|
65
|
-
return 'You cannot offer a
|
|
66
|
-
case
|
|
65
|
+
case ERROR_ROLE_GRANT_OFFER_SELF_TARGET:
|
|
66
|
+
return 'You cannot offer a role_grant to yourself.';
|
|
67
|
+
case ERROR_ROLE_GRANT_OFFER_ROLE_NOT_GRANTABLE:
|
|
67
68
|
return 'That role cannot be offered through this form.';
|
|
68
|
-
case
|
|
69
|
+
case ERROR_ROLE_GRANT_OFFER_NOT_AUTHORIZED:
|
|
69
70
|
return 'You are not authorized to offer that role.';
|
|
70
|
-
case
|
|
71
|
+
case ERROR_ROLE_GRANT_OFFER_ACTOR_ACCOUNT_MISMATCH:
|
|
71
72
|
return 'That actor is not on the recipient account.';
|
|
72
|
-
case
|
|
73
|
+
case ERROR_ROLE_GRANT_OFFER_ACTOR_MISMATCH:
|
|
73
74
|
return 'This offer is for a different actor on the recipient account.';
|
|
74
75
|
default:
|
|
75
76
|
return null;
|
|
@@ -83,7 +84,7 @@
|
|
|
83
84
|
form_state.focus('role');
|
|
84
85
|
return;
|
|
85
86
|
}
|
|
86
|
-
const offer = await
|
|
87
|
+
const offer = await role_grant_offers.create({
|
|
87
88
|
to_account_id,
|
|
88
89
|
to_actor_id,
|
|
89
90
|
role: selected_role,
|
|
@@ -97,12 +98,12 @@
|
|
|
97
98
|
return;
|
|
98
99
|
}
|
|
99
100
|
// Structured error data carries the reason; fall back to raw error string.
|
|
100
|
-
const data =
|
|
101
|
+
const data = role_grant_offers.error_data as
|
|
101
102
|
| {data?: {reason?: string}; reason?: string}
|
|
102
103
|
| null
|
|
103
104
|
| undefined;
|
|
104
105
|
const reason = data?.data?.reason ?? data?.reason ?? null;
|
|
105
|
-
local_error = surface_error(reason) ??
|
|
106
|
+
local_error = surface_error(reason) ?? role_grant_offers.error;
|
|
106
107
|
};
|
|
107
108
|
</script>
|
|
108
109
|
|
|
@@ -133,7 +134,7 @@
|
|
|
133
134
|
<textarea
|
|
134
135
|
name="message"
|
|
135
136
|
bind:value={message}
|
|
136
|
-
maxlength={
|
|
137
|
+
maxlength={ROLE_GRANT_OFFER_MESSAGE_LENGTH_MAX}
|
|
137
138
|
placeholder="optional note for the recipient"
|
|
138
139
|
disabled={submitting}
|
|
139
140
|
></textarea>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type RoleGrantOfferJson } from '../auth/role_grant_offer_schema.js';
|
|
2
2
|
type $$ComponentProps = {
|
|
3
3
|
to_account_id: string;
|
|
4
4
|
/**
|
|
@@ -7,14 +7,14 @@ type $$ComponentProps = {
|
|
|
7
7
|
* actor on the recipient account may accept.
|
|
8
8
|
*/
|
|
9
9
|
to_actor_id?: string | null;
|
|
10
|
-
/** Roles the caller may offer — caller filters
|
|
10
|
+
/** Roles the caller may offer — caller filters upstream (default: admin-grant-path). */
|
|
11
11
|
roles: Array<string>;
|
|
12
12
|
/** Resource scope for the offer; `null` (default) yields a global offer. */
|
|
13
13
|
scope_id?: string | null;
|
|
14
|
-
on_created?: (offer:
|
|
14
|
+
on_created?: (offer: RoleGrantOfferJson) => void;
|
|
15
15
|
format_role?: (role: string) => string;
|
|
16
16
|
};
|
|
17
|
-
declare const
|
|
18
|
-
type
|
|
19
|
-
export default
|
|
20
|
-
//# sourceMappingURL=
|
|
17
|
+
declare const RoleGrantOfferForm: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
18
|
+
type RoleGrantOfferForm = ReturnType<typeof RoleGrantOfferForm>;
|
|
19
|
+
export default RoleGrantOfferForm;
|
|
20
|
+
//# sourceMappingURL=RoleGrantOfferForm.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RoleGrantOfferForm.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/RoleGrantOfferForm.svelte"],"names":[],"mappings":"AAkBA,OAAO,EAEL,KAAK,kBAAkB,EACvB,MAAM,oCAAoC,CAAC;AAS5C,KAAK,gBAAgB,GAAI;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,wFAAwF;IACxF,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACrB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACjD,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACvC,CAAC;AA4GH,QAAA,MAAM,kBAAkB,sDAAwC,CAAC;AACjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,eAAe,kBAAkB,CAAC"}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
/**
|
|
3
|
-
* Both-directions
|
|
3
|
+
* Both-directions role_grant offer history table.
|
|
4
4
|
*
|
|
5
5
|
* Shows every offer involving the current account — recipient or grantor
|
|
6
6
|
* — including terminal rows (accepted, declined, retracted, superseded,
|
|
7
|
-
* expired). Backed by `
|
|
8
|
-
* via `
|
|
7
|
+
* expired). Backed by `role_grant_offer_history` (new RPC action); seeded
|
|
8
|
+
* via `RoleGrantOffersState.fetch_history()`.
|
|
9
9
|
*
|
|
10
10
|
* Consumers plug in optional `format_actor` / `format_scope` callbacks
|
|
11
11
|
* for display names.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import {
|
|
14
|
+
import {role_grant_offers_state_context} from './role_grant_offers_state.svelte.js';
|
|
15
15
|
import Datatable from './Datatable.svelte';
|
|
16
16
|
import type {DatatableColumn} from './datatable.js';
|
|
17
17
|
import {format_relative_time, format_datetime_local, truncate_uuid} from './ui_format.js';
|
|
18
|
-
import type {
|
|
18
|
+
import type {RoleGrantOfferJson} from '../auth/role_grant_offer_schema.js';
|
|
19
19
|
import {format_scope_context, resolve_scope_label, type FormatScope} from './format_scope.js';
|
|
20
20
|
|
|
21
21
|
const {
|
|
@@ -36,13 +36,13 @@
|
|
|
36
36
|
format_role?: (role: string) => string;
|
|
37
37
|
} = $props();
|
|
38
38
|
|
|
39
|
-
const
|
|
39
|
+
const role_grant_offers = role_grant_offers_state_context.get();
|
|
40
40
|
const get_format_scope = format_scope_context.get();
|
|
41
41
|
const format_scope_from_context = $derived(get_format_scope());
|
|
42
42
|
|
|
43
43
|
const now = $state.raw(Date.now());
|
|
44
44
|
|
|
45
|
-
const status_of = (offer:
|
|
45
|
+
const status_of = (offer: RoleGrantOfferJson): string => {
|
|
46
46
|
if (offer.accepted_at) return 'accepted';
|
|
47
47
|
if (offer.declined_at) return 'declined';
|
|
48
48
|
if (offer.retracted_at) return 'retracted';
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
const scope_label = (scope_id: string | null, role: string): string =>
|
|
71
71
|
resolve_scope_label(scope_id, role, format_scope ?? format_scope_from_context, 'global');
|
|
72
72
|
|
|
73
|
-
const columns: Array<DatatableColumn<
|
|
73
|
+
const columns: Array<DatatableColumn<RoleGrantOfferJson>> = [
|
|
74
74
|
{key: 'from_actor_id', label: 'direction', width: 110},
|
|
75
75
|
{key: 'role', label: 'role', width: 140},
|
|
76
76
|
{key: 'scope_id', label: 'scope', width: 160},
|
|
@@ -82,12 +82,12 @@
|
|
|
82
82
|
<section>
|
|
83
83
|
<h2>offer history</h2>
|
|
84
84
|
|
|
85
|
-
{#if
|
|
85
|
+
{#if role_grant_offers.loading}
|
|
86
86
|
<p class="text_50">loading history...</p>
|
|
87
|
-
{:else if
|
|
88
|
-
<p class="color_c_50">{
|
|
87
|
+
{:else if role_grant_offers.error}
|
|
88
|
+
<p class="color_c_50">{role_grant_offers.error}</p>
|
|
89
89
|
{:else}
|
|
90
|
-
<Datatable {columns} rows={
|
|
90
|
+
<Datatable {columns} rows={role_grant_offers.history} height="400px" row_key="id">
|
|
91
91
|
{#snippet cell(column, row)}
|
|
92
92
|
{#if column.key === 'from_actor_id'}
|
|
93
93
|
{#if current_actor_id && row.from_actor_id === current_actor_id}
|
|
@@ -11,7 +11,7 @@ type $$ComponentProps = {
|
|
|
11
11
|
format_scope?: FormatScope;
|
|
12
12
|
format_role?: (role: string) => string;
|
|
13
13
|
};
|
|
14
|
-
declare const
|
|
15
|
-
type
|
|
16
|
-
export default
|
|
17
|
-
//# sourceMappingURL=
|
|
14
|
+
declare const RoleGrantOfferHistory: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
15
|
+
type RoleGrantOfferHistory = ReturnType<typeof RoleGrantOfferHistory>;
|
|
16
|
+
export default RoleGrantOfferHistory;
|
|
17
|
+
//# sourceMappingURL=RoleGrantOfferHistory.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RoleGrantOfferHistory.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/RoleGrantOfferHistory.svelte"],"names":[],"mappings":"AAmBA,OAAO,EAA4C,KAAK,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAE7F,KAAK,gBAAgB,GAAI;IACxB,oFAAoF;IACpF,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,YAAY,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,CAAC;IACjD;;;;OAIG;IACH,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACvC,CAAC;AAkGH,QAAA,MAAM,qBAAqB,sDAAwC,CAAC;AACpE,KAAK,qBAAqB,GAAG,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACtE,eAAe,qBAAqB,CAAC"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Recipient-side pending offer inbox.
|
|
4
4
|
*
|
|
5
|
-
* Renders `
|
|
5
|
+
* Renders `RoleGrantOffersState.incoming` (pending, soonest-expiry first)
|
|
6
6
|
* with accept + decline-with-reason controls. Grantor and scope rendering
|
|
7
7
|
* are delegated via optional callback props — consumers plug in display
|
|
8
8
|
* names once they know what a `from_actor_id` / `scope_id` represents
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
import PendingButton from '@fuzdev/fuz_ui/PendingButton.svelte';
|
|
13
13
|
import {SvelteMap} from 'svelte/reactivity';
|
|
14
14
|
|
|
15
|
-
import {
|
|
15
|
+
import {role_grant_offers_state_context} from './role_grant_offers_state.svelte.js';
|
|
16
16
|
import ConfirmButton from './ConfirmButton.svelte';
|
|
17
17
|
import {format_relative_time, format_datetime_local, truncate_uuid} from './ui_format.js';
|
|
18
|
-
import {
|
|
18
|
+
import {ROLE_GRANT_OFFER_MESSAGE_LENGTH_MAX} from '../auth/role_grant_offer_schema.js';
|
|
19
19
|
import {format_scope_context, resolve_scope_label, type FormatScope} from './format_scope.js';
|
|
20
20
|
|
|
21
21
|
const {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
format_role?: (role: string) => string;
|
|
36
36
|
} = $props();
|
|
37
37
|
|
|
38
|
-
const
|
|
38
|
+
const role_grant_offers = role_grant_offers_state_context.get();
|
|
39
39
|
const get_format_scope = format_scope_context.get();
|
|
40
40
|
const format_scope_from_context = $derived(get_format_scope());
|
|
41
41
|
|
|
@@ -45,18 +45,18 @@
|
|
|
45
45
|
const decline_reasons: SvelteMap<string, string> = new SvelteMap();
|
|
46
46
|
</script>
|
|
47
47
|
|
|
48
|
-
<section class="
|
|
48
|
+
<section class="role-grant-offer-inbox">
|
|
49
49
|
<h2>pending offers</h2>
|
|
50
50
|
|
|
51
|
-
{#if
|
|
52
|
-
<p class="color_c_50">{
|
|
51
|
+
{#if role_grant_offers.error}
|
|
52
|
+
<p class="color_c_50">{role_grant_offers.error}</p>
|
|
53
53
|
{/if}
|
|
54
54
|
|
|
55
|
-
{#if
|
|
55
|
+
{#if role_grant_offers.incoming.length === 0}
|
|
56
56
|
<p class="text_50">No pending offers.</p>
|
|
57
57
|
{:else}
|
|
58
58
|
<ul class="column gap_md">
|
|
59
|
-
{#each
|
|
59
|
+
{#each role_grant_offers.incoming as offer (offer.id)}
|
|
60
60
|
<li class="box p_md column gap_sm">
|
|
61
61
|
<div class="row gap_sm align_center">
|
|
62
62
|
<span class="chip color_a">{format_role(offer.role)}</span>
|
|
@@ -76,9 +76,9 @@
|
|
|
76
76
|
|
|
77
77
|
<div class="row gap_sm">
|
|
78
78
|
<PendingButton
|
|
79
|
-
pending={
|
|
80
|
-
disabled={
|
|
81
|
-
onclick={() =>
|
|
79
|
+
pending={role_grant_offers.loading}
|
|
80
|
+
disabled={role_grant_offers.loading}
|
|
81
|
+
onclick={() => role_grant_offers.accept(offer.id)}
|
|
82
82
|
class="color_b"
|
|
83
83
|
>
|
|
84
84
|
accept
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
position="bottom"
|
|
90
90
|
onconfirm={() => {
|
|
91
91
|
const reason = decline_reasons.get(offer.id) ?? '';
|
|
92
|
-
void
|
|
92
|
+
void role_grant_offers.decline(offer.id, reason || null);
|
|
93
93
|
decline_reasons.delete(offer.id);
|
|
94
94
|
}}
|
|
95
95
|
>
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
<div class="title">reason (optional)</div>
|
|
103
103
|
<textarea
|
|
104
104
|
name="decline-reason"
|
|
105
|
-
maxlength={
|
|
105
|
+
maxlength={ROLE_GRANT_OFFER_MESSAGE_LENGTH_MAX}
|
|
106
106
|
placeholder="optional reason"
|
|
107
107
|
value={decline_reasons.get(offer.id) ?? ''}
|
|
108
108
|
oninput={(e) =>
|
|
@@ -11,7 +11,7 @@ type $$ComponentProps = {
|
|
|
11
11
|
/** Display label for a role constant. Defaults to identity. */
|
|
12
12
|
format_role?: (role: string) => string;
|
|
13
13
|
};
|
|
14
|
-
declare const
|
|
15
|
-
type
|
|
16
|
-
export default
|
|
17
|
-
//# sourceMappingURL=
|
|
14
|
+
declare const RoleGrantOfferInbox: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
15
|
+
type RoleGrantOfferInbox = ReturnType<typeof RoleGrantOfferInbox>;
|
|
16
|
+
export default RoleGrantOfferInbox;
|
|
17
|
+
//# sourceMappingURL=RoleGrantOfferInbox.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RoleGrantOfferInbox.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/RoleGrantOfferInbox.svelte"],"names":[],"mappings":"AAmBA,OAAO,EAA4C,KAAK,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAE7F,KAAK,gBAAgB,GAAI;IACxB,uEAAuE;IACvE,YAAY,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,CAAC;IACjD;;;;OAIG;IACH,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,+DAA+D;IAC/D,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACvC,CAAC;AA2FH,QAAA,MAAM,mBAAmB,sDAAwC,CAAC;AAClE,KAAK,mBAAmB,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAClE,eAAe,mBAAmB,CAAC"}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
import PendingButton from '@fuzdev/fuz_ui/PendingButton.svelte';
|
|
17
17
|
import {autofocus} from '@fuzdev/fuz_ui/autofocus.svelte.js';
|
|
18
18
|
|
|
19
|
-
import {Username} from '../
|
|
19
|
+
import {Username} from '../primitive_schemas.js';
|
|
20
20
|
import {PASSWORD_LENGTH_MIN} from '../auth/password.js';
|
|
21
21
|
import {auth_state_context} from './auth_state.svelte.js';
|
|
22
22
|
import {FormState} from './form_state.svelte.js';
|