Compare commits

...

5 commits

Author SHA1 Message Date
ceredpl
4f61782e85
Merge 7c67daf7cc into 7a9191761d 2025-01-26 10:52:24 +00:00
DayShift
7a9191761d
fix: make sure that stripping backslashes for notification urls cannot cause catastophic backtracking (ReDOS) (#5573)
Co-authored-by: Frank Elsinga <frank@elsinga.de>
2025-01-26 11:52:12 +01:00
czarek
7c67daf7cc lang fix 2024-11-21 23:50:08 +01:00
czarek
e13a67acb3 add doc 2024-11-21 23:33:45 +01:00
Czarek
909a0d081e ceredpl sms 2024-11-21 20:29:33 +01:00
7 changed files with 78 additions and 3 deletions

View file

@ -0,0 +1,45 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
class CeredSMS extends NotificationProvider {
name = "ceredsms";
/**
* @inheritdoc
*/
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
let okMsg = "Sent Successfully.";
try {
let config = {
headers: {
"Content-Type": "application/json",
}
};
let data = {
"key": notification.ceredsmsApiKey,
"from": notification.ceredsmsSenderName,
"phone_number": notification.ceredsmsPhoneNumber,
"message": msg.replace(/[^\x00-\x7F]/g, "")
};
let resp = await axios.post("https://sms.cered.pl/api/send", data, config);
if (!resp.data.message_id) {
if (resp.data.message) {
let error = `CeredSMS.pl API returned error message: ${resp.data.error.message}`;
this.throwGeneralAxiosError(error);
} else {
let error = "CeredSMS.pl API returned an unexpected response";
this.throwGeneralAxiosError(error);
}
}
return okMsg;
} catch (error) {
this.throwGeneralAxiosError(error);
}
}
}
module.exports = CeredSMS;

View file

@ -11,7 +11,8 @@ class PushDeer extends NotificationProvider {
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
const okMsg = "Sent Successfully."; const okMsg = "Sent Successfully.";
const serverUrl = notification.pushdeerServer || "https://api2.pushdeer.com"; const serverUrl = notification.pushdeerServer || "https://api2.pushdeer.com";
const url = `${serverUrl.trim().replace(/\/*$/, "")}/message/push`; // capture group below is nessesary to prevent an ReDOS-attack
const url = `${serverUrl.trim().replace(/([^/])\/+$/, "$1")}/message/push`;
let valid = msg != null && monitorJSON != null && heartbeatJSON != null; let valid = msg != null && monitorJSON != null && heartbeatJSON != null;

View file

@ -24,7 +24,7 @@ class Whapi extends NotificationProvider {
"body": msg, "body": msg,
}; };
let url = (notification.whapiApiUrl || "https://gate.whapi.cloud/").replace(/\/+$/, "") + "/messages/text"; let url = (notification.whapiApiUrl || "https://gate.whapi.cloud/").replace(/([^/])\/+$/, "$1") + "/messages/text";
await axios.post(url, data, config); await axios.post(url, data, config);

View file

@ -69,6 +69,7 @@ const Cellsynt = require("./notification-providers/cellsynt");
const Onesender = require("./notification-providers/onesender"); const Onesender = require("./notification-providers/onesender");
const Wpush = require("./notification-providers/wpush"); const Wpush = require("./notification-providers/wpush");
const SendGrid = require("./notification-providers/send-grid"); const SendGrid = require("./notification-providers/send-grid");
const CeredSMS = require("./notification-providers/ceredsms");
class Notification { class Notification {
@ -154,7 +155,8 @@ class Notification {
new GtxMessaging(), new GtxMessaging(),
new Cellsynt(), new Cellsynt(),
new Wpush(), new Wpush(),
new SendGrid() new SendGrid(),
new CeredSMS()
]; ];
for (let item of list) { for (let item of list) {
if (! item.name) { if (! item.name) {

View file

@ -183,6 +183,7 @@ export default {
"ServerChan": "ServerChan (Server酱)", "ServerChan": "ServerChan (Server酱)",
"smsc": "SMSC", "smsc": "SMSC",
"WPush": "WPush(wpush.cn)", "WPush": "WPush(wpush.cn)",
"ceredsms": "cered.pl",
}; };
// Sort by notification name // Sort by notification name

View file

@ -0,0 +1,24 @@
<template>
<div class="mb-3">
<label for="ceredsms-key" class="form-label">{{ $t('API Key') }}</label>
<HiddenInput id="ceredsms-key" v-model="$parent.notification.ceredsmsApiKey" :required="true" autocomplete="new-password"></HiddenInput>
</div>
<div class="mb-3">
<label for="ceredsms-phone-number" class="form-label">{{ $t("To Phone Number") }}</label>
<input id="ceredsms-phone-number" v-model="$parent.notification.ceredsmsPhoneNumber" type="text" class="form-control" required>
</div>
<div class="mb-3">
<label for="ceredsms-sender-name" class="form-label">{{ $t("Originator") }}</label>
<input id="ceredsms-sender-name" v-model="$parent.notification.ceredsmsSenderName" type="text" minlength="3" maxlength="11" class="form-control">
</div>
</template>
<script>
import HiddenInput from "../HiddenInput.vue";
export default {
components: {
HiddenInput,
},
};
</script>

View file

@ -67,6 +67,7 @@ import Cellsynt from "./Cellsynt.vue";
import WPush from "./WPush.vue"; import WPush from "./WPush.vue";
import SIGNL4 from "./SIGNL4.vue"; import SIGNL4 from "./SIGNL4.vue";
import SendGrid from "./SendGrid.vue"; import SendGrid from "./SendGrid.vue";
import CeredSMS from "./CeredSMS.vue";
/** /**
* Manage all notification form. * Manage all notification form.
@ -142,6 +143,7 @@ const NotificationFormList = {
"Cellsynt": Cellsynt, "Cellsynt": Cellsynt,
"WPush": WPush, "WPush": WPush,
"SendGrid": SendGrid, "SendGrid": SendGrid,
"ceredsms": CeredSMS,
}; };
export default NotificationFormList; export default NotificationFormList;