Merge branch 'master' into public-dashboard

pull/124/head
LouisLam 3 years ago
commit 2ab06f87b8

@ -10,5 +10,6 @@ currently being supported with security updates.
| 1.x.x | :white_check_mark: | | 1.x.x | :white_check_mark: |
## Reporting a Vulnerability ## 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.

@ -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;

@ -13,6 +13,7 @@ const RocketChat = require("./notification-providers/rocket-chat");
const Signal = require("./notification-providers/signal"); const Signal = require("./notification-providers/signal");
const Slack = require("./notification-providers/slack"); const Slack = require("./notification-providers/slack");
const SMTP = require("./notification-providers/smtp"); const SMTP = require("./notification-providers/smtp");
const Teams = require("./notification-providers/teams");
const Telegram = require("./notification-providers/telegram"); const Telegram = require("./notification-providers/telegram");
const Webhook = require("./notification-providers/webhook"); const Webhook = require("./notification-providers/webhook");
@ -28,6 +29,7 @@ class Notification {
const list = [ const list = [
new Apprise(), new Apprise(),
new Discord(), new Discord(),
new Teams(),
new Gotify(), new Gotify(),
new Line(), new Line(),
new LunaSea(), new LunaSea(),

@ -17,6 +17,7 @@
<option value="webhook">Webhook</option> <option value="webhook">Webhook</option>
<option value="smtp">{{ $t("Email") }} (SMTP)</option> <option value="smtp">{{ $t("Email") }} (SMTP)</option>
<option value="discord">Discord</option> <option value="discord">Discord</option>
<option value="teams">Microsoft Teams</option>
<option value="signal">Signal</option> <option value="signal">Signal</option>
<option value="gotify">Gotify</option> <option value="gotify">Gotify</option>
<option value="slack">Slack</option> <option value="slack">Slack</option>
@ -400,6 +401,8 @@
<!-- DEPRECATED! Please create vue component in "./src/components/notifications/{notification name}.vue" --> <!-- DEPRECATED! Please create vue component in "./src/components/notifications/{notification name}.vue" -->
<Teams v-if="notification.type === 'teams'" />
<div class="mb-3 mt-4"> <div class="mb-3 mt-4">
<hr class="dropdown-divider mb-4"> <hr class="dropdown-divider mb-4">
@ -449,6 +452,7 @@ import { ucfirst } from "../util.ts"
import Confirm from "./Confirm.vue"; import Confirm from "./Confirm.vue";
import HiddenInput from "./HiddenInput.vue"; import HiddenInput from "./HiddenInput.vue";
import Telegram from "./notifications/Telegram.vue"; import Telegram from "./notifications/Telegram.vue";
import Teams from "./notifications/Teams.vue";
import SMTP from "./notifications/SMTP.vue"; import SMTP from "./notifications/SMTP.vue";
export default { export default {
@ -456,6 +460,7 @@ export default {
Confirm, Confirm,
HiddenInput, HiddenInput,
Telegram, Telegram,
Teams,
SMTP, SMTP,
}, },
props: {}, props: {},

@ -0,0 +1,29 @@
<template>
<div class="mb-3">
<label for="teams-webhookurl" class="form-label">Webhook URL</label>
<input
id="teams-webhookurl"
v-model="$parent.notification.webhookUrl"
type="text"
class="form-control"
required
/>
<div class="form-text">
You can learn how to create a webhook url
<a
href="https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook"
target="_blank"
>here</a>.
</div>
</div>
</template>
<script>
export default {
data() {
return {
name: "teams",
};
},
};
</script>

@ -13,6 +13,7 @@ import pl from "./languages/pl";
import ruRU from "./languages/ru-RU"; import ruRU from "./languages/ru-RU";
import sr from "./languages/sr"; import sr from "./languages/sr";
import srLatn from "./languages/sr-latn"; import srLatn from "./languages/sr-latn";
import trTR from "./languages/tr-TR";
import svSE from "./languages/sv-SE"; import svSE from "./languages/sv-SE";
import zhCN from "./languages/zh-CN"; import zhCN from "./languages/zh-CN";
import zhHK from "./languages/zh-HK"; import zhHK from "./languages/zh-HK";
@ -30,6 +31,7 @@ const languageList = {
"sr": sr, "sr": sr,
"sr-latn": srLatn, "sr-latn": srLatn,
"sv-SE": svSE, "sv-SE": svSE,
"tr-TR": trTR,
"ko-KR": koKR, "ko-KR": koKR,
"ru-RU": ruRU, "ru-RU": ruRU,
"zh-CN": zhCN, "zh-CN": zhCN,

@ -157,4 +157,5 @@ export default {
Indigo: "Indigo", Indigo: "Indigo",
Purple: "Lila", Purple: "Lila",
Pink: "Pink", Pink: "Pink",
"Search...": "Suchen...",
} }

@ -157,4 +157,5 @@ export default {
Indigo: "Indigo", Indigo: "Indigo",
Purple: "Purple", Purple: "Purple",
Pink: "Pink", Pink: "Pink",
"Search...": "Search...",
} }

@ -20,6 +20,10 @@ export default {
clearEventsMsg: "Si è certi di voler eliminare tutti gli eventi per questo servizio?", 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?", clearHeartbeatsMsg: "Si è certi di voler eliminare tutti gli intervalli di controllo per questo servizio?",
confirmClearStatisticsMsg: "Si è certi di voler eliminare TUTTE le statistiche?", 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", Settings: "Impostazioni",
Dashboard: "Cruscotto", Dashboard: "Cruscotto",
"New Update": "Nuovo Aggiornamento Disponibile", "New Update": "Nuovo Aggiornamento Disponibile",
@ -117,7 +121,7 @@ export default {
respTime: "Tempo di Risposta (ms)", respTime: "Tempo di Risposta (ms)",
notAvailableShort: "N/D", notAvailableShort: "N/D",
"Default enabled": "Abilitato di default", "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", Create: "Crea",
"Clear Data": "Cancella dati", "Clear Data": "Cancella dati",
Events: "Eventi", 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.", backupDescription3: "Dati sensibili come i token di autenticazione saranno inclusi nel backup, tenere quindi in un luogo sicuro.",
alertNoFile: "Selezionare il file da importare.", alertNoFile: "Selezionare il file da importare.",
alertWrongFileType: "Selezionare un file JSON.", alertWrongFileType: "Selezionare un file JSON.",
"Clear all statistics": "Pulisci tutte le statistiche", "Verify Token": "Verifica Token",
twoFAVerifyLabel: "Please type in your token to verify that 2FA is working", "Setup 2FA": "Imposta l'autenticazione a due fattori",
tokenValidSettingsMsg: "Token is valid! You can now save the 2FA settings.", "Enable 2FA": "Abilita l'autenticazione a due fattori",
confirmEnableTwoFAMsg: "Are you sure you want to enable 2FA?", "Disable 2FA": "Disabilita l'autenticazione a due fattori",
confirmDisableTwoFAMsg: "Are you sure you want to disable 2FA?", "2FA Settings": "Impostazioni autenticazione a due fattori",
"Apply on all existing monitors": "Apply on all existing monitors", "Two Factor Authentication": "Autenticazione a due fattori",
"Verify Token": "Verify Token", Active: "Attivata",
"Setup 2FA": "Setup 2FA", Inactive: "Disattivata",
"Enable 2FA": "Enable 2FA",
"Disable 2FA": "Disable 2FA",
"2FA Settings": "2FA Settings",
"Two Factor Authentication": "Two Factor Authentication",
Active: "Active",
Inactive: "Inactive",
Token: "Token", 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...",
} }

@ -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"
}

@ -232,6 +232,12 @@
<p>Molim Vas koristite ovo sa pažnjom.</p> <p>Molim Vas koristite ovo sa pažnjom.</p>
</template> </template>
<template v-else-if="$i18n.locale === 'tr-TR' ">
<p><strong>Şifreli girişi devre dışı bırakmak istediğinizden</strong>emin misiniz?</p>
<p>Bu, Uptime Kuma'nın önünde Cloudflare Access gibi <strong>üçüncü taraf yetkilendirmesi olan</strong> kişiler içindir.</p>
<p>Lütfen dikkatli kullanın.</p>
</template>
<template v-else-if="$i18n.locale === 'ko-KR' "> <template v-else-if="$i18n.locale === 'ko-KR' ">
<p>정말로 <strong>인증 기능을 끌까요</strong>?</p> <p>정말로 <strong>인증 기능을 끌까요</strong>?</p>
<p> 기능은 <strong>Cloudflare Access와 같은 서드파티 인증</strong> Uptime Kuma 앞에 사용자를 위한 기능이에요.</p> <p> 기능은 <strong>Cloudflare Access와 같은 서드파티 인증</strong> Uptime Kuma 앞에 사용자를 위한 기능이에요.</p>

Loading…
Cancel
Save