mirror of
https://github.com/louislam/uptime-kuma.git
synced 2024-10-01 01:25:45 -04:00
Feat: Improve Certificaet Info Display
This commit is contained in:
parent
2aaed66b38
commit
13bdfefa9d
@ -59,7 +59,7 @@ class Prometheus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
monitor_cert_days_remaining.set(this.monitorLabelValues, tlsInfo.daysRemaining)
|
monitor_cert_days_remaining.set(this.monitorLabelValues, tlsInfo.certInfo.daysRemaining)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
}
|
}
|
||||||
|
@ -185,38 +185,42 @@ const getDaysRemaining = (validFrom, validTo) => {
|
|||||||
return daysRemaining;
|
return daysRemaining;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.checkCertificate = function (res) {
|
// Fix certificate Info for display
|
||||||
const {
|
// param: info - the chain obtained from getPeerCertificate()
|
||||||
valid_from,
|
const parseCertificateInfo = function (info) {
|
||||||
valid_to,
|
let link = info;
|
||||||
subjectaltname,
|
|
||||||
issuer,
|
|
||||||
fingerprint,
|
|
||||||
} = res.request.res.socket.getPeerCertificate(false);
|
|
||||||
|
|
||||||
if (!valid_from || !valid_to || !subjectaltname) {
|
while (link) {
|
||||||
throw {
|
if (!link.valid_from || !link.valid_to) {
|
||||||
message: "No TLS certificate in response",
|
break;
|
||||||
};
|
}
|
||||||
|
link.validTo = new Date(link.valid_to);
|
||||||
|
link.validFor = link.subjectaltname?.replace(/DNS:|IP Address:/g, "").split(", ");
|
||||||
|
link.daysRemaining = getDaysRemaining(new Date(), link.validTo);
|
||||||
|
|
||||||
|
// Move up the chain until loop is encountered
|
||||||
|
if (link.issuerCertificate == null) {
|
||||||
|
break;
|
||||||
|
} else if (link.fingerprint == link.issuerCertificate.fingerprint) {
|
||||||
|
link.issuerCertificate = null;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
link = link.issuerCertificate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.checkCertificate = function (res) {
|
||||||
|
const info = res.request.res.socket.getPeerCertificate(true);
|
||||||
const valid = res.request.res.socket.authorized || false;
|
const valid = res.request.res.socket.authorized || false;
|
||||||
|
|
||||||
const validTo = new Date(valid_to);
|
const parsedInfo = parseCertificateInfo(info);
|
||||||
|
|
||||||
const validFor = subjectaltname
|
|
||||||
.replace(/DNS:|IP Address:/g, "")
|
|
||||||
.split(", ");
|
|
||||||
|
|
||||||
const daysRemaining = getDaysRemaining(new Date(), validTo);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
valid,
|
valid: valid,
|
||||||
validFor,
|
certInfo: parsedInfo
|
||||||
validTo,
|
|
||||||
daysRemaining,
|
|
||||||
issuer,
|
|
||||||
fingerprint,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
30
src/components/CertificateInfo.vue
Normal file
30
src/components/CertificateInfo.vue
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h4>{{ $t("Certificate Info") }}</h4>
|
||||||
|
{{ $t("Certificate Chain") }}:
|
||||||
|
<div v-if="valid" class="rounded d-inline-flex ms-2 py-1 px-3 bg-success text-white">{{ $t("Valid") }}</div>
|
||||||
|
<div v-if="!valid" class="rounded d-inline-flex ms-2 py-1 px-3 bg-danger text-white">{{ $t("Invalid") }}</div>
|
||||||
|
<certificate-info-row :cert="certInfo" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import CertificateInfoRow from "./CertificateInfoRow.vue";
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
CertificateInfoRow,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
certInfo: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
valid: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
106
src/components/CertificateInfoRow.vue
Normal file
106
src/components/CertificateInfoRow.vue
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="d-flex flex-row align-items-center p-1 overflow-hidden">
|
||||||
|
<div class="m-3 ps-3">
|
||||||
|
<font-awesome-icon class="cert-icon" icon="file-contract" />
|
||||||
|
</div>
|
||||||
|
<div class="m-3">
|
||||||
|
<table class="text-start">
|
||||||
|
<tbody>
|
||||||
|
<tr class="my-3">
|
||||||
|
<td class="px-3">Subject:</td>
|
||||||
|
<td>{{ formatSubject(cert.subject) }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="my-3">
|
||||||
|
<td class="px-3">Valid To:</td>
|
||||||
|
<td><Datetime :value="cert.validTo" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="my-3">
|
||||||
|
<td class="px-3">Days Remaining:</td>
|
||||||
|
<td>{{ cert.daysRemaining }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="my-3">
|
||||||
|
<td class="px-3">Issuer:</td>
|
||||||
|
<td>{{ formatSubject(cert.issuer) }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="my-3">
|
||||||
|
<td class="px-3">Fingerprint:</td>
|
||||||
|
<td>{{ cert.fingerprint }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex">
|
||||||
|
<font-awesome-icon
|
||||||
|
v-if="cert.issuerCertificate"
|
||||||
|
class="m-2 ps-6 link-icon"
|
||||||
|
icon="link"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<certificate-info-row
|
||||||
|
v-if="cert.issuerCertificate"
|
||||||
|
:cert="cert.issuerCertificate"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Datetime from "../components/Datetime.vue";
|
||||||
|
export default {
|
||||||
|
name: "CertificateInfoRow",
|
||||||
|
components: {
|
||||||
|
Datetime,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
cert: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
formatSubject(subject) {
|
||||||
|
if (subject.O && subject.CN && subject.C) {
|
||||||
|
return `${subject.CN} - ${subject.O} (${subject.C})`;
|
||||||
|
} else if (subject.O && subject.CN) {
|
||||||
|
return `${subject.CN} - ${subject.O}`;
|
||||||
|
} else if (subject.CN) {
|
||||||
|
return subject.CN;
|
||||||
|
} else {
|
||||||
|
return "no info";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../assets/vars.scss";
|
||||||
|
|
||||||
|
table {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cert-icon {
|
||||||
|
font-size: 70px;
|
||||||
|
color: $link-color;
|
||||||
|
opacity: 0.5;
|
||||||
|
|
||||||
|
.dark & {
|
||||||
|
color: $dark-font-color;
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-icon {
|
||||||
|
font-size: 20px;
|
||||||
|
margin-left: 50px !important;
|
||||||
|
color: $link-color;
|
||||||
|
opacity: 0.5;
|
||||||
|
|
||||||
|
.dark & {
|
||||||
|
color: $dark-font-color;
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -30,6 +30,8 @@ import {
|
|||||||
faUpload,
|
faUpload,
|
||||||
faCopy,
|
faCopy,
|
||||||
faCheck,
|
faCheck,
|
||||||
|
faFileContract,
|
||||||
|
faLink,
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
|
|
||||||
library.add(
|
library.add(
|
||||||
@ -59,6 +61,8 @@ library.add(
|
|||||||
faUpload,
|
faUpload,
|
||||||
faCopy,
|
faCopy,
|
||||||
faCheck,
|
faCheck,
|
||||||
|
faFileContract,
|
||||||
|
faLink,
|
||||||
);
|
);
|
||||||
|
|
||||||
export { FontAwesomeIcon };
|
export { FontAwesomeIcon };
|
||||||
|
@ -30,7 +30,7 @@ export default {
|
|||||||
importantHeartbeatList: { },
|
importantHeartbeatList: { },
|
||||||
avgPingList: { },
|
avgPingList: { },
|
||||||
uptimeList: { },
|
uptimeList: { },
|
||||||
certInfoList: {},
|
tlsInfoList: {},
|
||||||
notificationList: [],
|
notificationList: [],
|
||||||
connectionErrorMsg: "Cannot connect to the socket server. Reconnecting...",
|
connectionErrorMsg: "Cannot connect to the socket server. Reconnecting...",
|
||||||
};
|
};
|
||||||
@ -154,7 +154,7 @@ export default {
|
|||||||
});
|
});
|
||||||
|
|
||||||
socket.on("certInfo", (monitorID, data) => {
|
socket.on("certInfo", (monitorID, data) => {
|
||||||
this.certInfoList[monitorID] = JSON.parse(data);
|
this.tlsInfoList[monitorID] = JSON.parse(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("importantHeartbeatList", (monitorID, data, overwrite) => {
|
socket.on("importantHeartbeatList", (monitorID, data, overwrite) => {
|
||||||
|
@ -73,11 +73,11 @@
|
|||||||
<span class="num"><Uptime :monitor="monitor" type="720" /></span>
|
<span class="num"><Uptime :monitor="monitor" type="720" /></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="certInfo" class="col">
|
<div v-if="tlsInfo" class="col">
|
||||||
<h4>{{ $t("Cert Exp.") }}</h4>
|
<h4>{{ $t("Cert Exp.") }}</h4>
|
||||||
<p>(<Datetime :value="certInfo.validTo" date-only />)</p>
|
<p>(<Datetime :value="tlsInfo.certInfo.validTo" date-only />)</p>
|
||||||
<span class="num">
|
<span class="num">
|
||||||
<a href="#" @click.prevent="toggleCertInfoBox = !toggleCertInfoBox">{{ certInfo.daysRemaining }} {{ $t("days") }}</a>
|
<a href="#" @click.prevent="toggleCertInfoBox = !toggleCertInfoBox">{{ tlsInfo.certInfo.daysRemaining }} {{ $t("days") }}</a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -87,41 +87,7 @@
|
|||||||
<div v-if="showCertInfoBox" class="shadow-box big-padding text-center">
|
<div v-if="showCertInfoBox" class="shadow-box big-padding text-center">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<h4>{{ $t("Certificate Info") }}</h4>
|
<certificate-info :certInfo="tlsInfo.certInfo" :valid="tlsInfo.valid" />
|
||||||
<table class="text-start">
|
|
||||||
<tbody>
|
|
||||||
<tr class="my-3">
|
|
||||||
<td class="px-3">
|
|
||||||
Valid:
|
|
||||||
</td>
|
|
||||||
<td>{{ certInfo.valid }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="my-3">
|
|
||||||
<td class="px-3">
|
|
||||||
Valid To:
|
|
||||||
</td>
|
|
||||||
<td><Datetime :value="certInfo.validTo" /></td>
|
|
||||||
</tr>
|
|
||||||
<tr class="my-3">
|
|
||||||
<td class="px-3">
|
|
||||||
Days Remaining:
|
|
||||||
</td>
|
|
||||||
<td>{{ certInfo.daysRemaining }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="my-3">
|
|
||||||
<td class="px-3">
|
|
||||||
Issuer:
|
|
||||||
</td>
|
|
||||||
<td>{{ certInfo.issuer }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="my-3">
|
|
||||||
<td class="px-3">
|
|
||||||
Fingerprint:
|
|
||||||
</td>
|
|
||||||
<td>{{ certInfo.fingerprint }}</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -207,8 +173,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineAsyncComponent } from "vue";
|
import { defineAsyncComponent } from "vue";
|
||||||
import { useToast } from "vue-toastification"
|
import { useToast } from "vue-toastification";
|
||||||
const toast = useToast()
|
const toast = useToast();
|
||||||
import Confirm from "../components/Confirm.vue";
|
import Confirm from "../components/Confirm.vue";
|
||||||
import HeartbeatBar from "../components/HeartbeatBar.vue";
|
import HeartbeatBar from "../components/HeartbeatBar.vue";
|
||||||
import Status from "../components/Status.vue";
|
import Status from "../components/Status.vue";
|
||||||
@ -218,6 +184,7 @@ import Uptime from "../components/Uptime.vue";
|
|||||||
import Pagination from "v-pagination-3";
|
import Pagination from "v-pagination-3";
|
||||||
const PingChart = defineAsyncComponent(() => import("../components/PingChart.vue"));
|
const PingChart = defineAsyncComponent(() => import("../components/PingChart.vue"));
|
||||||
import Tag from "../components/Tag.vue";
|
import Tag from "../components/Tag.vue";
|
||||||
|
import CertificateInfo from "../components/CertificateInfo.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -230,6 +197,7 @@ export default {
|
|||||||
Pagination,
|
Pagination,
|
||||||
PingChart,
|
PingChart,
|
||||||
Tag,
|
Tag,
|
||||||
|
CertificateInfo,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -239,32 +207,32 @@ export default {
|
|||||||
toggleCertInfoBox: false,
|
toggleCertInfoBox: false,
|
||||||
showPingChartBox: true,
|
showPingChartBox: true,
|
||||||
paginationConfig: {
|
paginationConfig: {
|
||||||
texts:{
|
texts: {
|
||||||
count:`${this.$t("Showing {from} to {to} of {count} records")}|{count} ${this.$t("records")}|${this.$t("One record")}`,
|
count: `${this.$t("Showing {from} to {to} of {count} records")}|{count} ${this.$t("records")}|${this.$t("One record")}`,
|
||||||
first:this.$t("First"),
|
first: this.$t("First"),
|
||||||
last:this.$t("Last"),
|
last: this.$t("Last"),
|
||||||
nextPage:'>',
|
nextPage: ">",
|
||||||
nextChunk:'>>',
|
nextChunk: ">>",
|
||||||
prevPage:'<',
|
prevPage: "<",
|
||||||
prevChunk:'<<'
|
prevChunk: "<<"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
monitor() {
|
monitor() {
|
||||||
let id = this.$route.params.id
|
let id = this.$route.params.id;
|
||||||
return this.$root.monitorList[id];
|
return this.$root.monitorList[id];
|
||||||
},
|
},
|
||||||
|
|
||||||
lastHeartBeat() {
|
lastHeartBeat() {
|
||||||
if (this.monitor.id in this.$root.lastHeartbeatList && this.$root.lastHeartbeatList[this.monitor.id]) {
|
if (this.monitor.id in this.$root.lastHeartbeatList && this.$root.lastHeartbeatList[this.monitor.id]) {
|
||||||
return this.$root.lastHeartbeatList[this.monitor.id]
|
return this.$root.lastHeartbeatList[this.monitor.id];
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: -1,
|
status: -1,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
ping() {
|
ping() {
|
||||||
@ -272,7 +240,7 @@ export default {
|
|||||||
return this.lastHeartBeat.ping;
|
return this.lastHeartBeat.ping;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.$t("notAvailableShort")
|
return this.$t("notAvailableShort");
|
||||||
},
|
},
|
||||||
|
|
||||||
avgPing() {
|
avgPing() {
|
||||||
@ -280,14 +248,14 @@ export default {
|
|||||||
return this.$root.avgPingList[this.monitor.id];
|
return this.$root.avgPingList[this.monitor.id];
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.$t("notAvailableShort")
|
return this.$t("notAvailableShort");
|
||||||
},
|
},
|
||||||
|
|
||||||
importantHeartBeatList() {
|
importantHeartBeatList() {
|
||||||
if (this.$root.importantHeartbeatList[this.monitor.id]) {
|
if (this.$root.importantHeartbeatList[this.monitor.id]) {
|
||||||
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
|
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
|
||||||
this.heartBeatList = this.$root.importantHeartbeatList[this.monitor.id];
|
this.heartBeatList = this.$root.importantHeartbeatList[this.monitor.id];
|
||||||
return this.$root.importantHeartbeatList[this.monitor.id]
|
return this.$root.importantHeartbeatList[this.monitor.id];
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
@ -295,22 +263,22 @@ export default {
|
|||||||
|
|
||||||
status() {
|
status() {
|
||||||
if (this.$root.statusList[this.monitor.id]) {
|
if (this.$root.statusList[this.monitor.id]) {
|
||||||
return this.$root.statusList[this.monitor.id]
|
return this.$root.statusList[this.monitor.id];
|
||||||
}
|
}
|
||||||
|
|
||||||
return { }
|
return { };
|
||||||
},
|
},
|
||||||
|
|
||||||
certInfo() {
|
tlsInfo() {
|
||||||
if (this.$root.certInfoList[this.monitor.id]) {
|
if (this.$root.tlsInfoList[this.monitor.id]) {
|
||||||
return this.$root.certInfoList[this.monitor.id]
|
return this.$root.tlsInfoList[this.monitor.id];
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null;
|
||||||
},
|
},
|
||||||
|
|
||||||
showCertInfoBox() {
|
showCertInfoBox() {
|
||||||
return this.certInfo != null && this.toggleCertInfoBox;
|
return this.tlsInfo != null && this.toggleCertInfoBox;
|
||||||
},
|
},
|
||||||
|
|
||||||
displayedRecords() {
|
displayedRecords() {
|
||||||
@ -324,8 +292,8 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
testNotification() {
|
testNotification() {
|
||||||
this.$root.getSocket().emit("testNotification", this.monitor.id)
|
this.$root.getSocket().emit("testNotification", this.monitor.id);
|
||||||
toast.success("Test notification is requested.")
|
toast.success("Test notification is requested.");
|
||||||
},
|
},
|
||||||
|
|
||||||
pauseDialog() {
|
pauseDialog() {
|
||||||
@ -334,14 +302,14 @@ export default {
|
|||||||
|
|
||||||
resumeMonitor() {
|
resumeMonitor() {
|
||||||
this.$root.getSocket().emit("resumeMonitor", this.monitor.id, (res) => {
|
this.$root.getSocket().emit("resumeMonitor", this.monitor.id, (res) => {
|
||||||
this.$root.toastRes(res)
|
this.$root.toastRes(res);
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
pauseMonitor() {
|
pauseMonitor() {
|
||||||
this.$root.getSocket().emit("pauseMonitor", this.monitor.id, (res) => {
|
this.$root.getSocket().emit("pauseMonitor", this.monitor.id, (res) => {
|
||||||
this.$root.toastRes(res)
|
this.$root.toastRes(res);
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
deleteDialog() {
|
deleteDialog() {
|
||||||
@ -360,11 +328,11 @@ export default {
|
|||||||
this.$root.deleteMonitor(this.monitor.id, (res) => {
|
this.$root.deleteMonitor(this.monitor.id, (res) => {
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
toast.success(res.msg);
|
toast.success(res.msg);
|
||||||
this.$router.push("/dashboard")
|
this.$router.push("/dashboard");
|
||||||
} else {
|
} else {
|
||||||
toast.error(res.msg);
|
toast.error(res.msg);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
clearEvents() {
|
clearEvents() {
|
||||||
@ -372,7 +340,7 @@ export default {
|
|||||||
if (! res.ok) {
|
if (! res.ok) {
|
||||||
toast.error(res.msg);
|
toast.error(res.msg);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
clearHeartbeats() {
|
clearHeartbeats() {
|
||||||
@ -380,13 +348,13 @@ export default {
|
|||||||
if (! res.ok) {
|
if (! res.ok) {
|
||||||
toast.error(res.msg);
|
toast.error(res.msg);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
pingTitle(average = false) {
|
pingTitle(average = false) {
|
||||||
let translationPrefix = ""
|
let translationPrefix = "";
|
||||||
if (average) {
|
if (average) {
|
||||||
translationPrefix = "Avg. "
|
translationPrefix = "Avg. ";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.monitor.type === "http") {
|
if (this.monitor.type === "http") {
|
||||||
@ -396,7 +364,7 @@ export default {
|
|||||||
return this.$t(translationPrefix + "Ping");
|
return this.$t(translationPrefix + "Ping");
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
Loading…
Reference in New Issue
Block a user