Merge branch 'louislam:master' into master

This commit is contained in:
Phuong Nguyen Minh 2021-11-15 11:55:09 +07:00 committed by GitHub
commit fac94fa2a9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 669 additions and 281 deletions

View file

@ -1,8 +1,23 @@
name: "❓ Ask for help" name: "❓ Ask for help"
description: "Submit any question related to Uptime Kuma" description: "Submit any question related to Uptime Kuma"
title: "[Help]: <title>" #title: "[Help] "
labels: [help] labels: [help]
body: body:
- type: checkboxes
id: no-duplicate-issues
attributes:
label: "⚠️ Please verify that this bug has NOT been raised before."
description: "Search in the issues sections by clicking [HERE](https://github.com/louislam/uptime-kuma/issues?q=)"
options:
- label: "I checked and didn't find similar issue"
required: true
- type: checkboxes
attributes:
label: "🛡️ Security Policy"
description: Please review the security policy before reporting security related issues/bugs.
options:
- label: I agree to have read this project [Security Policy](https://github.com/louislam/uptime-kuma/security/policy)
required: true
- type: textarea - type: textarea
id: steps-to-reproduce id: steps-to-reproduce
validations: validations:
@ -14,17 +29,17 @@ body:
- type: input - type: input
id: uptime-kuma-version id: uptime-kuma-version
attributes: attributes:
label: "🐻 Uptime-Kuma version" label: "🐻 Uptime-Kuma Version"
description: "Which version of Uptime-Kuma are you running?" description: "Which version of Uptime-Kuma are you running? Please do NOT provide the docker tag such as latest or 1"
placeholder: "Ex. 1.9.x" placeholder: "Ex. 1.10.0"
validations: validations:
required: true required: true
- type: input - type: input
id: operating-system id: operating-system
attributes: attributes:
label: "💻 Operating System" label: "💻 Operating System and Arch"
description: "Which OS is your server/device running on?" description: "Which OS is your server/device running on?"
placeholder: "Ex. Ubuntu 20.04" placeholder: "Ex. Ubuntu 20.04 x86"
validations: validations:
required: true required: true
- type: input - type: input
@ -32,23 +47,15 @@ body:
attributes: attributes:
label: "🌐 Browser" label: "🌐 Browser"
description: "Which browser are you running on?" description: "Which browser are you running on?"
placeholder: "Ex. Firefox" placeholder: "Ex. Google Chrome 95.0.4638.69"
validations: validations:
required: true required: true
- type: input - type: input
id: docker-version id: docker-version
attributes: attributes:
label: "🐋 Docker" label: "🐋 Docker Version"
description: "If running with Docker, which version are you running?" description: "If running with Docker, which version are you running?"
placeholder: "Ex. 20.10.9" placeholder: "Ex. Docker 20.10.9 / K8S / Podman"
validations:
required: false
- type: input
id: docker-image-tag
attributes:
label: "🏷️ Docker Image Tag"
description: "Which Docker image tag are you using? If running '1' or 'latest', please specify image hash."
placeholder: "Ex. 1.9.1"
validations: validations:
required: false required: false
- type: input - type: input
@ -56,21 +63,6 @@ body:
attributes: attributes:
label: "🟩 NodeJS Version" label: "🟩 NodeJS Version"
description: "If running with Node.js? which version are you running?" description: "If running with Node.js? which version are you running?"
placeholder: "14.x" placeholder: "Ex. 14.18.0"
validations: validations:
required: false required: false
- type: checkboxes
id: no-duplicate-issues
attributes:
label: "⚠️ Please verify that this question has NOT been raised before."
description: "Search in the issues sections by clicking [HERE](https://github.com/louislam/uptime-kuma/issues?q=)"
options:
- label: "I checked and didn't find similar question"
required: true
- type: checkboxes
attributes:
label: "🛡️ Security Policy"
description: Please review the security policy before reporting security related issues/bugs.
options:
- label: I agree to have read this project [Security Policy](https://github.com/louislam/uptime-kuma/security/policy)
required: true

View file

@ -1,88 +1,8 @@
name: "🐛 Bug Report" name: "🐛 Bug Report"
description: "Submit a bug report to help us improve" description: "Submit a bug report to help us improve"
title: "[Bug]: <title>" #title: "[Bug] "
labels: [bug] labels: [bug]
body: body:
- type: textarea
id: steps-to-reproduce
validations:
required: true
attributes:
label: "👟 Reproduction steps"
description: "How do you trigger this bug? Please walk us through it step by step."
placeholder: "..."
- type: textarea
id: expected-behavior
validations:
required: true
attributes:
label: "👍 Expected behavior"
description: "What did you think would happen?"
placeholder: "..."
- type: textarea
id: actual-behavior
validations:
required: true
attributes:
label: "👎 Actual Behavior"
description: "What actually happen?"
placeholder: "..."
- type: input
id: uptime-kuma-version
attributes:
label: "🐻 Uptime-Kuma version"
description: "Which version of Uptime-Kuma are you running?"
placeholder: "Ex. 1.9.x"
validations:
required: true
- type: input
id: operating-system
attributes:
label: "💻 Operating System"
description: "Which OS is your server/device running on?"
placeholder: "Ex. Ubuntu 20.04"
validations:
required: true
- type: input
id: browser-vendor
attributes:
label: "🌐 Browser"
description: "Which browser are you running on?"
placeholder: "Ex. Firefox"
validations:
required: true
- type: input
id: docker-version
attributes:
label: "🐋 Docker"
description: "If running with Docker, which version are you running?"
placeholder: "Ex. 20.10.9"
validations:
required: false
- type: input
id: docker-image-tag
attributes:
label: "🏷️ Docker Image Tag"
description: "Which Docker image tag are you using? If running '1' or 'latest', please specify image hash."
placeholder: "Ex. 1.9.1"
validations:
required: false
- type: input
id: nodejs-version
attributes:
label: "🟩 NodeJS Version"
description: "If running with Node.js? which version are you running?"
placeholder: "14.x"
validations:
required: false
- type: textarea
id: logs
attributes:
label: "📝 Relevant log output"
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
render: shell
validations:
required: false
- type: checkboxes - type: checkboxes
id: no-duplicate-issues id: no-duplicate-issues
attributes: attributes:
@ -98,3 +18,82 @@ body:
options: options:
- label: I agree to have read this project [Security Policy](https://github.com/louislam/uptime-kuma/security/policy) - label: I agree to have read this project [Security Policy](https://github.com/louislam/uptime-kuma/security/policy)
required: true required: true
- type: textarea
id: description
validations:
required: false
attributes:
label: "Description"
description: "You could also upload screenshots"
- type: textarea
id: steps-to-reproduce
validations:
required: true
attributes:
label: "👟 Reproduction steps"
description: "How do you trigger this bug? Please walk us through it step by step."
placeholder: "..."
- type: textarea
id: expected-behavior
validations:
required: true
attributes:
label: "👀 Expected behavior"
description: "What did you think would happen?"
placeholder: "..."
- type: textarea
id: actual-behavior
validations:
required: true
attributes:
label: "😓 Actual Behavior"
description: "What actually happen?"
placeholder: "..."
- type: input
id: uptime-kuma-version
attributes:
label: "🐻 Uptime-Kuma Version"
description: "Which version of Uptime-Kuma are you running? Please do NOT provide the docker tag such as latest or 1"
placeholder: "Ex. 1.10.0"
validations:
required: true
- type: input
id: operating-system
attributes:
label: "💻 Operating System and Arch"
description: "Which OS is your server/device running on?"
placeholder: "Ex. Ubuntu 20.04 x86"
validations:
required: true
- type: input
id: browser-vendor
attributes:
label: "🌐 Browser"
description: "Which browser are you running on?"
placeholder: "Ex. Google Chrome 95.0.4638.69"
validations:
required: true
- type: input
id: docker-version
attributes:
label: "🐋 Docker Version"
description: "If running with Docker, which version are you running?"
placeholder: "Ex. Docker 20.10.9 / K8S / Podman"
validations:
required: false
- type: input
id: nodejs-version
attributes:
label: "🟩 NodeJS Version"
description: "If running with Node.js? which version are you running?"
placeholder: "Ex. 14.18.0"
validations:
required: false
- type: textarea
id: logs
attributes:
label: "📝 Relevant log output"
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
render: shell
validations:
required: false

View file

@ -1,8 +1,16 @@
name: 🚀 Feature Request name: 🚀 Feature Request
description: "Submit a proposal for a new feature" description: "Submit a proposal for a new feature"
title: "[Feature]: <title>" #title: "[Feature] "
labels: [enhancement] labels: [feature-request]
body: body:
- type: checkboxes
id: no-duplicate-issues
attributes:
label: "⚠️ Please verify that this feature request has NOT been suggested before."
description: "Search in the issues sections by clicking [HERE](https://github.com/louislam/uptime-kuma/issues?q=)"
options:
- label: "I checked and didn't find similar feature request"
required: true
- type: dropdown - type: dropdown
id: feature-area id: feature-area
attributes: attributes:
@ -49,11 +57,3 @@ body:
label: "📝 Additional Context" label: "📝 Additional Context"
description: "Add any other context or screenshots about the feature request here." description: "Add any other context or screenshots about the feature request here."
placeholder: "..." placeholder: "..."
- type: checkboxes
id: no-duplicate-issues
attributes:
label: "⚠️ Please verify that this feature request has NOT been suggested before."
description: "Search in the issues sections by clicking [HERE](https://github.com/louislam/uptime-kuma/issues?q=)"
options:
- label: "I checked and didn't find similar feature request"
required: true

View file

@ -24,3 +24,5 @@ Please delete options that are not relevant.
- [ ] My code needed automated testing. I have added them (this is optional task) - [ ] My code needed automated testing. I have added them (this is optional task)
## Screenshots (if any) ## Screenshots (if any)
Please do not use any external image service. Instead, just paste in or drag and drop the image here and it will be uploaded automatically.

View file

@ -1,5 +1,11 @@
# Security Policy # Security Policy
## Reporting a Vulnerability
Please report security issues to uptime@kuma.pet.
Do not use the issue tracker or discuss it in the public as it will cause more damage.
## Supported Versions ## Supported Versions
Use this section to tell people about which versions of your project are Use this section to tell people about which versions of your project are
@ -23,9 +29,3 @@ currently being supported with security updates.
| debian | :white_check_mark: | | debian | :white_check_mark: |
| alpine | :white_check_mark: | | alpine | :white_check_mark: |
| All other tags | ❌ | | All other tags | ❌ |
## Reporting a Vulnerability
Please report security issues to uptime@kuma.pet.
Do not use the issue tracker or discuss it in the public as it will cause more damage.

View file

@ -1,25 +1,41 @@
/* /*
* This script should be run after a period of time (180s), because the server may need some time to prepare. * This script should be run after a period of time (180s), because the server may need some time to prepare.
*/ */
const { FBSD } = require("../server/util-server");
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
let client; let client;
if (process.env.SSL_KEY && process.env.SSL_CERT) { const sslKey = process.env.UPTIME_KUMA_SSL_KEY || process.env.SSL_KEY || undefined;
const sslCert = process.env.UPTIME_KUMA_SSL_CERT || process.env.SSL_CERT || undefined;
if (sslKey && sslCert) {
client = require("https"); client = require("https");
} else { } else {
client = require("http"); client = require("http");
} }
// If host is omitted, the server will accept connections on the unspecified IPv6 address (::) when IPv6 is available and the unspecified IPv4 address (0.0.0.0) otherwise.
// Dual-stack support for (::)
let hostname = process.env.UPTIME_KUMA_HOST;
// Also read HOST if not FreeBSD, as HOST is a system environment variable in FreeBSD
if (!hostname && !FBSD) {
hostname = process.env.HOST;
}
const port = parseInt(process.env.UPTIME_KUMA_PORT || process.env.PORT || 3001);
let options = { let options = {
host: process.env.HOST || "127.0.0.1", host: hostname || "127.0.0.1",
port: parseInt(process.env.PORT) || 3001, port: port,
timeout: 28 * 1000, timeout: 28 * 1000,
}; };
let request = client.request(options, (res) => { let request = client.request(options, (res) => {
console.log(`Health Check OK [Res Code: ${res.statusCode}]`); console.log(`Health Check OK [Res Code: ${res.statusCode}]`);
if (res.statusCode === 200) { if (res.statusCode === 302) {
process.exit(0); process.exit(0);
} else { } else {
process.exit(1); process.exit(1);

View file

@ -1,6 +1,6 @@
{ {
"name": "uptime-kuma", "name": "uptime-kuma",
"version": "1.10.0", "version": "1.10.2",
"license": "MIT", "license": "MIT",
"repository": { "repository": {
"type": "git", "type": "git",
@ -30,13 +30,13 @@
"build-docker": "npm run build-docker-debian && npm run build-docker-alpine", "build-docker": "npm run build-docker-debian && npm run build-docker-alpine",
"build-docker-alpine-base": "docker buildx build -f docker/alpine-base.dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:base-alpine . --push", "build-docker-alpine-base": "docker buildx build -f docker/alpine-base.dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:base-alpine . --push",
"build-docker-debian-base": "docker buildx build -f docker/debian-base.dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:base-debian . --push", "build-docker-debian-base": "docker buildx build -f docker/debian-base.dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:base-debian . --push",
"build-docker-alpine": "docker buildx build -f docker/dockerfile-alpine --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:alpine -t louislam/uptime-kuma:1-alpine -t louislam/uptime-kuma:1.10.0-alpine --target release . --push", "build-docker-alpine": "docker buildx build -f docker/dockerfile-alpine --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:alpine -t louislam/uptime-kuma:1-alpine -t louislam/uptime-kuma:1.10.2-alpine --target release . --push",
"build-docker-debian": "docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma -t louislam/uptime-kuma:1 -t louislam/uptime-kuma:1.10.0 -t louislam/uptime-kuma:debian -t louislam/uptime-kuma:1-debian -t louislam/uptime-kuma:1.10.0-debian --target release . --push", "build-docker-debian": "docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma -t louislam/uptime-kuma:1 -t louislam/uptime-kuma:1.10.2 -t louislam/uptime-kuma:debian -t louislam/uptime-kuma:1-debian -t louislam/uptime-kuma:1.10.2-debian --target release . --push",
"build-docker-nightly": "docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:nightly --target nightly . --push", "build-docker-nightly": "docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:nightly --target nightly . --push",
"build-docker-nightly-alpine": "docker buildx build -f docker/dockerfile-alpine --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:nightly-alpine --target nightly . --push", "build-docker-nightly-alpine": "docker buildx build -f docker/dockerfile-alpine --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:nightly-alpine --target nightly . --push",
"build-docker-nightly-amd64": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:nightly-amd64 --target nightly . --push --progress plain", "build-docker-nightly-amd64": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:nightly-amd64 --target nightly . --push --progress plain",
"upload-artifacts": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:upload-artifact --build-arg GITHUB_TOKEN --target upload-artifact . --progress plain", "upload-artifacts": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:upload-artifact --build-arg GITHUB_TOKEN --target upload-artifact . --progress plain",
"setup": "git checkout 1.10.0 && npm ci --production && npm run download-dist", "setup": "git checkout 1.10.2 && npm ci --production && npm run download-dist",
"download-dist": "node extra/download-dist.js", "download-dist": "node extra/download-dist.js",
"update-version": "node extra/update-version.js", "update-version": "node extra/update-version.js",
"mark-as-nightly": "node extra/mark-as-nightly.js", "mark-as-nightly": "node extra/mark-as-nightly.js",
@ -61,7 +61,7 @@
"args-parser": "~1.3.0", "args-parser": "~1.3.0",
"axios": "~0.21.4", "axios": "~0.21.4",
"bcryptjs": "~2.4.3", "bcryptjs": "~2.4.3",
"bootstrap": "~5.1.3", "bootstrap": "5.1.3",
"bree": "~6.3.1", "bree": "~6.3.1",
"chardet": "^1.3.0", "chardet": "^1.3.0",
"chart.js": "~3.6.0", "chart.js": "~3.6.0",

View file

@ -141,6 +141,7 @@ class Monitor extends BeanModel {
// Do not do any queries/high loading things before the "bean.ping" // Do not do any queries/high loading things before the "bean.ping"
let startTime = dayjs().valueOf(); let startTime = dayjs().valueOf();
debug(`[${this.name}] Prepare Options for axios`);
const options = { const options = {
url: this.url, url: this.url,
method: (this.method || "get").toLowerCase(), method: (this.method || "get").toLowerCase(),
@ -160,6 +161,8 @@ class Monitor extends BeanModel {
return checkStatusCode(status, this.getAcceptedStatuscodes()); return checkStatusCode(status, this.getAcceptedStatuscodes());
}, },
}; };
debug(`[${this.name}] Axios Request`);
let res = await axios.request(options); let res = await axios.request(options);
bean.msg = `${res.status} - ${res.statusText}`; bean.msg = `${res.status} - ${res.statusText}`;
bean.ping = dayjs().valueOf() - startTime; bean.ping = dayjs().valueOf() - startTime;
@ -167,12 +170,13 @@ class Monitor extends BeanModel {
// Check certificate if https is used // Check certificate if https is used
let certInfoStartTime = dayjs().valueOf(); let certInfoStartTime = dayjs().valueOf();
if (this.getUrl()?.protocol === "https:") { if (this.getUrl()?.protocol === "https:") {
debug(`[${this.name}] Check cert`);
try { try {
let tlsInfoObject = checkCertificate(res); let tlsInfoObject = checkCertificate(res);
tlsInfo = await this.updateTlsInfo(tlsInfoObject); tlsInfo = await this.updateTlsInfo(tlsInfoObject);
if (!this.getIgnoreTls()) { if (!this.getIgnoreTls()) {
debug("call sendCertNotification"); debug(`[${this.name}] call sendCertNotification`);
await this.sendCertNotification(tlsInfoObject); await this.sendCertNotification(tlsInfoObject);
} }
@ -351,15 +355,19 @@ class Monitor extends BeanModel {
let beatInterval = this.interval; let beatInterval = this.interval;
debug(`[${this.name}] Check isImportant`);
let isImportant = Monitor.isImportantBeat(isFirstBeat, previousBeat?.status, bean.status); let isImportant = Monitor.isImportantBeat(isFirstBeat, previousBeat?.status, bean.status);
// Mark as important if status changed, ignore pending pings, // Mark as important if status changed, ignore pending pings,
// Don't notify if disrupted changes to up // Don't notify if disrupted changes to up
if (isImportant) { if (isImportant) {
bean.important = true; bean.important = true;
debug(`[${this.name}] sendNotification`);
await Monitor.sendNotification(isFirstBeat, this, bean); await Monitor.sendNotification(isFirstBeat, this, bean);
// Clear Status Page Cache // Clear Status Page Cache
debug(`[${this.name}] apicache clear`);
apicache.clear(); apicache.clear();
} else { } else {
@ -377,10 +385,14 @@ class Monitor extends BeanModel {
console.warn(`Monitor #${this.id} '${this.name}': Failing: ${bean.msg} | Interval: ${beatInterval} seconds | Type: ${this.type}`); console.warn(`Monitor #${this.id} '${this.name}': Failing: ${bean.msg} | Interval: ${beatInterval} seconds | Type: ${this.type}`);
} }
debug(`[${this.name}] Send to socket`);
io.to(this.user_id).emit("heartbeat", bean.toJSON()); io.to(this.user_id).emit("heartbeat", bean.toJSON());
Monitor.sendStats(io, this.id, this.user_id); Monitor.sendStats(io, this.id, this.user_id);
debug(`[${this.name}] Store`);
await R.store(bean); await R.store(bean);
debug(`[${this.name}] prometheus.update`);
prometheus.update(bean, tlsInfo); prometheus.update(bean, tlsInfo);
previousBeat = bean; previousBeat = bean;
@ -394,7 +406,10 @@ class Monitor extends BeanModel {
} }
} }
debug(`[${this.name}] SetTimeout for next check.`);
this.heartbeatInterval = setTimeout(safeBeat, beatInterval * 1000); this.heartbeatInterval = setTimeout(safeBeat, beatInterval * 1000);
} else {
console.log(`[${this.name}] isStop = true, no next check.`);
} }
}; };

View file

@ -27,7 +27,7 @@ class Feishu extends NotificationProvider {
content: { content: {
post: { post: {
zh_cn: { zh_cn: {
title: "UptimeKuma Alert: " + monitorJSON["name"], title: "UptimeKuma Alert: [Down] " + monitorJSON["name"],
content: [ content: [
[ [
{ {
@ -54,7 +54,7 @@ class Feishu extends NotificationProvider {
content: { content: {
post: { post: {
zh_cn: { zh_cn: {
title: "UptimeKuma Alert: " + monitorJSON["name"], title: "UptimeKuma Alert: [Up] " + monitorJSON["name"],
content: [ content: [
[ [
{ {

View file

@ -101,6 +101,10 @@ router.get("/api/status-page/config", async (_request, response) => {
config.statusPagePublished = true; config.statusPagePublished = true;
} }
if (! config.statusPageTags) {
config.statusPageTags = false;
}
if (! config.title) { if (! config.title) {
config.title = "Uptime Kuma"; config.title = "Uptime Kuma";
} }
@ -140,10 +144,25 @@ router.get("/api/status-page/monitor-list", cache("5 minutes"), async (_request,
try { try {
await checkPublished(); await checkPublished();
const publicGroupList = []; const publicGroupList = [];
let list = await R.find("group", " public = 1 ORDER BY weight "); const tagsVisible = (await getSettings("statusPage")).statusPageTags;
const list = await R.find("group", " public = 1 ORDER BY weight ");
for (let groupBean of list) { for (let groupBean of list) {
publicGroupList.push(await groupBean.toPublicJSON()); let monitorGroup = await groupBean.toPublicJSON();
if (tagsVisible) {
monitorGroup.monitorList = await Promise.all(monitorGroup.monitorList.map(async (monitor) => {
// Includes tags as an array in response, allows for tags to be displayed on public status page
const tags = await R.getAll(
`SELECT monitor_tag.monitor_id, monitor_tag.value, tag.name, tag.color
FROM monitor_tag
JOIN tag
ON monitor_tag.tag_id = tag.id
WHERE monitor_tag.monitor_id = ?`, [monitor.id]
);
return {...monitor, tags: tags}
}));
}
publicGroupList.push(monitorGroup);
} }
response.json(publicGroupList); response.json(publicGroupList);

View file

@ -186,6 +186,15 @@ exports.entryPage = "dashboard";
// Normal Router here // Normal Router here
// *************************** // ***************************
// Entry Page
app.get("/", async (_request, response) => {
if (exports.entryPage === "statusPage") {
response.redirect("/status");
} else {
response.redirect("/dashboard");
}
});
// Robots.txt // Robots.txt
app.get("/robots.txt", async (_request, response) => { app.get("/robots.txt", async (_request, response) => {
let txt = "User-agent: *\nDisallow:"; let txt = "User-agent: *\nDisallow:";

View file

@ -201,8 +201,13 @@ const getDaysRemaining = (validFrom, validTo) => {
// param: info - the chain obtained from getPeerCertificate() // param: info - the chain obtained from getPeerCertificate()
const parseCertificateInfo = function (info) { const parseCertificateInfo = function (info) {
let link = info; let link = info;
let i = 0;
const existingList = {};
while (link) { while (link) {
debug(`[${i}] ${link.fingerprint}`);
if (!link.valid_from || !link.valid_to) { if (!link.valid_from || !link.valid_to) {
break; break;
} }
@ -210,15 +215,24 @@ const parseCertificateInfo = function (info) {
link.validFor = link.subjectaltname?.replace(/DNS:|IP Address:/g, "").split(", "); link.validFor = link.subjectaltname?.replace(/DNS:|IP Address:/g, "").split(", ");
link.daysRemaining = getDaysRemaining(new Date(), link.validTo); link.daysRemaining = getDaysRemaining(new Date(), link.validTo);
existingList[link.fingerprint] = true;
// Move up the chain until loop is encountered // Move up the chain until loop is encountered
if (link.issuerCertificate == null) { if (link.issuerCertificate == null) {
break; break;
} else if (link.fingerprint == link.issuerCertificate.fingerprint) { } else if (link.issuerCertificate.fingerprint in existingList) {
debug(`[Last] ${link.issuerCertificate.fingerprint}`);
link.issuerCertificate = null; link.issuerCertificate = null;
break; break;
} else { } else {
link = link.issuerCertificate; link = link.issuerCertificate;
} }
// Should be no use, but just in case.
if (i > 500) {
throw new Error("Dead loop occurred in parseCertificateInfo");
}
i++;
} }
return info; return info;
@ -228,6 +242,7 @@ exports.checkCertificate = function (res) {
const info = res.request.res.socket.getPeerCertificate(true); const info = res.request.res.socket.getPeerCertificate(true);
const valid = res.request.res.socket.authorized || false; const valid = res.request.res.socket.authorized || false;
debug("Parsing Certificate Info");
const parsedInfo = parseCertificateInfo(info); const parsedInfo = parseCertificateInfo(info);
return { return {

View file

@ -189,7 +189,7 @@ textarea.form-control {
opacity: 1; opacity: 1;
} }
.table-hover > tbody > tr:hover { .table-hover > tbody > tr:hover > * {
--bs-table-accent-bg: #070a10; --bs-table-accent-bg: #070a10;
color: $dark-font-color; color: $dark-font-color;
} }
@ -346,6 +346,10 @@ textarea.form-control {
&.active { &.active {
background-color: #cdf8f4; background-color: #cdf8f4;
} }
.tags {
// Removes margin to line up tags list with uptime percentage
margin-left: -0.25rem;
}
} }
} }

View file

@ -41,6 +41,9 @@
<Uptime :monitor="monitor.element" type="24" :pill="true" /> <Uptime :monitor="monitor.element" type="24" :pill="true" />
{{ monitor.element.name }} {{ monitor.element.name }}
</div> </div>
<div class="tags">
<Tag v-for="tag in monitor.element.tags" :key="tag" :item="tag" :size="'sm'" />
</div>
</div> </div>
<div :key="$root.userHeartbeatBar" class="col-3 col-md-4"> <div :key="$root.userHeartbeatBar" class="col-3 col-md-4">
<HeartbeatBar size="small" :monitor-id="monitor.element.id" /> <HeartbeatBar size="small" :monitor-id="monitor.element.id" />
@ -59,12 +62,14 @@
import Draggable from "vuedraggable"; import Draggable from "vuedraggable";
import HeartbeatBar from "./HeartbeatBar.vue"; import HeartbeatBar from "./HeartbeatBar.vue";
import Uptime from "./Uptime.vue"; import Uptime from "./Uptime.vue";
import Tag from "./Tag.vue";
export default { export default {
components: { components: {
Draggable, Draggable,
HeartbeatBar, HeartbeatBar,
Uptime, Uptime,
Tag,
}, },
props: { props: {
editMode: { editMode: {

View file

@ -1,5 +1,5 @@
<template> <template>
<span :class="className">{{ uptime }}</span> <span :class="className" :title="24 + $t('-hour')">{{ uptime }}</span>
</template> </template>
<script> <script>

View file

@ -77,7 +77,7 @@ export default {
"Accepted Status Codes": "Допустими статус кодове", "Accepted Status Codes": "Допустими статус кодове",
Save: "Запази", Save: "Запази",
Notifications: "Известявания", Notifications: "Известявания",
"Not available, please setup.": "Не е налично. Моля, настройте.", "Not available, please setup.": "Не са налични. Моля, настройте.",
"Setup Notification": "Настройки за известявания", "Setup Notification": "Настройки за известявания",
Light: "Светла", Light: "Светла",
Dark: "Тъмна", Dark: "Тъмна",
@ -141,7 +141,7 @@ export default {
Overwrite: "Презапиши", Overwrite: "Презапиши",
Options: "Опции", Options: "Опции",
"Keep both": "Запази двете", "Keep both": "Запази двете",
"Verify Token": "Проверка на токен код", "Verify Token": "Провери токен код",
"Setup 2FA": "Настройка 2FA", "Setup 2FA": "Настройка 2FA",
"Enable 2FA": "Включи 2FA", "Enable 2FA": "Включи 2FA",
"Disable 2FA": "Изключи 2FA", "Disable 2FA": "Изключи 2FA",
@ -298,8 +298,13 @@ export default {
HeadersInvalidFormat: "Заявените хедъри не са валидни JSON: ", HeadersInvalidFormat: "Заявените хедъри не са валидни JSON: ",
BodyInvalidFormat: "Заявеното съобщение не е валиден JSON: ", BodyInvalidFormat: "Заявеното съобщение не е валиден JSON: ",
"Monitor History": "История на мониторите", "Monitor History": "История на мониторите",
clearDataOlderThan: "Ще се съхранява за {0} дни.", clearDataOlderThan: "Ще се съхранява {0} дни.",
records: "записа", records: "записа",
"One record": "Един запис", "One record": "Един запис",
steamApiKeyDescription: "За да мониторирате Steam Gameserver се нуждаете от Steam Web-API ключ. Може да регистрирате Вашия API ключ тук: ", steamApiKeyDescription: "За да мониторирате Steam Gameserver се нуждаете от Steam Web-API ключ. Може да регистрирате Вашия API ключ тук: ",
clicksendsms: "ClickSend SMS",
apiCredentials: "API удостоверяване",
PasswordsDoNotMatch: "Паролите не съвпадат.",
"Current User": "Текущ потребител",
recent: "Скорошни",
}; };

View file

@ -279,4 +279,29 @@ export default {
promosmsTypeSpeed: "SMS SPEED - La plus haute des priorités dans le système. Très rapide et fiable mais cher (environ le double du prix d'un SMS FULL).", promosmsTypeSpeed: "SMS SPEED - La plus haute des priorités dans le système. Très rapide et fiable mais cher (environ le double du prix d'un SMS FULL).",
promosmsPhoneNumber: "Numéro de téléphone (Poiur les déstinataires Polonais, vous pouvez enlever les codes interna.)", promosmsPhoneNumber: "Numéro de téléphone (Poiur les déstinataires Polonais, vous pouvez enlever les codes interna.)",
promosmsSMSSender: "SMS Expéditeur : Nom pré-enregistré ou l'un de base: InfoSMS, SMS Info, MaxSMS, INFO, SMS", promosmsSMSSender: "SMS Expéditeur : Nom pré-enregistré ou l'un de base: InfoSMS, SMS Info, MaxSMS, INFO, SMS",
"Primary Base URL": "Primary Base URL",
emailCustomSubject: "Sujet personalisé",
clicksendsms: "ClickSend SMS",
checkPrice: "Vérification {0} tarifs:",
apiCredentials: "Crédentials de l'API",
octopushLegacyHint: "Vous utilisez l'ancienne version d'Octopush (2011-2020) ou la nouvelle version ?",
"Feishu WebHookUrl": "Feishu WebHookURL",
matrixHomeserverURL: "L'URL du serveur (avec http(s):// et le port de manière facultatif)",
"Internal Room Id": "ID de la salle interne",
matrixDesc1: "Vous pouvez trouvez l'ID de salle interne en regardant dans la section avancée des paramètres dans le client Matrix. C'est sensé ressembler à: !QMdRCpUIfLwsfjxye6:home.server.",
matrixDesc2: "Il est fortement recommandé de créer un nouvel utilisateur et de ne pas utiliser le jeton d'accès de votre propre utilisateur Matrix, car il vous donnera un accès complet à votre compte et à toutes les salles que vous avez rejointes. Au lieu de cela, créez un nouvel utilisateur et invitez-le uniquement dans la salle dans laquelle vous souhaitez recevoir la notification. Vous pouvez obtenir le jeton d'accès en exécutant {0}",
Method: "Méthode",
Body: "Le corps",
Headers: "En-têtes",
PushUrl: "Push URL",
HeadersInvalidFormat: "L'en-têtes de la requête n'est pas dans un format JSON valide: ",
BodyInvalidFormat: "Le corps de la requête n'est pas dans un format JSON valide: ",
"Monitor History": "Historique de la sonde",
clearDataOlderThan: "Garder l'historique des données de la sonde durant {0} jours.",
PasswordsDoNotMatch: "Les mots de passe ne correspondent pas.",
records: "Enregistrements",
"One record": "Un enregistrement",
steamApiKeyDescription: "Pour surveiller un serveur Steam, vous avez besoin d'une clé Steam Web-API. Vous pouvez enregistrer votre clé ici: ",
"Current User": "Utilisateur actuel",
recent: "Récent",
}; };

View file

@ -2,15 +2,14 @@ export default {
languageName: "Hrvatski", languageName: "Hrvatski",
checkEverySecond: "Provjera svake {0} sekunde", checkEverySecond: "Provjera svake {0} sekunde",
retryCheckEverySecond: "Ponovni pokušaj svake {0} sekunde", retryCheckEverySecond: "Ponovni pokušaj svake {0} sekunde",
retriesDescription: "Broj ponovnih pokušaja prije nego će se servis označiti kao DOWN te poslati obavijest", retriesDescription: "Broj ponovnih pokušaja prije nego će se servis označiti kao nedostupan te poslati obavijest",
ignoreTLSError: "Ignoriraj TLS/SSL pogreške za HTTPS web stranice", ignoreTLSError: "Ignoriraj TLS/SSL pogreške za HTTPS web stranice",
upsideDownModeDescription: "Preokreni logiku statusa. Ako je usluga dostupna, smatra se da je DOWN.", upsideDownModeDescription: "Preokreni logiku statusa. Ako se primi pozitivan odgovor, smatra se da je usluga nedostupna.",
maxRedirectDescription: "Maksimalan broj preusmjeravanja. Postaviti na 0 kako bi se preusmjeravanja onemogućila.", maxRedirectDescription: "Maksimalan broj preusmjeravanja. Postaviti na 0 kako bi se preusmjeravanja onemogućila.",
acceptedStatusCodesDescription: "Odaberite statusne kodove koji se smatraju uspješnim odgovorom.", acceptedStatusCodesDescription: "Odaberite statusne kodove koji se smatraju uspješnim odgovorom.",
passwordNotMatchMsg: "Lozinke se ne poklapaju.", passwordNotMatchMsg: "Lozinke se ne poklapaju.",
notificationDescription: "Obavijesti će funkcionirati samo ako su dodijeljene monitoru.", notificationDescription: "Obavijesti će funkcionirati samo ako su dodijeljene monitoru.",
keywordDescription: "Ključna riječ za pretragu kao običan HTML ili u JSON formatu. Pretraga je case-sensitive.", keywordDescription: "Ključna riječ za pretragu, u obliku običnog HTML-a ili u JSON formatu. Pretraga je osjetljiva na velika i mala slova.",
pauseDashboardHome: "Pauziraj",
deleteMonitorMsg: "Jeste li sigurni da želite izbrisati monitor?", deleteMonitorMsg: "Jeste li sigurni da želite izbrisati monitor?",
deleteNotificationMsg: "Jeste li sigurni da želite izbrisati ovu obavijest za sve monitore?", deleteNotificationMsg: "Jeste li sigurni da želite izbrisati ovu obavijest za sve monitore?",
resoverserverDescription: "Cloudflare je zadani DNS poslužitelj. Možete to promijeniti u bilo kojem trenutku.", resoverserverDescription: "Cloudflare je zadani DNS poslužitelj. Možete to promijeniti u bilo kojem trenutku.",
@ -25,7 +24,7 @@ export default {
twoFAVerifyLabel: "Unesite svoj 2FA token:", twoFAVerifyLabel: "Unesite svoj 2FA token:",
tokenValidSettingsMsg: "Token je važeći! Sada možete spremiti postavke dvofaktorske autentikacije.", tokenValidSettingsMsg: "Token je važeći! Sada možete spremiti postavke dvofaktorske autentikacije.",
confirmEnableTwoFAMsg: "Želite li omogućiti dvofaktorsku autentikaciju?", confirmEnableTwoFAMsg: "Želite li omogućiti dvofaktorsku autentikaciju?",
confirmDisableTwoFAMsg: "Are you sure you want to disable dvofaktorsku autentikaciju?", confirmDisableTwoFAMsg: "Jeste li sigurni da želite onemogućiti dvofaktorsku autentikaciju?",
Settings: "Postavke", Settings: "Postavke",
Dashboard: "Kontrolna ploča", Dashboard: "Kontrolna ploča",
"New Update": "Novo ažuriranje", "New Update": "Novo ažuriranje",
@ -44,17 +43,18 @@ export default {
Down: "Nedostupno", Down: "Nedostupno",
Pending: "U tijeku", Pending: "U tijeku",
Unknown: "Nepoznato", Unknown: "Nepoznato",
Pause: "Pauzirano", pauseDashboardHome: "Pauzirano",
Name: "Naziv monitora", Name: "Naziv",
Status: "Status", Status: "Status",
DateTime: "Vremenska oznaka", DateTime: "Vremenska oznaka",
Message: "Izvještaj", Message: "Izvještaj",
"No important events": "Nema važnih događaja", "No important events": "Nema važnih događaja",
Pause: "Pauziraj",
Resume: "Nastavi", Resume: "Nastavi",
Edit: "Uredi", Edit: "Uredi",
Delete: "Obriši", Delete: "Obriši",
Current: "Trenutno", Current: "Trenutno",
Uptime: "Uptime", Uptime: "Dostupnost",
"Cert Exp.": "Istek cert.", "Cert Exp.": "Istek cert.",
days: "dana", days: "dana",
day: "dan", day: "dan",
@ -65,12 +65,12 @@ export default {
Ping: "Odziv", Ping: "Odziv",
"Monitor Type": "Vrsta Monitora", "Monitor Type": "Vrsta Monitora",
Keyword: "Ključna riječ", Keyword: "Ključna riječ",
"Friendly Name": "Lijep naziv", "Friendly Name": "Prilagođen naziv",
URL: "URL", URL: "URL",
Hostname: "Domaćin", Hostname: "Domaćin",
Port: "Port", Port: "Port",
"Heartbeat Interval": "Interval provjere", "Heartbeat Interval": "Interval provjere",
Retries: "Ponovnih pokušaja", Retries: "Broj ponovnih pokušaja",
"Heartbeat Retry Interval": "Interval ponovnih pokušaja", "Heartbeat Retry Interval": "Interval ponovnih pokušaja",
Advanced: "Napredne postavke", Advanced: "Napredne postavke",
"Upside Down Mode": "Obrnuti način", "Upside Down Mode": "Obrnuti način",
@ -86,14 +86,14 @@ export default {
Light: "Svijetli način", Light: "Svijetli način",
Dark: "Tamni način", Dark: "Tamni način",
Auto: "Automatski", Auto: "Automatski",
"Theme - Heartbeat Bar": "Tema - Statusna traka", "Theme - Heartbeat Bar": "Tema za traku dostupnosti",
Normal: "Normalno", Normal: "Normalno",
Bottom: "Ispod", Bottom: "Ispod",
None: "Isključeno", None: "Isključeno",
Timezone: "Vremenska zona", Timezone: "Vremenska zona",
"Search Engine Visibility": "Vidljivost pretraživačima", "Search Engine Visibility": "Vidljivost tražilicama",
"Allow indexing": "Dopusti indeksiranje", "Allow indexing": "Dopusti indeksiranje",
"Discourage search engines from indexing site": "Sprječavanje indeksiranja stranice", "Discourage search engines from indexing site": "Sprječavanje indeksiranja",
"Change Password": "Promjena lozinke", "Change Password": "Promjena lozinke",
"Current Password": "Trenutna lozinka", "Current Password": "Trenutna lozinka",
"New Password": "Nova lozinka", "New Password": "Nova lozinka",
@ -103,7 +103,7 @@ export default {
"Enable Auth": "Omogući autentikaciju", "Enable Auth": "Omogući autentikaciju",
Logout: "Odjava", Logout: "Odjava",
Leave: "Poništi", Leave: "Poništi",
"I understand, please disable": "Razumijem, onemogući", "I understand, please disable": "Razumijem, svejedno onemogući",
Confirm: "Potvrda", Confirm: "Potvrda",
Yes: "Da", Yes: "Da",
No: "Ne", No: "Ne",
@ -112,10 +112,10 @@ export default {
"Remember me": "Zapamti me", "Remember me": "Zapamti me",
Login: "Prijava", Login: "Prijava",
"No Monitors, please": "Nema monitora, ", "No Monitors, please": "Nema monitora, ",
"add one": "dodaj jednog", "add one": "dodaj jedan",
"Notification Type": "Tip obavijesti", "Notification Type": "Tip obavijesti",
Email: "E-pošta", Email: "E-pošta",
Test: "Test", Test: "Testiraj",
"Certificate Info": "Informacije o certifikatu", "Certificate Info": "Informacije o certifikatu",
"Resolver Server": "DNS poslužitelj", "Resolver Server": "DNS poslužitelj",
"Resource Record Type": "Vrsta DNS zapisa", "Resource Record Type": "Vrsta DNS zapisa",
@ -130,14 +130,14 @@ export default {
notAvailableShort: "N/A", notAvailableShort: "N/A",
"Default enabled": "Omogući za nove monitore", "Default enabled": "Omogući za nove monitore",
"Apply on all existing monitors": "Primijeni na postojeće monitore", "Apply on all existing monitors": "Primijeni na postojeće monitore",
Create: "Create", Create: "Kreiraj",
"Clear Data": "Clear Data", "Clear Data": "Obriši podatke",
Events: "Events", Events: "Događaji",
Heartbeats: "Provjere", Heartbeats: "Provjere",
"Auto Get": "Automatski dohvat", "Auto Get": "Automatski dohvat",
backupDescription: "Moguće je napraviti sigurnosnu kopiju svih monitora i obavijesti koja će biti spremljena kao JSON datoteka.", backupDescription: "Moguće je napraviti sigurnosnu kopiju svih monitora i obavijesti koja će biti spremljena kao JSON datoteka.",
backupDescription2: "Napomena: povijest i podaci o događajima nisu uključeni u sigurnosnu kopiju.", backupDescription2: "Napomena: povijest i podaci o događajima nisu uključeni u sigurnosnu kopiju.",
backupDescription3: "Osjetljivi podaci poput tokena za obavijesti jesu uključeni u sigurnosnu kopiju. Zato je potrebno čuvati izvoz na sigurnom mjestu.", backupDescription3: "Osjetljivi podaci poput tokena za obavijesti uključeni su u sigurnosnu kopiju. Zato je potrebno čuvati izvoz na sigurnom mjestu.",
alertNoFile: "Datoteka za uvoz nije odabrana.", alertNoFile: "Datoteka za uvoz nije odabrana.",
alertWrongFileType: "Datoteka za uvoz nije u JSON formatu.", alertWrongFileType: "Datoteka za uvoz nije u JSON formatu.",
"Clear all statistics": "Obriši sve statistike", "Clear all statistics": "Obriši sve statistike",
@ -152,7 +152,7 @@ export default {
"2FA Settings": "Postavke 2FA", "2FA Settings": "Postavke 2FA",
"Two Factor Authentication": "Dvofaktorska autentikacija", "Two Factor Authentication": "Dvofaktorska autentikacija",
Active: "Aktivna", Active: "Aktivna",
Inactive: "Neaktivna", Inactive: "Neaktivno",
Token: "Token", Token: "Token",
"Show URI": "Pokaži URI", "Show URI": "Pokaži URI",
Tags: "Oznake", Tags: "Oznake",
@ -172,7 +172,7 @@ export default {
"Search...": "Pretraga...", "Search...": "Pretraga...",
"Avg. Ping": "Prosječni odziv", "Avg. Ping": "Prosječni odziv",
"Avg. Response": "Prosječni odgovor", "Avg. Response": "Prosječni odgovor",
"Entry Page": "Entry Page", "Entry Page": "Početna stranica",
statusPageNothing: "Ovdje nema ničega, dodajte grupu ili monitor.", statusPageNothing: "Ovdje nema ničega, dodajte grupu ili monitor.",
"No Services": "Nema usluga", "No Services": "Nema usluga",
"All Systems Operational": "Svi sustavi su operativni", "All Systems Operational": "Svi sustavi su operativni",
@ -183,7 +183,7 @@ export default {
"Edit Status Page": "Uredi Statusnu stranicu", "Edit Status Page": "Uredi Statusnu stranicu",
"Go to Dashboard": "Na Kontrolnu ploču", "Go to Dashboard": "Na Kontrolnu ploču",
"Status Page": "Statusna stranica", "Status Page": "Statusna stranica",
defaultNotificationName: "Moja {notification} obavijest ({number})", defaultNotificationName: "Moja {number}. {notification} obavijest",
here: "ovdje", here: "ovdje",
Required: "Potrebno", Required: "Potrebno",
telegram: "Telegram", telegram: "Telegram",
@ -195,11 +195,11 @@ export default {
"YOUR BOT TOKEN HERE": "OVDJE IDE TOKEN BOTA", "YOUR BOT TOKEN HERE": "OVDJE IDE TOKEN BOTA",
chatIDNotFound: "ID razgovora nije pronađen; prvo morate poslati poruku botu", chatIDNotFound: "ID razgovora nije pronađen; prvo morate poslati poruku botu",
webhook: "Webhook", webhook: "Webhook",
"Post URL": "Post URL", "Post URL": "URL Post zahtjeva",
"Content Type": "Tip sadržaja (Content Type)", "Content Type": "Tip sadržaja (Content Type)",
webhookJsonDesc: "{0} je dobra opcija za moderne HTTP poslužitelje poput Express.js-a", webhookJsonDesc: "{0} je dobra opcija za moderne HTTP poslužitelje poput Express.js-a",
webhookFormDataDesc: "{multipart} je moguća alternativa za PHP, samo je potrebno parsirati JSON koristeći {decodeFunction}", webhookFormDataDesc: "{multipart} je moguća alternativa za PHP, samo je potrebno parsirati JSON koristeći {decodeFunction}",
smtp: "E-pošta (SMTP)", smtp: "E-mail (SMTP)",
secureOptionNone: "Bez sigurnosti / STARTTLS (25, 587)", secureOptionNone: "Bez sigurnosti / STARTTLS (25, 587)",
secureOptionTLS: "TLS (465)", secureOptionTLS: "TLS (465)",
"Ignore TLS Error": "Ignoriraj greške TLS-a", "Ignore TLS Error": "Ignoriraj greške TLS-a",
@ -215,7 +215,7 @@ export default {
"Prefix Custom Message": "Prefiks prilagođene poruke", "Prefix Custom Message": "Prefiks prilagođene poruke",
"Hello @everyone is...": "Pozdrav {'@'}everyone...", "Hello @everyone is...": "Pozdrav {'@'}everyone...",
teams: "Microsoft Teams", teams: "Microsoft Teams",
"Webhook URL": "URL Teams webhooka", "Webhook URL": "URL webhooka",
wayToGetTeamsURL: "Više informacija o Teams webhookovima možete pročitati {0}.", wayToGetTeamsURL: "Više informacija o Teams webhookovima možete pročitati {0}.",
signal: "Signal", signal: "Signal",
Number: "Broj", Number: "Broj",
@ -242,7 +242,7 @@ export default {
promosms: "PromoSMS", promosms: "PromoSMS",
clicksendsms: "ClickSend SMS", clicksendsms: "ClickSend SMS",
lunasea: "LunaSea", lunasea: "LunaSea",
apprise: "Apprise (Support 50+ Notification services)", apprise: "Apprise (Podržava preko 50 usluga za obavijesti)",
pushbullet: "Pushbullet", pushbullet: "Pushbullet",
line: "LINE", line: "LINE",
mattermost: "Mattermost", mattermost: "Mattermost",
@ -307,4 +307,5 @@ export default {
"Showing {from} to {to} of {count} records": "Prikaz zapisa {from}-{to} od sveukupno {count}", "Showing {from} to {to} of {count} records": "Prikaz zapisa {from}-{to} od sveukupno {count}",
steamApiKeyDescription: "Za praćenje Steam poslužitelja za igru, potrebno je imati Steam Web-API ključ. Možete registrirati vlastiti ključ ovdje: ", steamApiKeyDescription: "Za praćenje Steam poslužitelja za igru, potrebno je imati Steam Web-API ključ. Možete registrirati vlastiti ključ ovdje: ",
"Current User": "Trenutni korisnik", "Current User": "Trenutni korisnik",
recent: "Nedavno",
}; };

View file

@ -33,6 +33,7 @@ export default {
Appearance: "Aspetto", Appearance: "Aspetto",
Theme: "Tema", Theme: "Tema",
General: "Generali", General: "Generali",
"Primary Base URL": "URL base primario",
Version: "Versione", Version: "Versione",
"Check Update On GitHub": "Controlla aggiornamenti su GitHub", "Check Update On GitHub": "Controlla aggiornamenti su GitHub",
List: "Lista", List: "Lista",
@ -64,7 +65,7 @@ export default {
Ping: "Ping", Ping: "Ping",
"Monitor Type": "Tipo di Monitoraggio", "Monitor Type": "Tipo di Monitoraggio",
Keyword: "Parola chiave", Keyword: "Parola chiave",
"Friendly Name": "Nome Amichevole", "Friendly Name": "Nomignolo",
URL: "URL", URL: "URL",
Hostname: "Nome Host", Hostname: "Nome Host",
Port: "Porta", Port: "Porta",
@ -75,6 +76,9 @@ export default {
"Upside Down Mode": "Modalità capovolta", "Upside Down Mode": "Modalità capovolta",
"Max. Redirects": "Reindirizzamenti massimi", "Max. Redirects": "Reindirizzamenti massimi",
"Accepted Status Codes": "Codici di stato accettati", "Accepted Status Codes": "Codici di stato accettati",
"Push URL": "Push URL",
needPushEvery: "Notificare questo URL ogni {0} secondi.",
pushOptionalParams: "Parametri aggiuntivi: {0}",
Save: "Salva", Save: "Salva",
Notifications: "Notifiche", Notifications: "Notifiche",
"Not available, please setup.": "Non disponibili, da impostare.", "Not available, please setup.": "Non disponibili, da impostare.",
@ -166,8 +170,8 @@ export default {
Purple: "Viola", Purple: "Viola",
Pink: "Rosa", Pink: "Rosa",
"Search...": "Cerca...", "Search...": "Cerca...",
"Avg. Ping": "Ping medio", "Avg. Ping": "Tempo di risposta al ping medio",
"Avg. Response": "Risposta media", "Avg. Response": "Tempo di risposta medio",
"Entry Page": "Entry Page", "Entry Page": "Entry Page",
statusPageNothing: "Non c'è nulla qui, aggiungere un gruppo oppure un monitoraggio.", statusPageNothing: "Non c'è nulla qui, aggiungere un gruppo oppure un monitoraggio.",
"No Services": "Nessun Servizio", "No Services": "Nessun Servizio",
@ -178,23 +182,129 @@ export default {
"Add a monitor": "Aggiungi un monitoraggio", "Add a monitor": "Aggiungi un monitoraggio",
"Edit Status Page": "Modifica pagina di stato", "Edit Status Page": "Modifica pagina di stato",
"Go to Dashboard": "Vai al Cruscotto", "Go to Dashboard": "Vai al Cruscotto",
"Status Page": "Status Page", "Status Page": "Pagina di stato",
telegram: "Telegram", defaultNotificationName: "Allarme {notification} ({number})",
webhook: "Webhook", here: "qui",
smtp: "Email (SMTP)", "Required": "Richiesto",
discord: "Discord", "telegram": "Telegram",
teams: "Microsoft Teams", "Bot Token": "Token del Bot",
signal: "Signal", "You can get a token from": "Puoi ricevere un token da",
gotify: "Gotify", "Chat ID": "ID Chat",
slack: "Slack", supportTelegramChatID: "Supporta Chat dirette / di Gruppo / ID Canale",
wayToGetTelegramChatID: "Puoi ricereve l'ID chat mandando un messaggio al bot andando in questo url per visualizzare il chat_id:",
"YOUR BOT TOKEN HERE": "QUI IL TOKEN DEL BOT",
chatIDNotFound: "Non trovo l'ID chat. Prima bisogna mandare un messaggio al bot",
"webhook": "Webhook",
"Post URL": "Post URL",
"Content Type": "Content Type",
webhookJsonDesc: "{0} va bene per qualsiasi server http moderno ad esempio express.js",
webhookFormDataDesc: "{multipart} va bene per PHP, c'è solo bisogno di analizzare il json con {decodeFunction}",
"smtp": "E-mail (SMTP)",
secureOptionNone: "Nessuno / STARTTLS (25, 587)",
secureOptionTLS: "TLS (465)",
"Ignore TLS Error": "Ignora gli errori TLS",
"From Email": "Mittente",
emailCustomSubject: "Oggetto personalizzato",
"To Email": "Destinatario",
smtpCC: "CC",
smtpBCC: "CCn",
"discord": "Discord",
"Discord Webhook URL": "URL Webhook di Discord",
wayToGetDiscordURL: "È possibile recuperarlo da Impostazioni server -> Integrazioni -> Creare Webhook",
"Bot Display Name": "Nome del Bot",
"Prefix Custom Message": "Prefisso per il messaggio personalizzato",
"Hello @everyone is...": "Ciao a {'@'}everyone ...",
"teams": "Microsoft Teams",
"Webhook URL": "URL Webhook",
wayToGetTeamsURL: "È possibile imparare a creare un URL Webhook {0}.",
"signal": "Signal",
"Number": "Numero",
"Recipients": "Destinatari",
needSignalAPI: "È necessario avere un client Signal con le API REST.",
wayToCheckSignalURL: "Controllare questo url per capire come impostarne uno:",
signalImportant: "IMPORTANTE: Non è possibile mischiare gruppi e numeri all'interno dei destinatari!",
"gotify": "Gotify",
"Application Token": "Token Applicazione",
"Server URL": "URL Server",
"Priority": "Priorità",
"slack": "Slack",
"Icon Emoji": "Icona Emoji",
"Channel Name": "Nome Canale",
"Uptime Kuma URL": "Indirizzo Uptime Kuma",
aboutWebhooks: "Maggiori informazioni riguardo ai webhooks su: {0}",
aboutChannelName: "Inserire il nome del canale nel campo \"Nome Canale\" {0} se si vuole bypassare il canale webhook. Ad esempio: #altro-canale",
aboutKumaURL: "Se si lascia bianco il campo Indirizzo Uptime Kuma, la pagina GitHub sarà il valore predefinito.",
emojiCheatSheet: "Lista Emoji: {0}",
"rocket.chat": "Rocket.chat", "rocket.chat": "Rocket.chat",
pushover: "Pushover", pushover: "Pushover",
pushy: "Pushy", pushy: "Pushy",
octopush: "Octopush", octopush: "Octopush",
promosms: "PromoSMS", promosms: "PromoSMS",
clicksendsms: "ClickSend SMS",
lunasea: "LunaSea", lunasea: "LunaSea",
apprise: "Apprise (Support 50+ Notification services)", apprise: "Apprise (Supporta più di 50 servizi di notifica)",
pushbullet: "Pushbullet", pushbullet: "Pushbullet",
line: "Line Messenger", line: "Line Messenger",
mattermost: "Mattermost", mattermost: "Mattermost",
"User Key": "Chiave Utente",
"Device": "Dispositivo",
"Message Title": "Titolo Messaggio",
"Notification Sound": "Suono di Notifica",
"More info on:": "Maggiori informazioni su: {0}",
pushoverDesc1: "Priorità di Emergenza (2) ha 30 secondi di timeout tra un tentativo e l'altro e scadrà dopo un'ora.",
pushoverDesc2: "Se si vuole inviare la notifica a dispositivi differenti, riempire il campo Dispositivi.",
"SMS Type": "Tipo di SMS",
octopushTypePremium: "Premium (Veloce - raccomandato per allertare)",
octopushTypeLowCost: "A Basso Costo (Lento - talvolta bloccato dall'operatore)",
checkPrice: "Controlla {0} prezzi:",
apiCredentials: "Credenziali API",
octopushLegacyHint: "Si vuole utilizzare la vecchia versione (2011-2020) oppure la nuova versione di Octopush?",
"Check octopush prices": "Controlla i prezzi di Octopush {0}.",
octopushPhoneNumber: "Numero di telefono (formato internazionale (p.e.): +33612345678) ",
octopushSMSSender: "Nome del mittente: 3-11 caratteri alfanumerici e spazi (a-zA-Z0-9)",
"LunaSea Device ID": "ID dispositivo LunaSea",
"Apprise URL": "URL Apprise",
"Example:": "Esempio: {0}",
"Read more:": "Maggiori informazioni: {0}",
"Status:": "Stato: {0}",
"Read more": "Maggiori informazioni",
appriseInstalled: "Apprise è installato.",
appriseNotInstalled: "Apprise non è installato. {0}",
"Access Token": "Token di accesso",
"Channel access token": "Token di accesso al canale",
"Line Developers Console": "Console sviluppatori Line",
lineDevConsoleTo: "Console sviluppatori Line - {0}",
"Basic Settings": "Impostazioni Base",
"User ID": "ID Utente",
"Messaging API": "API di Messaggistica",
wayToGetLineChannelToken: "Prima accedi a {0}, crea un provider e un canale (API di Messaggistica), dopodiché puoi avere il token di accesso e l'id utente dal menù sopra.",
"Icon URL": "URL Icona",
aboutIconURL: "È possibile impostare un collegameno a una immagine in \"URL Icona\" per modificare l'immagine di profilo. Non verrà utilizzata se è impostata l'Icona Emoji.",
aboutMattermostChannelName: "È possibile modificare il canale predefinito che dove il webhook manda messaggi immettendo il nome del canale nel campo \"Nome Canale\". Questo va abilitato nelle impostazioni webhook di Mattermost webhook. P.E.: #altro-canale",
"matrix": "Matrix",
promosmsTypeEco: "SMS ECO - economico, ma lento e spesso sovraccarico. Limitato solamente a destinatari Polacchi.",
promosmsTypeFlash: "SMS FLASH - Il messaggio sarà automaticamente mostrato sul dispositivo dei destinatari. Limitato solo a destinatari Polacchi.",
promosmsTypeFull: "SMS FULL - Premium, È possibile utilizzare il proprio come come mittente (è necessario prima registrare il nome). Affidabile per gli allarmi.",
promosmsTypeSpeed: "SMS SPEED - Maggior priorità. Rapido, affidabile, ma costoso (costa il doppio di SMS FULL).",
promosmsPhoneNumber: "Numero di Telefono (per destinatari Polacchi si può omettere il codice area)",
promosmsSMSSender: "Mittente SMS : Nome preregistrato oppure uno dei seguenti: InfoSMS, SMS Info, MaxSMS, INFO, SMS",
"Feishu WebHookUrl": "URL WebHook di Feishu",
matrixHomeserverURL: "URL Server (con http(s):// e opzionalmente la porta)",
"Internal Room Id": "ID Stanza Interna",
matrixDesc1: "È possibile recuperare l'ID della stanza all'interno delle impostazioni avanzate della stanza nel client Matrix. Dovrebbe essere simile a !QMdRCpUIfLwsfjxye6:server.di.casa.",
matrixDesc2: "È altamente raccomandata la creazione di un nuovo utente e di non utilizare il proprio token di accesso Matrix poiché darà pieno controllo al proprio account e a tutte le stanze in cui si ha accesso. Piuttosto, si crei un nuovo utente per invitarlo nella stanza dove si vuole ricevere le notifiche. Si può accedere al token eseguendo {0}",
Method: "Metodo",
Body: "Corpo",
Headers: "Headers",
PushUrl: "URL di Push",
HeadersInvalidFormat: "L'header di richiesta non è un JSON valido: ",
BodyInvalidFormat: "Il corpo di richiesta non è un JSON valido: ",
"Monitor History": "Storico monitoraggio",
clearDataOlderThan: "Mantieni lo storico per {0} giorni.",
PasswordsDoNotMatch: "Le password non corrispondono.",
records: "records",
"One record": "One record",
steamApiKeyDescription: "Per monitorare un server di gioco Steam si necessita della chiave Steam Web-API. È possibile registrare la propria chiave API qui: ",
"Current User": "Utente corrente",
recent: "Recenti",
}; };

View file

@ -116,7 +116,7 @@ export default {
"Repeat Password": "Herhaal wachtwoord", "Repeat Password": "Herhaal wachtwoord",
Export: "Exporteren", Export: "Exporteren",
Import: "Importeren", Import: "Importeren",
respTime: "resp. tijd (ms)", respTime: "reactietijd (ms)",
notAvailableShort: "N.v.t.", notAvailableShort: "N.v.t.",
"Default enabled": "Default enabled", "Default enabled": "Default enabled",
"Apply on all existing monitors": "Pas toe op alle bestaande monitors", "Apply on all existing monitors": "Pas toe op alle bestaande monitors",
@ -138,48 +138,48 @@ export default {
"Two Factor Authentication": "Two Factor Authenticatie", "Two Factor Authentication": "Two Factor Authenticatie",
Active: "Actief", Active: "Actief",
Inactive: "Inactief", Inactive: "Inactief",
"Also apply to existing monitors": "Also apply to existing monitors", "Also apply to existing monitors": "Voeg ook toe aan bestaande monitors",
Token: "Token", Token: "Token",
"Show URI": "Toon URI", "Show URI": "Toon URI",
"Clear all statistics": "Wis alle statistieken", "Clear all statistics": "Wis alle statistieken",
retryCheckEverySecond: "Retry every {0} seconds.", retryCheckEverySecond: "Probeer elke {0} seconden.",
importHandleDescription: "Choose 'Skip existing' if you want to skip every monitor or notification with the same name. 'Overwrite' will delete every existing monitor and notification.", importHandleDescription: "Kies 'Sla bestaande over' als je elke monitor of melding met dezelfde naam wilt overslaan. Kies 'Overschrijf' als je elke monitor of notificatie wilt verwijderen.",
confirmImportMsg: "Are you sure to import the backup? Please make sure you've selected the right import option.", confirmImportMsg: "Weet je zeker dat je dit bestand wilt importeren?",
"Heartbeat Retry Interval": "Heartbeat Retry Interval", "Heartbeat Retry Interval": "Heartbeat Retry Interval",
"Import Backup": "Import Backup", "Import Backup": "Importeer Backup",
"Export Backup": "Export Backup", "Export Backup": "Exporteer Backup",
"Skip existing": "Skip existing", "Skip existing": "Sla bestaande over",
Overwrite: "Overwrite", Overwrite: "Overschrijf",
Options: "Options", Options: "Opties",
"Keep both": "Keep both", "Keep both": "Bewaar beide",
Tags: "Tags", Tags: "Labels",
"Add New below or Select...": "Add New below or Select...", "Add New below or Select...": "Voeg nieuwe toe of selecteer...",
"Tag with this name already exist.": "Tag with this name already exist.", "Tag with this name already exist.": "Label met deze naam bestaat al",
"Tag with this value already exist.": "Tag with this value already exist.", "Tag with this value already exist.": "Label met deze waarde bestaat al",
color: "color", color: "Kleur",
"value (optional)": "value (optional)", "value (optional)": "waarde (optioneel)",
Gray: "Gray", Gray: "Grijs",
Red: "Red", Red: "Rood",
Orange: "Orange", Orange: "Oranje",
Green: "Green", Green: "Groen",
Blue: "Blue", Blue: "Blauw",
Indigo: "Indigo", Indigo: "Indigo",
Purple: "Purple", Purple: "Paars",
Pink: "Pink", Pink: "Roze",
"Search...": "Search...", "Search...": "Zoeken...",
"Avg. Ping": "Avg. Ping", "Avg. Ping": "Gemiddelde Ping",
"Avg. Response": "Avg. Response", "Avg. Response": "Gemiddelde Response",
"Entry Page": "Entry Page", "Entry Page": "Entry Page",
statusPageNothing: "Nothing here, please add a group or a monitor.", statusPageNothing: "Niets hier, voeg een groep of monitor toe.",
"No Services": "No Services", "No Services": "No Services",
"All Systems Operational": "All Systems Operational", "All Systems Operational": "Alle systemen operationeel",
"Partially Degraded Service": "Partially Degraded Service", "Partially Degraded Service": "Gedeeltelijk verminderde prestaties",
"Degraded Service": "Degraded Service", "Degraded Service": "Verminderde prestaties",
"Add Group": "Add Group", "Add Group": "Voeg groep toe",
"Add a monitor": "Add a monitor", "Add a monitor": "Voeg monitor toe",
"Edit Status Page": "Edit Status Page", "Edit Status Page": "Wijzig status pagina",
"Go to Dashboard": "Go to Dashboard", "Go to Dashboard": "Ga naar Dashboard",
"Status Page": "Status Page", "Status Page": "Status Pagina",
telegram: "Telegram", telegram: "Telegram",
webhook: "Webhook", webhook: "Webhook",
smtp: "Email (SMTP)", smtp: "Email (SMTP)",

View file

@ -28,7 +28,7 @@ export default {
confirmDisableTwoFAMsg: "Jesteś pewien, że chcesz wyłączyć 2FA?", confirmDisableTwoFAMsg: "Jesteś pewien, że chcesz wyłączyć 2FA?",
Settings: "Ustawienia", Settings: "Ustawienia",
Dashboard: "Panel", Dashboard: "Panel",
"New Update": "Nowa Aktualizacja", "New Update": "Nowa aktualizacja",
Language: "Język", Language: "Język",
Appearance: "Wygląd", Appearance: "Wygląd",
Theme: "Motyw", Theme: "Motyw",
@ -37,7 +37,7 @@ export default {
"Check Update On GitHub": "Sprawdź aktualizację na GitHub", "Check Update On GitHub": "Sprawdź aktualizację na GitHub",
List: "Lista", List: "Lista",
Add: "Dodaj", Add: "Dodaj",
"Add New Monitor": "Dodaj Monitor", "Add New Monitor": "Dodaj monitor",
"Quick Stats": "Szybki podgląd statystyk", "Quick Stats": "Szybki podgląd statystyk",
Up: "Online", Up: "Online",
Down: "Offline", Down: "Offline",
@ -53,8 +53,8 @@ export default {
Edit: "Edytuj", Edit: "Edytuj",
Delete: "Usuń", Delete: "Usuń",
Current: "Aktualny", Current: "Aktualny",
Uptime: "Czas Pracy", Uptime: "Czas pracy",
"Cert Exp.": "Certyfikat Wygasa", "Cert Exp.": "Certyfikat wygasa",
days: "dni", days: "dni",
day: "dzień", day: "dzień",
"-day": " dni", "-day": " dni",
@ -62,9 +62,9 @@ export default {
"-hour": " godzin", "-hour": " godzin",
Response: "Odpowiedź", Response: "Odpowiedź",
Ping: "Ping", Ping: "Ping",
"Monitor Type": "Rodzaj Monitora", "Monitor Type": "Rodzaj monitora",
Keyword: "Słowo kluczowe", Keyword: "Słowo kluczowe",
"Friendly Name": "Przyjazna Nazwa", "Friendly Name": "Przyjazna nazwa",
URL: "URL", URL: "URL",
Hostname: "Hostname", Hostname: "Hostname",
Port: "Port", Port: "Port",
@ -73,12 +73,12 @@ export default {
"Heartbeat Retry Interval": "Częstotliwość ponawiania bicia serca", "Heartbeat Retry Interval": "Częstotliwość ponawiania bicia serca",
Advanced: "Zaawansowane", Advanced: "Zaawansowane",
"Upside Down Mode": "Tryb odwrócony", "Upside Down Mode": "Tryb odwrócony",
"Max. Redirects": "Maks. Przekierowań", "Max. Redirects": "Maks. przekierowań",
"Accepted Status Codes": "Akceptowane kody statusu", "Accepted Status Codes": "Akceptowane kody statusu",
Save: "Zapisz", Save: "Zapisz",
Notifications: "Powiadomienia", Notifications: "Powiadomienia",
"Not available, please setup.": "Niedostępne, proszę skonfigurować.", "Not available, please setup.": "Niedostępne, proszę skonfigurować.",
"Setup Notification": "Skonfiguruj Powiadomienie", "Setup Notification": "Skonfiguruj powiadomienie",
Light: "Jasny", Light: "Jasny",
Dark: "Ciemny", Dark: "Ciemny",
Auto: "Automatyczny", Auto: "Automatyczny",
@ -122,7 +122,7 @@ export default {
"Export Backup": "Eksportuj kopię zapasową", "Export Backup": "Eksportuj kopię zapasową",
Export: "Eksportuj", Export: "Eksportuj",
Import: "Importuj", Import: "Importuj",
respTime: "Czas Odp. (ms)", respTime: "Czas odp. (ms)",
notAvailableShort: "N/A", notAvailableShort: "N/A",
"Default enabled": "Włącz domyślnie", "Default enabled": "Włącz domyślnie",
"Apply on all existing monitors": "Zastosuj do istniejących monitorów", "Apply on all existing monitors": "Zastosuj do istniejących monitorów",
@ -183,10 +183,10 @@ export default {
here: "tutaj", here: "tutaj",
Required: "Wymagane", Required: "Wymagane",
telegram: "Telegram", telegram: "Telegram",
"Bot Token": "Token Bota", "Bot Token": "Token bota",
wayToGetTelegramToken: "Token można uzyskać z {0}.", wayToGetTelegramToken: "Token można uzyskać z {0}.",
"Chat ID": "Identyfikator Czatu", "Chat ID": "Identyfikator czatu",
supportTelegramChatID: "Czat wsprarcia technicznego / Bezpośrednia Rozmowa / Czat Grupowy", supportTelegramChatID: "Czat wsparcia technicznego / Bezpośrednia rozmowa / Czat grupowy",
wayToGetTelegramChatID: "Możesz uzyskać swój identyfikator czatu, wysyłając wiadomość do bota i przechodząc pod ten adres URL, aby wyświetlić identyfikator czatu:", wayToGetTelegramChatID: "Możesz uzyskać swój identyfikator czatu, wysyłając wiadomość do bota i przechodząc pod ten adres URL, aby wyświetlić identyfikator czatu:",
"YOUR BOT TOKEN HERE": "TWOJ TOKEN BOTA", "YOUR BOT TOKEN HERE": "TWOJ TOKEN BOTA",
chatIDNotFound: "Identyfikator czatu nie znaleziony, najpierw napisz do bota", chatIDNotFound: "Identyfikator czatu nie znaleziony, najpierw napisz do bota",
@ -198,20 +198,20 @@ export default {
smtp: "Email (SMTP)", smtp: "Email (SMTP)",
secureOptionNone: "Brak / STARTTLS (25, 587)", secureOptionNone: "Brak / STARTTLS (25, 587)",
secureOptionTLS: "TLS (465)", secureOptionTLS: "TLS (465)",
"Ignore TLS Error": "Zignrouj Błędy TLS", "Ignore TLS Error": "Zignoruj błędy TLS",
"From Email": "Nadawca (OD)", "From Email": "Nadawca (OD)",
"To Email": "Odbiorca (DO)", "To Email": "Odbiorca (DO)",
smtpCC: "DW", smtpCC: "DW",
smtpBCC: "UDW", smtpBCC: "UDW",
discord: "Discord", discord: "Discord",
"Discord Webhook URL": "URL Webhook Discorda", "Discord Webhook URL": "URL webhook Discorda",
wayToGetDiscordURL: "Możesz go uzyskać przechodząc do Ustawienia Serwera -> Integracje -> Tworzenie Webhooka", wayToGetDiscordURL: "Możesz go uzyskać przechodząc do Ustawienia serwera -> Integracje -> Tworzenie webhooka",
"Bot Display Name": "Wyświetlana Nazwa Bota", "Bot Display Name": "Wyświetlana nazwa bota",
"Prefix Custom Message": "Własny Początek Wiadomości", "Prefix Custom Message": "Własny początek wiadomości",
"Hello @everyone is...": "Hej {'@'}everyone ...", "Hello @everyone is...": "Hej {'@'}everyone ...",
teams: "Microsoft Teams", teams: "Microsoft Teams",
"Webhook URL": "URL Webhooka", "Webhook URL": "URL webhooka",
wayToGetTeamsURL: "You can learn how to create a webhook url {0}.", wayToGetTeamsURL: "Możesz dowiedzieć się, jak utworzyć adres url webhooka {0}.",
signal: "Signal", signal: "Signal",
Number: "Numer", Number: "Numer",
Recipients: "Odbiorcy", Recipients: "Odbiorcy",
@ -219,66 +219,66 @@ export default {
wayToCheckSignalURL: "W celu dowiedzenia się, jak go skonfigurować, odwiedź poniższy link:", wayToCheckSignalURL: "W celu dowiedzenia się, jak go skonfigurować, odwiedź poniższy link:",
signalImportant: "UWAGA: Nie można mieszać nazw grup i numerów odbiorców!", signalImportant: "UWAGA: Nie można mieszać nazw grup i numerów odbiorców!",
gotify: "Gotify", gotify: "Gotify",
"Application Token": "Token Aplikacji", "Application Token": "Token aplikacji",
"Server URL": "Server URL", "Server URL": "Server URL",
Priority: "Priorytet", Priority: "Priorytet",
slack: "Slack", slack: "Slack",
"Icon Emoji": "Ikona Emoji", "Icon Emoji": "Ikona emoji",
"Channel Name": "Nazwa Kanału", "Channel Name": "Nazwa kanału",
"Uptime Kuma URL": "Adres Uptime Kuma", "Uptime Kuma URL": "Adres Uptime Kuma",
aboutWebhooks: "Więcej informacji na temat webhooków: {0}", aboutWebhooks: "Więcej informacji na temat webhooków: {0}",
aboutChannelName: "Podaj nazwę kanału {0} w polu Nazwa Kanału, jeśli chcesz pominąć kanał webhooka. Np.: #inny-kanal", aboutChannelName: "Podaj nazwę kanału {0} w polu Nazwa kanału, jeśli chcesz pominąć kanał webhooka. Np.: #inny-kanal",
aboutKumaURL: "Jeśli pozostawisz pole Adres Uptime Kuma puste, domyślnie będzie to strona projektu na Github.", aboutKumaURL: "Jeśli pozostawisz pole Adres Uptime Kuma puste, domyślnie będzie to strona projektu na GitHub.",
emojiCheatSheet: "Ściąga Emoji: {0}", emojiCheatSheet: "Ściąga emoji: {0}",
"rocket.chat": "Rocket.chat", "rocket.chat": "Rocket.chat",
pushover: "Pushover", pushover: "Pushover",
pushy: "Pushy", pushy: "Pushy",
octopush: "Octopush", octopush: "Octopush",
promosms: "PromoSMS", promosms: "PromoSMS",
lunasea: "LunaSea", lunasea: "LunaSea",
apprise: "Apprise (Obsługuje 50+ usług powiadomień)", apprise: "Apprise (obsługuje 50+ usług powiadomień)",
pushbullet: "Pushbullet", pushbullet: "Pushbullet",
line: "Line Messenger", line: "Line Messenger",
mattermost: "Mattermost", mattermost: "Mattermost",
"User Key": "Klucz Użytkownika", "User Key": "Klucz użytkownika",
Device: "Urządzenie", Device: "Urządzenie",
"Message Title": "Tytuł Wiadomości", "Message Title": "Tytuł wiadomości",
"Notification Sound": "Dźwięk Powiadomienia", "Notification Sound": "Dźwięk powiadomienia",
"More info on:": "Więcej informacji na: {0}", "More info on:": "Więcej informacji na: {0}",
pushoverDesc1: "Priorytet awaryjny (2) ma domyślny 30-sekundowy limit czasu między kolejnymi próbami i wygaśnie po 1 godzinie.", pushoverDesc1: "Priorytet awaryjny (2) ma domyślny 30-sekundowy limit czasu między kolejnymi próbami i wygaśnie po 1 godzinie.",
pushoverDesc2: "Jeśli chcesz wysyłać powiadomienia na różne urządzenia, wypełnij pole Urządzenie.", pushoverDesc2: "Jeśli chcesz wysyłać powiadomienia na różne urządzenia, wypełnij pole Urządzenie.",
"SMS Type": "Rodzaj SMS", "SMS Type": "Rodzaj SMS",
octopushTypePremium: "Premium (Szybki - rekomendowany dla powiadomień)", octopushTypePremium: "Premium (szybki - rekomendowany dla powiadomień)",
octopushTypeLowCost: "Low Cost (Wolny, czasami blokowany przez operatorów)", octopushTypeLowCost: "Low Cost (wolny, czasami blokowany przez operatorów)",
"Check octopush prices": "Sprawdź ceny Octopush {0}.", "Check octopush prices": "Sprawdź ceny Octopush {0}.",
octopushPhoneNumber: "Numer Telefonu (Format międzynarodowy np.: +33612345678)", octopushPhoneNumber: "Numer telefonu (format międzynarodowy np.: +33612345678)",
octopushSMSSender: "Nadawca SMS : 3-11 znaków alfanumerycznych i spacji (a-zA-Z0-9)", octopushSMSSender: "Nadawca SMS: 3-11 znaków alfanumerycznych i spacji (a-zA-Z0-9)",
"LunaSea Device ID": "Idetyfikator Urządzenia LunaSea", "LunaSea Device ID": "Identyfikator urządzenia LunaSea",
"Apprise URL": "URL Apprise", "Apprise URL": "URL Apprise",
"Example:": "Przykład: {0}", "Example:": "Przykład: {0}",
"Read more:": "Czytaj Dalej: {0}", "Read more:": "Czytaj dalej: {0}",
"Status:": "Status: {0}", "Status:": "Status: {0}",
"Read more": "Czytaj dalej", "Read more": "Czytaj dalej",
appriseInstalled: "Apprise jest zostało zainstalowane.", appriseInstalled: "Apprise jest zostało zainstalowane.",
appriseNotInstalled: "Apprise nie zostało zainstalowane. {0}", appriseNotInstalled: "Apprise nie zostało zainstalowane. {0}",
"Access Token": "Token Dostępu", "Access Token": "Token dostępu",
"Channel access token": "Token Dostępu Kanału", "Channel access token": "Token dostępu kanału",
"Line Developers Console": "Konsola Dewelopersja Line", "Line Developers Console": "Konsola deweloperska Line",
lineDevConsoleTo: "Konsola Dewelopersja Line - {0}", lineDevConsoleTo: "Konsola deweloperska Line - {0}",
"Basic Settings": "Ustawienia Ogólne", "Basic Settings": "Ustawienia ogólne",
"User ID": "Idetyfikator Użytkownika", "User ID": "Identyfikator użytkownika",
"Messaging API": "API Wiadomości", "Messaging API": "API wiadomości",
wayToGetLineChannelToken: "Najpierw uzyskaj dostęp do {0}, utwórz dostawcę i kanał (Messaging API), a następnie możesz uzyskać token dostępu do kanału i identyfikator użytkownika z wyżej wymienionych pozycji menu.", wayToGetLineChannelToken: "Najpierw uzyskaj dostęp do {0}, utwórz dostawcę i kanał (Messaging API), a następnie możesz uzyskać token dostępu do kanału i identyfikator użytkownika z wyżej wymienionych pozycji menu.",
"Icon URL": "Adres Ikony", "Icon URL": "Adres Ikony",
aboutIconURL: "Możesz podać link do zdjęcia w \"Adres URL ikony\", aby zastąpić domyślne zdjęcie profilowe. Nie będzie używany, jeśli ustawiona jest ikona Emoji.", aboutIconURL: "Możesz podać link do zdjęcia w \"Adres URL ikony\", aby zastąpić domyślne zdjęcie profilowe. Nie będzie używany, jeśli ustawiona jest ikona emoji.",
aboutMattermostChannelName: "Możesz zastąpić domyślny kanał, na którym publikowane są posty webhooka, wpisując nazwę kanału w polu \"Nazwa Kanału\". Należy to włączyć w ustawieniach webhooka Mattermost. Np.: #inny-kanał", aboutMattermostChannelName: "Możesz zastąpić domyślny kanał, na którym publikowane są posty webhooka, wpisując nazwę kanału w polu \"Nazwa kanału\". Należy to włączyć w ustawieniach webhooka Mattermost. Np.: #inny-kanał",
matrix: "Matrix", matrix: "Matrix",
promosmsTypeEco: "SMS ECO - Tanie, lecz wolne. Dostępne tylko w Polsce", promosmsTypeEco: "SMS ECO - tanie, lecz wolne. Dostępne tylko w Polsce",
promosmsTypeFlash: "SMS FLASH - Wiadomość automatycznie wyświetli się na urządzeniu. Dostępne tylko w Polsce.", promosmsTypeFlash: "SMS FLASH - wiadomość automatycznie wyświetli się na urządzeniu. Dostępne tylko w Polsce.",
promosmsTypeFull: "SMS FULL - Szybkie i dostępne międzynarodowo. Wersja premium usługi, która pozwala min. ustawić własną nazwę nadawcy.", promosmsTypeFull: "SMS FULL - szybkie i dostępne międzynarodowo. Wersja premium usługi, która pozwala min. ustawić własną nazwę nadawcy.",
promosmsTypeSpeed: "SMS SPEED - Wysyłka priorytetowa, posiada wszystkie zalety SMS FULL", promosmsTypeSpeed: "SMS SPEED - wysyłka priorytetowa, posiada wszystkie zalety SMS FULL",
promosmsPhoneNumber: "Numer Odbiorcy", promosmsPhoneNumber: "Numer odbiorcy",
promosmsSMSSender: "Nadawca SMS (Wcześniej zatwierdzone nazwy z panelu PromoSMS)", promosmsSMSSender: "Nadawca SMS (wcześniej zatwierdzone nazwy z panelu PromoSMS)",
"Primary Base URL": "Główny URL", "Primary Base URL": "Główny URL",
"Push URL": "Push URL", "Push URL": "Push URL",
needPushEvery: "Powinieneś wywoływać ten URL co {0} sekund", needPushEvery: "Powinieneś wywoływać ten URL co {0} sekund",
@ -305,4 +305,6 @@ export default {
steamApiKeyDescription: "Do monitorowania serwera gier Steam potrzebny jest klucz Steam Web-API. Możesz zarejestrować swój klucz API tutaj: ", steamApiKeyDescription: "Do monitorowania serwera gier Steam potrzebny jest klucz Steam Web-API. Możesz zarejestrować swój klucz API tutaj: ",
"Current User": "Aktualny użytkownik", "Current User": "Aktualny użytkownik",
recent: "Ostatnie", recent: "Ostatnie",
clicksendsms: "ClickSend SMS",
apiCredentials: "Poświadczenia API",
}; };

View file

@ -1,5 +1,6 @@
import { io } from "socket.io-client"; import { io } from "socket.io-client";
import { useToast } from "vue-toastification"; import { useToast } from "vue-toastification";
import jwt_decode from "jwt-decode";
const toast = useToast(); const toast = useToast();
let socket; let socket;
@ -217,6 +218,15 @@ export default {
return (this.remember) ? localStorage : sessionStorage; return (this.remember) ? localStorage : sessionStorage;
}, },
getJWTPayload() {
const jwtToken = this.$root.storage().token;
if (jwtToken && jwtToken !== "autoLogin") {
return jwt_decode(jwtToken);
}
return undefined;
},
getSocket() { getSocket() {
return socket; return socket;
}, },

View file

@ -515,9 +515,11 @@ export default {
}, },
loadUsername() { loadUsername() {
const jwtToken = this.$root.storage().token; const jwtPayload = this.$root.getJWTPayload();
const jwtPayload = jwt_decode(jwtToken);
if (jwtPayload) {
this.username = jwtPayload.username; this.username = jwtPayload.username;
}
}, },
loadSettings() { loadSettings() {
@ -568,6 +570,7 @@ export default {
this.settings.disableAuth = false; this.settings.disableAuth = false;
this.saveSettings(); this.saveSettings();
this.$root.storage().removeItem("token"); this.$root.storage().removeItem("token");
location.reload();
}, },
downloadBackup() { downloadBackup() {

View file

@ -77,6 +77,17 @@
<font-awesome-icon icon="save" /> <font-awesome-icon icon="save" />
{{ $t("Switch to Dark Theme") }} {{ $t("Switch to Dark Theme") }}
</button> </button>
<button class="btn btn-secondary me-2" @click="changeTagsVisibilty(!tagsVisible)">
<template v-if="tagsVisible">
<font-awesome-icon icon="eye-slash" />
{{ $t("Hide Tags") }}
</template>
<template v-else>
<font-awesome-icon icon="eye" />
{{ $t("Show Tags") }}
</template>
</button>
</div> </div>
</div> </div>
@ -292,6 +303,10 @@ export default {
return this.config.statusPageTheme; return this.config.statusPageTheme;
}, },
tagsVisible() {
return this.config.statusPageTags
},
logoClass() { logoClass() {
if (this.editMode) { if (this.editMode) {
return { return {
@ -472,6 +487,25 @@ export default {
changeTheme(name) { changeTheme(name) {
this.config.statusPageTheme = name; this.config.statusPageTheme = name;
}, },
changeTagsVisibilty(newState) {
this.config.statusPageTags = newState;
// On load, the status page will not include tags if it's not enabled for security reasons
// Which means if we enable tags, it won't show in the UI until saved
// So we have this to enhance UX and load in the tags from the authenticated source instantly
this.$root.publicGroupList = this.$root.publicGroupList.map((group) => {
return {
...group,
monitorList: group.monitorList.map((monitor) => {
// We only include the tags if visible so we can reuse the logic to hide the tags on disable
return {
...monitor,
tags: newState ? this.$root.monitorList[monitor.id].tags : []
}
})
}
});
},
/** /**
* Crop Success * Crop Success

View file

@ -1,4 +1,125 @@
const { genSecret, sleep } = require("../src/util"); const { genSecret, sleep } = require("../src/util");
const utilServerRewire = require("../server/util-server");
describe("Test parseCertificateInfo", () => {
it("should handle undefined", async () => {
const parseCertificateInfo = utilServerRewire.__get__("parseCertificateInfo");
const info = parseCertificateInfo(undefined);
expect(info).toEqual(undefined);
}, 5000);
it("should handle normal cert chain", async () => {
const parseCertificateInfo = utilServerRewire.__get__("parseCertificateInfo");
const chain1 = {
fingerprint: "CF:2C:F3:6A:FE:6B:10:EC:44:77:C8:95:BB:96:2E:06:1F:0E:15:DA",
valid_from: "Oct 22 12:00:00 2013 GMT",
valid_to: "Oct 22 12:00:00 2028 GMT",
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
};
const chain2 = {
fingerprint: "A0:31:C4:67:82:E6:E6:C6:62:C2:C8:7C:76:DA:9A:A6:2C:CA:BD:8E",
valid_from: "Oct 22 12:00:00 2013 GMT",
valid_to: "Oct 22 12:00:00 2028 GMT",
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
};
const chain3 = {
fingerprint: "5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25",
valid_from: "Oct 22 12:00:00 2013 GMT",
valid_to: "Oct 22 12:00:00 2028 GMT",
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
};
chain1.issuerCertificate = chain2;
chain2.issuerCertificate = chain3;
chain3.issuerCertificate = chain3;
const info = parseCertificateInfo(chain1);
expect(chain1).toEqual(info);
}, 5000);
it("should handle cert chain with strange circle", async () => {
const parseCertificateInfo = utilServerRewire.__get__("parseCertificateInfo");
const chain1 = {
fingerprint: "CF:2C:F3:6A:FE:6B:10:EC:44:77:C8:95:BB:96:2E:06:1F:0E:15:DA",
valid_from: "Oct 22 12:00:00 2013 GMT",
valid_to: "Oct 22 12:00:00 2028 GMT",
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
};
const chain2 = {
fingerprint: "A0:31:C4:67:82:E6:E6:C6:62:C2:C8:7C:76:DA:9A:A6:2C:CA:BD:8E",
valid_from: "Oct 22 12:00:00 2013 GMT",
valid_to: "Oct 22 12:00:00 2028 GMT",
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
};
const chain3 = {
fingerprint: "5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25",
valid_from: "Oct 22 12:00:00 2013 GMT",
valid_to: "Oct 22 12:00:00 2028 GMT",
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
};
const chain4 = {
fingerprint: "haha",
valid_from: "Oct 22 12:00:00 2013 GMT",
valid_to: "Oct 22 12:00:00 2028 GMT",
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
};
chain1.issuerCertificate = chain2;
chain2.issuerCertificate = chain3;
chain3.issuerCertificate = chain4;
chain4.issuerCertificate = chain2;
const info = parseCertificateInfo(chain1);
expect(chain1).toEqual(info);
}, 5000);
it("should handle cert chain with last undefined (should be happen in real, but just in case)", async () => {
const parseCertificateInfo = utilServerRewire.__get__("parseCertificateInfo");
const chain1 = {
fingerprint: "CF:2C:F3:6A:FE:6B:10:EC:44:77:C8:95:BB:96:2E:06:1F:0E:15:DA",
valid_from: "Oct 22 12:00:00 2013 GMT",
valid_to: "Oct 22 12:00:00 2028 GMT",
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
};
const chain2 = {
fingerprint: "A0:31:C4:67:82:E6:E6:C6:62:C2:C8:7C:76:DA:9A:A6:2C:CA:BD:8E",
valid_from: "Oct 22 12:00:00 2013 GMT",
valid_to: "Oct 22 12:00:00 2028 GMT",
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
};
const chain3 = {
fingerprint: "5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25",
valid_from: "Oct 22 12:00:00 2013 GMT",
valid_to: "Oct 22 12:00:00 2028 GMT",
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
};
const chain4 = {
fingerprint: "haha",
valid_from: "Oct 22 12:00:00 2013 GMT",
valid_to: "Oct 22 12:00:00 2028 GMT",
subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net",
};
chain1.issuerCertificate = chain2;
chain2.issuerCertificate = chain3;
chain3.issuerCertificate = chain4;
chain4.issuerCertificate = undefined;
const info = parseCertificateInfo(chain1);
expect(chain1).toEqual(info);
}, 5000);
});
describe("Test genSecret", () => { describe("Test genSecret", () => {
@ -42,3 +163,4 @@ describe("Test reset-password", () => {
await require("../extra/reset-password").main(); await require("../extra/reset-password").main();
}, 120000); }, 120000);
}); });