Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
import { nonNullish } from '@dfinity/utils';
import type { Principal } from '@icp-sdk/core/principal';
import type { MissionControlDid } from '$declarations';
import { listMissionControlControllers } from '$lib/api/mission-control.api';
import AccessKeys from '$lib/components/modules/access-keys/AccessKeys.svelte';
import { authIdentity } from '$lib/derived/auth.derived';
import { listMissionControlControllers } from '$lib/services/access-keys/mission-control.key.list.services';
import {
addMissionControlAccessKey,
removeMissionControlAccessKey
Expand All @@ -13,7 +13,8 @@
import type {
AddAccessKeyResult,
AddAccessKeyParams,
AccessKeyIdParam
AccessKeyIdParam,
AccessKeyUi
} from '$lib/types/access-keys';
import type { MissionControlId } from '$lib/types/mission-control';

Expand All @@ -23,7 +24,7 @@

let { missionControlId }: Props = $props();

const list = (): Promise<[Principal, MissionControlDid.AccessKey][]> =>
const list = (): Promise<[Principal, AccessKeyUi][]> =>
listMissionControlControllers({ missionControlId, identity: $authIdentity });

const remove = async (accessKey: AccessKeyIdParam): Promise<AddAccessKeyResult> =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
let step: 'init' | 'in_progress' | 'ready' | 'error' = $state('init');

let accessKeyId = $state('');
let scope = $state<AddAccessKeyScope>('write');
// svelte-ignore state_referenced_locally
let scope = $state<AddAccessKeyScope>(segment.segment === 'ufo' ? 'admin' : 'write');
let identity: string | undefined = $state();

const initAccessKey = (): string | undefined => {
Expand Down Expand Up @@ -180,7 +181,7 @@
{#snippet label()}
{$i18n.controllers.scope}
{/snippet}
<select name="scope" bind:value={scope}>
<select name="scope" disabled={segment.segment === 'ufo'} bind:value={scope}>
<option value="submit">{$i18n.controllers.submit}</option>
<option value="write">{$i18n.controllers.write}</option>
<option value="admin">{$i18n.controllers.admin}</option>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
<script lang="ts">
import { isNullish } from '@dfinity/utils';
import type { Principal } from '@icp-sdk/core/principal';
import type { SatelliteDid } from '$declarations';
import Confirmation from '$lib/components/app/core/Confirmation.svelte';
import Value from '$lib/components/ui/Value.svelte';
import { busy } from '$lib/stores/app/busy.store';
import { i18n } from '$lib/stores/app/i18n.store';
import { toasts } from '$lib/stores/app/toasts.store';
import type { AccessKeyIdParam, AddAccessKeyResult } from '$lib/types/access-keys';
import type { AccessKeyIdParam, AccessKeyUi, AddAccessKeyResult } from '$lib/types/access-keys';

interface Props {
visible?: boolean;
selectedController: [Principal, SatelliteDid.AccessKey | undefined] | undefined;
selectedController: [Principal, AccessKeyUi | undefined] | undefined;
remove: (params: AccessKeyIdParam) => Promise<AddAccessKeyResult>;
load: () => Promise<void>;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import { nonNullish } from '@dfinity/utils';
import type { Principal } from '@icp-sdk/core/principal';
import { onMount } from 'svelte';
import type { MissionControlDid } from '$declarations';
import AccessKeyAdd from '$lib/components/modules/access-keys/AccessKeyAdd.svelte';
import AccessKeyDelete from '$lib/components/modules/access-keys/AccessKeyDelete.svelte';
import AccessKeyInfo from '$lib/components/modules/access-keys/AccessKeyInfo.svelte';
Expand All @@ -15,23 +14,24 @@
import type {
AddAccessKeyResult,
AddAccessKeyParams,
AccessKeyIdParam
AccessKeyIdParam,
AccessKeyUi
} from '$lib/types/access-keys';
import type { CanisterSegmentWithLabel } from '$lib/types/canister';
import { metadataProfile } from '$lib/utils/metadata.utils';

interface Props {
list: () => Promise<[Principal, MissionControlDid.AccessKey][]>;
list: () => Promise<[Principal, AccessKeyUi][]>;
remove: (params: AccessKeyIdParam) => Promise<AddAccessKeyResult>;
add: (params: AddAccessKeyParams) => Promise<AddAccessKeyResult>;
segment: CanisterSegmentWithLabel;
// The canister and user are controllers of the mission control but not added in its state per default
extraControllers?: [Principal, MissionControlDid.AccessKey][];
extraControllers?: [Principal, AccessKeyUi][];
}

let { list, remove, add, segment, extraControllers = [] }: Props = $props();

let controllers = $state<[Principal, MissionControlDid.AccessKey][]>([]);
let controllers = $state<[Principal, AccessKeyUi][]>([]);

const load = async () => {
try {
Expand All @@ -52,9 +52,7 @@

let visibleDelete = $state(false);
let visibleInfo = $state(false);
let selectedController = $state<[Principal, MissionControlDid.AccessKey | undefined] | undefined>(
undefined
);
let selectedController = $state<[Principal, AccessKeyUi | undefined] | undefined>(undefined);

const isMissionControl = (controllerId: Principal): boolean =>
nonNullish($missionControlId) && $missionControlId.toText() === controllerId.toText();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
<script lang="ts">
import type { Principal } from '@icp-sdk/core/principal';
import type { MissionControlDid } from '$declarations';
import { deleteOrbitersController, setOrbitersController } from '$lib/api/mission-control.api';
import { listOrbiterControllers } from '$lib/api/orbiter.api';
import AccessKeys from '$lib/components/modules/access-keys/AccessKeys.svelte';
import { authIdentity } from '$lib/derived/auth.derived';
import { missionControlId } from '$lib/derived/console/account.mission-control.derived';
import { addAccessKey, removeAccessKey } from '$lib/services/access-keys/access-keys.services';
import { addOrbiterAccessKey } from '$lib/services/access-keys/orbiter.key.add.services';
import { listOrbiterControllers } from '$lib/services/access-keys/orbiter.key.list.services';
import { removeOrbiterAccessKey } from '$lib/services/access-keys/orbiter.key.remove.services';
import { i18n } from '$lib/stores/app/i18n.store';
import type {
AddAccessKeyResult,
AddAccessKeyParams,
AccessKeyWithDevFn,
AccessKeyWithMissionControlFn,
AccessKeyIdParam
AccessKeyIdParam,
AccessKeyUi
} from '$lib/types/access-keys';

interface Props {
Expand All @@ -24,7 +24,7 @@

let { orbiterId }: Props = $props();

const list = (): Promise<[Principal, MissionControlDid.AccessKey][]> =>
const list = (): Promise<[Principal, AccessKeyUi][]> =>
listOrbiterControllers({ orbiterId, identity: $authIdentity });

const remove = async (accessKey: AccessKeyIdParam): Promise<AddAccessKeyResult> => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
<script lang="ts">
import type { Principal } from '@icp-sdk/core/principal';
import type { MissionControlDid } from '$declarations';
import {
deleteSatellitesController,
setSatellitesController
} from '$lib/api/mission-control.api';
import { listControllers } from '$lib/api/satellites.api';
import AccessKeys from '$lib/components/modules/access-keys/AccessKeys.svelte';
import { authIdentity } from '$lib/derived/auth.derived';
import { missionControlId } from '$lib/derived/console/account.mission-control.derived';
import { addAccessKey, removeAccessKey } from '$lib/services/access-keys/access-keys.services';
import { addSatellitesAccessKey } from '$lib/services/access-keys/satellites.key.add.services';
import { listSatelliteControllers } from '$lib/services/access-keys/satellites.key.list.services';
import { removeSatellitesAccessKey } from '$lib/services/access-keys/satellites.key.remove.services';
import { i18n } from '$lib/stores/app/i18n.store';
import type {
AddAccessKeyResult,
AddAccessKeyParams,
AccessKeyWithDevFn,
AccessKeyWithMissionControlFn,
AccessKeyIdParam
AccessKeyIdParam,
AccessKeyUi
} from '$lib/types/access-keys';
import type { Satellite } from '$lib/types/satellite';

Expand All @@ -28,8 +28,8 @@

let { satellite }: Props = $props();

const list = (): Promise<[Principal, MissionControlDid.AccessKey][]> =>
listControllers({ satelliteId: satellite.satellite_id, identity: $authIdentity });
const list = (): Promise<[Principal, AccessKeyUi][]> =>
listSatelliteControllers({ satelliteId: satellite.satellite_id, identity: $authIdentity });

const remove = async (accessKey: AccessKeyIdParam): Promise<AddAccessKeyResult> => {
const satelliteIds = [satellite.satellite_id];
Expand Down
52 changes: 52 additions & 0 deletions src/frontend/src/lib/components/ufos/setup/UfoAccessKeys.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<script lang="ts">
import type { Principal } from '@icp-sdk/core/principal';
import AccessKeys from '$lib/components/modules/access-keys/AccessKeys.svelte';
import { authIdentity } from '$lib/derived/auth.derived';
import {
addUfoController,
listUfoControllers,
removeUfoController
} from '$lib/services/access-keys/ufo.key.services';
import { i18n } from '$lib/stores/app/i18n.store';
import type {
AddAccessKeyResult,
AddAccessKeyParams,
AccessKeyIdParam,
AccessKeyUi
} from '$lib/types/access-keys';
import type { Ufo } from '$lib/types/ufo';

interface Props {
ufo: Ufo;
}

let { ufo }: Props = $props();

const list = (): Promise<[Principal, AccessKeyUi][]> =>
listUfoControllers({ ufoId: ufo.ufo_id, identity: $authIdentity });

const remove = async (accessKey: AccessKeyIdParam): Promise<AddAccessKeyResult> =>
await removeUfoController({
identity: $authIdentity,
ufoId: ufo.ufo_id,
accessKey
});

const add = async (accessKey: AddAccessKeyParams): Promise<AddAccessKeyResult> =>
await addUfoController({
identity: $authIdentity,
accessKey,
ufoId: ufo.ufo_id
});
</script>

<AccessKeys
{add}
{list}
{remove}
segment={{
label: $i18n.ufo.title,
canisterId: ufo.ufo_id.toText(),
segment: 'ufo'
}}
/>
5 changes: 3 additions & 2 deletions src/frontend/src/lib/components/ufos/setup/UfoSettings.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
<script lang="ts">
import CanisterSettings from '$lib/components/modules/canister/settings/CanisterSettings.svelte';
import Snapshots from '$lib/components/modules/snapshot/Snapshots.svelte';
import SatelliteAccessKeys from '$lib/components/satellites/setup/SatelliteAccessKeys.svelte';
import UfoAccessKeys from '$lib/components/ufos/setup/UfoAccessKeys.svelte';
import { i18n } from '$lib/stores/app/i18n.store';
import type { Satellite } from '$lib/types/satellite';
import type { Ufo } from '$lib/types/ufo';

interface Props {
Expand All @@ -15,4 +14,6 @@

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

<UfoAccessKeys {ufo} />

<Snapshots canisterId={ufo.ufo_id} segment="ufo" segmentLabel={$i18n.ufo.title} />
1 change: 1 addition & 0 deletions src/frontend/src/lib/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,7 @@
"controllers_no_selection": "No access key to delete selected.",
"controllers_add": "Unexpected error(s) while adding the access key.",
"controllers_delete": "Unexpected error(s) while deleting the access key.",
"ufo_controller_not_admin": "Only access keys with admin privileges can be added to a UFO.",
"data_delete": "Unexpected error(s) while deleting.",
"key_invalid": "Key is invalid or empty.",
"full_path_invalid": "Key (full_path) is invalid or empty.",
Expand Down
1 change: 1 addition & 0 deletions src/frontend/src/lib/i18n/zh-cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,7 @@
"controllers_no_selection": "未选择要删除的密钥。",
"controllers_add": "添加访问密钥时发生意外错误。",
"controllers_delete": "删除密钥时发生意外错误。",
"ufo_controller_not_admin": "只有具有管理员权限的访问密钥才能添加到 UFO。",
"data_delete": "删除时发生意外错误。",
"key_invalid": "密钥无效或为空。",
"full_path_invalid": "密钥(full_path)无效或为空。",
Expand Down
18 changes: 18 additions & 0 deletions src/frontend/src/lib/services/access-keys/_key.list.services.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { MissionControlDid } from '$declarations';
import type { AccessKeyUi } from '$lib/types/access-keys';
import type { MissionControlId } from '$lib/types/mission-control';
import { fromNullable } from '@dfinity/utils';
import type { Principal } from '@icp-sdk/core/principal';

export const mapAccessKeysUi = (
keys: [Principal, MissionControlDid.AccessKey][]
): [MissionControlId, AccessKeyUi][] =>
keys.map(([id, { expires_at, updated_at, created_at, ...rest }]) => [
id,
{
...rest,
expiresAt: fromNullable(expires_at),
createdAt: created_at,
updatedAt: updated_at
}
]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { listMissionControlControllers as listMissionControlControllersApi } from '$lib/api/mission-control.api';
import { mapAccessKeysUi } from '$lib/services/access-keys/_key.list.services';
import type { AccessKeyUi } from '$lib/types/access-keys';
import type { NullishIdentity } from '$lib/types/itentity';
import type { MissionControlId } from '$lib/types/mission-control';

export const listMissionControlControllers = async (params: {
missionControlId: MissionControlId;
identity: NullishIdentity;
}): Promise<[MissionControlId, AccessKeyUi][]> => {
const accessKeys = await listMissionControlControllersApi(params);
return mapAccessKeysUi(accessKeys);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { listOrbiterControllers as listOrbiterControllersApi } from '$lib/api/orbiter.api';
import { mapAccessKeysUi } from '$lib/services/access-keys/_key.list.services';
import type { AccessKeyUi } from '$lib/types/access-keys';
import type { NullishIdentity } from '$lib/types/itentity';
import type { OrbiterId } from '$lib/types/orbiter';

export const listOrbiterControllers = async (params: {
orbiterId: OrbiterId;
identity: NullishIdentity;
}): Promise<[OrbiterId, AccessKeyUi][]> => {
const accessKeys = await listOrbiterControllersApi(params);
return mapAccessKeysUi(accessKeys);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { listControllers } from '$lib/api/satellites.api';
import { mapAccessKeysUi } from '$lib/services/access-keys/_key.list.services';
import type { AccessKeyUi } from '$lib/types/access-keys';
import type { NullishIdentity } from '$lib/types/itentity';
import type { SatelliteId } from '$lib/types/satellite';

export const listSatelliteControllers = async (params: {
satelliteId: SatelliteId;
identity: NullishIdentity;
}): Promise<[SatelliteId, AccessKeyUi][]> => {
const accessKeys = await listControllers(params);
return mapAccessKeysUi(accessKeys);
};
Loading
Loading