From 60b4697b5ac77984d35d6d42b335db6ed6a8016f Mon Sep 17 00:00:00 2001 From: Lewis Date: Tue, 17 Mar 2026 17:04:57 +0200 Subject: [PATCH] chore: inline delegation audit page --- frontend/src/App.svelte | 2 +- frontend/src/components/HandleInput.svelte | 2 +- .../dashboard/ControllersContent.svelte | 231 +++++++++++++- .../dashboard/DelegationAuditContent.svelte | 282 ------------------ .../dashboard/InviteCodesContent.svelte | 5 - frontend/src/lib/types/routes.ts | 2 +- frontend/src/locales/en.json | 5 +- frontend/src/locales/fi.json | 5 +- frontend/src/locales/ja.json | 5 +- frontend/src/locales/ko.json | 5 +- frontend/src/locales/sv.json | 5 +- frontend/src/locales/zh.json | 5 +- frontend/src/routes/Dashboard.svelte | 12 +- .../tests/migration/atproto-client.test.ts | 2 +- 14 files changed, 241 insertions(+), 327 deletions(-) delete mode 100644 frontend/src/components/dashboard/DelegationAuditContent.svelte diff --git a/frontend/src/App.svelte b/frontend/src/App.svelte index 88fab77..2982b8d 100644 --- a/frontend/src/App.svelte +++ b/frontend/src/App.svelte @@ -91,7 +91,7 @@ '/comms', '/repo', '/controllers', - '/delegation-audit', + '/invite-codes', '/did-document', '/admin', diff --git a/frontend/src/components/HandleInput.svelte b/frontend/src/components/HandleInput.svelte index cb05fe5..2d589e4 100644 --- a/frontend/src/components/HandleInput.svelte +++ b/frontend/src/components/HandleInput.svelte @@ -6,7 +6,7 @@ disabled?: boolean placeholder?: string id?: string - autocomplete?: string + autocomplete?: HTMLInputElement['autocomplete'] onInput: (value: string) => void onDomainChange: (domain: string) => void } diff --git a/frontend/src/components/dashboard/ControllersContent.svelte b/frontend/src/components/dashboard/ControllersContent.svelte index 23961e0..a0af2fb 100644 --- a/frontend/src/components/dashboard/ControllersContent.svelte +++ b/frontend/src/components/dashboard/ControllersContent.svelte @@ -1,13 +1,13 @@
@@ -454,6 +575,10 @@ {$_('delegation.createDelegatedAccountButton')} {/if} + +
+

{$_('delegation.controlledAccountsLocalOnly')}

+
@@ -461,7 +586,43 @@

{$_('delegation.auditLog')}

{$_('delegation.auditLogDesc')}

- {$_('delegation.viewAuditLog')} + + {#if auditLoading} +
{$_('common.loading')}
+ {:else if auditEntries.length === 0} +

{$_('delegation.noAuditEntries')}

+ {:else} +
+ {#each auditEntries as entry} +
+
+ {formatActionType(entry.actionType)} + +
+
+
+ {$_('delegation.actor')} + {entry.actorDid} +
+ {#if entry.delegatedDid} +
+ {$_('delegation.target')} + {entry.delegatedDid} +
+ {/if} + {#if entry.actionDetails} +
+ {$_('delegation.details')} + {formatActionDetails(entry.actionDetails)} +
+ {/if} +
+
+ {/each} +
+ + + {/if} {/if} @@ -505,6 +666,7 @@ border: 1px solid var(--border-color); border-radius: var(--radius-md); padding: var(--space-4); + margin-top: var(--space-4); } .constraint-notice p { @@ -846,6 +1008,52 @@ border: 1px solid var(--info-border, var(--border-color)); } + .audit-entries { + display: flex; + flex-direction: column; + gap: var(--space-3); + } + + .audit-entry { + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: var(--space-4); + } + + .audit-entry-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: var(--space-3); + } + + .action-type { + font-weight: var(--font-medium); + padding: var(--space-1) var(--space-2); + background: var(--accent); + color: var(--text-inverse); + border-radius: var(--radius-md); + font-size: var(--text-sm); + } + + .audit-entry-date { + font-size: var(--text-sm); + color: var(--text-secondary); + } + + .audit-entry-details { + display: flex; + flex-direction: column; + gap: var(--space-2); + } + + .audit-details-value { + font-family: var(--font-mono); + font-size: var(--text-xs); + word-break: break-word; + } + @media (max-width: 600px) { .item-card { flex-direction: column; @@ -861,5 +1069,18 @@ width: 100%; text-align: center; } + + .audit-entry-header { + flex-direction: column; + align-items: flex-start; + gap: var(--space-2); + } + + .audit-entry-details .value.did { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + max-width: 60vw; + } } diff --git a/frontend/src/components/dashboard/DelegationAuditContent.svelte b/frontend/src/components/dashboard/DelegationAuditContent.svelte deleted file mode 100644 index beb1f3b..0000000 --- a/frontend/src/components/dashboard/DelegationAuditContent.svelte +++ /dev/null @@ -1,282 +0,0 @@ - - -
-
- -
- - {#if loading} -
{$_('common.loading')}
- {:else if entries.length === 0} -

{$_('delegation.noAuditEntries')}

- {:else} -
- {#each entries as entry} -
-
- {formatActionType(entry.actionType)} - -
-
-
- {$_('delegation.actor')} - {truncateDid(entry.actorDid)} -
- {#if entry.delegatedDid} -
- {$_('delegation.target')} - {truncateDid(entry.delegatedDid)} -
- {/if} - {#if entry.actionDetails} -
- {$_('delegation.details')} - {formatActionDetails(entry.actionDetails)} -
- {/if} -
-
- {/each} -
- - - {/if} -
- - diff --git a/frontend/src/components/dashboard/InviteCodesContent.svelte b/frontend/src/components/dashboard/InviteCodesContent.svelte index 3cb76b7..4ef5299 100644 --- a/frontend/src/components/dashboard/InviteCodesContent.svelte +++ b/frontend/src/components/dashboard/InviteCodesContent.svelte @@ -255,11 +255,6 @@ flex-shrink: 0; } - .danger-text { - color: var(--error-text); - flex-shrink: 0; - } - .code-meta { display: flex; gap: var(--space-4); diff --git a/frontend/src/lib/types/routes.ts b/frontend/src/lib/types/routes.ts index 4118de2..d728875 100644 --- a/frontend/src/lib/types/routes.ts +++ b/frontend/src/lib/types/routes.ts @@ -9,7 +9,7 @@ export const routes = { comms: "/comms", repo: "/repo", controllers: "/controllers", - delegationAudit: "/delegation-audit", + actAs: "/act-as", didDocument: "/did-document", migrate: "/migrate", diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 0d0cfbb..ae95b30 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -144,7 +144,6 @@ "navComms": "Communication Preferences", "navRepo": "Repository Explorer", "navDelegation": "Delegation", - "navDelegationAudit": "Delegation Audit", "navAdmin": "Admin Panel", "navDidDocument": "DID Document", "migrated": "Migrated", @@ -836,6 +835,7 @@ "controllerRemoved": "Controller removed successfully", "controlledAccounts": "Controlled Accounts", "controlledAccountsDesc": "Accounts you can act on behalf of", + "controlledAccountsLocalOnly": "Only accounts on this PDS are shown. Another PDS may have granted you controller access separately", "noControlledAccounts": "You do not have access to any delegated accounts.", "actAs": "Act As", "cannotControlAccounts": "You cannot control other accounts because this account has controllers. An account can either have controllers or control other accounts, but not both.", @@ -848,7 +848,6 @@ "accountCreated": "Created delegated account: {handle}", "auditLog": "Audit Log", "auditLogDesc": "View all delegation activity", - "viewAuditLog": "View Audit Log", "scopeOwner": "Owner", "scopeViewer": "Viewer", "scopeCustom": "Custom", @@ -856,7 +855,6 @@ "details": "Details", "previous": "Previous", "next": "Next", - "refresh": "Refresh", "actionGrantCreated": "Grant Created", "actionGrantRevoked": "Grant Revoked", "actionScopesModified": "Scopes Modified", @@ -866,7 +864,6 @@ "actionAccountAction": "Account Action", "noAuditEntries": "No audit entries", "target": "Target", - "pageInfo": "{start} - {end} of {total}", "failedToLoadAudit": "Failed to load audit log" }, "actAs": { diff --git a/frontend/src/locales/fi.json b/frontend/src/locales/fi.json index 5f40173..20d45fa 100644 --- a/frontend/src/locales/fi.json +++ b/frontend/src/locales/fi.json @@ -124,7 +124,6 @@ "dashboard": { "title": "Hallintapaneeli", "accountManager": "Tilinhallinta", - "navDelegationAudit": "Delegointiloki", "switchAccount": "Vaihda tiliä", "addAnotherAccount": "Lisää toinen tili", "signOut": "Kirjaudu ulos @{handle}", @@ -835,6 +834,7 @@ "controllerRemoved": "Hallinnoija poistettu", "controlledAccounts": "Hallinnoidut tilit", "controlledAccountsDesc": "Tilit, joiden puolesta voit toimia", + "controlledAccountsLocalOnly": "Vain tämän PDS:n tilit näytetään. Toinen PDS on voinut myöntää sinulle ohjausoikeuden erikseen", "noControlledAccounts": "Sinulla ei ole pääsyä delegoituihin tileihin.", "actAs": "Toimi käyttäjänä", "cannotControlAccounts": "Et voi hallinnoida muita tilejä, koska tällä tilillä on hallinnoijia. Tili voi joko olla hallinnoija tai hallinnoidaan, mutta ei molempia.", @@ -847,7 +847,6 @@ "accountCreated": "Delegoitu tili luotu: {handle}", "auditLog": "Tapahtumaloki", "auditLogDesc": "Näytä kaikki delegointitoiminta", - "viewAuditLog": "Näytä tapahtumaloki", "scopeOwner": "Omistaja", "scopeViewer": "Katsoja", "scopeCustom": "Mukautettu", @@ -855,7 +854,6 @@ "details": "Tiedot", "previous": "Edellinen", "next": "Seuraava", - "refresh": "Päivitä", "actionGrantCreated": "Oikeus luotu", "actionGrantRevoked": "Oikeus peruttu", "actionScopesModified": "Oikeuksia muokattu", @@ -865,7 +863,6 @@ "actionAccountAction": "Tilitoiminto", "noAuditEntries": "Ei lokimerkintöjä", "target": "Kohde", - "pageInfo": "{start} - {end} / {total}", "failedToLoadAudit": "Lokin lataus epäonnistui" }, "actAs": { diff --git a/frontend/src/locales/ja.json b/frontend/src/locales/ja.json index 87b96e3..691302a 100644 --- a/frontend/src/locales/ja.json +++ b/frontend/src/locales/ja.json @@ -124,7 +124,6 @@ "dashboard": { "title": "ダッシュボード", "accountManager": "アカウント管理", - "navDelegationAudit": "委任監査", "switchAccount": "アカウント切替", "addAnotherAccount": "別のアカウントを追加", "signOut": "@{handle} からサインアウト", @@ -834,7 +833,6 @@ "actionAccountAction": "アカウントアクション", "previous": "前へ", "next": "次へ", - "refresh": "更新", "adding": "追加中...", "accessLevel": "アクセスレベル", "addControllerButton": "+ コントローラーを追加", @@ -848,6 +846,7 @@ "cannotAddControllers": "他のアカウントを管理しているため、コントローラーを追加できません。アカウントはコントローラーを持つか、他のアカウントを管理するかのいずれかのみ可能です。", "cannotControlAccounts": "このアカウントにはコントローラーがいるため、他のアカウントを管理できません。アカウントはコントローラーを持つか、他のアカウントを管理するかのいずれかのみ可能です。", "controlledAccountsDesc": "あなたが代わりに操作できるアカウント", + "controlledAccountsLocalOnly": "このPDS上のアカウントのみ表示されます。別のPDSがコントローラーアクセスを個別に付与している場合があります", "controllerAdded": "コントローラーを追加しました", "controllerDid": "コントローラーDID", "controllerRemoved": "コントローラーを削除しました", @@ -860,12 +859,10 @@ "inactive": "非アクティブ", "remove": "削除", "removeConfirm": "このコントローラーを削除しますか?", - "viewAuditLog": "監査ログを表示", "yourAccessLevel": "あなたのアクセスレベル", "accountCreated": "委任アカウントを作成しました: {handle}", "noAuditEntries": "監査エントリなし", "target": "対象", - "pageInfo": "{start} - {end} / {total}", "failedToLoadAudit": "監査ログの読み込みに失敗しました" }, "actAs": { diff --git a/frontend/src/locales/ko.json b/frontend/src/locales/ko.json index e59e0b4..e7d3305 100644 --- a/frontend/src/locales/ko.json +++ b/frontend/src/locales/ko.json @@ -124,7 +124,6 @@ "dashboard": { "title": "대시보드", "accountManager": "계정 관리", - "navDelegationAudit": "위임 감사", "switchAccount": "계정 전환", "addAnotherAccount": "다른 계정 추가", "signOut": "@{handle} 로그아웃", @@ -834,7 +833,6 @@ "actionAccountAction": "계정 작업", "previous": "이전", "next": "다음", - "refresh": "새로고침", "adding": "추가 중...", "accessLevel": "액세스 수준", "addControllerButton": "+ 컨트롤러 추가", @@ -848,6 +846,7 @@ "cannotAddControllers": "다른 계정을 관리하고 있어 컨트롤러를 추가할 수 없습니다. 계정은 컨트롤러를 가지거나 다른 계정을 관리할 수 있지만 둘 다는 불가능합니다.", "cannotControlAccounts": "이 계정에 컨트롤러가 있어 다른 계정을 관리할 수 없습니다. 계정은 컨트롤러를 가지거나 다른 계정을 관리할 수 있지만 둘 다는 불가능합니다.", "controlledAccountsDesc": "귀하가 대신 작업할 수 있는 계정", + "controlledAccountsLocalOnly": "이 PDS의 계정만 표시됩니다. 다른 PDS에서 별도로 컨트롤러 액세스를 부여했을 수 있습니다", "controllerAdded": "컨트롤러가 추가되었습니다", "controllerDid": "컨트롤러 DID", "controllerRemoved": "컨트롤러가 제거되었습니다", @@ -860,12 +859,10 @@ "inactive": "비활성", "remove": "제거", "removeConfirm": "이 컨트롤러를 제거하시겠습니까?", - "viewAuditLog": "감사 로그 보기", "yourAccessLevel": "귀하의 액세스 수준", "accountCreated": "위임 계정이 생성되었습니다: {handle}", "noAuditEntries": "감사 항목 없음", "target": "대상", - "pageInfo": "{start} - {end} / {total}", "failedToLoadAudit": "감사 로그 로딩 실패" }, "actAs": { diff --git a/frontend/src/locales/sv.json b/frontend/src/locales/sv.json index 9cde91a..37f91e4 100644 --- a/frontend/src/locales/sv.json +++ b/frontend/src/locales/sv.json @@ -124,7 +124,6 @@ "dashboard": { "title": "Kontrollpanel", "accountManager": "Kontohantering", - "navDelegationAudit": "Delegeringsgranskning", "switchAccount": "Byt konto", "addAnotherAccount": "Lägg till ett annat konto", "signOut": "Logga ut @{handle}", @@ -834,7 +833,6 @@ "actionAccountAction": "Kontoåtgärd", "previous": "Föregående", "next": "Nästa", - "refresh": "Uppdatera", "adding": "Lägger till...", "accessLevel": "Åtkomstnivå", "addControllerButton": "+ Lägg till kontrollant", @@ -848,6 +846,7 @@ "cannotAddControllers": "Du kan inte lägga till kontrollanter eftersom detta konto kontrollerar andra konton. Ett konto kan antingen ha kontrollanter eller kontrollera andra konton, men inte båda.", "cannotControlAccounts": "Du kan inte kontrollera andra konton eftersom detta konto har kontrollanter. Ett konto kan antingen ha kontrollanter eller kontrollera andra konton, men inte båda.", "controlledAccountsDesc": "Konton du kan agera för", + "controlledAccountsLocalOnly": "Endast konton på denna PDS visas. En annan PDS kan ha beviljat dig kontrollåtkomst separat", "controllerAdded": "Kontrollant tillagd", "controllerDid": "Kontrollant-DID", "controllerRemoved": "Kontrollant borttagen", @@ -860,12 +859,10 @@ "inactive": "Inaktiv", "remove": "Ta bort", "removeConfirm": "Vill du ta bort denna kontrollant?", - "viewAuditLog": "Visa granskningslogg", "yourAccessLevel": "Din åtkomstnivå", "accountCreated": "Skapade delegerat konto: {handle}", "noAuditEntries": "Inga granskningsposter", "target": "Mål", - "pageInfo": "{start} - {end} av {total}", "failedToLoadAudit": "Kunde inte ladda granskningslogg" }, "actAs": { diff --git a/frontend/src/locales/zh.json b/frontend/src/locales/zh.json index 06a3a96..18f3f06 100644 --- a/frontend/src/locales/zh.json +++ b/frontend/src/locales/zh.json @@ -124,7 +124,6 @@ "dashboard": { "title": "控制台", "accountManager": "账户管理", - "navDelegationAudit": "委托审计", "switchAccount": "切换账户", "addAnotherAccount": "添加其他账户", "signOut": "退出 @{handle}", @@ -835,7 +834,6 @@ "actionAccountAction": "账户操作", "previous": "上一页", "next": "下一页", - "refresh": "刷新", "adding": "添加中...", "accessLevel": "访问级别", "addControllerButton": "+ 添加控制者", @@ -849,6 +847,7 @@ "cannotAddControllers": "因为此账户正在控制其他账户,所以无法添加控制者。账户只能拥有控制者或控制其他账户,不能同时两者兼备。", "cannotControlAccounts": "因为此账户有控制者,所以无法控制其他账户。账户只能拥有控制者或控制其他账户,不能同时两者兼备。", "controlledAccountsDesc": "您可以代理操作的账户", + "controlledAccountsLocalOnly": "仅显示此PDS上的账户。其他PDS可能已单独授予您控制者访问权限", "controllerAdded": "控制者已添加", "controllerDid": "控制者 DID", "controllerRemoved": "控制者已移除", @@ -861,11 +860,9 @@ "inactive": "未激活", "remove": "移除", "removeConfirm": "确定要移除此控制者吗?", - "viewAuditLog": "查看审计日志", "yourAccessLevel": "您的访问级别", "noAuditEntries": "无审计记录", "target": "目标", - "pageInfo": "{start} - {end} / {total}", "failedToLoadAudit": "加载审计日志失败" }, "actAs": { diff --git a/frontend/src/routes/Dashboard.svelte b/frontend/src/routes/Dashboard.svelte index 3e93edf..36925af 100644 --- a/frontend/src/routes/Dashboard.svelte +++ b/frontend/src/routes/Dashboard.svelte @@ -24,9 +24,8 @@ import InviteCodesContent from '../components/dashboard/InviteCodesContent.svelte' import DidDocumentContent from '../components/dashboard/DidDocumentContent.svelte' import AdminContent from '../components/dashboard/AdminContent.svelte' - import DelegationAuditContent from '../components/dashboard/DelegationAuditContent.svelte' - type Section = 'settings' | 'security' | 'sessions' | 'app-passwords' | 'comms' | 'repo' | 'controllers' | 'delegation-audit' | 'invite-codes' | 'did-document' | 'admin' + type Section = 'settings' | 'security' | 'sessions' | 'app-passwords' | 'comms' | 'repo' | 'controllers' | 'invite-codes' | 'did-document' | 'admin' const auth = $derived(getAuthState()) let dropdownOpen = $state(false) @@ -72,7 +71,7 @@ '/comms': 'comms', '/repo': 'repo', '/controllers': 'controllers', - '/delegation-audit': 'delegation-audit', + '/invite-codes': 'invite-codes', '/did-document': 'did-document', '/admin': 'admin', @@ -147,7 +146,7 @@ 'comms': '/comms', 'repo': '/repo', 'controllers': '/controllers', - 'delegation-audit': '/delegation-audit', + 'invite-codes': '/invite-codes', 'did-document': '/did-document', 'admin': '/admin', @@ -176,7 +175,7 @@ { id: 'comms', label: $_('dashboard.navComms'), show: session?.accountKind !== 'migrated' }, { id: 'repo', label: $_('dashboard.navRepo'), show: session?.accountKind !== 'migrated' }, { id: 'controllers', label: $_('dashboard.navDelegation'), show: session?.accountKind !== 'migrated' }, - { id: 'delegation-audit', label: $_('dashboard.navDelegationAudit'), show: session?.accountKind !== 'migrated' }, + { id: 'invite-codes', label: $_('dashboard.navInviteCodes'), show: inviteCodesEnabled && (session?.isAdmin ?? false) && session?.accountKind !== 'migrated' }, { id: 'did-document', label: $_('dashboard.navDidDocument'), show: isPdsHostedDidWeb || session?.accountKind === 'migrated', highlight: session?.accountKind === 'migrated' ? 'migrated' : 'did-web' }, { id: 'admin', label: $_('dashboard.navAdmin'), show: session?.isAdmin ?? false, highlight: 'admin' }, @@ -303,8 +302,7 @@ {:else if currentSection === 'controllers'} - {:else if currentSection === 'delegation-audit'} - + {:else if currentSection === 'invite-codes'} {:else if currentSection === 'did-document'} diff --git a/frontend/src/tests/migration/atproto-client.test.ts b/frontend/src/tests/migration/atproto-client.test.ts index cd2202d..b21a69a 100644 --- a/frontend/src/tests/migration/atproto-client.test.ts +++ b/frontend/src/tests/migration/atproto-client.test.ts @@ -1,4 +1,4 @@ -import { beforeEach, describe, expect, it } from "vitest"; +import { beforeEach, describe, expect, it, vi } from "vitest"; import { AtprotoClient, base64UrlDecode,