diff --git a/SECURITY.md b/SECURITY.md
index 47f0786f..1271565a 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -10,5 +10,6 @@ currently being supported with security updates.
| 1.x.x | :white_check_mark: |
## Reporting a Vulnerability
+Please report security issues to uptime@kuma.pet.
-https://github.com/louislam/uptime-kuma/issues
+Do not use the issue tracker or discuss it in the public as it will cause more damage.
diff --git a/server/notification-providers/teams.js b/server/notification-providers/teams.js
new file mode 100644
index 00000000..72409ffc
--- /dev/null
+++ b/server/notification-providers/teams.js
@@ -0,0 +1,124 @@
+const NotificationProvider = require("./notification-provider");
+const axios = require("axios");
+const { DOWN, UP } = require("../../src/util");
+
+class Teams extends NotificationProvider {
+ name = "teams";
+
+ _statusMessageFactory = (status, monitorName) => {
+ if (status === DOWN) {
+ return `🔴 Application [${monitorName}] went down`;
+ } else if (status === UP) {
+ return `✅ Application [${monitorName}] is back online`;
+ }
+ return "Notification";
+ };
+
+ _getThemeColor = (status) => {
+ if (status === DOWN) {
+ return "ff0000";
+ }
+ if (status === UP) {
+ return "00e804";
+ }
+ return "008cff";
+ };
+
+ _notificationPayloadFactory = ({
+ status,
+ monitorMessage,
+ monitorName,
+ monitorUrl,
+ }) => {
+ const notificationMessage = this._statusMessageFactory(
+ status,
+ monitorName
+ );
+
+ const facts = [];
+
+ if (monitorName) {
+ facts.push({
+ name: "Monitor",
+ value: monitorName,
+ });
+ }
+
+ if (monitorUrl) {
+ facts.push({
+ name: "URL",
+ value: monitorUrl,
+ });
+ }
+
+ return {
+ "@context": "https://schema.org/extensions",
+ "@type": "MessageCard",
+ themeColor: this._getThemeColor(status),
+ summary: notificationMessage,
+ sections: [
+ {
+ activityImage:
+ "https://raw.githubusercontent.com/louislam/uptime-kuma/master/public/icon.png",
+ activityTitle: "**Uptime Kuma**",
+ },
+ {
+ activityTitle: notificationMessage,
+ },
+ {
+ activityTitle: "**Description**",
+ text: monitorMessage,
+ facts,
+ },
+ ],
+ };
+ };
+
+ _sendNotification = async (webhookUrl, payload) => {
+ await axios.post(webhookUrl, payload);
+ };
+
+ _handleGeneralNotification = (webhookUrl, msg) => {
+ const payload = this._notificationPayloadFactory({
+ monitorMessage: msg
+ });
+
+ return this._sendNotification(webhookUrl, payload);
+ };
+
+ async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
+ let okMsg = "Sent Successfully. ";
+
+ try {
+ if (heartbeatJSON == null) {
+ await this._handleGeneralNotification(notification.webhookUrl, msg);
+ return okMsg;
+ }
+
+ let url;
+
+ if (monitorJSON["type"] === "port") {
+ url = monitorJSON["hostname"];
+ if (monitorJSON["port"]) {
+ url += ":" + monitorJSON["port"];
+ }
+ } else {
+ url = monitorJSON["url"];
+ }
+
+ const payload = this._notificationPayloadFactory({
+ monitorMessage: heartbeatJSON.msg,
+ monitorName: monitorJSON.name,
+ monitorUrl: url,
+ status: heartbeatJSON.status,
+ });
+
+ await this._sendNotification(notification.webhookUrl, payload);
+ return okMsg;
+ } catch (error) {
+ this.throwGeneralAxiosError(error);
+ }
+ }
+}
+
+module.exports = Teams;
diff --git a/server/notification.js b/server/notification.js
index 83dabc53..13447241 100644
--- a/server/notification.js
+++ b/server/notification.js
@@ -13,6 +13,7 @@ const RocketChat = require("./notification-providers/rocket-chat");
const Signal = require("./notification-providers/signal");
const Slack = require("./notification-providers/slack");
const SMTP = require("./notification-providers/smtp");
+const Teams = require("./notification-providers/teams");
const Telegram = require("./notification-providers/telegram");
const Webhook = require("./notification-providers/webhook");
@@ -28,6 +29,7 @@ class Notification {
const list = [
new Apprise(),
new Discord(),
+ new Teams(),
new Gotify(),
new Line(),
new LunaSea(),
diff --git a/src/components/NotificationDialog.vue b/src/components/NotificationDialog.vue
index 0db46a78..220ff8d7 100644
--- a/src/components/NotificationDialog.vue
+++ b/src/components/NotificationDialog.vue
@@ -17,6 +17,7 @@
+
@@ -400,6 +401,8 @@
+
+
@@ -449,6 +452,7 @@ import { ucfirst } from "../util.ts"
import Confirm from "./Confirm.vue";
import HiddenInput from "./HiddenInput.vue";
import Telegram from "./notifications/Telegram.vue";
+import Teams from "./notifications/Teams.vue";
import SMTP from "./notifications/SMTP.vue";
export default {
@@ -456,6 +460,7 @@ export default {
Confirm,
HiddenInput,
Telegram,
+ Teams,
SMTP,
},
props: {},
diff --git a/src/components/notifications/Teams.vue b/src/components/notifications/Teams.vue
new file mode 100644
index 00000000..748bf7ad
--- /dev/null
+++ b/src/components/notifications/Teams.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
+ You can learn how to create a webhook url
+
here.
+
+
+
+
+
diff --git a/src/i18n.js b/src/i18n.js
index 0640a1ae..fe2612fb 100644
--- a/src/i18n.js
+++ b/src/i18n.js
@@ -13,6 +13,7 @@ import pl from "./languages/pl";
import ruRU from "./languages/ru-RU";
import sr from "./languages/sr";
import srLatn from "./languages/sr-latn";
+import trTR from "./languages/tr-TR";
import svSE from "./languages/sv-SE";
import zhCN from "./languages/zh-CN";
import zhHK from "./languages/zh-HK";
@@ -30,6 +31,7 @@ const languageList = {
"sr": sr,
"sr-latn": srLatn,
"sv-SE": svSE,
+ "tr-TR": trTR,
"ko-KR": koKR,
"ru-RU": ruRU,
"zh-CN": zhCN,
diff --git a/src/languages/de-DE.js b/src/languages/de-DE.js
index fcae9415..243c2157 100644
--- a/src/languages/de-DE.js
+++ b/src/languages/de-DE.js
@@ -157,4 +157,5 @@ export default {
Indigo: "Indigo",
Purple: "Lila",
Pink: "Pink",
+ "Search...": "Suchen...",
}
diff --git a/src/languages/en.js b/src/languages/en.js
index 4f88d304..a378ddcb 100644
--- a/src/languages/en.js
+++ b/src/languages/en.js
@@ -157,4 +157,5 @@ export default {
Indigo: "Indigo",
Purple: "Purple",
Pink: "Pink",
+ "Search...": "Search...",
}
diff --git a/src/languages/it-IT.js b/src/languages/it-IT.js
index fc510434..89c33fd6 100644
--- a/src/languages/it-IT.js
+++ b/src/languages/it-IT.js
@@ -20,6 +20,10 @@ export default {
clearEventsMsg: "Si è certi di voler eliminare tutti gli eventi per questo servizio?",
clearHeartbeatsMsg: "Si è certi di voler eliminare tutti gli intervalli di controllo per questo servizio?",
confirmClearStatisticsMsg: "Si è certi di voler eliminare TUTTE le statistiche?",
+ twoFAVerifyLabel: "Scrivi il token per verificare che l'autenticazione a due fattori funzioni",
+ tokenValidSettingsMsg: "Il token è valido! È ora possibile salvare le impostazioni.",
+ confirmEnableTwoFAMsg: "Si è certi di voler abilitare l'autenticazione a due fattori?",
+ confirmDisableTwoFAMsg: "Si è certi di voler disabilitare l'autenticazione a due fattori?",
Settings: "Impostazioni",
Dashboard: "Cruscotto",
"New Update": "Nuovo Aggiornamento Disponibile",
@@ -117,7 +121,7 @@ export default {
respTime: "Tempo di Risposta (ms)",
notAvailableShort: "N/D",
"Default enabled": "Abilitato di default",
- "Also apply to existing monitors": "Applica anche ai monitoraggi esistenti",
+ "Apply on all existing monitors": "Applica su tutti i monitoraggi",
Create: "Crea",
"Clear Data": "Cancella dati",
Events: "Eventi",
@@ -128,20 +132,30 @@ export default {
backupDescription3: "Dati sensibili come i token di autenticazione saranno inclusi nel backup, tenere quindi in un luogo sicuro.",
alertNoFile: "Selezionare il file da importare.",
alertWrongFileType: "Selezionare un file JSON.",
- "Clear all statistics": "Pulisci tutte le statistiche",
- twoFAVerifyLabel: "Please type in your token to verify that 2FA is working",
- tokenValidSettingsMsg: "Token is valid! You can now save the 2FA settings.",
- confirmEnableTwoFAMsg: "Are you sure you want to enable 2FA?",
- confirmDisableTwoFAMsg: "Are you sure you want to disable 2FA?",
- "Apply on all existing monitors": "Apply on all existing monitors",
- "Verify Token": "Verify Token",
- "Setup 2FA": "Setup 2FA",
- "Enable 2FA": "Enable 2FA",
- "Disable 2FA": "Disable 2FA",
- "2FA Settings": "2FA Settings",
- "Two Factor Authentication": "Two Factor Authentication",
- Active: "Active",
- Inactive: "Inactive",
+ "Verify Token": "Verifica Token",
+ "Setup 2FA": "Imposta l'autenticazione a due fattori",
+ "Enable 2FA": "Abilita l'autenticazione a due fattori",
+ "Disable 2FA": "Disabilita l'autenticazione a due fattori",
+ "2FA Settings": "Impostazioni autenticazione a due fattori",
+ "Two Factor Authentication": "Autenticazione a due fattori",
+ Active: "Attivata",
+ Inactive: "Disattivata",
Token: "Token",
- "Show URI": "Show URI",
+ "Show URI": "Mostra URI",
+ "Clear all statistics": "Pulisci tutte le statistiche",
+ Tags: "Etichette",
+ "Add New below or Select...": "Aggiungine una oppure scegli...",
+ "Tag with this name already exist.": "Un'etichetta con questo nome già esiste.",
+ "Tag with this value already exist.": "Un'etichetta con questo valore già esiste.",
+ color: "colori",
+ "value (optional)": "valore (opzionale)",
+ Gray: "Grigio",
+ Red: "Rosso",
+ Orange: "Arancione",
+ Green: "Verde",
+ Blue: "Blu",
+ Indigo: "Indigo",
+ Purple: "Viola",
+ Pink: "Rosa",
+ "Search...": "Cerca...",
}
diff --git a/src/languages/tr-TR.js b/src/languages/tr-TR.js
new file mode 100644
index 00000000..e05af23e
--- /dev/null
+++ b/src/languages/tr-TR.js
@@ -0,0 +1,120 @@
+export default {
+ languageName: "Türkçe",
+ checkEverySecond: "{0} Saniyede bir kontrol et.",
+ "Avg.": "Ortalama",
+ retriesDescription: "Servisin kapalı olarak işaretlenmeden ve bir bildirim gönderilmeden önce maksimum yeniden deneme sayısı",
+ ignoreTLSError: "HTTPS web siteleri için TLS/SSL hatasını yoksay",
+ upsideDownModeDescription: "Servisin durumunu tersine çevirir. Servis çalışıyorsa kapalı olarak işaretler.",
+ maxRedirectDescription: "İzlenecek maksimum yönlendirme sayısı. Yönlendirmeleri devre dışı bırakmak için 0'a ayarlayın.",
+ acceptedStatusCodesDescription: "Servisin çalıştığını hangi durum kodları belirlesin?",
+ passwordNotMatchMsg: "Şifre eşleşmiyor.",
+ notificationDescription: "Servislerin bildirim gönderebilmesi için bir bildirim yöntemi belirleyin.",
+ keywordDescription: "Anahtar kelimeyi düz html veya JSON yanıtında arayın ve büyük/küçük harfe duyarlıdır",
+ pauseDashboardHome: "Durdur",
+ deleteMonitorMsg: "Servisi silmek istediğinden emin misin?",
+ deleteNotificationMsg: "Bu bildirimi tüm servisler için silmek istediğinden emin misin?",
+ resoverserverDescription: "Cloudflare varsayılan sunucudur, çözümleyici sunucusunu istediğiniz zaman değiştirebilirsiniz.",
+ rrtypeDescription: "İzlemek istediğiniz servisin RR-Tipini seçin",
+ pauseMonitorMsg: "Durdurmak istediğinden emin misin?",
+ clearEventsMsg: "Bu servisin bütün kayıtlarını silmek istediğinden emin misin?",
+ clearHeartbeatsMsg: "Bu servis için tüm sağlık durumunu silmek istediğinden emin misin?",
+ confirmClearStatisticsMsg: "Tüm istatistikleri silmek istediğinden emin misin?",
+ Settings: "Ayarlar",
+ Dashboard: "Panel",
+ "New Update": "Yeni Güncelleme",
+ Language: "Dil",
+ Appearance: "Görünüm",
+ Theme: "Tema",
+ General: "Genel",
+ Version: "Versiyon",
+ "Check Update On GitHub": "GitHub'da Güncellemeyi Kontrol Edin",
+ List: "Liste",
+ Add: "Ekle",
+ "Add New Monitor": "Yeni Servis Ekle",
+ "Quick Stats": "Servis istatistikleri",
+ Up: "Normal",
+ Down: "Hatalı",
+ Pending: "Bekliyor",
+ Unknown: "Bilinmeyen",
+ Pause: "Durdur",
+ Name: "Servis ismi",
+ Status: "Durum",
+ DateTime: "Zaman",
+ Message: "Mesaj",
+ "No important events": "Önemli olay yok",
+ Resume: "Devam et",
+ Edit: "Düzenle",
+ Delete: "Sil",
+ Current: "Şu anda",
+ Uptime: "Çalışma zamanı",
+ "Cert Exp.": "Sertifika Süresi",
+ days: "günler",
+ day: "gün",
+ "-day": "-gün",
+ hour: "saat",
+ "-hour": "-saat",
+ Response: "Cevap Süresi",
+ Ping: "Ping",
+ "Monitor Type": "Servis Tipi",
+ Keyword: "Anahtar Kelime",
+ "Friendly Name": "Panelde görünecek isim",
+ URL: "URL",
+ Hostname: "IP Adresi",
+ Port: "Port",
+ "Heartbeat Interval": "Servis Test Aralığı",
+ Retries: "Yeniden deneme",
+ Advanced: "Gelişmiş",
+ "Upside Down Mode": "Ters/Düz Modu",
+ "Max. Redirects": "Maksimum Yönlendirme",
+ "Accepted Status Codes": "Kabul Edilen Durum Kodları",
+ Save: "Kaydet",
+ Notifications: "Bildirimler",
+ "Not available, please setup.": "Atanmış bildirim yöntemi yok. Ayarlardan belirleyebilirsiniz.",
+ "Setup Notification": "Bildirim yöntemi kur",
+ Light: "Açık",
+ Dark: "Koyu",
+ Auto: "Oto",
+ "Theme - Heartbeat Bar": "Servis Bar Konumu",
+ Normal: "Normal",
+ Bottom: "Aşağıda",
+ None: "Gösterme",
+ Timezone: "Zaman Dilimi",
+ "Search Engine Visibility": "Arama Motoru Görünürlüğü",
+ "Allow indexing": "İndekslemeye izin ver",
+ "Discourage search engines from indexing site": "İndekslemeyi reddet",
+ "Change Password": "Şifre Değiştir",
+ "Current Password": "Şuan ki Şifre",
+ "New Password": "Yeni Şifre",
+ "Repeat New Password": "Yeni Şifreyi Tekrar Girin",
+ "Update Password": "Şifreyi Değiştir",
+ "Disable Auth": "Şifreli girişi iptal et.",
+ "Enable Auth": "Şifreli girişi aktif et.",
+ Logout: "Çıkış yap",
+ Leave: "Ayrıl",
+ "I understand, please disable": "Evet farkındayım, iptal et",
+ Confirm: "Onayla",
+ Yes: "Evet",
+ No: "Hayır",
+ Username: "Kullanıcı Adı",
+ Password: "Şifre",
+ "Remember me": "Beni Hatırla",
+ Login: "Giriş yap",
+ "No Monitors, please": "Servis yok, lütfen",
+ "add one": "bir servis ekleyin",
+ "Notification Type": "Bildirim Yöntemi",
+ Email: "E-mail",
+ Test: "Test",
+ "Certificate Info": "Sertifika Bilgisi",
+ "Resolver Server": "Çözümleyici Sunucu",
+ "Resource Record Type": "Kaynak Kayıt Türü",
+ "Last Result": "En son sonuçlar",
+ "Create your admin account": "Yönetici hesabınızı oluşturun",
+ "Repeat Password": "Şifrenizi tekrar girin",
+ respTime: "Cevap Süresi (ms)",
+ notAvailableShort: "N/A",
+ Create: "Yarat",
+ "Clear Data": "Verileri Temizle",
+ Events: "Olaylar",
+ Heartbeats: "Sağlık Durumları",
+ "Auto Get": "Otomatik Al"
+}
diff --git a/src/pages/Settings.vue b/src/pages/Settings.vue
index 03fd89f5..0e809f73 100644
--- a/src/pages/Settings.vue
+++ b/src/pages/Settings.vue
@@ -232,6 +232,12 @@
Molim Vas koristite ovo sa pažnjom.
+
+ Şifreli girişi devre dışı bırakmak istediğinizdenemin misiniz?
+ Bu, Uptime Kuma'nın önünde Cloudflare Access gibi üçüncü taraf yetkilendirmesi olan kişiler içindir.
+ Lütfen dikkatli kullanın.
+
+
정말로 인증 기능을 끌까요?
이 기능은 Cloudflare Access와 같은 서드파티 인증을 Uptime Kuma 앞에 둔 사용자를 위한 기능이에요.