Added authentication option for SMTP

#893 and thank you @gdeeble!
This commit is contained in:
Donald Zou
2025-09-07 18:25:48 +08:00
parent 43d055a8b4
commit 4b713ab66e
3 changed files with 32 additions and 11 deletions

View File

@@ -73,6 +73,7 @@ class DashboardConfig:
"encryption": "", "encryption": "",
"username": "", "username": "",
"email_password": "", "email_password": "",
"authentication_required": "true",
"send_from": "", "send_from": "",
"email_template": "" "email_template": ""
}, },

View File

@@ -32,8 +32,14 @@ class EmailSender:
def SendFrom(self): def SendFrom(self):
return self.DashboardConfig.GetConfig("Email", "send_from")[1] return self.DashboardConfig.GetConfig("Email", "send_from")[1]
# Thank you, @gdeeble from GitHub
def AuthenticationRequired(self):
return self.DashboardConfig.GetConfig("Email", "authentication_required")[1]
def ready(self): def ready(self):
if self.AuthenticationRequired():
return all([self.Server(), self.Port(), self.Encryption(), self.Username(), self.Password(), self.SendFrom()]) return all([self.Server(), self.Port(), self.Encryption(), self.Username(), self.Password(), self.SendFrom()])
return all([self.Server(), self.Port(), self.Encryption(), self.SendFrom()])
def send(self, receiver, subject, body, includeAttachment = False, attachmentName = "") -> tuple[bool, str] | tuple[bool, None]: def send(self, receiver, subject, body, includeAttachment = False, attachmentName = "") -> tuple[bool, str] | tuple[bool, None]:
if self.ready(): if self.ready():
@@ -42,6 +48,8 @@ class EmailSender:
self.smtp.ehlo() self.smtp.ehlo()
if self.Encryption() == "STARTTLS": if self.Encryption() == "STARTTLS":
self.smtp.starttls() self.smtp.starttls()
if self.AuthenticationRequired():
print("Login")
self.smtp.login(self.Username(), self.Password()) self.smtp.login(self.Username(), self.Password())
message = MIMEMultipart() message = MIMEMultipart()
message['Subject'] = subject message['Subject'] = subject

View File

@@ -13,7 +13,7 @@ onMounted(() => {
await fetchPost("/api/updateDashboardConfigurationItem", { await fetchPost("/api/updateDashboardConfigurationItem", {
section: "Email", section: "Email",
key: id, key: id,
value: x.value value: store.Configuration.Email[id]
}, (res) => { }, (res) => {
if (res.status){ if (res.status){
x.classList.remove('is-invalid') x.classList.remove('is-invalid')
@@ -71,6 +71,16 @@ const sendTestEmail = async () => {
<div class="card-body d-flex flex-column gap-3"> <div class="card-body d-flex flex-column gap-3">
<form @submit="(e) => e.preventDefault(e)" id="emailAccount"> <form @submit="(e) => e.preventDefault(e)" id="emailAccount">
<div class="row gx-2 gy-2"> <div class="row gx-2 gy-2">
<div class="col-12">
<div class="form-check mb-2 form-switch">
<input class="form-check-input" type="checkbox" role="switch"
v-model="store.Configuration.Email.authentication_required"
id="authentication_required">
<label class="form-check-label" for="authentication_required">
<LocaleText t="Require SMTP Authentication"></LocaleText>
</label>
</div>
</div>
<div class="col-12 col-lg-4"> <div class="col-12 col-lg-4">
<div class="form-group"> <div class="form-group">
<label for="server" class="text-muted mb-1"> <label for="server" class="text-muted mb-1">
@@ -80,7 +90,7 @@ const sendTestEmail = async () => {
</label> </label>
<input id="server" <input id="server"
v-model="store.Configuration.Email.server" v-model="store.Configuration.Email.server"
type="text" class="form-control"> type="text" class="form-control rounded-3">
</div> </div>
</div> </div>
<div class="col-12 col-lg-4"> <div class="col-12 col-lg-4">
@@ -92,7 +102,7 @@ const sendTestEmail = async () => {
</label> </label>
<input id="port" <input id="port"
v-model="store.Configuration.Email.port" v-model="store.Configuration.Email.port"
type="text" class="form-control"> type="text" class="form-control rounded-3">
</div> </div>
</div> </div>
<div class="col-12 col-lg-4"> <div class="col-12 col-lg-4">
@@ -102,7 +112,7 @@ const sendTestEmail = async () => {
<LocaleText t="Encryption"></LocaleText> <LocaleText t="Encryption"></LocaleText>
</small></strong> </small></strong>
</label> </label>
<select class="form-select" <select class="form-select rounded-3"
v-model="store.Configuration.Email.encryption" v-model="store.Configuration.Email.encryption"
id="encryption"> id="encryption">
<option value="STARTTLS"> <option value="STARTTLS">
@@ -114,7 +124,7 @@ const sendTestEmail = async () => {
</select> </select>
</div> </div>
</div> </div>
<div class="col-12 col-lg-4"> <div class="col-12 col-lg-4" v-if="store.Configuration.Email.authentication_required">
<div class="form-group"> <div class="form-group">
<label for="username" class="text-muted mb-1"> <label for="username" class="text-muted mb-1">
<strong><small> <strong><small>
@@ -123,10 +133,10 @@ const sendTestEmail = async () => {
</label> </label>
<input id="username" <input id="username"
v-model="store.Configuration.Email.username" v-model="store.Configuration.Email.username"
type="text" class="form-control"> type="text" class="form-control rounded-3">
</div> </div>
</div> </div>
<div class="col-12 col-lg-4"> <div class="col-12 col-lg-4" v-if="store.Configuration.Email.authentication_required">
<div class="form-group"> <div class="form-group">
<label for="email_password" class="text-muted mb-1"> <label for="email_password" class="text-muted mb-1">
<strong><small> <strong><small>
@@ -135,9 +145,10 @@ const sendTestEmail = async () => {
</label> </label>
<input id="email_password" <input id="email_password"
v-model="store.Configuration.Email.email_password" v-model="store.Configuration.Email.email_password"
type="password" class="form-control"> type="password" class="form-control rounded-3">
</div> </div>
</div> </div>
<div class="col-12 col-lg-4"> <div class="col-12 col-lg-4">
<div class="form-group"> <div class="form-group">
<label for="send_from" class="text-muted mb-1"> <label for="send_from" class="text-muted mb-1">
@@ -147,9 +158,10 @@ const sendTestEmail = async () => {
</label> </label>
<input id="send_from" <input id="send_from"
v-model="store.Configuration.Email.send_from" v-model="store.Configuration.Email.send_from"
type="text" class="form-control"> type="text" class="form-control rounded-3">
</div> </div>
</div> </div>
</div> </div>
</form> </form>
<hr v-if="emailIsReady"> <hr v-if="emailIsReady">