From 1c2133d9868a2de3922aaa73b7b1cf3d90063cca Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 13 Nov 2023 16:45:26 +0100 Subject: [PATCH] post multiple access tokens in single request --- frontend/src/common/backend.ts | 13 +++++++++++-- frontend/src/components/CreateVault.vue | 2 +- frontend/src/components/GrantPermissionDialog.vue | 6 ++++-- frontend/src/components/RecoverVaultDialog.vue | 2 +- frontend/src/components/VaultDetails.vue | 2 +- 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/frontend/src/common/backend.ts b/frontend/src/common/backend.ts index 570f52b5..9456b072 100644 --- a/frontend/src/common/backend.ts +++ b/frontend/src/common/backend.ts @@ -59,6 +59,11 @@ export type DeviceDto = { export type VaultRole = 'MEMBER' | 'OWNER'; +export type AccessGrant = { + userId: string, + token: string +}; + enum AuthorityType { User = 'USER', Group = 'GROUP' @@ -265,8 +270,12 @@ class VaultService { .catch((error) => rethrowAndConvertIfExpected(error, 403)); } - public async grantAccess(vaultId: string, userId: string, jwe: string) { - await axiosAuth.put(`/vaults/${vaultId}/access-tokens/${userId}`, jwe, { headers: { 'Content-Type': 'text/plain' } }) + public async grantAccess(vaultId: string, ...grants: AccessGrant[]) { + var body = grants.reduce>((accumulator, curr) => { + accumulator[curr.userId] = curr.token; + return accumulator; + }, {}); + await axiosAuth.post(`/vaults/${vaultId}/access-tokens`, body) .catch((error) => rethrowAndConvertIfExpected(error, 404, 409)); } diff --git a/frontend/src/components/CreateVault.vue b/frontend/src/components/CreateVault.vue index c973bfe5..02cca908 100644 --- a/frontend/src/components/CreateVault.vue +++ b/frontend/src/components/CreateVault.vue @@ -295,7 +295,7 @@ async function createVault() { vaultConfig.value = await VaultConfig.create(vaultId, vaultKeys.value); const ownerJwe = await vaultKeys.value.encryptForUser(base64.parse(owner.publicKey)); await backend.vaults.createOrUpdateVault(vaultId, vaultName.value, false, vaultDescription.value); - await backend.vaults.grantAccess(vaultId, owner.id, ownerJwe); + await backend.vaults.grantAccess(vaultId, { userId: owner.id, token: ownerJwe }); state.value = State.Finished; } catch (error) { console.error('Creating vault failed.', error); diff --git a/frontend/src/components/GrantPermissionDialog.vue b/frontend/src/components/GrantPermissionDialog.vue index 1852f87a..ce21138e 100644 --- a/frontend/src/components/GrantPermissionDialog.vue +++ b/frontend/src/components/GrantPermissionDialog.vue @@ -71,7 +71,7 @@ import { ExclamationTriangleIcon } from '@heroicons/vue/24/outline'; import { base64 } from 'rfc4648'; import { onMounted, ref } from 'vue'; import { useI18n } from 'vue-i18n'; -import backend, { ConflictError, NotFoundError, UserDto, VaultDto } from '../common/backend'; +import backend, { AccessGrant, ConflictError, NotFoundError, UserDto, VaultDto } from '../common/backend'; import { getFingerprint } from '../common/crypto'; import { VaultKeys } from '../common/crypto'; @@ -124,13 +124,15 @@ async function grantAccess() { } async function giveUsersAccess(users: UserDto[]) { + let tokens: AccessGrant[] = []; for (const user of users) { if (user.publicKey) { // some users might not have set up their key pair, so we can't share secrets with them yet const publicKey = base64.parse(user.publicKey); const jwe = await props.vaultKeys.encryptForUser(publicKey); - await backend.vaults.grantAccess(props.vault.id, user.id, jwe); + tokens.push({ userId: user.id, token: jwe }); } } + await backend.vaults.grantAccess(props.vault.id, ...tokens); } diff --git a/frontend/src/components/RecoverVaultDialog.vue b/frontend/src/components/RecoverVaultDialog.vue index 92bba68c..280bb9bb 100644 --- a/frontend/src/components/RecoverVaultDialog.vue +++ b/frontend/src/components/RecoverVaultDialog.vue @@ -108,7 +108,7 @@ async function recoverVault() { if (props.me.publicKey && vaultKeys) { const publicKey = base64.parse(props.me.publicKey); const jwe = await vaultKeys.encryptForUser(publicKey); - await backend.vaults.grantAccess(props.vault.id, props.me.id, jwe); + await backend.vaults.grantAccess(props.vault.id, { userId: props.me.id, token: jwe }); emit('recovered'); open.value = false; } diff --git a/frontend/src/components/VaultDetails.vue b/frontend/src/components/VaultDetails.vue index f9cd7ff3..d368cdac 100644 --- a/frontend/src/components/VaultDetails.vue +++ b/frontend/src/components/VaultDetails.vue @@ -310,7 +310,7 @@ async function provedOwnership(keys: VaultKeys, ownerKeyPair: CryptoKeyPair) { const vaultKeyJwe = keys.encryptForUser(base64.parse(me.value.publicKey)); try { - await backend.vaults.grantAccess(props.vaultId, me.value.id, await vaultKeyJwe); + await backend.vaults.grantAccess(props.vaultId, { userId: me.value.id, token: await vaultKeyJwe }); } catch (error) { if (error instanceof ConflictError) { console.debug('User already member of this vault.');