mail/front/src/views/modals/AddAccountModal.vue
2023-04-02 16:44:54 +02:00

227 lines
5.1 KiB
Vue

<script setup>
import { ref, computed, watchEffect } from "vue";
import Modal from "./Modal";
import API from "../../services/imapAPI";
const modal = ref(false);
const email = ref("");
const pwd = ref("");
const xoauth = ref("");
const xoauth2 = ref("");
const host = ref("");
const port = ref(993);
const error = ref("");
const knownHosts = {
"outlook.com": {
host: "outlook.office365.com",
},
"hotmail.com": {
host: "outlook.office365.com",
},
"live.com": {
host: "outlook.office365.com",
},
"zoho.com": {
host: "imap.zoho.eu",
},
"yahoo.com": {
host: "imap.mail.yahoo.com",
},
"icloud.com": {
host: "imap.mail.me.com",
},
};
const refHost = computed({
set: (val) => {
host.value = val;
},
});
const err = computed({
set: (val) => {
error.value = val;
},
});
function validateEmail(email) {
const re =
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(String(email).toLowerCase());
}
function checkError() {
if (!validateEmail(email.value)) {
err.value = "The email is not valid.";
} else if (((pwd.value == xoauth.value) == xoauth2.value) == "") {
err.value = "You need at least one authentification method.";
} else if ([pwd.value, xoauth.value, xoauth2.value].filter((val) => val != "").length > 1) {
err.value = "You need only one authentification method.";
} else if (host.value == "" || port.value == "") {
err.value = "You need to complete the port and the host.";
} else {
err.value = "";
}
}
function addAccountRequest() {
checkError();
const data = {
email: email.value,
pwd: pwd.value,
xoauth: xoauth.value,
xoauth2: xoauth2.value,
host: host.value,
port: port.value,
tls: true,
};
API.registerAccount(data)
.then((res) => {
console.log(res.status);
})
.catch((err) => {
console.log(err.request.status);
});
}
watchEffect(() => {
if (error.value != "") {
checkError();
}
});
function mailChange() {
if (email.value.includes("@")) {
const domain = email.value.split("@")[1];
if (!knownHosts[domain]) {
refHost.value = "imap." + domain;
} else {
refHost.value = knownHosts[domain].host;
}
// todo check if manual
}
}
</script>
<template>
<div>
<button @click="modal = true">Open Modal!</button>
<Modal v-if="modal" title="Add new account" @close-modal="modal = false">
<template v-slot:body>
<div class="field">
<label>Email: </label>
<input @change="mailChange" v-model="email" type="email" required />
</div>
<fieldset>
<legend>Authentification method</legend>
<div class="field">
<label>Plain password:</label>
<input v-model="pwd" type="password" />
</div>
<div class="field">
<label>Xoauth:</label>
<input v-model="xoauth" type="text" />
</div>
<div class="field">
<label>Xoauth2:</label>
<input v-model="xoauth2" type="text" />
</div>
</fieldset>
<div class="config">
<input v-model="host" id="host" type="text" placeholder="imap host" />
<input v-model="port" id="port" type="number" placeholder="port" />
</div>
<!-- tls -->
<div>
<button :disabled="error != ''" @click="addAccountRequest">Add</button>
{{ error }}
</div>
</template>
</Modal>
</div>
</template>
<style>
/* Chrome, Safari, Edge, Opera */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
input[type="number"] {
appearance: textfield;
}
.field {
margin-bottom: 5px;
}
.field > input {
margin-top: 2px;
width: 95%;
}
fieldset {
margin-top: 5px;
border-radius: 5px;
display: grid;
}
.config {
margin: 10px 0;
}
#host {
margin-right: 8px;
width: calc(95% - 100px);
}
#port {
width: 70px;
}
button {
padding: 5px;
padding: 7px 18px;
background-color: #09a35b;
color: white;
border-radius: 5px;
border: none;
text-decoration: none;
display: inline-block;
transition: opacity 0.5s;
}
button:hover {
opacity: 0.6;
}
input {
-webkit-box-flex: 1;
background-color: #303a46;
border: none;
border-radius: 4px;
color: #fff;
-ms-flex: 1;
flex: 1;
font-family: inherit;
font-size: 1.4rem;
font-weight: 400;
min-width: 0;
padding: 8px 9px;
}
input:focus {
outline: none;
}
</style>