mirror of
				https://github.com/louislam/uptime-kuma.git
				synced 2025-11-04 13:46:13 +08:00 
			
		
		
		
	Merge remote-tracking branch 'origin/master'
This commit is contained in:
		@@ -39,8 +39,9 @@ class Slack extends NotificationProvider {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            const time = heartbeatJSON["time"];
 | 
					            const time = heartbeatJSON["time"];
 | 
				
			||||||
 | 
					            const textMsg = "Uptime Kuma Alert";
 | 
				
			||||||
            let data = {
 | 
					            let data = {
 | 
				
			||||||
                "text": "Uptime Kuma Alert",
 | 
					                "text": monitorJSON ? textMsg + `: ${monitorJSON.name}` : textMsg,
 | 
				
			||||||
                "channel": notification.slackchannel,
 | 
					                "channel": notification.slackchannel,
 | 
				
			||||||
                "username": notification.slackusername,
 | 
					                "username": notification.slackusername,
 | 
				
			||||||
                "icon_emoji": notification.slackiconemo,
 | 
					                "icon_emoji": notification.slackiconemo,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
const nodemailer = require("nodemailer");
 | 
					const nodemailer = require("nodemailer");
 | 
				
			||||||
const NotificationProvider = require("./notification-provider");
 | 
					const NotificationProvider = require("./notification-provider");
 | 
				
			||||||
 | 
					const { DOWN, UP } = require("../../src/util");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SMTP extends NotificationProvider {
 | 
					class SMTP extends NotificationProvider {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -20,6 +21,56 @@ class SMTP extends NotificationProvider {
 | 
				
			|||||||
                pass: notification.smtpPassword,
 | 
					                pass: notification.smtpPassword,
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        // Lets start with default subject and empty string for custom one
 | 
				
			||||||
 | 
					        let subject = msg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Change the subject if:
 | 
				
			||||||
 | 
					        //     - The msg ends with "Testing" or
 | 
				
			||||||
 | 
					        //     - Actual Up/Down Notification
 | 
				
			||||||
 | 
					        if ((monitorJSON && heartbeatJSON) || msg.endsWith("Testing")) {
 | 
				
			||||||
 | 
					            let customSubject = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Our subject cannot end with whitespace it's often raise spam score
 | 
				
			||||||
 | 
					            // Once I got "Cannot read property 'trim' of undefined", better be safe than sorry
 | 
				
			||||||
 | 
					            if (notification.customSubject) {
 | 
				
			||||||
 | 
					                customSubject = notification.customSubject.trim();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // If custom subject is not empty, change subject for notification
 | 
				
			||||||
 | 
					            if (customSubject !== "") {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Replace "MACROS" with corresponding variable
 | 
				
			||||||
 | 
					                let replaceName = new RegExp("{{NAME}}", "g");
 | 
				
			||||||
 | 
					                let replaceHostnameOrURL = new RegExp("{{HOSTNAME_OR_URL}}", "g");
 | 
				
			||||||
 | 
					                let replaceStatus = new RegExp("{{STATUS}}", "g");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Lets start with dummy values to simplify code
 | 
				
			||||||
 | 
					                let monitorName = "Test";
 | 
				
			||||||
 | 
					                let monitorHostnameOrURL = "testing.hostname";
 | 
				
			||||||
 | 
					                let serviceStatus = "⚠️ Test";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (monitorJSON !== null) {
 | 
				
			||||||
 | 
					                    monitorName = monitorJSON["name"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (monitorJSON["type"] === "http" || monitorJSON["type"] === "keyword") {
 | 
				
			||||||
 | 
					                        monitorHostnameOrURL = monitorJSON["url"];
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        monitorHostnameOrURL = monitorJSON["hostname"];
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (heartbeatJSON !== null) {
 | 
				
			||||||
 | 
					                    serviceStatus = (heartbeatJSON["status"] === DOWN) ? "🔴 Down" : "✅ Up";
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Break replace to one by line for better readability
 | 
				
			||||||
 | 
					                customSubject = customSubject.replace(replaceStatus, serviceStatus);
 | 
				
			||||||
 | 
					                customSubject = customSubject.replace(replaceName, monitorName);
 | 
				
			||||||
 | 
					                customSubject = customSubject.replace(replaceHostnameOrURL, monitorHostnameOrURL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                subject = customSubject;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let transporter = nodemailer.createTransport(config);
 | 
					        let transporter = nodemailer.createTransport(config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -34,7 +85,7 @@ class SMTP extends NotificationProvider {
 | 
				
			|||||||
            cc: notification.smtpCC,
 | 
					            cc: notification.smtpCC,
 | 
				
			||||||
            bcc: notification.smtpBCC,
 | 
					            bcc: notification.smtpBCC,
 | 
				
			||||||
            to: notification.smtpTo,
 | 
					            to: notification.smtpTo,
 | 
				
			||||||
            subject: msg,
 | 
					            subject: subject,
 | 
				
			||||||
            text: bodyTextContent,
 | 
					            text: bodyTextContent,
 | 
				
			||||||
            tls: {
 | 
					            tls: {
 | 
				
			||||||
                rejectUnauthorized: notification.smtpIgnoreTLSError || false,
 | 
					                rejectUnauthorized: notification.smtpIgnoreTLSError || false,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,6 +57,18 @@
 | 
				
			|||||||
        <label for="to-bcc" class="form-label">{{ $t("smtpBCC") }}</label>
 | 
					        <label for="to-bcc" class="form-label">{{ $t("smtpBCC") }}</label>
 | 
				
			||||||
        <input id="to-bcc" v-model="$parent.notification.smtpBCC" type="text" class="form-control" autocomplete="false" :required="!hasRecipient">
 | 
					        <input id="to-bcc" v-model="$parent.notification.smtpBCC" type="text" class="form-control" autocomplete="false" :required="!hasRecipient">
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <div class="mb-3">
 | 
				
			||||||
 | 
					        <label for="subject-email" class="form-label">{{ $t("emailCustomSubject") }}</label>
 | 
				
			||||||
 | 
					        <input id="subject-email" v-model="$parent.notification.customSubject" type="text" class="form-control" autocomplete="false" placeholder="">
 | 
				
			||||||
 | 
					        <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>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -201,6 +201,7 @@ export default {
 | 
				
			|||||||
    secureOptionTLS: "TLS (465)",
 | 
					    secureOptionTLS: "TLS (465)",
 | 
				
			||||||
    "Ignore TLS Error": "Ignore TLS Error",
 | 
					    "Ignore TLS Error": "Ignore TLS Error",
 | 
				
			||||||
    "From Email": "From Email",
 | 
					    "From Email": "From Email",
 | 
				
			||||||
 | 
					    emailCustomSubject: "Custom Subject",
 | 
				
			||||||
    "To Email": "To Email",
 | 
					    "To Email": "To Email",
 | 
				
			||||||
    smtpCC: "CC",
 | 
					    smtpCC: "CC",
 | 
				
			||||||
    smtpBCC: "BCC",
 | 
					    smtpBCC: "BCC",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,7 @@ export default {
 | 
				
			|||||||
    passwordNotMatchMsg: "Les mots de passe ne correspondent pas",
 | 
					    passwordNotMatchMsg: "Les mots de passe ne correspondent pas",
 | 
				
			||||||
    notificationDescription: "Une fois ajoutée, vous devez l'activer manuellement dans les paramètres de vos hôtes.",
 | 
					    notificationDescription: "Une fois ajoutée, vous devez l'activer manuellement dans les paramètres de vos hôtes.",
 | 
				
			||||||
    keywordDescription: "Le mot clé sera recherché dans la réponse HTML/JSON reçue du site internet.",
 | 
					    keywordDescription: "Le mot clé sera recherché dans la réponse HTML/JSON reçue du site internet.",
 | 
				
			||||||
    pauseDashboardHome: "Éléments mis en pause",
 | 
					    pauseDashboardHome: "En pause",
 | 
				
			||||||
    deleteMonitorMsg: "Êtes-vous sûr de vouloir supprimer cette sonde ?",
 | 
					    deleteMonitorMsg: "Êtes-vous sûr de vouloir supprimer cette sonde ?",
 | 
				
			||||||
    deleteNotificationMsg: "Êtes-vous sûr de vouloir supprimer ce type de notifications ? Une fois désactivée, les services qui l'utilisent ne pourront plus envoyer de notifications.",
 | 
					    deleteNotificationMsg: "Êtes-vous sûr de vouloir supprimer ce type de notifications ? Une fois désactivée, les services qui l'utilisent ne pourront plus envoyer de notifications.",
 | 
				
			||||||
    resoverserverDescription: "Le DNS de cloudflare est utilisé par défaut, mais vous pouvez le changer si vous le souhaitez.",
 | 
					    resoverserverDescription: "Le DNS de cloudflare est utilisé par défaut, mais vous pouvez le changer si vous le souhaitez.",
 | 
				
			||||||
@@ -54,7 +54,7 @@ export default {
 | 
				
			|||||||
    Delete: "Supprimer",
 | 
					    Delete: "Supprimer",
 | 
				
			||||||
    Current: "Actuellement",
 | 
					    Current: "Actuellement",
 | 
				
			||||||
    Uptime: "Uptime",
 | 
					    Uptime: "Uptime",
 | 
				
			||||||
    "Cert Exp.": "Certificat expiré",
 | 
					    "Cert Exp.": "Expiration SSL",
 | 
				
			||||||
    days: "jours",
 | 
					    days: "jours",
 | 
				
			||||||
    day: "jour",
 | 
					    day: "jour",
 | 
				
			||||||
    "-day": "-jours",
 | 
					    "-day": "-jours",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -116,39 +116,39 @@ export default {
 | 
				
			|||||||
    Events: "Olaylar",
 | 
					    Events: "Olaylar",
 | 
				
			||||||
    Heartbeats: "Sağlık Durumları",
 | 
					    Heartbeats: "Sağlık Durumları",
 | 
				
			||||||
    "Auto Get": "Otomatik Al",
 | 
					    "Auto Get": "Otomatik Al",
 | 
				
			||||||
    retryCheckEverySecond: "Retry every {0} seconds.",
 | 
					    retryCheckEverySecond: "{0} Saniyede bir dene.",
 | 
				
			||||||
    enableDefaultNotificationDescription: "For every new monitor this notification will be enabled by default. You can still disable the notification separately for each monitor.",
 | 
					    enableDefaultNotificationDescription: "Bu bildirim her yeni serviste aktif olacaktır. Bildirimi servisler için ayrı ayrı deaktive edebilirsiniz. ",
 | 
				
			||||||
    importHandleDescription: "Choose 'Skip existing' if you want to skip every monitor or notification with the same name. 'Overwrite' will delete every existing monitor and notification.",
 | 
					    importHandleDescription: "Aynı isimdeki bütün servisleri ve bildirimleri atlamak için 'Var olanı atla' seçiniz. 'Üzerine yaz' var olan bütün servisleri ve bildirimleri silecektir. ",
 | 
				
			||||||
    confirmImportMsg: "Are you sure to import the backup? Please make sure you've selected the right import option.",
 | 
					    confirmImportMsg: "Yedeği içeri aktarmak istediğinize emin misiniz? Lütfen doğru içeri aktarma seçeneğini seçtiğinizden emin olunuz. ",
 | 
				
			||||||
    twoFAVerifyLabel: "Please type in your token to verify that 2FA is working",
 | 
					    twoFAVerifyLabel: "Lütfen tokeni yazarak 2FA doğrulamanın çalıştığından emin olunuz.",
 | 
				
			||||||
    tokenValidSettingsMsg: "Token is valid! You can now save the 2FA settings.",
 | 
					    tokenValidSettingsMsg: "Token geçerli! Şimdi 2FA ayarlarını kaydedebilirsiniz. ",
 | 
				
			||||||
    confirmEnableTwoFAMsg: "Are you sure you want to enable 2FA?",
 | 
					    confirmEnableTwoFAMsg: "2FA'ı etkinleştirmek istediğinizden emin misiniz?",
 | 
				
			||||||
    confirmDisableTwoFAMsg: "Are you sure you want to disable 2FA?",
 | 
					    confirmDisableTwoFAMsg: "2FA'ı devre dışı bırakmak istediğinize emin misiniz?",
 | 
				
			||||||
    "Heartbeat Retry Interval": "Heartbeat Retry Interval",
 | 
					    "Heartbeat Retry Interval": "Sağlık Dırımları Tekrar Deneme Sıklığı",
 | 
				
			||||||
    "Import Backup": "Import Backup",
 | 
					    "Import Backup": "Yedeği içe aktar",
 | 
				
			||||||
    "Export Backup": "Export Backup",
 | 
					    "Export Backup": "Yedeği dışa aktar",
 | 
				
			||||||
    Export: "Export",
 | 
					    Export: "Dışa aktar",
 | 
				
			||||||
    Import: "Import",
 | 
					    Import: "İçe aktar",
 | 
				
			||||||
    "Default enabled": "Default enabled",
 | 
					    "Default enabled": "Varsayılan etkinleştirilmiş",
 | 
				
			||||||
    "Apply on all existing monitors": "Apply on all existing monitors",
 | 
					    "Apply on all existing monitors": "Var olan bütün servislere uygula",
 | 
				
			||||||
    backupDescription: "You can backup all monitors and all notifications into a JSON file.",
 | 
					    backupDescription: "Bütün servisleri ve bildirimleri JSON dosyasına yedekleyebilirsiniz.",
 | 
				
			||||||
    backupDescription2: "PS: History and event data is not included.",
 | 
					    backupDescription2: "Not: Geçmiş ve etkinlik verileri içinde değildir.",
 | 
				
			||||||
    backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.",
 | 
					    backupDescription3: "Dışa aktarma dosyasında bildirim tokeni gibi hassas veriler bulunur, dikkatli bir şekilde saklayınız.",
 | 
				
			||||||
    alertNoFile: "Please select a file to import.",
 | 
					    alertNoFile: "İçeri aktarmak için bir dosya seçiniz.",
 | 
				
			||||||
    alertWrongFileType: "Please select a JSON file.",
 | 
					    alertWrongFileType: "Lütfen bir JSON dosyası seçiniz.",
 | 
				
			||||||
    "Clear all statistics": "Clear all Statistics",
 | 
					    "Clear all statistics": "Bütün istatistikleri temizle",
 | 
				
			||||||
    "Skip existing": "Skip existing",
 | 
					    "Skip existing": "Var olanı atla",
 | 
				
			||||||
    Overwrite: "Overwrite",
 | 
					    Overwrite: "Üzerine yaz",
 | 
				
			||||||
    Options: "Options",
 | 
					    Options: "Seçenekler",
 | 
				
			||||||
    "Keep both": "Keep both",
 | 
					    "Keep both": "İkisini sakla",
 | 
				
			||||||
    "Verify Token": "Verify Token",
 | 
					    "Verify Token": "Tokeni doğrula",
 | 
				
			||||||
    "Setup 2FA": "Setup 2FA",
 | 
					    "Setup 2FA": "2FA Kur",
 | 
				
			||||||
    "Enable 2FA": "Enable 2FA",
 | 
					    "Enable 2FA": "2FA Etkinleştir",
 | 
				
			||||||
    "Disable 2FA": "Disable 2FA",
 | 
					    "Disable 2FA": "2FA Devre dışı bırak",
 | 
				
			||||||
    "2FA Settings": "2FA Settings",
 | 
					    "2FA Settings": "2FA Ayarları",
 | 
				
			||||||
    "Two Factor Authentication": "Two Factor Authentication",
 | 
					    "Two Factor Authentication": "İki Faktörlü Kimlik Doğrulama (2FA)",
 | 
				
			||||||
    Active: "Active",
 | 
					    Active: "Aktif",
 | 
				
			||||||
    Inactive: "Inactive",
 | 
					    Inactive: "İnaktif",
 | 
				
			||||||
    Token: "Token",
 | 
					    Token: "Token",
 | 
				
			||||||
    "Show URI": "Show URI",
 | 
					    "Show URI": "Show URI",
 | 
				
			||||||
    Tags: "Tags",
 | 
					    Tags: "Tags",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -63,6 +63,7 @@
 | 
				
			|||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
                            </div>
 | 
					                            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            <!-- Hostname -->
 | 
				
			||||||
                            <!-- TCP Port / Ping / DNS only -->
 | 
					                            <!-- TCP Port / Ping / DNS only -->
 | 
				
			||||||
                            <div v-if="monitor.type === 'port' || monitor.type === 'ping' || monitor.type === 'dns' " class="my-3">
 | 
					                            <div v-if="monitor.type === 'port' || monitor.type === 'ping' || monitor.type === 'dns' " class="my-3">
 | 
				
			||||||
                                <label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
 | 
					                                <label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user