@fuzdev/fuz_app 0.30.0 → 0.31.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 +630 -0
- package/dist/actions/action_rpc.d.ts +29 -0
- package/dist/actions/action_rpc.d.ts.map +1 -1
- package/dist/actions/action_rpc.js +42 -6
- package/dist/actions/action_types.d.ts +2 -2
- package/dist/actions/cancel.d.ts +12 -13
- package/dist/actions/cancel.d.ts.map +1 -1
- package/dist/actions/cancel.js +10 -13
- package/dist/actions/heartbeat.d.ts +8 -13
- package/dist/actions/heartbeat.d.ts.map +1 -1
- package/dist/actions/heartbeat.js +5 -8
- package/dist/actions/register_action_ws.d.ts +3 -3
- package/dist/actions/register_action_ws.js +2 -2
- package/dist/actions/register_ws_endpoint.d.ts +4 -4
- package/dist/actions/register_ws_endpoint.d.ts.map +1 -1
- package/dist/actions/register_ws_endpoint.js +3 -3
- package/dist/actions/socket.svelte.d.ts +16 -16
- package/dist/actions/socket.svelte.d.ts.map +1 -1
- package/dist/actions/socket.svelte.js +15 -15
- package/dist/actions/transports_ws_auth_guard.d.ts.map +1 -1
- package/dist/auth/CLAUDE.md +923 -0
- package/dist/auth/account_action_specs.d.ts +216 -0
- package/dist/auth/account_action_specs.d.ts.map +1 -0
- package/dist/auth/account_action_specs.js +159 -0
- package/dist/auth/account_actions.d.ts +51 -0
- package/dist/auth/account_actions.d.ts.map +1 -0
- package/dist/auth/account_actions.js +119 -0
- package/dist/auth/account_queries.d.ts +6 -2
- package/dist/auth/account_queries.d.ts.map +1 -1
- package/dist/auth/account_queries.js +40 -4
- package/dist/auth/account_routes.d.ts +94 -16
- package/dist/auth/account_routes.d.ts.map +1 -1
- package/dist/auth/account_routes.js +108 -180
- package/dist/auth/account_schema.d.ts +85 -30
- package/dist/auth/account_schema.d.ts.map +1 -1
- package/dist/auth/account_schema.js +40 -8
- package/dist/auth/admin_action_specs.d.ts +674 -0
- package/dist/auth/admin_action_specs.d.ts.map +1 -0
- package/dist/auth/admin_action_specs.js +287 -0
- package/dist/auth/admin_actions.d.ts +69 -0
- package/dist/auth/admin_actions.d.ts.map +1 -0
- package/dist/auth/admin_actions.js +256 -0
- package/dist/auth/api_token.d.ts +10 -0
- package/dist/auth/api_token.d.ts.map +1 -1
- package/dist/auth/api_token.js +9 -0
- package/dist/auth/api_token_queries.d.ts +3 -3
- package/dist/auth/api_token_queries.js +3 -3
- package/dist/auth/app_settings_schema.d.ts +4 -3
- package/dist/auth/app_settings_schema.d.ts.map +1 -1
- package/dist/auth/app_settings_schema.js +2 -1
- package/dist/auth/audit_log_routes.d.ts +14 -6
- package/dist/auth/audit_log_routes.d.ts.map +1 -1
- package/dist/auth/audit_log_routes.js +22 -79
- package/dist/auth/audit_log_schema.d.ts +100 -29
- package/dist/auth/audit_log_schema.d.ts.map +1 -1
- package/dist/auth/audit_log_schema.js +83 -11
- package/dist/auth/bootstrap_routes.d.ts +14 -0
- package/dist/auth/bootstrap_routes.d.ts.map +1 -1
- package/dist/auth/bootstrap_routes.js +10 -3
- package/dist/auth/cleanup.d.ts +63 -0
- package/dist/auth/cleanup.d.ts.map +1 -0
- package/dist/auth/cleanup.js +80 -0
- package/dist/auth/invite_schema.d.ts +11 -10
- package/dist/auth/invite_schema.d.ts.map +1 -1
- package/dist/auth/invite_schema.js +4 -3
- package/dist/auth/migrations.d.ts +6 -0
- package/dist/auth/migrations.d.ts.map +1 -1
- package/dist/auth/migrations.js +28 -0
- package/dist/auth/permit_offer_action_specs.d.ts +364 -0
- package/dist/auth/permit_offer_action_specs.d.ts.map +1 -0
- package/dist/auth/permit_offer_action_specs.js +216 -0
- package/dist/auth/permit_offer_actions.d.ts +96 -0
- package/dist/auth/permit_offer_actions.d.ts.map +1 -0
- package/dist/auth/permit_offer_actions.js +428 -0
- package/dist/auth/permit_offer_notifications.d.ts +361 -0
- package/dist/auth/permit_offer_notifications.d.ts.map +1 -0
- package/dist/auth/permit_offer_notifications.js +179 -0
- package/dist/auth/permit_offer_queries.d.ts +165 -0
- package/dist/auth/permit_offer_queries.d.ts.map +1 -0
- package/dist/auth/permit_offer_queries.js +390 -0
- package/dist/auth/permit_offer_schema.d.ts +103 -0
- package/dist/auth/permit_offer_schema.d.ts.map +1 -0
- package/dist/auth/permit_offer_schema.js +142 -0
- package/dist/auth/permit_queries.d.ts +77 -14
- package/dist/auth/permit_queries.d.ts.map +1 -1
- package/dist/auth/permit_queries.js +119 -24
- package/dist/auth/session_queries.d.ts +4 -2
- package/dist/auth/session_queries.d.ts.map +1 -1
- package/dist/auth/session_queries.js +4 -2
- package/dist/auth/signup_routes.d.ts +13 -0
- package/dist/auth/signup_routes.d.ts.map +1 -1
- package/dist/auth/signup_routes.js +14 -7
- package/dist/http/CLAUDE.md +584 -0
- package/dist/http/pending_effects.d.ts +29 -0
- package/dist/http/pending_effects.d.ts.map +1 -0
- package/dist/http/pending_effects.js +31 -0
- package/dist/http/route_spec.d.ts.map +1 -1
- package/dist/http/route_spec.js +4 -3
- package/dist/rate_limiter.d.ts +30 -0
- package/dist/rate_limiter.d.ts.map +1 -1
- package/dist/rate_limiter.js +25 -2
- package/dist/realtime/sse_auth_guard.d.ts +2 -0
- package/dist/realtime/sse_auth_guard.d.ts.map +1 -1
- package/dist/realtime/sse_auth_guard.js +5 -3
- package/dist/testing/CLAUDE.md +668 -1
- package/dist/testing/admin_integration.d.ts +10 -7
- package/dist/testing/admin_integration.d.ts.map +1 -1
- package/dist/testing/admin_integration.js +382 -482
- package/dist/testing/app_server.d.ts +7 -6
- package/dist/testing/app_server.d.ts.map +1 -1
- package/dist/testing/attack_surface.d.ts +9 -3
- package/dist/testing/attack_surface.d.ts.map +1 -1
- package/dist/testing/attack_surface.js +4 -4
- package/dist/testing/audit_completeness.d.ts +6 -0
- package/dist/testing/audit_completeness.d.ts.map +1 -1
- package/dist/testing/audit_completeness.js +158 -134
- package/dist/testing/auth_apps.d.ts.map +1 -1
- package/dist/testing/auth_apps.js +4 -33
- package/dist/testing/db.d.ts +1 -1
- package/dist/testing/db.d.ts.map +1 -1
- package/dist/testing/db.js +2 -0
- package/dist/testing/entities.d.ts +35 -13
- package/dist/testing/entities.d.ts.map +1 -1
- package/dist/testing/entities.js +17 -0
- package/dist/testing/integration.d.ts +10 -0
- package/dist/testing/integration.d.ts.map +1 -1
- package/dist/testing/integration.js +352 -340
- package/dist/testing/integration_helpers.d.ts +16 -5
- package/dist/testing/integration_helpers.d.ts.map +1 -1
- package/dist/testing/integration_helpers.js +24 -4
- package/dist/testing/rate_limiting.d.ts +7 -0
- package/dist/testing/rate_limiting.d.ts.map +1 -1
- package/dist/testing/rate_limiting.js +41 -10
- package/dist/testing/rpc_helpers.d.ts +153 -1
- package/dist/testing/rpc_helpers.d.ts.map +1 -1
- package/dist/testing/rpc_helpers.js +184 -8
- package/dist/testing/sse_round_trip.d.ts +8 -0
- package/dist/testing/sse_round_trip.d.ts.map +1 -1
- package/dist/testing/sse_round_trip.js +10 -3
- package/dist/testing/standard.d.ts +9 -1
- package/dist/testing/standard.d.ts.map +1 -1
- package/dist/testing/standard.js +6 -2
- package/dist/testing/surface_invariants.d.ts +7 -3
- package/dist/testing/surface_invariants.d.ts.map +1 -1
- package/dist/testing/surface_invariants.js +5 -4
- package/dist/testing/ws_round_trip.d.ts.map +1 -1
- package/dist/testing/ws_round_trip.js +9 -38
- package/dist/ui/AccountSessions.svelte +8 -4
- package/dist/ui/AccountSessions.svelte.d.ts.map +1 -1
- package/dist/ui/AdminAccounts.svelte +61 -33
- package/dist/ui/AdminAccounts.svelte.d.ts.map +1 -1
- package/dist/ui/AdminAuditLog.svelte +3 -2
- package/dist/ui/AdminAuditLog.svelte.d.ts.map +1 -1
- package/dist/ui/AdminInvites.svelte +3 -2
- package/dist/ui/AdminInvites.svelte.d.ts.map +1 -1
- package/dist/ui/AdminOverview.svelte +14 -9
- package/dist/ui/AdminOverview.svelte.d.ts.map +1 -1
- package/dist/ui/AdminPermitHistory.svelte +3 -2
- package/dist/ui/AdminPermitHistory.svelte.d.ts.map +1 -1
- package/dist/ui/AdminSessions.svelte +29 -25
- package/dist/ui/AdminSessions.svelte.d.ts.map +1 -1
- package/dist/ui/CLAUDE.md +351 -0
- package/dist/ui/OpenSignupToggle.svelte +6 -3
- package/dist/ui/OpenSignupToggle.svelte.d.ts.map +1 -1
- package/dist/ui/PermitOfferForm.svelte +141 -0
- package/dist/ui/PermitOfferForm.svelte.d.ts +14 -0
- package/dist/ui/PermitOfferForm.svelte.d.ts.map +1 -0
- package/dist/ui/PermitOfferHistory.svelte +109 -0
- package/dist/ui/PermitOfferHistory.svelte.d.ts +11 -0
- package/dist/ui/PermitOfferHistory.svelte.d.ts.map +1 -0
- package/dist/ui/PermitOfferInbox.svelte +121 -0
- package/dist/ui/PermitOfferInbox.svelte.d.ts +12 -0
- package/dist/ui/PermitOfferInbox.svelte.d.ts.map +1 -0
- package/dist/ui/account_sessions_state.svelte.d.ts +53 -3
- package/dist/ui/account_sessions_state.svelte.d.ts.map +1 -1
- package/dist/ui/account_sessions_state.svelte.js +39 -16
- package/dist/ui/admin_accounts_state.svelte.d.ts +118 -2
- package/dist/ui/admin_accounts_state.svelte.d.ts.map +1 -1
- package/dist/ui/admin_accounts_state.svelte.js +99 -23
- package/dist/ui/admin_invites_state.svelte.d.ts +47 -1
- package/dist/ui/admin_invites_state.svelte.d.ts.map +1 -1
- package/dist/ui/admin_invites_state.svelte.js +38 -26
- package/dist/ui/admin_sessions_state.svelte.d.ts +26 -0
- package/dist/ui/admin_sessions_state.svelte.d.ts.map +1 -1
- package/dist/ui/admin_sessions_state.svelte.js +35 -21
- package/dist/ui/app_settings_state.svelte.d.ts +39 -0
- package/dist/ui/app_settings_state.svelte.d.ts.map +1 -1
- package/dist/ui/app_settings_state.svelte.js +34 -18
- package/dist/ui/audit_log_state.svelte.d.ts +40 -3
- package/dist/ui/audit_log_state.svelte.d.ts.map +1 -1
- package/dist/ui/audit_log_state.svelte.js +36 -42
- package/dist/ui/auth_state.svelte.d.ts +4 -3
- package/dist/ui/auth_state.svelte.d.ts.map +1 -1
- package/dist/ui/auth_state.svelte.js +4 -1
- package/dist/ui/permit_offers_state.svelte.d.ts +125 -0
- package/dist/ui/permit_offers_state.svelte.d.ts.map +1 -0
- package/dist/ui/permit_offers_state.svelte.js +197 -0
- package/package.json +3 -3
- package/dist/auth/admin_routes.d.ts +0 -29
- package/dist/auth/admin_routes.d.ts.map +0 -1
- package/dist/auth/admin_routes.js +0 -226
- package/dist/auth/app_settings_routes.d.ts +0 -27
- package/dist/auth/app_settings_routes.d.ts.map +0 -1
- package/dist/auth/app_settings_routes.js +0 -66
- package/dist/auth/invite_routes.d.ts +0 -18
- package/dist/auth/invite_routes.d.ts.map +0 -1
- package/dist/auth/invite_routes.js +0 -129
|
@@ -1,45 +1,56 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Reactive state for admin invite management.
|
|
3
3
|
*
|
|
4
|
+
* Flows every operation through an injected `AdminInvitesRpc` adapter — the
|
|
5
|
+
* class stays decoupled from the concrete RPC client so tests can inject
|
|
6
|
+
* plain-function stubs. Mirrors `AdminAccountsRpc` / `AuditLogRpc`.
|
|
7
|
+
*
|
|
4
8
|
* @module
|
|
5
9
|
*/
|
|
6
10
|
import { SvelteSet } from 'svelte/reactivity';
|
|
11
|
+
import { create_context } from '@fuzdev/fuz_ui/context_helpers.js';
|
|
7
12
|
import { Loadable } from './loadable.svelte.js';
|
|
8
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Svelte context carrying the reactive `AdminInvitesRpc` accessor. Mirrors
|
|
15
|
+
* `admin_accounts_rpc_context`. Unset context falls back to `() => null`.
|
|
16
|
+
*/
|
|
17
|
+
export const admin_invites_rpc_context = create_context(() => () => null);
|
|
9
18
|
export class AdminInvitesState extends Loadable {
|
|
19
|
+
#get_rpc;
|
|
10
20
|
invites = $state.raw([]);
|
|
11
21
|
creating = $state.raw(false);
|
|
12
22
|
deleting_ids = new SvelteSet();
|
|
13
23
|
invite_count = $derived(this.invites.length);
|
|
14
24
|
unclaimed_count = $derived(this.invites.filter((i) => !i.claimed_at).length);
|
|
25
|
+
constructor(options) {
|
|
26
|
+
super();
|
|
27
|
+
this.#get_rpc = options?.get_rpc ?? (() => null);
|
|
28
|
+
}
|
|
29
|
+
/** True when an RPC adapter is wired. All ops require it. */
|
|
30
|
+
get has_rpc() {
|
|
31
|
+
return this.#get_rpc() !== null;
|
|
32
|
+
}
|
|
15
33
|
async fetch() {
|
|
34
|
+
const rpc = this.#get_rpc();
|
|
35
|
+
if (!rpc) {
|
|
36
|
+
this.error = 'rpc adapter not wired';
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
16
39
|
await this.run(async () => {
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
throw new Error(await parse_response_error(response, 'Failed to fetch invites'));
|
|
20
|
-
}
|
|
21
|
-
const data = await response.json();
|
|
22
|
-
this.invites = data.invites ?? [];
|
|
40
|
+
const { invites } = await rpc.list();
|
|
41
|
+
this.invites = invites;
|
|
23
42
|
});
|
|
24
43
|
}
|
|
25
44
|
async create_invite(email, username) {
|
|
45
|
+
const rpc = this.#get_rpc();
|
|
46
|
+
if (!rpc) {
|
|
47
|
+
this.error = 'rpc adapter not wired';
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
26
50
|
this.creating = true;
|
|
27
51
|
this.error = null;
|
|
28
52
|
try {
|
|
29
|
-
|
|
30
|
-
if (email)
|
|
31
|
-
body.email = email;
|
|
32
|
-
if (username)
|
|
33
|
-
body.username = username;
|
|
34
|
-
const response = await ui_fetch('/api/admin/invites', {
|
|
35
|
-
method: 'POST',
|
|
36
|
-
headers: { 'Content-Type': 'application/json' },
|
|
37
|
-
body: JSON.stringify(body),
|
|
38
|
-
});
|
|
39
|
-
if (!response.ok) {
|
|
40
|
-
this.error = await parse_response_error(response);
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
53
|
+
await rpc.create({ email: email ?? null, username: username ?? null });
|
|
43
54
|
await this.fetch();
|
|
44
55
|
return true;
|
|
45
56
|
}
|
|
@@ -52,13 +63,14 @@ export class AdminInvitesState extends Loadable {
|
|
|
52
63
|
}
|
|
53
64
|
}
|
|
54
65
|
async delete_invite(id) {
|
|
66
|
+
const rpc = this.#get_rpc();
|
|
67
|
+
if (!rpc) {
|
|
68
|
+
this.error = 'rpc adapter not wired';
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
55
71
|
this.deleting_ids.add(id);
|
|
56
72
|
try {
|
|
57
|
-
|
|
58
|
-
if (!response.ok) {
|
|
59
|
-
this.error = await parse_response_error(response);
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
73
|
+
await rpc.delete({ invite_id: id });
|
|
62
74
|
await this.fetch();
|
|
63
75
|
}
|
|
64
76
|
catch (e) {
|
|
@@ -1,16 +1,42 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Reactive state for admin session overview.
|
|
3
3
|
*
|
|
4
|
+
* Both the listing and the two revoke-all mutations flow through the shared
|
|
5
|
+
* `AdminAccountsRpc` adapter (`list_sessions`, `session_revoke_all`,
|
|
6
|
+
* `token_revoke_all`). The former REST `GET /api/admin/sessions` route moved
|
|
7
|
+
* to the `admin_session_list` RPC method in the 2026-04-23 migration.
|
|
8
|
+
*
|
|
4
9
|
* @module
|
|
5
10
|
*/
|
|
6
11
|
import { SvelteSet } from 'svelte/reactivity';
|
|
7
12
|
import { Loadable } from './loadable.svelte.js';
|
|
13
|
+
import type { AdminAccountsRpc } from './admin_accounts_state.svelte.js';
|
|
8
14
|
import type { AdminSessionJson } from '../auth/audit_log_schema.js';
|
|
15
|
+
/**
|
|
16
|
+
* Options for `AdminSessionsState`.
|
|
17
|
+
*
|
|
18
|
+
* The RPC adapter drives every operation (listing + the two revoke-all
|
|
19
|
+
* mutations). Without it, `fetch` and the revoke controls no-op with
|
|
20
|
+
* `'rpc adapter not wired'` on `error`.
|
|
21
|
+
*/
|
|
22
|
+
export interface AdminSessionsStateOptions {
|
|
23
|
+
/**
|
|
24
|
+
* Reactive accessor for the RPC adapter; returns `null` when unwired.
|
|
25
|
+
* Mirrors `AdminAccountsStateOptions.get_rpc` so a single adapter
|
|
26
|
+
* instance backs both states without tripping Svelte's
|
|
27
|
+
* `state_referenced_locally` warning.
|
|
28
|
+
*/
|
|
29
|
+
get_rpc?: () => AdminAccountsRpc | null;
|
|
30
|
+
}
|
|
9
31
|
export declare class AdminSessionsState extends Loadable {
|
|
32
|
+
#private;
|
|
10
33
|
sessions: Array<AdminSessionJson>;
|
|
11
34
|
readonly revoking_account_ids: SvelteSet<string>;
|
|
12
35
|
readonly revoking_token_account_ids: SvelteSet<string>;
|
|
13
36
|
readonly active_count: number;
|
|
37
|
+
constructor(options?: AdminSessionsStateOptions);
|
|
38
|
+
/** True when an RPC adapter is wired. `fetch` and the revoke controls no-op without it. */
|
|
39
|
+
get has_rpc(): boolean;
|
|
14
40
|
fetch(): Promise<void>;
|
|
15
41
|
revoke_all_for_account(account_id: string): Promise<void>;
|
|
16
42
|
revoke_all_tokens_for_account(account_id: string): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin_sessions_state.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/admin_sessions_state.svelte.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"admin_sessions_state.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/admin_sessions_state.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAC,SAAS,EAAC,MAAM,mBAAmB,CAAC;AAE5C,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAC9C,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,kCAAkC,CAAC;AACvE,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,6BAA6B,CAAC;AAElE;;;;;;GAMG;AACH,MAAM,WAAW,yBAAyB;IACzC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,gBAAgB,GAAG,IAAI,CAAC;CACxC;AAED,qBAAa,kBAAmB,SAAQ,QAAQ;;IAG/C,QAAQ,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAkB;IACnD,QAAQ,CAAC,oBAAoB,EAAE,SAAS,CAAC,MAAM,CAAC,CAAmB;IACnE,QAAQ,CAAC,0BAA0B,EAAE,SAAS,CAAC,MAAM,CAAC,CAAmB;IAEzE,QAAQ,CAAC,YAAY,SAAkC;gBAE3C,OAAO,CAAC,EAAE,yBAAyB;IAK/C,2FAA2F;IAC3F,IAAI,OAAO,IAAI,OAAO,CAErB;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAYtB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBzD,6BAA6B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAiBtE"}
|
|
@@ -1,36 +1,50 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Reactive state for admin session overview.
|
|
3
3
|
*
|
|
4
|
+
* Both the listing and the two revoke-all mutations flow through the shared
|
|
5
|
+
* `AdminAccountsRpc` adapter (`list_sessions`, `session_revoke_all`,
|
|
6
|
+
* `token_revoke_all`). The former REST `GET /api/admin/sessions` route moved
|
|
7
|
+
* to the `admin_session_list` RPC method in the 2026-04-23 migration.
|
|
8
|
+
*
|
|
4
9
|
* @module
|
|
5
10
|
*/
|
|
6
11
|
import { SvelteSet } from 'svelte/reactivity';
|
|
7
12
|
import { Loadable } from './loadable.svelte.js';
|
|
8
|
-
import { parse_response_error, ui_fetch } from './ui_fetch.js';
|
|
9
13
|
export class AdminSessionsState extends Loadable {
|
|
14
|
+
#get_rpc;
|
|
10
15
|
sessions = $state.raw([]);
|
|
11
16
|
revoking_account_ids = new SvelteSet();
|
|
12
17
|
revoking_token_account_ids = new SvelteSet();
|
|
13
18
|
active_count = $derived(this.sessions.length);
|
|
19
|
+
constructor(options) {
|
|
20
|
+
super();
|
|
21
|
+
this.#get_rpc = options?.get_rpc ?? (() => null);
|
|
22
|
+
}
|
|
23
|
+
/** True when an RPC adapter is wired. `fetch` and the revoke controls no-op without it. */
|
|
24
|
+
get has_rpc() {
|
|
25
|
+
return this.#get_rpc() !== null;
|
|
26
|
+
}
|
|
14
27
|
async fetch() {
|
|
28
|
+
const rpc = this.#get_rpc();
|
|
29
|
+
if (!rpc) {
|
|
30
|
+
this.error = 'rpc adapter not wired';
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
15
33
|
await this.run(async () => {
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
throw new Error(await parse_response_error(response, 'Failed to fetch sessions'));
|
|
19
|
-
}
|
|
20
|
-
const data = await response.json();
|
|
21
|
-
this.sessions = data.sessions ?? [];
|
|
34
|
+
const { sessions } = await rpc.list_sessions();
|
|
35
|
+
this.sessions = sessions;
|
|
22
36
|
});
|
|
23
37
|
}
|
|
24
38
|
async revoke_all_for_account(account_id) {
|
|
39
|
+
const rpc = this.#get_rpc();
|
|
40
|
+
if (!rpc) {
|
|
41
|
+
this.error = 'rpc adapter not wired';
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
25
44
|
this.revoking_account_ids.add(account_id);
|
|
26
45
|
try {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
});
|
|
30
|
-
if (!response.ok) {
|
|
31
|
-
this.error = await parse_response_error(response);
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
46
|
+
await rpc.session_revoke_all({ account_id });
|
|
47
|
+
this.error = null;
|
|
34
48
|
await this.fetch();
|
|
35
49
|
}
|
|
36
50
|
catch (e) {
|
|
@@ -41,15 +55,15 @@ export class AdminSessionsState extends Loadable {
|
|
|
41
55
|
}
|
|
42
56
|
}
|
|
43
57
|
async revoke_all_tokens_for_account(account_id) {
|
|
58
|
+
const rpc = this.#get_rpc();
|
|
59
|
+
if (!rpc) {
|
|
60
|
+
this.error = 'rpc adapter not wired';
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
44
63
|
this.revoking_token_account_ids.add(account_id);
|
|
45
64
|
try {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
});
|
|
49
|
-
if (!response.ok) {
|
|
50
|
-
this.error = await parse_response_error(response);
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
65
|
+
await rpc.token_revoke_all({ account_id });
|
|
66
|
+
this.error = null;
|
|
53
67
|
await this.fetch();
|
|
54
68
|
}
|
|
55
69
|
catch (e) {
|
|
@@ -1,13 +1,52 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Reactive state for admin app settings management.
|
|
3
3
|
*
|
|
4
|
+
* Flows every operation through an injected `AppSettingsRpc` adapter — mirrors
|
|
5
|
+
* `AdminInvitesRpc` / `AuditLogRpc`. Tests can inject plain-function stubs
|
|
6
|
+
* and consumers adapt their typed RPC client to the same shape.
|
|
7
|
+
*
|
|
4
8
|
* @module
|
|
5
9
|
*/
|
|
6
10
|
import { Loadable } from './loadable.svelte.js';
|
|
7
11
|
import type { AppSettingsWithUsernameJson } from '../auth/app_settings_schema.js';
|
|
12
|
+
/**
|
|
13
|
+
* Narrow RPC surface consumed by `AppSettingsState`. Consumers adapt their
|
|
14
|
+
* typed RPC client to this shape.
|
|
15
|
+
*/
|
|
16
|
+
export interface AppSettingsRpc {
|
|
17
|
+
get: () => Promise<{
|
|
18
|
+
settings: AppSettingsWithUsernameJson;
|
|
19
|
+
}>;
|
|
20
|
+
update: (params: {
|
|
21
|
+
open_signup: boolean;
|
|
22
|
+
}) => Promise<{
|
|
23
|
+
ok: true;
|
|
24
|
+
settings: AppSettingsWithUsernameJson;
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Svelte context carrying the reactive `AppSettingsRpc` accessor. Mirrors
|
|
29
|
+
* `admin_accounts_rpc_context`. Unset context falls back to `() => null` so
|
|
30
|
+
* `OpenSignupToggle` mounted outside a provisioner hides gracefully.
|
|
31
|
+
*/
|
|
32
|
+
export declare const app_settings_rpc_context: {
|
|
33
|
+
get: () => () => AppSettingsRpc | null;
|
|
34
|
+
set: (value?: (() => AppSettingsRpc | null) | undefined) => () => AppSettingsRpc | null;
|
|
35
|
+
};
|
|
36
|
+
export interface AppSettingsStateOptions {
|
|
37
|
+
/**
|
|
38
|
+
* Reactive accessor for the RPC adapter. `null` disables all operations
|
|
39
|
+
* (the state reports a descriptive error when fetch/update fires).
|
|
40
|
+
*/
|
|
41
|
+
get_rpc?: () => AppSettingsRpc | null;
|
|
42
|
+
}
|
|
8
43
|
export declare class AppSettingsState extends Loadable {
|
|
44
|
+
#private;
|
|
9
45
|
settings: AppSettingsWithUsernameJson | null;
|
|
10
46
|
updating: boolean;
|
|
47
|
+
constructor(options?: AppSettingsStateOptions);
|
|
48
|
+
/** True when an RPC adapter is wired. All ops require it. */
|
|
49
|
+
get has_rpc(): boolean;
|
|
11
50
|
fetch(): Promise<void>;
|
|
12
51
|
update_open_signup(value: boolean): Promise<void>;
|
|
13
52
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app_settings_state.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/app_settings_state.svelte.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"app_settings_state.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/app_settings_state.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAC9C,OAAO,KAAK,EAAC,2BAA2B,EAAC,MAAM,gCAAgC,CAAC;AAEhF;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,GAAG,EAAE,MAAM,OAAO,CAAC;QAAC,QAAQ,EAAE,2BAA2B,CAAA;KAAC,CAAC,CAAC;IAC5D,MAAM,EAAE,CAAC,MAAM,EAAE;QAChB,WAAW,EAAE,OAAO,CAAC;KACrB,KAAK,OAAO,CAAC;QAAC,EAAE,EAAE,IAAI,CAAC;QAAC,QAAQ,EAAE,2BAA2B,CAAA;KAAC,CAAC,CAAC;CACjE;AAED;;;;GAIG;AACH,eAAO,MAAM,wBAAwB;qBAAwB,cAAc,GAAG,IAAI;yBAArB,cAAc,GAAG,IAAI,wBAArB,cAAc,GAAG,IAAI;CAEjF,CAAC;AAEF,MAAM,WAAW,uBAAuB;IACvC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,cAAc,GAAG,IAAI,CAAC;CACtC;AAED,qBAAa,gBAAiB,SAAQ,QAAQ;;IAG7C,QAAQ,EAAE,2BAA2B,GAAG,IAAI,CAAoB;IAChE,QAAQ,UAAqB;gBAEjB,OAAO,CAAC,EAAE,uBAAuB;IAK7C,6DAA6D;IAC7D,IAAI,OAAO,IAAI,OAAO,CAErB;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAYtB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAiBvD"}
|
|
@@ -1,38 +1,54 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Reactive state for admin app settings management.
|
|
3
3
|
*
|
|
4
|
+
* Flows every operation through an injected `AppSettingsRpc` adapter — mirrors
|
|
5
|
+
* `AdminInvitesRpc` / `AuditLogRpc`. Tests can inject plain-function stubs
|
|
6
|
+
* and consumers adapt their typed RPC client to the same shape.
|
|
7
|
+
*
|
|
4
8
|
* @module
|
|
5
9
|
*/
|
|
10
|
+
import { create_context } from '@fuzdev/fuz_ui/context_helpers.js';
|
|
6
11
|
import { Loadable } from './loadable.svelte.js';
|
|
7
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Svelte context carrying the reactive `AppSettingsRpc` accessor. Mirrors
|
|
14
|
+
* `admin_accounts_rpc_context`. Unset context falls back to `() => null` so
|
|
15
|
+
* `OpenSignupToggle` mounted outside a provisioner hides gracefully.
|
|
16
|
+
*/
|
|
17
|
+
export const app_settings_rpc_context = create_context(() => () => null);
|
|
8
18
|
export class AppSettingsState extends Loadable {
|
|
19
|
+
#get_rpc;
|
|
9
20
|
settings = $state.raw(null);
|
|
10
21
|
updating = $state.raw(false);
|
|
22
|
+
constructor(options) {
|
|
23
|
+
super();
|
|
24
|
+
this.#get_rpc = options?.get_rpc ?? (() => null);
|
|
25
|
+
}
|
|
26
|
+
/** True when an RPC adapter is wired. All ops require it. */
|
|
27
|
+
get has_rpc() {
|
|
28
|
+
return this.#get_rpc() !== null;
|
|
29
|
+
}
|
|
11
30
|
async fetch() {
|
|
31
|
+
const rpc = this.#get_rpc();
|
|
32
|
+
if (!rpc) {
|
|
33
|
+
this.error = 'rpc adapter not wired';
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
12
36
|
await this.run(async () => {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
throw new Error(await parse_response_error(response, 'Failed to fetch settings'));
|
|
16
|
-
}
|
|
17
|
-
const data = await response.json();
|
|
18
|
-
this.settings = data.settings ?? null;
|
|
37
|
+
const { settings } = await rpc.get();
|
|
38
|
+
this.settings = settings;
|
|
19
39
|
});
|
|
20
40
|
}
|
|
21
41
|
async update_open_signup(value) {
|
|
42
|
+
const rpc = this.#get_rpc();
|
|
43
|
+
if (!rpc) {
|
|
44
|
+
this.error = 'rpc adapter not wired';
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
22
47
|
this.updating = true;
|
|
23
48
|
this.error = null;
|
|
24
49
|
try {
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
headers: { 'Content-Type': 'application/json' },
|
|
28
|
-
body: JSON.stringify({ open_signup: value }),
|
|
29
|
-
});
|
|
30
|
-
if (!response.ok) {
|
|
31
|
-
this.error = await parse_response_error(response);
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
const data = await response.json();
|
|
35
|
-
this.settings = data.settings ?? null;
|
|
50
|
+
const { settings } = await rpc.update({ open_signup: value });
|
|
51
|
+
this.settings = settings;
|
|
36
52
|
}
|
|
37
53
|
catch (e) {
|
|
38
54
|
this.error = e instanceof Error ? e.message : 'Failed to update settings';
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Reactive state for the audit log viewer.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Two fetch primitives (`fetch` for events, `fetch_permit_history` for the
|
|
5
|
+
* grant/revoke shortcut) flow through an injected RPC adapter; the SSE
|
|
6
|
+
* stream continues to use `EventSource` directly — streams aren't an RPC
|
|
7
|
+
* concern.
|
|
6
8
|
*
|
|
7
9
|
* @module
|
|
8
10
|
*/
|
|
@@ -14,6 +16,39 @@ export interface AuditLogFetchOptions {
|
|
|
14
16
|
account_id?: string;
|
|
15
17
|
limit?: number;
|
|
16
18
|
offset?: number;
|
|
19
|
+
since_seq?: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Narrow RPC surface consumed by `AuditLogState`. Consumers adapt their typed
|
|
23
|
+
* RPC client to this shape. Mirrors `AdminAccountsRpc` / `AdminInvitesRpc`.
|
|
24
|
+
*/
|
|
25
|
+
export interface AuditLogRpc {
|
|
26
|
+
list: (options?: AuditLogFetchOptions) => Promise<{
|
|
27
|
+
events: Array<AuditLogEventWithUsernamesJson>;
|
|
28
|
+
}>;
|
|
29
|
+
permit_history: (params?: {
|
|
30
|
+
limit?: number;
|
|
31
|
+
offset?: number;
|
|
32
|
+
}) => Promise<{
|
|
33
|
+
events: Array<PermitHistoryEventJson>;
|
|
34
|
+
}>;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Svelte context carrying the reactive `AuditLogRpc` accessor. Mirrors
|
|
38
|
+
* `admin_accounts_rpc_context`. Unset context falls back to `() => null`.
|
|
39
|
+
*/
|
|
40
|
+
export declare const audit_log_rpc_context: {
|
|
41
|
+
get: () => () => AuditLogRpc | null;
|
|
42
|
+
set: (value?: (() => AuditLogRpc | null) | undefined) => () => AuditLogRpc | null;
|
|
43
|
+
};
|
|
44
|
+
export interface AuditLogStateOptions {
|
|
45
|
+
/**
|
|
46
|
+
* Reactive accessor for the RPC adapter. Matches the `get_rpc` pattern on
|
|
47
|
+
* `AdminAccountsState` — `null` disables fetch operations (SSE still works).
|
|
48
|
+
*/
|
|
49
|
+
get_rpc?: () => AuditLogRpc | null;
|
|
50
|
+
/** SSE stream URL. Defaults to the shipped admin audit-log stream route. */
|
|
51
|
+
stream_url?: string;
|
|
17
52
|
}
|
|
18
53
|
export declare class AuditLogState extends Loadable {
|
|
19
54
|
#private;
|
|
@@ -22,7 +57,9 @@ export declare class AuditLogState extends Loadable {
|
|
|
22
57
|
readonly count: number;
|
|
23
58
|
/** Whether the SSE stream is currently connected. */
|
|
24
59
|
connected: boolean;
|
|
25
|
-
constructor(
|
|
60
|
+
constructor(options?: AuditLogStateOptions);
|
|
61
|
+
/** True when an RPC adapter is wired. `fetch`/`fetch_permit_history` no-op without it. */
|
|
62
|
+
get has_rpc(): boolean;
|
|
26
63
|
fetch(options?: AuditLogFetchOptions): Promise<void>;
|
|
27
64
|
fetch_permit_history(limit?: number, offset?: number): Promise<void>;
|
|
28
65
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit_log_state.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/audit_log_state.svelte.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"audit_log_state.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/audit_log_state.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAC9C,OAAO,KAAK,EAEX,8BAA8B,EAC9B,sBAAsB,EACtB,MAAM,6BAA6B,CAAC;AAGrC,6CAA6C;AAC7C,MAAM,WAAW,oBAAoB;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,CACL,OAAO,CAAC,EAAE,oBAAoB,KAC1B,OAAO,CAAC;QAAC,MAAM,EAAE,KAAK,CAAC,8BAA8B,CAAC,CAAA;KAAC,CAAC,CAAC;IAC9D,cAAc,EAAE,CAAC,MAAM,CAAC,EAAE;QACzB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KAChB,KAAK,OAAO,CAAC;QAAC,MAAM,EAAE,KAAK,CAAC,sBAAsB,CAAC,CAAA;KAAC,CAAC,CAAC;CACvD;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB;qBAAwB,WAAW,GAAG,IAAI;yBAAlB,WAAW,GAAG,IAAI,wBAAlB,WAAW,GAAG,IAAI;CAAmB,CAAC;AAEhG,MAAM,WAAW,oBAAoB;IACpC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,WAAW,GAAG,IAAI,CAAC;IACnC,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,aAAc,SAAQ,QAAQ;;IAG1C,MAAM,EAAE,KAAK,CAAC,8BAA8B,CAAC,CAAkB;IAC/D,qBAAqB,EAAE,KAAK,CAAC,sBAAsB,CAAC,CAAkB;IAEtE,QAAQ,CAAC,KAAK,SAAgC;IAE9C,qDAAqD;IACrD,SAAS,UAAqB;gBAWlB,OAAO,CAAC,EAAE,oBAAoB;IAM1C,0FAA0F;IAC1F,IAAI,OAAO,IAAI,OAAO,CAErB;IAEK,KAAK,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAapD,oBAAoB,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY1E;;;;;;;OAOG;IACH,SAAS,IAAI,MAAM,IAAI;IA0CvB,gCAAgC;IAChC,UAAU,IAAI,IAAI;CAiClB"}
|
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Reactive state for the audit log viewer.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Two fetch primitives (`fetch` for events, `fetch_permit_history` for the
|
|
5
|
+
* grant/revoke shortcut) flow through an injected RPC adapter; the SSE
|
|
6
|
+
* stream continues to use `EventSource` directly — streams aren't an RPC
|
|
7
|
+
* concern.
|
|
6
8
|
*
|
|
7
9
|
* @module
|
|
8
10
|
*/
|
|
9
11
|
import { DEV } from 'esm-env';
|
|
12
|
+
import { create_context } from '@fuzdev/fuz_ui/context_helpers.js';
|
|
10
13
|
import { Loadable } from './loadable.svelte.js';
|
|
11
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Svelte context carrying the reactive `AuditLogRpc` accessor. Mirrors
|
|
16
|
+
* `admin_accounts_rpc_context`. Unset context falls back to `() => null`.
|
|
17
|
+
*/
|
|
18
|
+
export const audit_log_rpc_context = create_context(() => () => null);
|
|
12
19
|
export class AuditLogState extends Loadable {
|
|
20
|
+
#get_rpc;
|
|
13
21
|
events = $state.raw([]);
|
|
14
22
|
permit_history_events = $state.raw([]);
|
|
15
23
|
count = $derived(this.events.length);
|
|
@@ -21,48 +29,36 @@ export class AuditLogState extends Loadable {
|
|
|
21
29
|
#event_source = null;
|
|
22
30
|
/** Path to the SSE stream endpoint. */
|
|
23
31
|
#stream_url;
|
|
24
|
-
constructor(
|
|
32
|
+
constructor(options) {
|
|
25
33
|
super();
|
|
26
|
-
this.#
|
|
34
|
+
this.#get_rpc = options?.get_rpc ?? (() => null);
|
|
35
|
+
this.#stream_url = options?.stream_url ?? '/api/admin/audit-log/stream';
|
|
36
|
+
}
|
|
37
|
+
/** True when an RPC adapter is wired. `fetch`/`fetch_permit_history` no-op without it. */
|
|
38
|
+
get has_rpc() {
|
|
39
|
+
return this.#get_rpc() !== null;
|
|
27
40
|
}
|
|
28
41
|
async fetch(options) {
|
|
42
|
+
const rpc = this.#get_rpc();
|
|
43
|
+
if (!rpc) {
|
|
44
|
+
this.error = 'rpc adapter not wired';
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
29
47
|
await this.run(async () => {
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
params.set('event_type', options.event_type);
|
|
33
|
-
if (options?.account_id)
|
|
34
|
-
params.set('account_id', options.account_id);
|
|
35
|
-
if (options?.limit != null)
|
|
36
|
-
params.set('limit', String(options.limit));
|
|
37
|
-
if (options?.offset != null)
|
|
38
|
-
params.set('offset', String(options.offset));
|
|
39
|
-
const qs = params.toString();
|
|
40
|
-
const url = `/api/admin/audit-log${qs ? `?${qs}` : ''}`;
|
|
41
|
-
const response = await ui_fetch(url);
|
|
42
|
-
if (!response.ok) {
|
|
43
|
-
throw new Error(await parse_response_error(response, 'Failed to fetch audit log'));
|
|
44
|
-
}
|
|
45
|
-
const data = await response.json();
|
|
46
|
-
this.events = data.events ?? [];
|
|
47
|
-
// track the highest seq for gap fill
|
|
48
|
+
const { events } = await rpc.list(options);
|
|
49
|
+
this.events = events;
|
|
48
50
|
this.#update_last_seq(this.events);
|
|
49
51
|
});
|
|
50
52
|
}
|
|
51
53
|
async fetch_permit_history(limit, offset) {
|
|
54
|
+
const rpc = this.#get_rpc();
|
|
55
|
+
if (!rpc) {
|
|
56
|
+
this.error = 'rpc adapter not wired';
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
52
59
|
await this.run(async () => {
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
params.set('limit', String(limit));
|
|
56
|
-
if (offset != null)
|
|
57
|
-
params.set('offset', String(offset));
|
|
58
|
-
const qs = params.toString();
|
|
59
|
-
const url = `/api/admin/audit-log/permit-history${qs ? `?${qs}` : ''}`;
|
|
60
|
-
const response = await ui_fetch(url);
|
|
61
|
-
if (!response.ok) {
|
|
62
|
-
throw new Error(await parse_response_error(response, 'Failed to fetch permit history'));
|
|
63
|
-
}
|
|
64
|
-
const data = await response.json();
|
|
65
|
-
this.permit_history_events = data.events ?? [];
|
|
60
|
+
const { events } = await rpc.permit_history({ limit, offset });
|
|
61
|
+
this.permit_history_events = events;
|
|
66
62
|
});
|
|
67
63
|
}
|
|
68
64
|
/**
|
|
@@ -123,13 +119,11 @@ export class AuditLogState extends Loadable {
|
|
|
123
119
|
}
|
|
124
120
|
/** Fetch events missed during disconnection, keyed by `since_seq`. */
|
|
125
121
|
async #fill_gap(since_seq) {
|
|
122
|
+
const rpc = this.#get_rpc();
|
|
123
|
+
if (!rpc)
|
|
124
|
+
return;
|
|
126
125
|
try {
|
|
127
|
-
const
|
|
128
|
-
const response = await ui_fetch(url);
|
|
129
|
-
if (!response.ok)
|
|
130
|
-
return;
|
|
131
|
-
const data = await response.json();
|
|
132
|
-
const gap_events = data.events ?? [];
|
|
126
|
+
const { events: gap_events } = await rpc.list({ since_seq, limit: 200 });
|
|
133
127
|
if (gap_events.length === 0)
|
|
134
128
|
return;
|
|
135
129
|
// merge — deduplicate by id, keep newest-first order
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
*
|
|
32
32
|
* @module
|
|
33
33
|
*/
|
|
34
|
-
import { type
|
|
34
|
+
import { type ActorSummaryJson, type PermitSummaryJson, type SessionAccount } from '../auth/account_schema.js';
|
|
35
35
|
/**
|
|
36
36
|
* Svelte context for `AuthState`.
|
|
37
37
|
* Use `auth_state_context.set(state)` in the provider and `auth_state_context.get()` to access.
|
|
@@ -46,8 +46,9 @@ export declare class AuthState {
|
|
|
46
46
|
verified: boolean;
|
|
47
47
|
verify_error: string | null;
|
|
48
48
|
account: SessionAccount | null;
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
actor: ActorSummaryJson | null;
|
|
50
|
+
permits: Array<PermitSummaryJson>;
|
|
51
|
+
readonly active_permits: Array<PermitSummaryJson>;
|
|
51
52
|
readonly roles: Array<string>;
|
|
52
53
|
/** True when bootstrap is available (no accounts exist yet). */
|
|
53
54
|
needs_bootstrap: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth_state.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/auth_state.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAKH,OAAO,
|
|
1
|
+
{"version":3,"file":"auth_state.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/auth_state.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAKH,OAAO,EACN,KAAK,gBAAgB,EAErB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,MAAM,2BAA2B,CAAC;AAEnC;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;;CAA8B,CAAC;AAE9D,qBAAa,SAAS;IACrB,SAAS,UAAqB;IAC9B,QAAQ,UAAqB;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAoB;IAC/C,OAAO,EAAE,cAAc,GAAG,IAAI,CAAoB;IAClD,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAoB;IAClD,OAAO,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAkB;IACnD,QAAQ,CAAC,cAAc,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAE/C;IACF,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAoD;IAEjF,gEAAgE;IAChE,eAAe,UAAqB;IAEpC;;;;;;OAMG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IA6BpC;;;;OAIG;IACG,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAwCjE;;;;OAIG;IACG,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiCpF;;;;OAIG;IACG,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA4ClF;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAW7B"}
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
*/
|
|
34
34
|
import { create_context } from '@fuzdev/fuz_ui/context_helpers.js';
|
|
35
35
|
import { ui_fetch } from './ui_fetch.js';
|
|
36
|
-
import { is_permit_active } from '../auth/account_schema.js';
|
|
36
|
+
import { is_permit_active, } from '../auth/account_schema.js';
|
|
37
37
|
/**
|
|
38
38
|
* Svelte context for `AuthState`.
|
|
39
39
|
* Use `auth_state_context.set(state)` in the provider and `auth_state_context.get()` to access.
|
|
@@ -44,6 +44,7 @@ export class AuthState {
|
|
|
44
44
|
verified = $state.raw(false);
|
|
45
45
|
verify_error = $state.raw(null);
|
|
46
46
|
account = $state.raw(null);
|
|
47
|
+
actor = $state.raw(null);
|
|
47
48
|
permits = $state.raw([]);
|
|
48
49
|
active_permits = $derived(this.permits.filter((p) => is_permit_active(p)));
|
|
49
50
|
roles = $derived(this.active_permits.map((p) => p.role));
|
|
@@ -64,6 +65,7 @@ export class AuthState {
|
|
|
64
65
|
const data = await response.json();
|
|
65
66
|
this.verified = true;
|
|
66
67
|
this.account = data.account ?? null;
|
|
68
|
+
this.actor = data.actor ?? null;
|
|
67
69
|
this.permits = data.permits ?? [];
|
|
68
70
|
this.needs_bootstrap = false;
|
|
69
71
|
}
|
|
@@ -233,6 +235,7 @@ export class AuthState {
|
|
|
233
235
|
}
|
|
234
236
|
this.verified = false;
|
|
235
237
|
this.account = null;
|
|
238
|
+
this.actor = null;
|
|
236
239
|
this.permits = [];
|
|
237
240
|
}
|
|
238
241
|
}
|