Skip to content

Commit

Permalink
added smtp monitor
Browse files Browse the repository at this point in the history
  • Loading branch information
koehn committed Jan 11, 2025
1 parent be2faf6 commit 712e345
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 5 deletions.
12 changes: 12 additions & 0 deletions db/knex_migrations/2025-01-01-0000-add-smtp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
exports.up = function (knex) {
return knex.schema
.alterTable("monitor", function (table) {
table.string("smtp_security").defaultTo(null);
});
};

exports.down = function (knex) {
return knex.schema.alterTable("monitor", function (table) {
table.dropColumn("smtp_security");
});
};
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions server/model/monitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ class Monitor extends BeanModel {
snmpOid: this.snmpOid,
jsonPathOperator: this.jsonPathOperator,
snmpVersion: this.snmpVersion,
smtpSecurity: this.smtpSecurity,
rabbitmqNodes: JSON.parse(this.rabbitmqNodes),
conditions: JSON.parse(this.conditions),
};
Expand Down
59 changes: 59 additions & 0 deletions server/monitor-types/smtp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const { MonitorType } = require("./monitor-type");
const { UP } = require("../../src/util");
const nodemailer = require("nodemailer");

class SMTPMonitorType extends MonitorType {
name = "smtp";

/**
* @param {*} smtpSecurity the user's SMTP security setting
* @returns {boolean} True if this should test SMTPS
*/
isSMTPS(smtpSecurity) {
return smtpSecurity === "secure";
}

/**
* @param {*} smtpSecurity the user's SMTP security setting
* @returns {boolean} True if this should not attempt STARTTLS, even if it is available
*/
isIgnoreTLS(smtpSecurity) {
return smtpSecurity === "nostarttls";
}

/**
* @param {*} smtpSecurity the user's SMTP security setting
* @returns {boolean} True if this should always test STARTTLS
*/
isRequireTLS(smtpSecurity) {
return smtpSecurity === "starttls";
}

/**
* @inheritdoc
*/
async check(monitor, heartbeat, _server) {
let options = {
port: monitor.port || 25,
host: monitor.hostname,
secure: this.isSMTPS(monitor.smtpSecurity), // use SMTPS (not STARTTLS)
ignoreTLS: this.isIgnoreTLS(monitor.smtpSecurity), // don't use STARTTLS even if it's available
requireTLS: this.isRequireTLS(monitor.smtpSecurity), // use STARTTLS or fail
};
let transporter = nodemailer.createTransport(options);
try {
await transporter.verify();

heartbeat.status = UP;
heartbeat.msg = "SMTP connection verifies successfully";
} catch (e) {
throw new Error(`SMTP connection doesn't verify: ${e}`);
} finally {
transporter.close();
}
}
}

module.exports = {
SMTPMonitorType,
};
1 change: 1 addition & 0 deletions server/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,7 @@ let needSetup = false;
monitor.kafkaProducerAllowAutoTopicCreation;
bean.gamedigGivenPortOnly = monitor.gamedigGivenPortOnly;
bean.remote_browser = monitor.remote_browser;
bean.smtpSecurity = monitor.smtpSecurity;
bean.snmpVersion = monitor.snmpVersion;
bean.snmpOid = monitor.snmpOid;
bean.jsonPathOperator = monitor.jsonPathOperator;
Expand Down
2 changes: 2 additions & 0 deletions server/uptime-kuma-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ class UptimeKumaServer {
UptimeKumaServer.monitorTypeList["tailscale-ping"] = new TailscalePing();
UptimeKumaServer.monitorTypeList["dns"] = new DnsMonitorType();
UptimeKumaServer.monitorTypeList["mqtt"] = new MqttMonitorType();
UptimeKumaServer.monitorTypeList["smtp"] = new SMTPMonitorType();
UptimeKumaServer.monitorTypeList["snmp"] = new SNMPMonitorType();
UptimeKumaServer.monitorTypeList["mongodb"] = new MongodbMonitorType();
UptimeKumaServer.monitorTypeList["rabbitmq"] = new RabbitMqMonitorType();
Expand Down Expand Up @@ -551,6 +552,7 @@ const { RealBrowserMonitorType } = require("./monitor-types/real-browser-monitor
const { TailscalePing } = require("./monitor-types/tailscale-ping");
const { DnsMonitorType } = require("./monitor-types/dns");
const { MqttMonitorType } = require("./monitor-types/mqtt");
const { SMTPMonitorType } = require("./monitor-types/smtp");
const { SNMPMonitorType } = require("./monitor-types/snmp");
const { MongodbMonitorType } = require("./monitor-types/mongodb");
const { RabbitMqMonitorType } = require("./monitor-types/rabbitmq");
Expand Down
18 changes: 15 additions & 3 deletions src/pages/EditMonitor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
<option value="ping">
Ping
</option>
<option value="smtp">
SMTP
</option>
<option value="snmp">
SNMP
</option>
Expand Down Expand Up @@ -281,8 +284,8 @@
</template>

<!-- Hostname -->
<!-- TCP Port / Ping / DNS / Steam / MQTT / Radius / Tailscale Ping / SNMP only -->
<div v-if="monitor.type === 'port' || monitor.type === 'ping' || monitor.type === 'dns' || monitor.type === 'steam' || monitor.type === 'gamedig' || monitor.type === 'mqtt' || monitor.type === 'radius' || monitor.type === 'tailscale-ping' || monitor.type === 'snmp'" class="my-3">
<!-- TCP Port / Ping / DNS / Steam / MQTT / Radius / Tailscale Ping / SNMP / SMTP only -->
<div v-if="monitor.type === 'port' || monitor.type === 'ping' || monitor.type === 'dns' || monitor.type === 'steam' || monitor.type === 'gamedig' || monitor.type === 'mqtt' || monitor.type === 'radius' || monitor.type === 'tailscale-ping' || monitor.type === 'smtp' || monitor.type === 'snmp'" class="my-3">
<label for="hostname" class="form-label">{{ $t("Hostname") }}</label>
<input
id="hostname"
Expand All @@ -297,7 +300,7 @@

<!-- Port -->
<!-- For TCP Port / Steam / MQTT / Radius Type / SNMP -->
<div v-if="monitor.type === 'port' || monitor.type === 'steam' || monitor.type === 'gamedig' || monitor.type === 'mqtt' || monitor.type === 'radius' || monitor.type === 'snmp'" class="my-3">
<div v-if="monitor.type === 'port' || monitor.type === 'steam' || monitor.type === 'gamedig' || monitor.type === 'mqtt' || monitor.type === 'radius' || monitor.type === 'smtp' || monitor.type === 'snmp'" class="my-3">
<label for="port" class="form-label">{{ $t("Port") }}</label>
<input id="port" v-model="monitor.port" type="number" class="form-control" required min="0" max="65535" step="1">
</div>
Expand Down Expand Up @@ -329,6 +332,15 @@
</select>
</div>

<div v-if="monitor.type === 'smtp'" class="my-3">
<label for="smtp_security" class="form-label">{{ $t("SMTP Security") }}</label>
<select id="smtp_security" v-model="monitor.smtpSecurity" class="form-select">
<option value="secure">SMTPS</option>
<option value="nostarttls">Ignore STARTTLS</option>
<option value="starttls">Use STARTTLS</option>
</select>
</div>

<!-- Json Query -->
<!-- For Json Query / SNMP -->
<div v-if="monitor.type === 'json-query' || monitor.type === 'snmp'" class="my-3">
Expand Down

0 comments on commit 712e345

Please sign in to comment.