From 27ed919a1c1c5c507e22f18b3ebf36a740c0c230 Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Sat, 3 Dec 2022 10:39:34 -0900 Subject: [PATCH] replace attachment specific tokens with gen token --- frontend/components/Item/AttachmentsList.vue | 29 +++---- frontend/composables/use-api.ts | 2 +- frontend/lib/api/base/base-api.ts | 14 +++- frontend/lib/api/classes/items.ts | 13 --- frontend/lib/api/types/data-contracts.ts | 1 + frontend/lib/api/user.ts | 4 +- frontend/pages/index.vue | 1 + frontend/pages/item/[id]/index.vue | 85 ++++++++++++++++---- frontend/stores/auth.ts | 2 + 9 files changed, 98 insertions(+), 53 deletions(-) diff --git a/frontend/components/Item/AttachmentsList.vue b/frontend/components/Item/AttachmentsList.vue index f215256..1dd8855 100644 --- a/frontend/components/Item/AttachmentsList.vue +++ b/frontend/components/Item/AttachmentsList.vue @@ -10,7 +10,12 @@ {{ attachment.document.title }}
- + + + + + +
@@ -31,26 +36,12 @@ }); const api = useUserApi(); - const toast = useNotifier(); - async function getAttachmentUrl(attachment: ItemAttachment) { - const url = await api.items.getAttachmentUrl(props.itemId, attachment.id); - if (!url) { - toast.error("Failed to get attachment url"); - return; - } - - if (!document) { - window.open(url, "_blank"); - return; - } - - const link = document.createElement("a"); - link.href = url; - link.target = "_blank"; - link.setAttribute("download", attachment.document.title); - link.click(); + function attachmentURL(attachmentId : string) { + return api.authURL(`/items/${props.itemId}/attachments/${attachmentId}`); } + + diff --git a/frontend/composables/use-api.ts b/frontend/composables/use-api.ts index 69da2ed..cd06588 100644 --- a/frontend/composables/use-api.ts +++ b/frontend/composables/use-api.ts @@ -43,5 +43,5 @@ export function useUserApi(): UserClient { requests.addResponseInterceptor(observer.handler); } - return new UserClient(requests); + return new UserClient(requests, authStore.attachmentToken); } diff --git a/frontend/lib/api/base/base-api.ts b/frontend/lib/api/base/base-api.ts index b48d10b..bef9326 100644 --- a/frontend/lib/api/base/base-api.ts +++ b/frontend/lib/api/base/base-api.ts @@ -27,9 +27,21 @@ export function parseDate(obj: T, keys: Array = []): T { export class BaseAPI { http: Requests; + attachmentToken: string - constructor(requests: Requests) { + constructor(requests: Requests, attachmentToken: string = "") { this.http = requests; + this.attachmentToken = attachmentToken; + } + + // if a attachmentToken is present it will be added to URL as a query param + // this is done with a simple appending of the query param to the URL. If your + // URL already has a query param, this will not work. + authURL(url: string): string { + if (this.attachmentToken) { + return `/api/v1${url}?access_token=${this.attachmentToken}`; + } + return url; } /** diff --git a/frontend/lib/api/classes/items.ts b/frontend/lib/api/classes/items.ts index a97152d..2d6cce7 100644 --- a/frontend/lib/api/classes/items.ts +++ b/frontend/lib/api/classes/items.ts @@ -1,7 +1,6 @@ import { BaseAPI, route } from "../base"; import { parseDate } from "../base/base-api"; import { - ItemAttachmentToken, ItemAttachmentUpdate, ItemCreate, ItemOut, @@ -79,18 +78,6 @@ export class ItemsApi extends BaseAPI { }); } - async getAttachmentUrl(id: string, attachmentId: string): Promise { - const payload = await this.http.get({ - url: route(`/items/${id}/attachments/${attachmentId}`), - }); - - if (!payload.data) { - return ""; - } - - return route(`/items/${id}/attachments/download`, { token: payload.data.token }); - } - async deleteAttachment(id: string, attachmentId: string) { return await this.http.delete({ url: route(`/items/${id}/attachments/${attachmentId}`) }); } diff --git a/frontend/lib/api/types/data-contracts.ts b/frontend/lib/api/types/data-contracts.ts index 9829f14..464b8e7 100644 --- a/frontend/lib/api/types/data-contracts.ts +++ b/frontend/lib/api/types/data-contracts.ts @@ -324,6 +324,7 @@ export interface ItemAttachmentToken { } export interface TokenResponse { + attachmentToken: string; expiresAt: Date; token: string; } diff --git a/frontend/lib/api/user.ts b/frontend/lib/api/user.ts index 5c4940f..31538a8 100644 --- a/frontend/lib/api/user.ts +++ b/frontend/lib/api/user.ts @@ -15,8 +15,8 @@ export class UserClient extends BaseAPI { user: UserApi; actions: ActionsAPI; - constructor(requests: Requests) { - super(requests); + constructor(requests: Requests, attachmentToken: string) { + super(requests, attachmentToken); this.locations = new LocationsApi(requests); this.labels = new LabelsApi(requests); diff --git a/frontend/pages/index.vue b/frontend/pages/index.vue index 44183c6..070fa05 100644 --- a/frontend/pages/index.vue +++ b/frontend/pages/index.vue @@ -105,6 +105,7 @@ authStore.$patch({ token: data.token, expires: data.expiresAt, + attachmentToken: data.attachmentToken, }); navigateTo("/home"); diff --git a/frontend/pages/item/[id]/index.vue b/frontend/pages/item/[id]/index.vue index e3d6afb..b003023 100644 --- a/frontend/pages/item/[id]/index.vue +++ b/frontend/pages/item/[id]/index.vue @@ -27,17 +27,30 @@ }); type FilteredAttachments = { - photos: ItemAttachment[]; attachments: ItemAttachment[]; warranty: ItemAttachment[]; manuals: ItemAttachment[]; receipts: ItemAttachment[]; }; + type Photo = { + src: string; + } + + const photos = computed(() => { + return item.value?.attachments.reduce((acc, cur) => { + if (cur.type === "photo") { + acc.push({ + src: api.authURL(`/items/${item.value.id}/attachments/${cur.id}`), + }) + } + return acc; + }, [] as Photo[]) || []; + }); + const attachments = computed(() => { if (!item.value) { return { - photos: [], attachments: [], manuals: [], warranty: [], @@ -48,8 +61,9 @@ return item.value.attachments.reduce( (acc, attachment) => { if (attachment.type === "photo") { - acc.photos.push(attachment); - } else if (attachment.type === "warranty") { + return acc; + } + if (attachment.type === "warranty") { acc.warranty.push(attachment); } else if (attachment.type === "manual") { acc.manuals.push(attachment); @@ -61,7 +75,6 @@ return acc; }, { - photos: [] as ItemAttachment[], attachments: [] as ItemAttachment[], warranty: [] as ItemAttachment[], manuals: [] as ItemAttachment[], @@ -144,7 +157,6 @@ } return ( - attachments.value.photos.length > 0 || attachments.value.attachments.length > 0 || attachments.value.warranty.length > 0 || attachments.value.manuals.length > 0 || @@ -163,10 +175,6 @@ }); }; - if (attachments.value.photos.length > 0) { - push("Photos"); - } - if (attachments.value.attachments.length > 0) { push("Attachments"); } @@ -292,10 +300,51 @@ toast.success("Item deleted"); navigateTo("/home"); } + + const refDialog = ref(); + const dialoged = reactive({ + src: "", + }) + + function openDialog(img: Photo) { + refDialog.value.showModal(); + dialoged.src = img.src; + } + + function closeDialog() { + refDialog.value.close(); + } + + const refDialogBody = ref(); + onClickOutside(refDialogBody, () => { + closeDialog(); + }); + + + -