Skip to content

Commit

Permalink
improve efficiency by reusing trust data
Browse files Browse the repository at this point in the history
  • Loading branch information
overheadhunter committed Jun 12, 2024
1 parent 7efc6a1 commit ef60c3e
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 41 deletions.
57 changes: 18 additions & 39 deletions frontend/src/components/TrustDetails.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
<template>
<div v-if="state === State.Loading">
<div v-if="onFetchError == null">
{{ t('common.loading') }}
</div>
<div v-else>
<FetchError :error="onFetchError" :retry="fetchData"/>
</div>
</div>
<Popover v-else-if="state === State.ShowTrust" as="div" class="relative inline-block text-left">
<Popover as="div" class="relative inline-block text-left">
<PopoverButton class="inline-flex items-center bg-gray-50 ring-1 ring-inset ring-gray-500/10 mx-1 p-1 rounded-full focus:outline-none focus:ring-primary">
<ShieldExclamationIcon v-if="trustLevel === -1" class="h-4 w-4 text-red-500" aria-label="Unverified" />
<ShieldCheckIcon v-else class="h-4 w-4 text-primary" aria-label="Verified" />
Expand All @@ -16,7 +8,7 @@
<transition enter-active-class="transition ease-out duration-100" enter-from-class="transform opacity-0 scale-95" enter-to-class="transform opacity-100 scale-100" leave-active-class="transition ease-in duration-75" leave-from-class="transform opacity-100 scale-100" leave-to-class="transform opacity-0 scale-95">
<PopoverPanel class="absolute right-0 z-10 mt-2 origin-top-right rounded-md bg-white p-4 shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none">
<p class="text-sm">Trust Level {{ trustLevel }}</p>
<button v-if="trustLevel === -1 && trustedUser.ecdsaPublicKey" @click="sign()" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-primary text-base font-medium text-white hover:bg-primary-d1 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary sm:ml-3 sm:w-auto sm:text-sm">
<button v-if="trustLevel !== 0 && trustedUser.ecdhPublicKey && trustedUser.ecdsaPublicKey" @click="sign()" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-primary text-base font-medium text-white hover:bg-primary-d1 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary sm:ml-3 sm:w-auto sm:text-sm">
TODO sign
</button>
</PopoverPanel>
Expand All @@ -27,61 +19,48 @@
<script setup lang="ts">
import { Popover, PopoverButton, PopoverPanel } from '@headlessui/vue';
import { ShieldCheckIcon, ShieldExclamationIcon } from '@heroicons/vue/20/solid';
import { onMounted, ref } from 'vue';
import { computed, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import backend, { TrustDto, UserDto } from '../common/backend';
import { TrustDto, UserDto } from '../common/backend';
import userdata from '../common/userdata';
import wot from '../common/wot';
import FetchError from './FetchError.vue';
enum State {
Loading,
ShowTrust
}
const { t } = useI18n({ useScope: 'global' });
const props = defineProps<{
trustedUser: UserDto
trustedUser: UserDto,
trusts: TrustDto[]
}>();
const state = ref(State.Loading);
const onFetchError = ref<Error | null>();
const trust = ref<TrustDto>();
const trustLevel = ref<number>(-1);
const emit = defineEmits<{
trustChanged: [TrustDto]
}>();
onMounted(fetchData);
const trust = computed(() => props.trusts.find(trust => trust.trustedUserId === props.trustedUser.id));
const trustLevel = ref<number>(-1);
async function fetchData() {
try {
trust.value = await backend.trust.get(props.trustedUser.id);
trustLevel.value = await computeTrustLevel(trust.value);
state.value = State.ShowTrust;
} catch (error) {
console.error('Fetching data failed.', error);
onFetchError.value = error instanceof Error ? error : new Error('Unknown Error');
}
}
watch(trust, computeTrustLevel, { immediate: true });
async function computeTrustLevel(trust?: TrustDto) {
const me = await userdata.me;
if (me.id === props.trustedUser.id) {
return 0; // Self
trustLevel.value = 0; // Self
} else if (trust && props.trustedUser.ecdhPublicKey && props.trustedUser.ecdsaPublicKey) {
try {
await wot.verify(trust.signatureChain, { ecdhPublicKey: props.trustedUser.ecdhPublicKey, ecdsaPublicKey: props.trustedUser.ecdsaPublicKey });
return trust.signatureChain.length;
trustLevel.value = trust.signatureChain.length;
} catch (error) {
console.error('WoT signature verification failed.', error);
return -1; // Unverified
trustLevel.value = -1; // Unverified
}
} else {
return -1; // Unverified
trustLevel.value = -1; // Unverified
}
}
async function sign() {
trust.value = await wot.sign(props.trustedUser);
const newTrust = await wot.sign(props.trustedUser);
emit('trustChanged', newTrust);
}
</script>
10 changes: 8 additions & 2 deletions frontend/src/components/VaultDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
<div class="flex items-center whitespace-nowrap w-full" :title="member.name">
<img :src="member.pictureUrl" alt="" class="w-8 h-8 rounded-full" />
<p class="w-full ml-4 text-sm font-medium text-gray-900 truncate">{{ member.name }}</p>
<TrustDetails v-if="member.type === 'USER'" :trusted-user="member"/>
<TrustDetails v-if="member.type === 'USER'" :trusted-user="member" :trusts="trusts" @trust-changed="refreshTrusts()"/>
<div v-if="member.role == 'OWNER'" class="ml-3 inline-flex items-center rounded-md bg-gray-50 px-2 py-1 text-xs font-medium text-gray-600 ring-1 ring-inset ring-gray-500/10">{{ t('vaultDetails.sharedWith.badge.owner') }}</div>
</div>
<Menu v-if="member.id != me?.id" as="div" class="relative ml-2 inline-block flex-shrink-0 text-left">
Expand Down Expand Up @@ -213,7 +213,7 @@ import { PlusSmallIcon } from '@heroicons/vue/24/solid';
import { computed, nextTick, onMounted, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import auth from '../common/auth';
import backend, { AuthorityDto, ConflictError, ForbiddenError, LicenseUserInfoDto, MemberDto, NotFoundError, PaymentRequiredError, UserDto, VaultDto, VaultRole } from '../common/backend';
import backend, { AuthorityDto, ConflictError, ForbiddenError, LicenseUserInfoDto, MemberDto, NotFoundError, PaymentRequiredError, TrustDto, UserDto, VaultDto, VaultRole } from '../common/backend';
import { VaultKeys } from '../common/crypto';
import { JWT, JWTHeader } from '../common/jwt';
import userdata from '../common/userdata';
Expand Down Expand Up @@ -266,6 +266,7 @@ const recoverVaultDialog = ref<typeof RecoverVaultDialog>();
const vault = ref<VaultDto>();
const vaultKeys = ref<VaultKeys>();
const members = ref<Map<string, MemberDto>>(new Map());
const trusts = ref<TrustDto[]>([]);
const usersRequiringAccessGrant = ref<UserDto[]>([]);
const claimVaultOwnershipDialog = ref<typeof ClaimVaultOwnershipDialog>();
const claimingVaultOwnership = ref(false);
Expand Down Expand Up @@ -298,6 +299,7 @@ async function fetchData() {
async function fetchOwnerData() {
try {
(await backend.vaults.getMembers(props.vaultId)).forEach(member => members.value.set(member.id, member));
await refreshTrusts();
usersRequiringAccessGrant.value = await backend.vaults.getUsersRequiringAccessGrant(props.vaultId);
vaultRecoveryRequired.value = false;
const vaultKeyJwe = await backend.vaults.accessToken(props.vaultId, true);
Expand Down Expand Up @@ -449,6 +451,10 @@ function permissionGranted() {
usersRequiringAccessGrant.value = [];
}
async function refreshTrusts() {
trusts.value = await backend.trust.listTrusted();
}
async function refreshLicense() {
license.value = await backend.license.getUserInfo();
emit('licenseStatusUpdated', license.value);
Expand Down

0 comments on commit ef60c3e

Please sign in to comment.