Liu Song’s Projects


~/Projects/uptime

git clone https://code.lsong.org/uptime

Commit

Commit
624cd862a5e38980cfce5b25b78acc0451ea45dc
Author
Nelson Chan <[email protected]>
Date
2021-12-19 13:30:53 +0800 +0800
Diffstat
 server/notification-providers/smtp.js | 8 +
 src/assets/app.scss | 14 ++
 src/components/ToggleSection.vue | 67 +++++++++++++
 src/components/notifications/SMTP.vue | 144 +++++++++++++++++++---------
 src/icon.js | 2 
 src/languages/en.js | 11 ++

Feat: Expose SMTP DKIM settings


diff --git a/server/notification-providers/smtp.js b/server/notification-providers/smtp.js
index 14429bcabffad59bfc9776c3b9d23ef996016e34..1be68aeab8cac9a89e0cc59a93e74a9134bdea36 100644
--- a/server/notification-providers/smtp.js
+++ b/server/notification-providers/smtp.js
@@ -15,6 +15,14 @@             secure: notification.smtpSecure,
             tls: {
                 rejectUnauthorized: notification.smtpIgnoreTLSError || false,
             },
+            dkim: {
+                domainName: notification.smtpDkimDomain,
+                keySelector: notification.smtpDkimKeySelector,
+                privateKey: notification.smtpDkimPrivateKey,
+                hashAlgo: notification.smtpDkimHashAlgo,
+                headerFieldNames: notification.smtpDkimheaderFieldNames,
+                skipFields: notification.smtpDkimskipFields,
+            }
         };
 
         // Should fix the issue in https://github.com/louislam/uptime-kuma/issues/26#issuecomment-896373904




diff --git a/src/assets/app.scss b/src/assets/app.scss
index 5578946bd3bf17cfbcbe18cb28b22d852805029e..cec64467636009430e368fc8a93d9a5e2cadb5a2 100644
--- a/src/assets/app.scss
+++ b/src/assets/app.scss
@@ -313,6 +313,20 @@     transform: translateX(50px);
     opacity: 0;
 }
 
+.slide-fade-up-enter-active {
+    transition: all 0.2s $easing-in;
+}
+
+.slide-fade-up-leave-active {
+    transition: all 0.2s $easing-in;
+}
+
+.slide-fade-up-enter-from,
+.slide-fade-up-leave-to {
+    transform: translateY(-50px);
+    opacity: 0;
+}
+
 .monitor-list {
     &.scrollbar {
         min-height: calc(100vh - 240px);




diff --git a/src/components/ToggleSection.vue b/src/components/ToggleSection.vue
new file mode 100644
index 0000000000000000000000000000000000000000..bc6028d706558473d3693654a835a9b8659202f8
--- /dev/null
+++ b/src/components/ToggleSection.vue
@@ -0,0 +1,67 @@
+<template>
+    <div class="my-3 py-3">
+        <h5 @click="isOpen = !isOpen">
+            <div
+                class="
+                    w-50
+                    d-flex
+                    justify-content-between
+                    align-items-center
+                    pe-2
+                "
+            >
+                <span class="pb-2">{{ heading }}</span>
+                <font-awesome-icon
+                    icon="chevron-down"
+                    class="animated"
+                    :class="{ open: isOpen }"
+                />
+            </div>
+        </h5>
+        <transition name="slide-fade-up">
+            <div v-if="isOpen" class="mt-3">
+                <slot></slot>
+            </div>
+        </transition>
+    </div>
+</template>
+
+<script>
+export default {
+    props: {
+        heading: {
+            type: String,
+            default: "",
+        },
+        defaultOpen: {
+            type: Boolean,
+            default: false,
+        },
+    },
+    data() {
+        return {
+            isOpen: this.defaultOpen,
+        };
+    },
+};
+</script>
+
+<style lang="scss" scoped>
+@import "../assets/vars.scss";
+
+h5:after {
+    content: "";
+    display: block;
+    width: 50%;
+    padding-top: 8px;
+    border-bottom: 1px solid $dark-border-color;
+}
+
+.open {
+    transform: rotate(180deg);
+}
+
+.animated {
+    transition: all 0.2s $easing-in;
+}
+</style>




diff --git a/src/components/notifications/SMTP.vue b/src/components/notifications/SMTP.vue
index ab660abed26434e4e63a30d817016db8c30e6c6f..899f8f9bd70f1d8bd4b476c0faf1401e6c44a540 100644
--- a/src/components/notifications/SMTP.vue
+++ b/src/components/notifications/SMTP.vue
@@ -1,104 +1,158 @@
 <template>
+
     <div class="mb-3">
+
         <label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
+
         <input id="hostname" v-model="$parent.notification.smtpHost" type="text" class="form-control" required>
+
     </div>
+        </div>
 
-    <div class="mb-3">
+        <div class="mb-3">
+            <label for="port" class="form-label">{{ $t("Port") }}</label>
+
         <label for="port" class="form-label">{{ $t("Port") }}</label>
-        <input id="port" v-model="$parent.notification.smtpPort" type="number" class="form-control" required min="0" max="65535" step="1">
+        </div>
-    </div>
+
 
+        <label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
-    <div class="mb-3">
+            <label for="secure" class="form-label">{{ $t("Security") }}</label>
+
         <label for="secure" class="form-label">{{ $t("Security") }}</label>
-<template>
+        <label for="port" class="form-label">{{ $t("Port") }}</label>
-<template>
+        <label for="port" class="form-label">{{ $t("Port") }}</label>
 <template>
-<template>
+        <label for="port" class="form-label">{{ $t("Port") }}</label>
     <div class="mb-3">
 <template>
-        <label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
+        <label for="secure" class="form-label">{{ $t("Security") }}</label>
-    </div>
+
 
+        <label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
-    <div class="mb-3">
+            <div class="form-check">
-<template>
+        <label for="port" class="form-label">{{ $t("Port") }}</label>
         <input id="hostname" v-model="$parent.notification.smtpHost" type="text" class="form-control" required>
-<template>
+        <label for="port" class="form-label">{{ $t("Port") }}</label>
     </div>
-<template>
+        <label for="port" class="form-label">{{ $t("Port") }}</label>
 
-<template>
+        <label for="port" class="form-label">{{ $t("Port") }}</label>
         <label for="port" class="form-label">{{ $t("Port") }}</label>
-<template>
+        <label for="port" class="form-label">{{ $t("Port") }}</label>
         <input id="port" v-model="$parent.notification.smtpPort" type="number" class="form-control" required min="0" max="65535" step="1">
         </div>
-    </div>
+
 
+        <label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
-    <div class="mb-3">
+            <label for="username" class="form-label">{{ $t("Username") }}</label>
-    <div class="mb-3">
+        <input id="port" v-model="$parent.notification.smtpPort" type="number" class="form-control" required min="0" max="65535" step="1">
-    <div class="mb-3">
 <template>
+        <label for="secure" class="form-label">{{ $t("Security") }}</label>
-    </div>
+
 
+        <label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
-    <div class="mb-3">
+            <label for="password" class="form-label">{{ $t("Password") }}</label>
-    <div class="mb-3">
+        <input id="port" v-model="$parent.notification.smtpPort" type="number" class="form-control" required min="0" max="65535" step="1">
     <div class="mb-3">
-        <HiddenInput id="password" v-model="$parent.notification.smtpPassword" :required="false" autocomplete="one-time-code"></HiddenInput>
+        </div>
-    </div>
+
 
+        <label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
-    <div class="mb-3">
+            <label for="from-email" class="form-label">{{ $t("From Email") }}</label>
-    <div class="mb-3">
+        <input id="port" v-model="$parent.notification.smtpPort" type="number" class="form-control" required min="0" max="65535" step="1">
         <input id="hostname" v-model="$parent.notification.smtpHost" type="text" class="form-control" required>
-    <div class="mb-3">
+        <input id="port" v-model="$parent.notification.smtpPort" type="number" class="form-control" required min="0" max="65535" step="1">
     </div>
-        <div class="form-text">
+            </div>
         </div>
-    </div>
+
 
+        <label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
-    <div class="mb-3">
+            <label for="to-email" class="form-label">{{ $t("To Email") }}</label>
-    <div class="mb-3">
+        <input id="port" v-model="$parent.notification.smtpPort" type="number" class="form-control" required min="0" max="65535" step="1">
         <label for="port" class="form-label">{{ $t("Port") }}</label>
-        <input id="to-email" v-model="$parent.notification.smtpTo" type="text" class="form-control" autocomplete="false" placeholder="[email protected], [email protected]" :required="!hasRecipient">
+        </div>
-    </div>
+
 
+        <label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
-    <div class="mb-3">
+            <label for="to-cc" class="form-label">{{ $t("smtpCC") }}</label>
-    <div class="mb-3">
+        <input id="port" v-model="$parent.notification.smtpPort" type="number" class="form-control" required min="0" max="65535" step="1">
         <label for="secure" class="form-label">{{ $t("Security") }}</label>
+        </div>
+
+
         <label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
+        <label for="secure" class="form-label">{{ $t("Security") }}</label>
-    </div>
+            <input id="to-bcc" v-model="$parent.notification.smtpBCC" type="text" class="form-control" autocomplete="false" :required="!hasRecipient">
+        </div>
 
+        <label for="secure" class="form-label">{{ $t("Security") }}</label>
     <div class="mb-3">
+        <label for="secure" class="form-label">{{ $t("Security") }}</label>
         <label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
-<template>
-        <input id="to-bcc" v-model="$parent.notification.smtpBCC" type="text" class="form-control" autocomplete="false" :required="!hasRecipient">
+                <a href="https://nodemailer.com/dkim/" target="_blank">{{ $t("documentation") }}</a>
+        <label for="secure" class="form-label">{{ $t("Security") }}</label>
     </div>
 
+            <div class="mb-3">
+                <label for="dkim-domain" class="form-label">{{ $t("smtpDkimDomain") }}</label>
+                <input id="dkim-domain" v-model="$parent.notification.smtpDkimDomain" type="text" class="form-control" autocomplete="false" placeholder="example.com">
+            </div>
+            <div class="mb-3">
+                <label for="dkim-key-selector" class="form-label">{{ $t("smtpDkimKeySelector") }}</label>
+                <input id="dkim-key-selector" v-model="$parent.notification.smtpDkimKeySelector" type="text" class="form-control" autocomplete="false" placeholder="2017">
+            </div>
+            <div class="mb-3">
+                <label for="dkim-private-key" class="form-label">{{ $t("smtpDkimPrivateKey") }}</label>
+        <select id="secure" v-model="$parent.notification.smtpSecure" class="form-select">
     <div class="mb-3">
-        <label for="subject-email" class="form-label">{{ $t("emailCustomSubject") }}</label>
+            </div>
+            <div class="mb-3">
+        <select id="secure" v-model="$parent.notification.smtpSecure" class="form-select">
         <label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
+        <select id="secure" v-model="$parent.notification.smtpSecure" class="form-select">
         <input id="hostname" v-model="$parent.notification.smtpHost" type="text" class="form-control" required>
-        <label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
+            </div>
+            <div class="mb-3">
+        <select id="secure" v-model="$parent.notification.smtpSecure" class="form-select">
     </div>
-        <label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
+        <select id="secure" v-model="$parent.notification.smtpSecure" class="form-select">
 
-        <label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
         <label for="port" class="form-label">{{ $t("Port") }}</label>
+        <input id="port" v-model="$parent.notification.smtpPort" type="number" class="form-control" required min="0" max="65535" step="1">
-        <label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
+            <div class="mb-3">
+                <label for="dkim-skip-fields" class="form-label">{{ $t("smtpDkimskipFields") }}</label>
+        <select id="secure" v-model="$parent.notification.smtpSecure" class="form-select">
         <input id="port" v-model="$parent.notification.smtpPort" type="number" class="form-control" required min="0" max="65535" step="1">
+            </div>
+        </ToggleSection>
+
+
         <label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
-        <label for="secure" class="form-label">{{ $t("Security") }}</label>
-        <input id="hostname" v-model="$parent.notification.smtpHost" type="text" class="form-control" required>
+            <option :value="false">{{ $t("secureOptionNone") }}</option>
 <template>
+            <option :value="false">{{ $t("secureOptionNone") }}</option>
+            <div v-pre class="form-text">
+                (leave blank for default one)<br />
+                {{NAME}}: Service Name<br />
+                {{HOSTNAME_OR_URL}}: Hostname or URL<br />
+                {{URL}}: URL<br />
+                {{STATUS}}: Status<br />
+            </div>
+<template>
         <label for="secure" class="form-label">{{ $t("Security") }}</label>
     </div>
 </template>
 
 <script>
 import HiddenInput from "../HiddenInput.vue";
+import ToggleSection from "../ToggleSection.vue";
 
 export default {
     components: {
         HiddenInput,
+        ToggleSection,
     },
     computed: {
         hasRecipient() {




diff --git a/src/icon.js b/src/icon.js
index e78992f200d3f4c7c87003696facd8faa506718f..88b8a8ecde7d471d5e50da34d4197e27a1eba615 100644
--- a/src/icon.js
+++ b/src/icon.js
@@ -33,6 +33,7 @@     faCheck,
     faFile,
     faAward,
     faLink,
+    faChevronDown,
 } from "@fortawesome/free-solid-svg-icons";
 
 library.add(
@@ -65,6 +66,7 @@     faCheck,
     faFile,
     faAward,
     faLink,
+    faChevronDown,
 );
 
 export { FontAwesomeIcon };




diff --git a/src/languages/en.js b/src/languages/en.js
index fee80a7609af538c14bbf6dd96cb091e1f86ad01..80caba9a3305cfb30cefb7cd1fafea61a9c23f01 100644
--- a/src/languages/en.js
+++ b/src/languages/en.js
@@ -340,7 +340,6 @@     "No monitors available.": "No monitors available.",
     "Add one": "Add one",
     "No Monitors": "No Monitors",
     Theme: "Theme",
-    Theme: "Theme",
     languageName: "English",
     Services: "Services",
     Discard: "Discard",
@@ -353,5 +352,15 @@     serwersmsAPIPassword: "API Password",
     serwersmsPhoneNumber: "Phone number",
     serwersmsSenderName: "SMS Sender Name (registered via customer portal)",
     General: "General",
+    checkEverySecond: "Check every {0} seconds",
+    smtpDkimSettings: "DKIM Settings",
+    smtpDkimDesc: "Please refer to the Nodemailer DKIM {0} for usage.",
+    documentation: "documentation",
+    smtpDkimDomain: "Domain Name",
+    smtpDkimKeySelector: "Key Selector",
+    smtpDkimPrivateKey: "Private Key",
+    smtpDkimHashAlgo: "Hash Algorithm (Optional)",
+    smtpDkimheaderFieldNames: "Header Keys to sign (Optional)",
+    "Primary Base URL": "Primary Base URL",
     checkEverySecond: "Check every {0} seconds",
 };