mirror of
https://github.com/louislam/uptime-kuma.git
synced 2024-11-27 16:54:04 +00:00
Merge pull request #2540 from twiggotronix/add-mqtt-schemes
Add mqtt, mqtts, ws and wss protocols to the mqtt monitor
This commit is contained in:
commit
31f45dcfc9
4 changed files with 58 additions and 10 deletions
|
@ -135,7 +135,7 @@ exports.mqttAsync = function (hostname, topic, okMessage, options = {}) {
|
||||||
const { port, username, password, interval = 20 } = options;
|
const { port, username, password, interval = 20 } = options;
|
||||||
|
|
||||||
// Adds MQTT protocol to the hostname if not already present
|
// Adds MQTT protocol to the hostname if not already present
|
||||||
if (!/^(?:http|mqtt)s?:\/\//.test(hostname)) {
|
if (!/^(?:http|mqtt|ws)s?:\/\//.test(hostname)) {
|
||||||
hostname = "mqtt://" + hostname;
|
hostname = "mqtt://" + hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,10 +145,11 @@ exports.mqttAsync = function (hostname, topic, okMessage, options = {}) {
|
||||||
reject(new Error("Timeout"));
|
reject(new Error("Timeout"));
|
||||||
}, interval * 1000 * 0.8);
|
}, interval * 1000 * 0.8);
|
||||||
|
|
||||||
log.debug("mqtt", "MQTT connecting");
|
const mqttUrl = `${hostname}:${port}`;
|
||||||
|
|
||||||
let client = mqtt.connect(hostname, {
|
log.debug("mqtt", `MQTT connecting to ${mqttUrl}`);
|
||||||
port,
|
|
||||||
|
let client = mqtt.connect(mqttUrl, {
|
||||||
username,
|
username,
|
||||||
password
|
password
|
||||||
});
|
});
|
||||||
|
|
|
@ -105,7 +105,7 @@
|
||||||
<!-- TCP Port / Ping / DNS / Steam / MQTT / Radius only -->
|
<!-- TCP Port / Ping / DNS / Steam / MQTT / Radius only -->
|
||||||
<div v-if="monitor.type === 'port' || monitor.type === 'ping' || monitor.type === 'dns' || monitor.type === 'steam' || monitor.type === 'mqtt' || monitor.type === 'radius'" class="my-3">
|
<div v-if="monitor.type === 'port' || monitor.type === 'ping' || monitor.type === 'dns' || monitor.type === 'steam' || monitor.type === 'mqtt' || monitor.type === 'radius'" class="my-3">
|
||||||
<label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
|
<label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
|
||||||
<input id="hostname" v-model="monitor.hostname" type="text" class="form-control" :pattern="`${ipRegexPattern}|${hostnameRegexPattern}`" required>
|
<input id="hostname" v-model="monitor.hostname" type="text" class="form-control" :pattern="`${monitor.type === 'mqtt' ? mqttIpOrHostnameRegexPattern : ipOrHostnameRegexPattern}`" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Port -->
|
<!-- Port -->
|
||||||
|
@ -576,6 +576,7 @@ import DockerHostDialog from "../components/DockerHostDialog.vue";
|
||||||
import ProxyDialog from "../components/ProxyDialog.vue";
|
import ProxyDialog from "../components/ProxyDialog.vue";
|
||||||
import TagsManager from "../components/TagsManager.vue";
|
import TagsManager from "../components/TagsManager.vue";
|
||||||
import { genSecret, isDev, MAX_INTERVAL_SECOND, MIN_INTERVAL_SECOND } from "../util.ts";
|
import { genSecret, isDev, MAX_INTERVAL_SECOND, MIN_INTERVAL_SECOND } from "../util.ts";
|
||||||
|
import { hostNameRegexPattern } from "../util-frontend";
|
||||||
|
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
|
@ -600,11 +601,8 @@ export default {
|
||||||
},
|
},
|
||||||
acceptedStatusCodeOptions: [],
|
acceptedStatusCodeOptions: [],
|
||||||
dnsresolvetypeOptions: [],
|
dnsresolvetypeOptions: [],
|
||||||
|
ipOrHostnameRegexPattern: hostNameRegexPattern(),
|
||||||
// Source: https://digitalfortress.tech/tips/top-15-commonly-used-regex/
|
mqttIpOrHostnameRegexPattern: hostNameRegexPattern(true)
|
||||||
ipRegexPattern: "((^\\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\\s*$)|(^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*$))",
|
|
||||||
// Source: https://stackoverflow.com/questions/106179/regular-expression-to-match-dns-hostname-or-ip-address
|
|
||||||
hostnameRegexPattern: "^(([a-zA-Z0-9_]|[a-zA-Z0-9_][a-zA-Z0-9\\-_]*[a-zA-Z0-9_])\\.)*([A-Za-z0-9_]|[A-Za-z0-9_][A-Za-z0-9\\-_]*[A-Za-z0-9_])$"
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -78,3 +78,19 @@ export function getResBaseURL() {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {} mqtt wheather or not the regex should take into account the fact that it is an mqtt uri
|
||||||
|
* @returns RegExp The requested regex
|
||||||
|
*/
|
||||||
|
export function hostNameRegexPattern(mqtt = false) {
|
||||||
|
// mqtt, mqtts, ws and wss schemes accepted by mqtt.js (https://github.com/mqttjs/MQTT.js/#connect)
|
||||||
|
const mqttSchemeRegexPattern = "((mqtt|ws)s?:\\/\\/)?";
|
||||||
|
// Source: https://digitalfortress.tech/tips/top-15-commonly-used-regex/
|
||||||
|
const ipRegexPattern = `((^\\s*${mqtt ? mqttSchemeRegexPattern : ""}((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\\s*$)|(^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*$))`;
|
||||||
|
// Source: https://stackoverflow.com/questions/106179/regular-expression-to-match-dns-hostname-or-ip-address
|
||||||
|
const hostNameRegexPattern = `^${mqtt ? mqttSchemeRegexPattern : ""}([a-zA-Z0-9])?(([a-zA-Z0-9_]|[a-zA-Z0-9_][a-zA-Z0-9\\-_]*[a-zA-Z0-9_])\\.)*([A-Za-z0-9_]|[A-Za-z0-9_][A-Za-z0-9\\-_]*[A-Za-z0-9_])$`;
|
||||||
|
|
||||||
|
return `${ipRegexPattern}|${hostNameRegexPattern}`;
|
||||||
|
}
|
||||||
|
|
33
test/cypress/unit/util-frontend.spec.js
Normal file
33
test/cypress/unit/util-frontend.spec.js
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import { hostNameRegexPattern } from "../../../src/util-frontend";
|
||||||
|
|
||||||
|
describe("Test util-frontend.js", () => {
|
||||||
|
|
||||||
|
describe("hostNameRegexPattern()", () => {
|
||||||
|
it('should return a valid regex for non mqtt hostnames', () => {
|
||||||
|
const regex = new RegExp(hostNameRegexPattern(false));
|
||||||
|
|
||||||
|
expect(regex.test("www.test.com")).to.be.true;
|
||||||
|
expect(regex.test("127.0.0.1")).to.be.true;
|
||||||
|
expect(regex.test("192.168.1.156")).to.be.true;
|
||||||
|
|
||||||
|
["mqtt", "mqtts", "ws", "wss"].forEach(schema => {
|
||||||
|
expect(regex.test(`${schema}://www.test.com`)).to.be.false;
|
||||||
|
expect(regex.test(`${schema}://127.0.0.1`)).to.be.false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should return a valid regex for mqtt hostnames', () => {
|
||||||
|
const hostnameString = hostNameRegexPattern(false);
|
||||||
|
console.log('*********', hostnameString, '***********');
|
||||||
|
const regex = new RegExp(hostNameRegexPattern(true));
|
||||||
|
|
||||||
|
expect(regex.test("www.test.com")).to.be.true;
|
||||||
|
expect(regex.test("127.0.0.1")).to.be.true;
|
||||||
|
expect(regex.test("192.168.1.156")).to.be.true;
|
||||||
|
|
||||||
|
["mqtt", "mqtts", "ws", "wss"].forEach(schema => {
|
||||||
|
expect(regex.test(`${schema}://www.test.com`)).to.be.true;
|
||||||
|
expect(regex.test(`${schema}://127.0.0.1`)).to.be.true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in a new issue