generated from Nodarx/template
7485e4c897
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
158 lines
3.8 KiB
Vue
158 lines
3.8 KiB
Vue
<script setup lang="ts">
|
|
import { computed, ref, watch } from 'vue'
|
|
import { IdentityBasic } from '@KTXM/MailManager/models/identity'
|
|
import { ServiceObject } from '@KTXM/MailManager/models/service'
|
|
import type { ServiceIdentity, ServiceIdentityBasic } from '@KTXM/MailManager/types/service'
|
|
import type { ProviderAuthPanelProps, ProviderAuthPanelEmits } from '@KTXM/MailManager/types/integration'
|
|
|
|
const props = defineProps<ProviderAuthPanelProps>()
|
|
const emit = defineEmits<ProviderAuthPanelEmits>()
|
|
|
|
const identity = ref('')
|
|
const secret = ref('')
|
|
|
|
const rules = {
|
|
required: (value: unknown) => !!value || 'This field is required'
|
|
}
|
|
|
|
const currentIdentity = computed((): ServiceIdentityBasic | null => {
|
|
if (!identity.value || !secret.value) {
|
|
return null
|
|
}
|
|
|
|
return {
|
|
type: 'BA',
|
|
identity: identity.value,
|
|
secret: secret.value,
|
|
}
|
|
})
|
|
|
|
watch(
|
|
() => props.service,
|
|
service => {
|
|
syncFromService(service)
|
|
},
|
|
{ immediate: true }
|
|
)
|
|
|
|
watch(
|
|
() => props.emailAddress,
|
|
value => {
|
|
if (value && !identity.value) {
|
|
identity.value = value
|
|
}
|
|
},
|
|
{ immediate: true }
|
|
)
|
|
|
|
watch(
|
|
currentIdentity,
|
|
value => {
|
|
const existingIdentity = props.service?.identity?.toJson() ?? null
|
|
if (sameIdentity(existingIdentity, value)) {
|
|
return
|
|
}
|
|
|
|
const nextService = props.service ?? new ServiceObject()
|
|
|
|
if (value === null) {
|
|
nextService.identity = null
|
|
emit('update:service', nextService)
|
|
return
|
|
}
|
|
|
|
if (nextService.identity instanceof IdentityBasic) {
|
|
nextService.identity.identity = value.identity
|
|
nextService.identity.secret = value.secret
|
|
} else {
|
|
nextService.identity = new IdentityBasic(value.identity, value.secret)
|
|
}
|
|
|
|
emit('update:service', nextService)
|
|
},
|
|
{ immediate: true, deep: true }
|
|
)
|
|
|
|
function syncFromService(service?: ServiceObject) {
|
|
const serviceIdentity = service?.identity?.toJson() ?? null
|
|
|
|
if (serviceIdentity?.type === 'BA') {
|
|
identity.value = serviceIdentity.identity || props.prefilledIdentity || props.emailAddress || ''
|
|
secret.value = serviceIdentity.secret || props.prefilledSecret || ''
|
|
return
|
|
}
|
|
|
|
identity.value = props.prefilledIdentity || props.emailAddress || ''
|
|
secret.value = props.prefilledSecret || ''
|
|
}
|
|
|
|
function sameIdentity(a: ServiceIdentity | null, b: ServiceIdentity | null): boolean {
|
|
if (a === null || b === null) {
|
|
return a === b
|
|
}
|
|
|
|
return a.type === 'BA'
|
|
&& b.type === 'BA'
|
|
&& a.identity === b.identity
|
|
&& a.secret === b.secret
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="imap-auth-panel">
|
|
<h3 class="text-h6 mb-4">Authentication</h3>
|
|
<p class="text-body-2 mb-6">Provide the username and password your IMAP server expects.</p>
|
|
|
|
<v-alert type="info" variant="tonal">
|
|
Most IMAP servers use your full email address as the username. Use an app password if your mail host requires one.
|
|
</v-alert>
|
|
|
|
<v-text-field
|
|
v-model="identity"
|
|
label="Username / Email"
|
|
hint="Account login used by the IMAP server"
|
|
persistent-hint
|
|
variant="outlined"
|
|
prepend-inner-icon="mdi-account"
|
|
class="mb-4"
|
|
autocomplete="username"
|
|
autocorrect="off"
|
|
autocapitalize="none"
|
|
:rules="[rules.required]"
|
|
/>
|
|
|
|
<v-text-field
|
|
v-model="secret"
|
|
type="password"
|
|
label="Password"
|
|
hint="Password or app-specific password"
|
|
persistent-hint
|
|
variant="outlined"
|
|
prepend-inner-icon="mdi-lock"
|
|
class="mb-4"
|
|
autocomplete="current-password"
|
|
:rules="[rules.required]"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.imap-auth-panel {
|
|
max-width: 800px;
|
|
}
|
|
|
|
.text-h6 {
|
|
font-size: 1.25rem;
|
|
font-weight: 500;
|
|
line-height: 2rem;
|
|
letter-spacing: 0.0125em;
|
|
}
|
|
|
|
.text-body-2 {
|
|
font-size: 0.875rem;
|
|
font-weight: 400;
|
|
line-height: 1.25rem;
|
|
letter-spacing: 0.0178571429em;
|
|
color: rgba(var(--v-theme-on-surface), 0.7);
|
|
}
|
|
</style> |