Skip to content

Commit

Permalink
Merge pull request #140 from buggregator/feature/smtp-attachments-api
Browse files Browse the repository at this point in the history
Refactors SMTP attachments fetching from HTTP endpoint
  • Loading branch information
butschster authored May 5, 2024
2 parents efc9caf + 9274020 commit 9903686
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 24 deletions.
18 changes: 15 additions & 3 deletions pages/smtp/[id].vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useSmtp } from "~/src/entities/smtp";
import type { SMTP } from "~/src/entities/smtp/types";
import { REST_API_URL } from "~/src/shared/lib/io";
import { useEvents } from "~/src/shared/lib/use-events";
import type { EventId, ServerEvent } from "~/src/shared/types";
import type { Attachment, EventId, ServerEvent } from "~/src/shared/types";
const { normalizeSmtpEvent } = useSmtp();
Expand All @@ -21,16 +21,19 @@ useHead({
});
const { events } = useEvents();
const { smtp } = useSmtp();
const isLoading = ref(false);
const serverEvent = ref<Event | null>(null);
const serverAttachments = ref<Attachment[]>([]);
const event = computed(() =>
serverEvent.value
? normalizeSmtpEvent(serverEvent.value as unknown as ServerEvent<SMTP>)
: null
);
const attachments = computed(() => serverAttachments.value);
const html = computed(
() => `<iframe src="${REST_API_URL}/api/smtp/${eventId}/html"/>`
);
Expand All @@ -57,6 +60,11 @@ const getEvent = async () => {
router.push("/404");
},
});
await smtp.getAttachments(eventId)
.then((attachments: Attachment[]) => {
serverAttachments.value = attachments;
});
};
onMounted(getEvent);
Expand All @@ -81,7 +89,11 @@ onMounted(getEvent);
</div>

<div class="smtp-event__body">
<SmtpPage v-if="event" :event="event" :html-source="html" />
<SmtpPage v-if="event"
:event="event"
:attachments="attachments"
:html-source="html"
/>
</div>
</main>
</template>
Expand Down
11 changes: 8 additions & 3 deletions src/entities/smtp/lib/use-smtp.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import type { ServerEvent, NormalizedEvent } from '~/src/shared/types';
import type { SMTP } from "../types";
import { normalizeSmtpEvent } from "./normalize-smtp-event";
import { type TUseSmtpApi, useSmtpApi } from "~/src/shared/lib/use-smtp";

type TUseSmtp = () => {
normalizeSmtpEvent: (event: ServerEvent<SMTP>) => NormalizedEvent<SMTP>
smtp: TUseSmtpApi
}

export const useSmtp: TUseSmtp = () => ({
normalizeSmtpEvent
})
export const useSmtp: TUseSmtp = () => {
return {
normalizeSmtpEvent,
smtp: useSmtpApi()
}
}
30 changes: 13 additions & 17 deletions src/screens/smtp/ui/smtp-page/smtp-page.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ import { SmtpPagePreview } from "../smtp-page-preview";
type Props = {
event: NormalizedEvent<SMTP>;
attachments: Attachment[];
htmlSource: string;
};
const props = defineProps<Props>();
const props = withDefaults(defineProps<Props>(), {
attachments: [],
});
const htmlSource = ref(props.htmlSource || props.event.payload.html);
Expand Down Expand Up @@ -60,12 +63,6 @@ const mail = computed(() => props.event.payload);
const date = computed(() =>
moment(props.event.date).format("DD.MM.YYYY HH:mm:ss")
);
const attachments = computed(() =>
Array.isArray(props.event.payload.attachments)
? props.event.payload.attachments
: (Object.values(props.event.payload.attachments || {}) as Attachment[])
);
</script>

<template>
Expand Down Expand Up @@ -108,7 +105,7 @@ const attachments = computed(() =>
suffix="<span class='smtp-page__body-tab-badge'>HTML</span>"
>
<SmtpPagePreview device="tablet">
<div v-html="htmlSource" />
<div v-html="htmlSource"/>
</SmtpPagePreview>
</Tab>
<Tab v-if="isHtml" name="HTML">
Expand All @@ -127,14 +124,13 @@ const attachments = computed(() =>
</Tab>
<Tab
v-if="attachments.length"
name="Attachments"
:suffix="`<span class='smtp-page__body-tab-badge'>${attachments.length}</span>`"
:name="`Attachments (${attachments.length})`"
>
<section class="mb-5">
<div class="flex gap-x-3">
<FileAttachment
v-for="a in attachments"
:key="a.id"
:key="a.uuid"
:event-id="event.id"
:event="event"
:attachment="a"
Expand All @@ -143,7 +139,7 @@ const attachments = computed(() =>
</section>
</Tab>
<Tab name="Raw">
<CodeSnippet language="html" :code="event.payload.raw" />
<CodeSnippet language="html" :code="event.payload.raw"/>
</Tab>
<Tab name="Tech Info">
<section>
Expand All @@ -156,22 +152,22 @@ const attachments = computed(() =>
{{ event.payload.subject }}
</TableBaseRow>
<TableBaseRow title="From">
<SmtpPageAddresses :addresses="event.payload.from" />
<SmtpPageAddresses :addresses="event.payload.from"/>
</TableBaseRow>
<TableBaseRow title="To">
<SmtpPageAddresses :addresses="event.payload.to" />
<SmtpPageAddresses :addresses="event.payload.to"/>
</TableBaseRow>
<TableBaseRow v-if="event.payload.cc.length" title="Cc">
<SmtpPageAddresses :addresses="event.payload.cc" />
<SmtpPageAddresses :addresses="event.payload.cc"/>
</TableBaseRow>
<TableBaseRow v-if="event.payload.bcc.length" title="Bcc">
<SmtpPageAddresses :addresses="event.payload.bcc" />
<SmtpPageAddresses :addresses="event.payload.bcc"/>
</TableBaseRow>
<TableBaseRow
v-if="event.payload.reply_to.length"
title="Reply to"
>
<SmtpPageAddresses :addresses="event.payload.reply_to" />
<SmtpPageAddresses :addresses="event.payload.reply_to"/>
</TableBaseRow>
</TableBase>
</section>
Expand Down
1 change: 1 addition & 0 deletions src/shared/lib/io/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './constants';
export * from './types';
export * from './use-events-requests';
export * from './use-smtp-requests';
export * from './logger';
export * from './centrifuge';
41 changes: 41 additions & 0 deletions src/shared/lib/io/use-smtp-requests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Attachment, EventId } from "../../types";
import { type NuxtApp, useNuxtApp } from "#app"; // eslint-disable-line @conarti/feature-sliced/layers-slices
import { REST_API_URL } from "./constants";

type TUseSmtpRequests = () => {
getAttachments: (id: EventId) => Promise<Attachment[]>
}

// TODO: add 403 response handling

export const useSmtpRequests: TUseSmtpRequests = () => {

const app: NuxtApp = useNuxtApp()
const { token } = app.$authToken ?? { token: null }
const headers = { "X-Auth-Token": token || '' }

const getAttachmentsRestUrl = (id: EventId): string => `${REST_API_URL}/api/smtp/${id}/attachments`

const getAttachments = (id: EventId) => fetch(getAttachmentsRestUrl(id), { headers })
.then((response) => response.json())
.then((response) => {
if (response?.data) {
return response.data as Attachment[]
}

if (response?.code === 403) {
console.error('Forbidden')
return [];
}

console.error('Fetch Error')

return [];
})
.then((attachments: Attachment[]) => attachments)

return {
getAttachmentsRestUrl,
getAttachments
}
}
1 change: 1 addition & 0 deletions src/shared/lib/use-smtp/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./use-smtp-api";
16 changes: 16 additions & 0 deletions src/shared/lib/use-smtp/use-smtp-api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { Attachment, EventId } from '../../types';
import { useSmtpRequests } from "../io";

export type TUseSmtpApi = {
getAttachments: (id: EventId) => Promise<Attachment[]>
}

export const useSmtpApi: TUseSmtpApi = () => {
const {
getAttachments
} = useSmtpRequests()

return {
getAttachments
}
}
9 changes: 9 additions & 0 deletions src/shared/types/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export enum EVENT_TYPES {
}

export type EventId = string;
export type Uuid = string;

export type EventType = OneOfValues<typeof EVENT_TYPES>;

Expand All @@ -35,3 +36,11 @@ export interface NormalizedEvent<T> {
date: Date | null,
payload: T
}

export interface Attachment {
uuid: Uuid,
name: string,
path: string,
size: number,
mime: string,
}
2 changes: 1 addition & 1 deletion src/shared/ui/file-attachment/file-attachment.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const props = defineProps<Props>();
const size = computed(() => formatFileSize(props.attachment.size || 0));
const downloadUrl = computed(
() =>
`${REST_API_URL}/api/smtp/${props.eventId}/attachment/${props.attachment.id}`
`${REST_API_URL}/api/smtp/${props.eventId}/attachments/${props.attachment.uuid}`
);
</script>

Expand Down

0 comments on commit 9903686

Please sign in to comment.