160 lines
4.5 KiB
Vue
160 lines
4.5 KiB
Vue
<template>
|
|
<v-card>
|
|
<v-card-title class="text-h6 d-flex align-center">
|
|
<v-icon class="mr-2">mdi-email-lock</v-icon>
|
|
Email Account Setup
|
|
</v-card-title>
|
|
<v-card-text>
|
|
<v-alert type="info" variant="tonal" class="mb-4">
|
|
Enter your email credentials to send and receive emails. Your password is encrypted and stored only for this session.
|
|
</v-alert>
|
|
|
|
<v-form @submit.prevent="testConnection" ref="form">
|
|
<v-text-field
|
|
v-model="credentials.email"
|
|
label="Email Address"
|
|
type="email"
|
|
variant="outlined"
|
|
density="comfortable"
|
|
prepend-inner-icon="mdi-email"
|
|
:rules="[rules.required, rules.email]"
|
|
:disabled="testing"
|
|
/>
|
|
|
|
<v-text-field
|
|
v-model="credentials.password"
|
|
label="Password"
|
|
:type="showPassword ? 'text' : 'password'"
|
|
variant="outlined"
|
|
density="comfortable"
|
|
prepend-inner-icon="mdi-lock"
|
|
:append-inner-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
|
|
@click:append-inner="showPassword = !showPassword"
|
|
:rules="[rules.required]"
|
|
:disabled="testing"
|
|
/>
|
|
|
|
<v-expansion-panels variant="accordion" class="mb-4">
|
|
<v-expansion-panel>
|
|
<v-expansion-panel-title>
|
|
<v-icon class="mr-2">mdi-cog</v-icon>
|
|
Advanced Settings
|
|
</v-expansion-panel-title>
|
|
<v-expansion-panel-text>
|
|
<v-text-field
|
|
v-model="credentials.imapHost"
|
|
label="IMAP Host"
|
|
variant="outlined"
|
|
density="comfortable"
|
|
placeholder="mail.portnimara.com"
|
|
:disabled="testing"
|
|
/>
|
|
<v-text-field
|
|
v-model="credentials.smtpHost"
|
|
label="SMTP Host"
|
|
variant="outlined"
|
|
density="comfortable"
|
|
placeholder="mail.portnimara.com"
|
|
:disabled="testing"
|
|
/>
|
|
</v-expansion-panel-text>
|
|
</v-expansion-panel>
|
|
</v-expansion-panels>
|
|
|
|
<v-btn
|
|
type="submit"
|
|
color="primary"
|
|
block
|
|
size="large"
|
|
:loading="testing"
|
|
:disabled="testing"
|
|
>
|
|
<v-icon start>mdi-connection</v-icon>
|
|
Test Connection & Continue
|
|
</v-btn>
|
|
</v-form>
|
|
</v-card-text>
|
|
</v-card>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { ref, onMounted } from 'vue';
|
|
|
|
interface Emits {
|
|
(e: 'connected', email: string): void;
|
|
}
|
|
|
|
const emit = defineEmits<Emits>();
|
|
|
|
const user = useDirectusUser();
|
|
const toast = useToast();
|
|
|
|
const form = ref();
|
|
const testing = ref(false);
|
|
const showPassword = ref(false);
|
|
|
|
const credentials = ref({
|
|
email: '',
|
|
password: '',
|
|
imapHost: '',
|
|
smtpHost: ''
|
|
});
|
|
|
|
const rules = {
|
|
required: (v: string) => !!v || 'Required',
|
|
email: (v: string) => /.+@.+\..+/.test(v) || 'Invalid email'
|
|
};
|
|
|
|
// Generate or get session ID
|
|
const getSessionId = () => {
|
|
let sessionId = sessionStorage.getItem('emailSessionId');
|
|
if (!sessionId) {
|
|
sessionId = `session-${Date.now()}-${Math.random().toString(36).substring(2)}`;
|
|
sessionStorage.setItem('emailSessionId', sessionId);
|
|
}
|
|
return sessionId;
|
|
};
|
|
|
|
const testConnection = async () => {
|
|
const { valid } = await form.value.validate();
|
|
if (!valid) return;
|
|
|
|
testing.value = true;
|
|
|
|
try {
|
|
const response = await $fetch<{ success: boolean; message: string; email: string }>('/api/email/test-connection', {
|
|
method: 'POST',
|
|
headers: {
|
|
'x-tag': user.value?.email ? '094ut234' : 'pjnvü1230',
|
|
},
|
|
body: {
|
|
email: credentials.value.email,
|
|
password: credentials.value.password,
|
|
imapHost: credentials.value.imapHost || undefined,
|
|
smtpHost: credentials.value.smtpHost || undefined,
|
|
sessionId: getSessionId()
|
|
}
|
|
});
|
|
|
|
if (response.success) {
|
|
toast.success('Email connection successful!');
|
|
// Store email in session for later use
|
|
sessionStorage.setItem('connectedEmail', credentials.value.email);
|
|
emit('connected', credentials.value.email);
|
|
}
|
|
} catch (error: any) {
|
|
console.error('Connection test failed:', error);
|
|
toast.error(error.data?.statusMessage || 'Failed to connect to email server');
|
|
} finally {
|
|
testing.value = false;
|
|
}
|
|
};
|
|
|
|
// Pre-fill email from user if available
|
|
onMounted(() => {
|
|
if (user.value?.email) {
|
|
credentials.value.email = user.value.email;
|
|
}
|
|
});
|
|
</script>
|