Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Features/228 signed url store #229

Merged
merged 2 commits into from
Jan 15, 2024
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
38 changes: 6 additions & 32 deletions frontend/src/components/NavBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,27 +37,17 @@
</div>
<drop-down class="self-center">
<template #trigger>
<div
class="w-12 h-12 mr-4 self-center flex-center rounded-full text-lg bg-white font-normal text-white"
:class="{'bg-teal-500': user.data.avatarUrl === null}"
>
<span v-if="user.data.avatarUrl === null">
{{ initials(user.data.name) }}
</span>
<span v-else>
<img class="rounded-full w-[48px] h-[48px]" :alt="initials(user.data.name)" :src="user.data.avatarUrl"/>
</span>
</div>
<avatar />
</template>
<template #default>
<div class="flex flex-col gap-2 rounded-md w-48 p-4 bg-white dark:bg-gray-700 shadow-md">
<router-link :to="{ name: 'profile' }" class="p-2">
{{ t('label.userProfile') }}
</router-link>
<text-button
v-show="signedUserUrl"
v-show="user.data.signedUrl"
:label="t('label.shareMyLink')"
:copy="signedUserUrl"
:copy="user.data.signedUrl"
class="border-none flex-row-reverse justify-between !text-inherit !text-base !font-normal hover:bg-inherit hover:shadow-none"
/>
<hr class="border-teal-500" />
Expand All @@ -72,13 +62,13 @@
</template>

<script setup>
import { ref, inject, onMounted } from 'vue';
import { inject } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router';
import { initials } from '@/utils';
import { useUserStore } from '@/stores/user-store';
import NavBarItem from "@/elements/NavBarItem";
import Avatar from "@/elements/Avatar";
import DropDown from "@/elements/DropDown";
import NavBarItem from "@/elements/NavBarItem";
import TextButton from "@/elements/TextButton";

// component constants
Expand All @@ -93,25 +83,9 @@ defineProps({
navItems: Array, // list of route names that are also lang keys (format: label.<key>), used as nav items
});

const signedUserUrl = ref('');

// do log out
const logout = async () => {
await user.logout(call);
await router.push('/');
};

const getSignedUserUrl = async () => {
// Retrieve the user short url
const { data, error } = await call('me/signature').get().json();
if (error.value) {
return;
}

signedUserUrl.value = data.value.url;
};

onMounted(async () => {
await getSignedUserUrl();
});
</script>
25 changes: 4 additions & 21 deletions frontend/src/components/ScheduleCreation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,9 @@
<!-- action buttons -->
<div class="flex justify-center gap-4 mt-auto">
<primary-button
v-if="publicLink && existing"
v-if="user.data.signedUrl && existing"
:label="t('label.shareMyLink')"
:copy="publicLink"
:copy="user.data.signedUrl"
/>
</div>
<div class="flex gap-4 mt-auto">
Expand Down Expand Up @@ -301,7 +301,7 @@
:open="savedConfirmation.show"
:is-schedule="true"
:title="savedConfirmation.title"
:public-link="publicLink"
:public-link="user.data.signedUrl"
@close="closeCreatedModal"
/>
</template>
Expand Down Expand Up @@ -475,15 +475,6 @@ const resetSchedule = () => {
state.value = scheduleCreationState.details;
};

// hold public availability link of user
const publicLink = ref('');
onMounted(async () => {
const { data, error } = await call('me/signature').get().json();
if (!error.value) {
publicLink.value = data.value.url;
}
});

// handle actual schedule creation/update
const savingInProgress = ref(false);
const saveSchedule = async (withConfirmation = true) => {
Expand Down Expand Up @@ -519,17 +510,9 @@ const saveSchedule = async (withConfirmation = true) => {
return;
}

if (withConfirmation) {
// Retrieve the user short url
const { data: sig_data, error: sig_error } = await call('me/signature').get().json();
if (sig_error.value) {
savingInProgress.value = false;
return;
}

if (withConfirmation) {
// show confirmation
savedConfirmation.title = data.value.name;
publicLink.value = sig_data.value.url;
savedConfirmation.show = true;
}

Expand Down
29 changes: 6 additions & 23 deletions frontend/src/components/SettingsAccount.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@
<div class="w-full flex justify-between items-center gap-4">
<div class="relative w-full">
<input
v-model="signedUserUrl"
:value="user.data.signedUrl"
type="text"
class="w-full rounded-md mr-2 pr-7"
readonly
/>
<a :href="signedUserUrl" target="_blank" class="text-gray-500 absolute right-1.5 top-1/2 -translate-y-1/2">
<a :href="user.data.signedUrl" target="_blank" class="text-gray-500 absolute right-1.5 top-1/2 -translate-y-1/2">
<icon-external-link class="w-5 h-5" />
</a>
</div>
<text-button :label="t('label.copyLink')" :copy="signedUserUrl" />
<text-button :label="t('label.copyLink')" :copy="user.data.signedUrl" />
</div>
</label>
<div class="self-end flex gap-4 mt-6">
Expand Down Expand Up @@ -177,9 +177,6 @@ const deleteAccountSecondModalOpen = ref(false);
const refreshLinkModalOpen = ref(false);
const updateUsernameModalOpen = ref(false);

// calculate signed link
const signedUserUrl = ref('');

const closeModals = () => {
downloadAccountModalOpen.value = false;
deleteAccountFirstModalOpen.value = false;
Expand All @@ -188,18 +185,8 @@ const closeModals = () => {
updateUsernameModalOpen.value = false;
};

const getSignedUserUrl = async () => {
// Retrieve the user short url
const { data, error } = await call('me/signature').get().json();
if (error.value) {
return;
}

signedUserUrl.value = data.value.url;
};

const refreshData = async () => Promise.all([
getSignedUserUrl(),
user.updateSignedUrl(call),
externalConnectionsStore.fetch(call),
]);

Expand All @@ -214,6 +201,7 @@ const updateUser = async () => {
if (!error.value) {
// update user in store
user.$patch({ data: { ...user.data, ...inputData }});
await user.updateSignedUrl(call);
errorUsername.value = false;
// TODO show some confirmation
await refreshData();
Expand Down Expand Up @@ -270,12 +258,7 @@ const refreshLink = async () => {
};

const refreshLinkConfirm = async () => {
const { data, error } = await call('me/signature').post().json();

if (error.value) {
console.log('Error!', data.value);
}

await user.changeSignedUrl(call);
await refreshData();
closeModals();
};
Expand Down
19 changes: 19 additions & 0 deletions frontend/src/elements/Avatar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<template>
<div
class="w-12 h-12 mr-4 self-center flex-center rounded-full text-lg bg-white font-normal text-white"
:class="{'!bg-teal-500': user.data.avatarUrl === null}"
>
<span v-if="user.data.avatarUrl === null">
{{ initials(user.data.name) }}
</span>
<span v-else>
<img class="rounded-full w-[48px] h-[48px]" :alt="initials(user.data.name)" :src="user.data.avatarUrl"/>
</span>
</div>
</template>

<script setup>
import { initials } from '@/utils';
import { useUserStore } from '@/stores/user-store';
const user = useUserStore();
</script>
27 changes: 26 additions & 1 deletion frontend/src/stores/user-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const initialUserObject = {
name: null,
timezone: null,
username: null,
signedUrl: null,
avatarUrl: null,
accessToken: null,
};
Expand Down Expand Up @@ -42,8 +43,32 @@ export const useUserStore = defineStore('user', {
}
});

return await this.signedUrl(fetch);
},
// retrieve the current signed url and update store
async updateSignedUrl(fetch) {
const { error, data } = await fetch('me/signature').get().json();

if (error.value || !data.value.url) {
console.error(error.value, data.value);
return false;
}

this.data.signedUrl = data.value.url;

return true;
},
// invalidate the current signed url and replace it with a new one
async changeSignedUrl(fetch) {
const { error, data } = await fetch('me/signature').post().json();

if (error.value) {
console.error(error.value, data.value);
return false;
}

return this.updateSignedUrl(fetch);
},
async login(fetch, username, password) {
this.reset();

Expand All @@ -67,7 +92,7 @@ export const useUserStore = defineStore('user', {
return await this.profile(fetch);
},
async logout(fetch) {
const { error, data } = await fetch('logout').get().json();
const { error } = await fetch('logout').get().json();

if (error.value) {
console.warn("Error logging out: ", error.value);
Expand Down