Skip to content

Commit 9623738

Browse files
feat(frontend): ufo access keys (#2782)
* feat(frontend): ufo access keys * feat: set admin controller * feat: remove controller * feat: always admin * chore: fmt
1 parent a8fd6ba commit 9623738

17 files changed

Lines changed: 311 additions & 27 deletions

src/frontend/src/lib/components/mission-control/setup/MissionControlAccessKeys.svelte

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
import { nonNullish } from '@dfinity/utils';
33
import type { Principal } from '@icp-sdk/core/principal';
44
import type { MissionControlDid } from '$declarations';
5-
import { listMissionControlControllers } from '$lib/api/mission-control.api';
65
import AccessKeys from '$lib/components/modules/access-keys/AccessKeys.svelte';
76
import { authIdentity } from '$lib/derived/auth.derived';
7+
import { listMissionControlControllers } from '$lib/services/access-keys/mission-control.key.list.services';
88
import {
99
addMissionControlAccessKey,
1010
removeMissionControlAccessKey
@@ -13,7 +13,8 @@
1313
import type {
1414
AddAccessKeyResult,
1515
AddAccessKeyParams,
16-
AccessKeyIdParam
16+
AccessKeyIdParam,
17+
AccessKeyUi
1718
} from '$lib/types/access-keys';
1819
import type { MissionControlId } from '$lib/types/mission-control';
1920
@@ -23,7 +24,7 @@
2324
2425
let { missionControlId }: Props = $props();
2526
26-
const list = (): Promise<[Principal, MissionControlDid.AccessKey][]> =>
27+
const list = (): Promise<[Principal, AccessKeyUi][]> =>
2728
listMissionControlControllers({ missionControlId, identity: $authIdentity });
2829
2930
const remove = async (accessKey: AccessKeyIdParam): Promise<AddAccessKeyResult> =>

src/frontend/src/lib/components/modals/setup/AccessKeyCreateModal.svelte

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
let step: 'init' | 'in_progress' | 'ready' | 'error' = $state('init');
2727
2828
let accessKeyId = $state('');
29-
let scope = $state<AddAccessKeyScope>('write');
29+
// svelte-ignore state_referenced_locally
30+
let scope = $state<AddAccessKeyScope>(segment.segment === 'ufo' ? 'admin' : 'write');
3031
let identity: string | undefined = $state();
3132
3233
const initAccessKey = (): string | undefined => {
@@ -180,7 +181,7 @@
180181
{#snippet label()}
181182
{$i18n.controllers.scope}
182183
{/snippet}
183-
<select name="scope" bind:value={scope}>
184+
<select name="scope" disabled={segment.segment === 'ufo'} bind:value={scope}>
184185
<option value="submit">{$i18n.controllers.submit}</option>
185186
<option value="write">{$i18n.controllers.write}</option>
186187
<option value="admin">{$i18n.controllers.admin}</option>

src/frontend/src/lib/components/modules/access-keys/AccessKeyDelete.svelte

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
<script lang="ts">
22
import { isNullish } from '@dfinity/utils';
33
import type { Principal } from '@icp-sdk/core/principal';
4-
import type { SatelliteDid } from '$declarations';
54
import Confirmation from '$lib/components/app/core/Confirmation.svelte';
65
import Value from '$lib/components/ui/Value.svelte';
76
import { busy } from '$lib/stores/app/busy.store';
87
import { i18n } from '$lib/stores/app/i18n.store';
98
import { toasts } from '$lib/stores/app/toasts.store';
10-
import type { AccessKeyIdParam, AddAccessKeyResult } from '$lib/types/access-keys';
9+
import type { AccessKeyIdParam, AccessKeyUi, AddAccessKeyResult } from '$lib/types/access-keys';
1110
1211
interface Props {
1312
visible?: boolean;
14-
selectedController: [Principal, SatelliteDid.AccessKey | undefined] | undefined;
13+
selectedController: [Principal, AccessKeyUi | undefined] | undefined;
1514
remove: (params: AccessKeyIdParam) => Promise<AddAccessKeyResult>;
1615
load: () => Promise<void>;
1716
}

src/frontend/src/lib/components/modules/access-keys/AccessKeys.svelte

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import { nonNullish } from '@dfinity/utils';
33
import type { Principal } from '@icp-sdk/core/principal';
44
import { onMount } from 'svelte';
5-
import type { MissionControlDid } from '$declarations';
65
import AccessKeyAdd from '$lib/components/modules/access-keys/AccessKeyAdd.svelte';
76
import AccessKeyDelete from '$lib/components/modules/access-keys/AccessKeyDelete.svelte';
87
import AccessKeyInfo from '$lib/components/modules/access-keys/AccessKeyInfo.svelte';
@@ -15,23 +14,24 @@
1514
import type {
1615
AddAccessKeyResult,
1716
AddAccessKeyParams,
18-
AccessKeyIdParam
17+
AccessKeyIdParam,
18+
AccessKeyUi
1919
} from '$lib/types/access-keys';
2020
import type { CanisterSegmentWithLabel } from '$lib/types/canister';
2121
import { metadataProfile } from '$lib/utils/metadata.utils';
2222
2323
interface Props {
24-
list: () => Promise<[Principal, MissionControlDid.AccessKey][]>;
24+
list: () => Promise<[Principal, AccessKeyUi][]>;
2525
remove: (params: AccessKeyIdParam) => Promise<AddAccessKeyResult>;
2626
add: (params: AddAccessKeyParams) => Promise<AddAccessKeyResult>;
2727
segment: CanisterSegmentWithLabel;
2828
// The canister and user are controllers of the mission control but not added in its state per default
29-
extraControllers?: [Principal, MissionControlDid.AccessKey][];
29+
extraControllers?: [Principal, AccessKeyUi][];
3030
}
3131
3232
let { list, remove, add, segment, extraControllers = [] }: Props = $props();
3333
34-
let controllers = $state<[Principal, MissionControlDid.AccessKey][]>([]);
34+
let controllers = $state<[Principal, AccessKeyUi][]>([]);
3535
3636
const load = async () => {
3737
try {
@@ -52,9 +52,7 @@
5252
5353
let visibleDelete = $state(false);
5454
let visibleInfo = $state(false);
55-
let selectedController = $state<[Principal, MissionControlDid.AccessKey | undefined] | undefined>(
56-
undefined
57-
);
55+
let selectedController = $state<[Principal, AccessKeyUi | undefined] | undefined>(undefined);
5856
5957
const isMissionControl = (controllerId: Principal): boolean =>
6058
nonNullish($missionControlId) && $missionControlId.toText() === controllerId.toText();

src/frontend/src/lib/components/orbiter/setup/OrbiterAccessKeys.svelte

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
<script lang="ts">
22
import type { Principal } from '@icp-sdk/core/principal';
3-
import type { MissionControlDid } from '$declarations';
43
import { deleteOrbitersController, setOrbitersController } from '$lib/api/mission-control.api';
5-
import { listOrbiterControllers } from '$lib/api/orbiter.api';
64
import AccessKeys from '$lib/components/modules/access-keys/AccessKeys.svelte';
75
import { authIdentity } from '$lib/derived/auth.derived';
86
import { missionControlId } from '$lib/derived/console/account.mission-control.derived';
97
import { addAccessKey, removeAccessKey } from '$lib/services/access-keys/access-keys.services';
108
import { addOrbiterAccessKey } from '$lib/services/access-keys/orbiter.key.add.services';
9+
import { listOrbiterControllers } from '$lib/services/access-keys/orbiter.key.list.services';
1110
import { removeOrbiterAccessKey } from '$lib/services/access-keys/orbiter.key.remove.services';
1211
import { i18n } from '$lib/stores/app/i18n.store';
1312
import type {
1413
AddAccessKeyResult,
1514
AddAccessKeyParams,
1615
AccessKeyWithDevFn,
1716
AccessKeyWithMissionControlFn,
18-
AccessKeyIdParam
17+
AccessKeyIdParam,
18+
AccessKeyUi
1919
} from '$lib/types/access-keys';
2020
2121
interface Props {
@@ -24,7 +24,7 @@
2424
2525
let { orbiterId }: Props = $props();
2626
27-
const list = (): Promise<[Principal, MissionControlDid.AccessKey][]> =>
27+
const list = (): Promise<[Principal, AccessKeyUi][]> =>
2828
listOrbiterControllers({ orbiterId, identity: $authIdentity });
2929
3030
const remove = async (accessKey: AccessKeyIdParam): Promise<AddAccessKeyResult> => {

src/frontend/src/lib/components/satellites/setup/SatelliteAccessKeys.svelte

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
<script lang="ts">
22
import type { Principal } from '@icp-sdk/core/principal';
3-
import type { MissionControlDid } from '$declarations';
43
import {
54
deleteSatellitesController,
65
setSatellitesController
76
} from '$lib/api/mission-control.api';
8-
import { listControllers } from '$lib/api/satellites.api';
97
import AccessKeys from '$lib/components/modules/access-keys/AccessKeys.svelte';
108
import { authIdentity } from '$lib/derived/auth.derived';
119
import { missionControlId } from '$lib/derived/console/account.mission-control.derived';
1210
import { addAccessKey, removeAccessKey } from '$lib/services/access-keys/access-keys.services';
1311
import { addSatellitesAccessKey } from '$lib/services/access-keys/satellites.key.add.services';
12+
import { listSatelliteControllers } from '$lib/services/access-keys/satellites.key.list.services';
1413
import { removeSatellitesAccessKey } from '$lib/services/access-keys/satellites.key.remove.services';
1514
import { i18n } from '$lib/stores/app/i18n.store';
1615
import type {
1716
AddAccessKeyResult,
1817
AddAccessKeyParams,
1918
AccessKeyWithDevFn,
2019
AccessKeyWithMissionControlFn,
21-
AccessKeyIdParam
20+
AccessKeyIdParam,
21+
AccessKeyUi
2222
} from '$lib/types/access-keys';
2323
import type { Satellite } from '$lib/types/satellite';
2424
@@ -28,8 +28,8 @@
2828
2929
let { satellite }: Props = $props();
3030
31-
const list = (): Promise<[Principal, MissionControlDid.AccessKey][]> =>
32-
listControllers({ satelliteId: satellite.satellite_id, identity: $authIdentity });
31+
const list = (): Promise<[Principal, AccessKeyUi][]> =>
32+
listSatelliteControllers({ satelliteId: satellite.satellite_id, identity: $authIdentity });
3333
3434
const remove = async (accessKey: AccessKeyIdParam): Promise<AddAccessKeyResult> => {
3535
const satelliteIds = [satellite.satellite_id];
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<script lang="ts">
2+
import type { Principal } from '@icp-sdk/core/principal';
3+
import AccessKeys from '$lib/components/modules/access-keys/AccessKeys.svelte';
4+
import { authIdentity } from '$lib/derived/auth.derived';
5+
import {
6+
addUfoController,
7+
listUfoControllers,
8+
removeUfoController
9+
} from '$lib/services/access-keys/ufo.key.services';
10+
import { i18n } from '$lib/stores/app/i18n.store';
11+
import type {
12+
AddAccessKeyResult,
13+
AddAccessKeyParams,
14+
AccessKeyIdParam,
15+
AccessKeyUi
16+
} from '$lib/types/access-keys';
17+
import type { Ufo } from '$lib/types/ufo';
18+
19+
interface Props {
20+
ufo: Ufo;
21+
}
22+
23+
let { ufo }: Props = $props();
24+
25+
const list = (): Promise<[Principal, AccessKeyUi][]> =>
26+
listUfoControllers({ ufoId: ufo.ufo_id, identity: $authIdentity });
27+
28+
const remove = async (accessKey: AccessKeyIdParam): Promise<AddAccessKeyResult> =>
29+
await removeUfoController({
30+
identity: $authIdentity,
31+
ufoId: ufo.ufo_id,
32+
accessKey
33+
});
34+
35+
const add = async (accessKey: AddAccessKeyParams): Promise<AddAccessKeyResult> =>
36+
await addUfoController({
37+
identity: $authIdentity,
38+
accessKey,
39+
ufoId: ufo.ufo_id
40+
});
41+
</script>
42+
43+
<AccessKeys
44+
{add}
45+
{list}
46+
{remove}
47+
segment={{
48+
label: $i18n.ufo.title,
49+
canisterId: ufo.ufo_id.toText(),
50+
segment: 'ufo'
51+
}}
52+
/>

src/frontend/src/lib/components/ufos/setup/UfoSettings.svelte

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
<script lang="ts">
22
import CanisterSettings from '$lib/components/modules/canister/settings/CanisterSettings.svelte';
33
import Snapshots from '$lib/components/modules/snapshot/Snapshots.svelte';
4-
import SatelliteAccessKeys from '$lib/components/satellites/setup/SatelliteAccessKeys.svelte';
4+
import UfoAccessKeys from '$lib/components/ufos/setup/UfoAccessKeys.svelte';
55
import { i18n } from '$lib/stores/app/i18n.store';
6-
import type { Satellite } from '$lib/types/satellite';
76
import type { Ufo } from '$lib/types/ufo';
87
98
interface Props {
@@ -15,4 +14,6 @@
1514

1615
<CanisterSettings canisterId={ufo.ufo_id} segment="ufo" segmentLabel={$i18n.ufo.title} />
1716

17+
<UfoAccessKeys {ufo} />
18+
1819
<Snapshots canisterId={ufo.ufo_id} segment="ufo" segmentLabel={$i18n.ufo.title} />

src/frontend/src/lib/i18n/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,7 @@
660660
"controllers_no_selection": "No access key to delete selected.",
661661
"controllers_add": "Unexpected error(s) while adding the access key.",
662662
"controllers_delete": "Unexpected error(s) while deleting the access key.",
663+
"ufo_controller_not_admin": "Only access keys with admin privileges can be added to a UFO.",
663664
"data_delete": "Unexpected error(s) while deleting.",
664665
"key_invalid": "Key is invalid or empty.",
665666
"full_path_invalid": "Key (full_path) is invalid or empty.",

src/frontend/src/lib/i18n/zh-cn.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,7 @@
662662
"controllers_no_selection": "未选择要删除的密钥。",
663663
"controllers_add": "添加访问密钥时发生意外错误。",
664664
"controllers_delete": "删除密钥时发生意外错误。",
665+
"ufo_controller_not_admin": "只有具有管理员权限的访问密钥才能添加到 UFO。",
665666
"data_delete": "删除时发生意外错误。",
666667
"key_invalid": "密钥无效或为空。",
667668
"full_path_invalid": "密钥(full_path)无效或为空。",

0 commit comments

Comments
 (0)