diff --git a/.github/workflows/stale-bot b/.github/workflows/stale-bot new file mode 100644 index 0000000..5dc5013 --- /dev/null +++ b/.github/workflows/stale-bot @@ -0,0 +1,22 @@ +name: 'Automatically close stale issues and PRs' +on: + schedule: + - cron: '0 0 * * *' +#Run once a day at midnight + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v4 + with: + stale-issue-message: 'We are clearing up our old issues and your ticket has been open for 6 months with no activity. Remove stale label or comment or this will be closed in 7 days.' + stale-pr-message: 'We are clearing up our old Pull Requests and yours has been open for 6 months with no activity. Remove stale label or comment or this will be closed in 7 days.' + close-issue-message: 'This issue was closed because it has been stalled for 7 days with no activity.' + close-pr-message: 'This PR was closed because it has been stalled for 7 days with no activity.' + days-before-stale: 180 + days-before-close: 7 + exempt-issue-labels: 'News,Medium,High,discussion,bug,doc,' + exempt-pr-labels: 'awaiting-approval,work-in-progress,enhancement,' + exempt-issue-assignees: 'louislam' + exempt-pr-assignees: 'louislam' diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index b618a2c..746334e 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -60,7 +60,7 @@ representative at an online or offline event. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at -louis@uptimekuma.louislam.net. +uptime@kuma.pet. All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the diff --git a/README.md b/README.md index 1dc492b..6caa1a8 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Try it! https://demo.uptime.kuma.pet -It is a 10 minutes live demo, all data will be deleted after that. The server is located at Tokyo, if you live far away from here, it may affact your experience. I suggest that you should install to try it. +It is a temporary live demo, all data will be deleted after 10 minutes. The server is located at Tokyo, so if you live far from there it may affect your experience. I suggest that you should install and try it out for the best demo experience. VPS is sponsored by Uptime Kuma sponsors on [Open Collective](https://opencollective.com/uptime-kuma)! Thank you so much! @@ -25,7 +25,7 @@ VPS is sponsored by Uptime Kuma sponsors on [Open Collective](https://opencollec * Monitoring uptime for HTTP(s) / TCP / Ping / DNS Record / Push. * Fancy, Reactive, Fast UI/UX. * Notifications via Telegram, Discord, Gotify, Slack, Pushover, Email (SMTP), and [70+ notification services, click here for the full list](https://github.com/louislam/uptime-kuma/tree/master/src/components/notifications). -* 20 seconds interval. +* 20 second intervals. * [Multi Languages](https://github.com/louislam/uptime-kuma/tree/master/src/languages) * Simple Status Page * Ping Chart @@ -40,7 +40,7 @@ docker volume create uptime-kuma docker run -d --restart=always -p 3001:3001 -v uptime-kuma:/app/data --name uptime-kuma louislam/uptime-kuma:1 ``` -Browse to http://localhost:3001 after started. +Browse to http://localhost:3001 after starting. ### 💪🏻 Without Docker @@ -58,11 +58,11 @@ npm run setup node server/server.js # (Recommended) Option 2. Run in background using PM2 -# Install PM2 if you don't have: npm install pm2 -g +# Install PM2 if you don't have it: npm install pm2 -g pm2 start server/server.js --name uptime-kuma ``` -Browse to http://localhost:3001 after started. +Browse to http://localhost:3001 after starting. ### Advanced Installation @@ -124,7 +124,7 @@ You can discuss or ask for help in [Issues](https://github.com/louislam/uptime-k ### Subreddit My Reddit account: louislamlam -You can mention me if you ask question on Reddit. +You can mention me if you ask a question on Reddit. https://www.reddit.com/r/UptimeKuma/ ## Contribute diff --git a/docker/dockerfile b/docker/dockerfile index 9765574..e2a3725 100644 --- a/docker/dockerfile +++ b/docker/dockerfile @@ -31,14 +31,15 @@ WORKDIR / RUN apt update && \ apt --yes install curl file +COPY --from=build /app /app + +ARG VERSION=1.9.1 ARG GITHUB_TOKEN ARG TARGETARCH ARG PLATFORM=debian -ARG VERSION ARG FILE=$PLATFORM-$TARGETARCH-$VERSION.tar.gz ARG DIST=dist.tar.gz -COPY --from=build /app /app RUN chmod +x /app/extra/upload-github-release-asset.sh # Full Build diff --git a/kubernetes/README.md b/kubernetes/README.md deleted file mode 100644 index e85b0c4..0000000 --- a/kubernetes/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# Uptime-Kuma K8s Deployment - -⚠ Warning: K8s deployment is provided by contributors. I have no experience with K8s and I can't fix error in the future. I only test Docker and Node.js. Use at your own risk. - -## How does it work? - -Kustomize is a tool which builds a complete deployment file for all config elements. -You can edit the files in the ```uptime-kuma``` folder except the ```kustomization.yml``` until you know what you're doing. -If you want to choose another namespace you can edit the ```kustomization.yml``` in the ```kubernetes```-Folder and change the ```namespace: uptime-kuma``` to something you like. - -It creates a certificate with the specified Issuer and creates the Ingress for the Uptime-Kuma ClusterIP-Service. - -## What do I have to edit? - -You have to edit the ```ingressroute.yml``` to your needs. -This ingressroute.yml is for the [nginx-ingress-controller](https://kubernetes.github.io/ingress-nginx/) in combination with the [cert-manager](https://cert-manager.io/). - -- Host -- Secrets and secret names -- (Cluster)Issuer (optional) -- The Version in the Deployment-File - - Update: - - Change to newer version and run the above commands, it will update the pods one after another - -## How To use - -- Install [kustomize](https://kubectl.docs.kubernetes.io/installation/kustomize/) -- Edit files mentioned above to your needs -- Run ```kustomize build > apply.yml``` -- Run ```kubectl apply -f apply.yml``` - -Now you should see some k8s magic and Uptime-Kuma should be available at the specified address. diff --git a/kubernetes/kustomization.yml b/kubernetes/kustomization.yml deleted file mode 100644 index 0daf10f..0000000 --- a/kubernetes/kustomization.yml +++ /dev/null @@ -1,10 +0,0 @@ -namespace: uptime-kuma -namePrefix: uptime-kuma- - -commonLabels: - app: uptime-kuma - -bases: - - uptime-kuma - - diff --git a/kubernetes/uptime-kuma/deployment.yml b/kubernetes/uptime-kuma/deployment.yml deleted file mode 100644 index b97ece2..0000000 --- a/kubernetes/uptime-kuma/deployment.yml +++ /dev/null @@ -1,45 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - component: uptime-kuma - name: deployment -spec: - selector: - matchLabels: - component: uptime-kuma - replicas: 1 - strategy: - type: Recreate - - template: - metadata: - labels: - component: uptime-kuma - spec: - containers: - - name: app - image: louislam/uptime-kuma:1 - ports: - - containerPort: 3001 - volumeMounts: - - mountPath: /app/data - name: storage - livenessProbe: - exec: - command: - - node - - extra/healthcheck.js - initialDelaySeconds: 180 - periodSeconds: 60 - timeoutSeconds: 30 - readinessProbe: - httpGet: - path: / - port: 3001 - scheme: HTTP - - volumes: - - name: storage - persistentVolumeClaim: - claimName: pvc diff --git a/kubernetes/uptime-kuma/ingressroute.yml b/kubernetes/uptime-kuma/ingressroute.yml deleted file mode 100644 index 71f7027..0000000 --- a/kubernetes/uptime-kuma/ingressroute.yml +++ /dev/null @@ -1,39 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - annotations: - kubernetes.io/ingress.class: nginx - cert-manager.io/cluster-issuer: letsencrypt-prod - nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" - nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" - nginx.ingress.kubernetes.io/server-snippets: | - location / { - proxy_set_header Upgrade $http_upgrade; - proxy_http_version 1.1; - proxy_set_header X-Forwarded-Host $http_host; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For $remote_addr; - proxy_set_header Host $host; - proxy_set_header Connection "upgrade"; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Upgrade $http_upgrade; - proxy_cache_bypass $http_upgrade; - } - name: ingress -spec: - tls: - - hosts: - - example.com - secretName: example-com-tls - rules: - - host: example.com - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: service - port: - number: 3001 diff --git a/kubernetes/uptime-kuma/kustomization.yml b/kubernetes/uptime-kuma/kustomization.yml deleted file mode 100644 index 638a2ab..0000000 --- a/kubernetes/uptime-kuma/kustomization.yml +++ /dev/null @@ -1,5 +0,0 @@ -resources: - - deployment.yml - - service.yml - - ingressroute.yml - - pvc.yml \ No newline at end of file diff --git a/kubernetes/uptime-kuma/pvc.yml b/kubernetes/uptime-kuma/pvc.yml deleted file mode 100644 index eda3b8b..0000000 --- a/kubernetes/uptime-kuma/pvc.yml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: pvc -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 4Gi diff --git a/kubernetes/uptime-kuma/service.yml b/kubernetes/uptime-kuma/service.yml deleted file mode 100644 index 5fa812e..0000000 --- a/kubernetes/uptime-kuma/service.yml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: service -spec: - selector: - component: uptime-kuma - type: ClusterIP - ports: - - name: http - port: 3001 - targetPort: 3001 - protocol: TCP diff --git a/package.json b/package.json index 7353cf1..4c79982 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "uptime-kuma", - "version": "1.8.0", + "version": "1.9.1", "license": "MIT", "repository": { "type": "git", @@ -30,13 +30,13 @@ "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-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.8.0-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.8.0 -t louislam/uptime-kuma:debian -t louislam/uptime-kuma:1-debian -t louislam/uptime-kuma:1.8.0-debian --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.9.1-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.9.1 -t louislam/uptime-kuma:debian -t louislam/uptime-kuma:1-debian -t louislam/uptime-kuma:1.9.1-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-alpine": "docker buildx build -f 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", - "upload-artifacts": "docker buildx build --platform linux/amd64 -t louislam/uptime-kuma:upload-artifact --build-arg GITHUB_TOKEN --target upload-artifact . --progress plain", - "setup": "git checkout 1.8.0 && npm ci --production && npm run download-dist", + "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.9.1 && npm ci --production && npm run download-dist", "download-dist": "node extra/download-dist.js", "update-version": "node extra/update-version.js", "mark-as-nightly": "node extra/mark-as-nightly.js", diff --git a/server/database.js b/server/database.js index 297df65..aa36384 100644 --- a/server/database.js +++ b/server/database.js @@ -53,7 +53,7 @@ class Database { } /** - * The finally version should be 10 after merged tag feature + * The final version should be 10 after merged tag feature * @deprecated Use patchList for any new feature */ static latestVersion = 10; @@ -131,7 +131,7 @@ class Database { console.info("Latest database version: " + this.latestVersion); if (version === this.latestVersion) { - console.info("Database no need to patch"); + console.info("Database patch not needed"); } else if (version > this.latestVersion) { console.info("Warning: Database version is newer than expected"); } else { @@ -152,8 +152,8 @@ class Database { await Database.close(); console.error(ex); - console.error("Start Uptime-Kuma failed due to patch db failed"); - console.error("Please submit the bug report if you still encounter the problem after restart: https://github.com/louislam/uptime-kuma/issues"); + console.error("Start Uptime-Kuma failed due to issue patching the database"); + console.error("Please submit a bug report if you still encounter the problem after restart: https://github.com/louislam/uptime-kuma/issues"); this.restore(); process.exit(1); @@ -191,7 +191,7 @@ class Database { await Database.close(); console.error(ex); - console.error("Start Uptime-Kuma failed due to patch db failed"); + console.error("Start Uptime-Kuma failed due to issue patching the database"); console.error("Please submit the bug report if you still encounter the problem after restart: https://github.com/louislam/uptime-kuma/issues"); this.restore(); @@ -232,7 +232,7 @@ class Database { this.patched = true; await this.importSQLFile("./db/" + sqlFilename); databasePatchedFiles[sqlFilename] = true; - console.log(sqlFilename + " is patched successfully"); + console.log(sqlFilename + " was patched successfully"); } else { debug(sqlFilename + " is already patched, skip"); @@ -287,7 +287,7 @@ class Database { }; process.addListener("unhandledRejection", listener); - console.log("Closing DB"); + console.log("Closing the database"); while (true) { Database.noReject = true; @@ -297,7 +297,7 @@ class Database { if (Database.noReject) { break; } else { - console.log("Waiting to close the db"); + console.log("Waiting to close the database"); } } console.log("SQLite closed"); @@ -312,7 +312,7 @@ class Database { */ static backup(version) { if (! this.backupPath) { - console.info("Backup the db"); + console.info("Backing up the database"); this.backupPath = this.dataDir + "kuma.db.bak" + version; fs.copyFileSync(Database.path, this.backupPath); @@ -335,7 +335,7 @@ class Database { */ static restore() { if (this.backupPath) { - console.error("Patch db failed!!! Restoring the backup"); + console.error("Patching the database failed!!! Restoring the backup"); const shmPath = Database.path + "-shm"; const walPath = Database.path + "-wal"; @@ -354,7 +354,7 @@ class Database { fs.unlinkSync(walPath); } } catch (e) { - console.log("Restore failed, you may need to restore the backup manually"); + console.log("Restore failed; you may need to restore the backup manually"); process.exit(1); } diff --git a/server/model/monitor.js b/server/model/monitor.js index 3640c73..fb73629 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -7,7 +7,7 @@ dayjs.extend(timezone); const axios = require("axios"); const { Prometheus } = require("../prometheus"); const { debug, UP, DOWN, PENDING, flipStatus, TimeLogger } = require("../../src/util"); -const { tcping, ping, dnsResolve, checkCertificate, checkStatusCode, getTotalClientInRoom } = require("../util-server"); +const { tcping, ping, dnsResolve, checkCertificate, checkStatusCode, getTotalClientInRoom, setting } = require("../util-server"); const { R } = require("redbean-node"); const { BeanModel } = require("redbean-node/dist/bean-model"); const { Notification } = require("../notification"); @@ -272,6 +272,46 @@ class Monitor extends BeanModel { return; } + } else if (this.type === "steam") { + const steamApiUrl = "https://api.steampowered.com/IGameServersService/GetServerList/v1/"; + const steamAPIKey = await setting("steamAPIKey"); + const filter = `addr\\${this.hostname}:${this.port}`; + + if (!steamAPIKey) { + throw new Error("Steam API Key not found"); + } + + let res = await axios.get(steamApiUrl, { + timeout: this.interval * 1000 * 0.8, + headers: { + "Accept": "*/*", + "User-Agent": "Uptime-Kuma/" + version, + }, + httpsAgent: new https.Agent({ + maxCachedSessions: 0, // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940) + rejectUnauthorized: ! this.getIgnoreTls(), + }), + maxRedirects: this.maxredirects, + validateStatus: (status) => { + return checkStatusCode(status, this.getAcceptedStatuscodes()); + }, + params: { + filter: filter, + key: steamAPIKey, + } + }); + + if (res.data.response && res.data.response.servers && res.data.response.servers.length > 0) { + bean.status = UP; + bean.msg = res.data.response.servers[0].name; + + try { + bean.ping = await ping(this.hostname); + } catch (_) { } + } else { + throw new Error("Server not found on Steam"); + } + } else { bean.msg = "Unknown Monitor Type"; bean.status = PENDING; diff --git a/server/server.js b/server/server.js index 6496699..d5f2d37 100644 --- a/server/server.js +++ b/server/server.js @@ -77,12 +77,13 @@ const port = parseInt(process.env.UPTIME_KUMA_PORT || process.env.PORT || args.p // SSL const sslKey = process.env.UPTIME_KUMA_SSL_KEY || process.env.SSL_KEY || args["ssl-key"] || undefined; const sslCert = process.env.UPTIME_KUMA_SSL_CERT || process.env.SSL_CERT || args["ssl-cert"] || undefined; +const disableFrameSameOrigin = !!process.env.UPTIME_KUMA_DISABLE_FRAME_SAMEORIGIN || args["disable-frame-sameorigin"] || false; // 2FA / notp verification defaults const twofa_verification_opts = { "window": 1, "time": 30 -} +}; /** * Run unit test after the server is ready @@ -119,6 +120,15 @@ const { statusPageSocketHandler } = require("./socket-handlers/status-page-socke app.use(express.json()); +// Global Middleware +app.use(function (req, res, next) { + if (!disableFrameSameOrigin) { + res.setHeader("X-Frame-Options", "SAMEORIGIN"); + } + res.removeHeader("X-Powered-By"); + next(); +}); + /** * Total WebSocket client connected to server currently, no actual use * @type {number} @@ -192,7 +202,7 @@ exports.entryPage = "dashboard"; const apiRouter = require("./routers/api-router"); app.use(apiRouter); - // Universal Route Handler, must be at the end of all express route. + // Universal Route Handler, must be at the end of all express routes. app.get("*", async (_request, response) => { if (_request.originalUrl.startsWith("/upload/")) { response.status(404).send("File not found."); @@ -321,7 +331,7 @@ exports.entryPage = "dashboard"; ]); if (user.twofa_status == 0) { - let newSecret = await genSecret(); + let newSecret = genSecret(); let encodedSecret = base32.encode(newSecret); // Google authenticator doesn't like equal signs @@ -449,7 +459,7 @@ exports.entryPage = "dashboard"; socket.on("setup", async (username, password, callback) => { try { if ((await R.count("user")) !== 0) { - throw new Error("Uptime Kuma has been setup. If you want to setup again, please delete the database."); + throw new Error("Uptime Kuma has been initialized. If you want to run setup again, please delete the database."); } let user = R.dispense("user"); @@ -1339,7 +1349,7 @@ async function initDatabase() { fs.copyFileSync(Database.templatePath, Database.path); } - console.log("Connecting to Database"); + console.log("Connecting to the Database"); await Database.connect(); console.log("Connected"); @@ -1439,7 +1449,7 @@ async function shutdownFunction(signal) { } function finalFunction() { - console.log("Graceful shutdown successfully!"); + console.log("Graceful shutdown successful!"); } gracefulShutdown(server, { diff --git a/src/components/notifications/PromoSMS.vue b/src/components/notifications/PromoSMS.vue index 06dea0b..61e61a9 100644 --- a/src/components/notifications/PromoSMS.vue +++ b/src/components/notifications/PromoSMS.vue @@ -10,8 +10,8 @@
{{ $t("checkPrice", [$t("promosms")]) }} diff --git a/src/languages/en.js b/src/languages/en.js index eacb147..d3a69c1 100644 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -1,28 +1,28 @@ export default { languageName: "English", - checkEverySecond: "Check every {0} seconds.", - retryCheckEverySecond: "Retry every {0} seconds.", + checkEverySecond: "Check every {0} seconds", + retryCheckEverySecond: "Retry every {0} seconds", retriesDescription: "Maximum retries before the service is marked as down and a notification is sent", ignoreTLSError: "Ignore TLS/SSL error for HTTPS websites", upsideDownModeDescription: "Flip the status upside down. If the service is reachable, it is DOWN.", maxRedirectDescription: "Maximum number of redirects to follow. Set to 0 to disable redirects.", acceptedStatusCodesDescription: "Select status codes which are considered as a successful response.", passwordNotMatchMsg: "The repeat password does not match.", - notificationDescription: "Please assign a notification to monitor(s) to get it to work.", - keywordDescription: "Search keyword in plain html or JSON response and it is case-sensitive", + notificationDescription: "Notifications must be assigned to a monitor to function.", + keywordDescription: "Search keyword in plain HTML or JSON response. The search is case-sensitive.", pauseDashboardHome: "Pause", deleteMonitorMsg: "Are you sure want to delete this monitor?", deleteNotificationMsg: "Are you sure want to delete this notification for all monitors?", - resoverserverDescription: "Cloudflare is the default server, you can change the resolver server anytime.", - rrtypeDescription: "Select the RR-Type you want to monitor", + resoverserverDescription: "Cloudflare is the default server. You can change the resolver server anytime.", + rrtypeDescription: "Select the RR type you want to monitor", pauseMonitorMsg: "Are you sure want to pause?", - enableDefaultNotificationDescription: "For every new monitor this notification will be enabled by default. You can still disable the notification separately for each monitor.", + enableDefaultNotificationDescription: "This notification will be enabled by default for new monitors. You can still disable the notification separately for each monitor.", clearEventsMsg: "Are you sure want to delete all events for this monitor?", clearHeartbeatsMsg: "Are you sure want to delete all heartbeats for this monitor?", confirmClearStatisticsMsg: "Are you sure you want to delete ALL statistics?", 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.", - confirmImportMsg: "Are you sure to import the backup? Please make sure you've selected the right import option.", - twoFAVerifyLabel: "Please type in your token to verify that 2FA is working", + confirmImportMsg: "Are you sure you want to import the backup? Please verify you've selected the correct import option.", + twoFAVerifyLabel: "Please enter your token to verify 2FA:", tokenValidSettingsMsg: "Token is valid! You can now save the 2FA settings.", confirmEnableTwoFAMsg: "Are you sure you want to enable 2FA?", confirmDisableTwoFAMsg: "Are you sure you want to disable 2FA?", @@ -77,7 +77,7 @@ export default { "Max. Redirects": "Max. Redirects", "Accepted Status Codes": "Accepted Status Codes", "Push URL": "Push URL", - needPushEvery: "You should call this url every {0} seconds.", + needPushEvery: "You should call this URL every {0} seconds.", pushOptionalParams: "Optional parameters: {0}", Save: "Save", Notifications: "Notifications", @@ -135,9 +135,9 @@ export default { Events: "Events", Heartbeats: "Heartbeats", "Auto Get": "Auto Get", - backupDescription: "You can backup all monitors and all notifications into a JSON file.", - backupDescription2: "PS: History and event data is not included.", - backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", + backupDescription: "You can backup all monitors and notifications into a JSON file.", + backupDescription2: "Note: history and event data is not included.", + backupDescription3: "Sensitive data such as notification tokens are included in the export file; please store export securely.", alertNoFile: "Please select a file to import.", alertWrongFileType: "Please select a JSON file.", "Clear all statistics": "Clear all Statistics", @@ -157,8 +157,8 @@ export default { "Show URI": "Show URI", Tags: "Tags", "Add New below or Select...": "Add New below or Select...", - "Tag with this name already exist.": "Tag with this name already exist.", - "Tag with this value already exist.": "Tag with this value already exist.", + "Tag with this name already exist.": "Tag with this name already exists.", + "Tag with this value already exist.": "Tag with this value already exists.", color: "color", "value (optional)": "value (optional)", Gray: "Gray", @@ -192,14 +192,14 @@ export default { wayToGetTelegramToken: "You can get a token from {0}.", "Chat ID": "Chat ID", supportTelegramChatID: "Support Direct Chat / Group / Channel's Chat ID", - wayToGetTelegramChatID: "You can get your chat id by sending message to the bot and go to this url to view the chat_id:", + wayToGetTelegramChatID: "You can get your chat ID by sending a message to the bot and going to this URL to view the chat_id:", "YOUR BOT TOKEN HERE": "YOUR BOT TOKEN HERE", - chatIDNotFound: "Chat ID is not found, please send a message to this bot first", + chatIDNotFound: "Chat ID is not found; please send a message to this bot first", "webhook": "Webhook", "Post URL": "Post URL", "Content Type": "Content Type", - webhookJsonDesc: "{0} is good for any modern http servers such as express.js", - webhookFormDataDesc: "{multipart} is good for PHP, you just need to parse the json by {decodeFunction}", + webhookJsonDesc: "{0} is good for any modern HTTP servers such as Express.js", + webhookFormDataDesc: "{multipart} is good for PHP. The JSON will need to be parsed with {decodeFunction}", "smtp": "Email (SMTP)", secureOptionNone: "None / STARTTLS (25, 587)", secureOptionTLS: "TLS (465)", @@ -217,12 +217,12 @@ export default { "Hello @everyone is...": "Hello {'@'}everyone is...", "teams": "Microsoft Teams", "Webhook URL": "Webhook URL", - wayToGetTeamsURL: "You can learn how to create a webhook url {0}.", + wayToGetTeamsURL: "You can learn how to create a webhook URL {0}.", "signal": "Signal", "Number": "Number", "Recipients": "Recipients", needSignalAPI: "You need to have a signal client with REST API.", - wayToCheckSignalURL: "You can check this url to view how to setup one:", + wayToCheckSignalURL: "You can check this URL to view how to set one up:", signalImportant: "IMPORTANT: You cannot mix groups and numbers in recipients!", "gotify": "Gotify", "Application Token": "Application Token", @@ -232,11 +232,11 @@ export default { "Icon Emoji": "Icon Emoji", "Channel Name": "Channel Name", "Uptime Kuma URL": "Uptime Kuma URL", - aboutWebhooks: "More info about webhooks on: {0}", - aboutChannelName: "Enter the channel name on {0} Channel Name field if you want to bypass the webhook channel. Ex: #other-channel", - aboutKumaURL: "If you leave the Uptime Kuma URL field blank, it will default to the Project Github page.", + aboutWebhooks: "More info about Webhooks on: {0}", + aboutChannelName: "Enter the channel name on {0} Channel Name field if you want to bypass the Webhook channel. Ex: #other-channel", + aboutKumaURL: "If you leave the Uptime Kuma URL field blank, it will default to the Project GitHub page.", emojiCheatSheet: "Emoji cheat sheet: {0}", - "rocket.chat": "Rocket.chat", + "rocket.chat": "Rocket.Chat", pushover: "Pushover", pushy: "Pushy", octopush: "Octopush", @@ -255,7 +255,7 @@ export default { pushoverDesc2: "If you want to send notifications to different devices, fill out Device field.", "SMS Type": "SMS Type", octopushTypePremium: "Premium (Fast - recommended for alerting)", - octopushTypeLowCost: "Low Cost (Slow, sometimes blocked by operator)", + octopushTypeLowCost: "Low Cost (Slow - sometimes blocked by operator)", checkPrice: "Check {0} prices:", octopushLegacyHint: "Do you use the legacy version of Octopush (2011-2020) or the new version?", "Check octopush prices": "Check octopush prices {0}.", @@ -276,20 +276,20 @@ export default { "Basic Settings": "Basic Settings", "User ID": "User ID", "Messaging API": "Messaging API", - wayToGetLineChannelToken: "First access the {0}, create a provider and channel (Messaging API), then you can get the channel access token and user id from the above mentioned menu items.", + wayToGetLineChannelToken: "First access the {0}, create a provider and channel (Messaging API), then you can get the channel access token and user ID from the above mentioned menu items.", "Icon URL": "Icon URL", aboutIconURL: "You can provide a link to a picture in \"Icon URL\" to override the default profile picture. Will not be used if Icon Emoji is set.", - aboutMattermostChannelName: "You can override the default channel that webhook posts to by entering the channel name into \"Channel Name\" field. This needs to be enabled in Mattermost webhook settings. Ex: #other-channel", + aboutMattermostChannelName: "You can override the default channel that the Webhook posts to by entering the channel name into \"Channel Name\" field. This needs to be enabled in the Mattermost Webhook settings. Ex: #other-channel", "matrix": "Matrix", promosmsTypeEco: "SMS ECO - cheap but slow and often overloaded. Limited only to Polish recipients.", promosmsTypeFlash: "SMS FLASH - Message will automatically show on recipient device. Limited only to Polish recipients.", - promosmsTypeFull: "SMS FULL - Premium tier of SMS, You can use Your Sender Name (You need to register name first). Reliable for alerts.", + promosmsTypeFull: "SMS FULL - Premium tier of SMS, You can use your Sender Name (You need to register name first). Reliable for alerts.", promosmsTypeSpeed: "SMS SPEED - Highest priority in system. Very quick and reliable but costly (about twice of SMS FULL price).", promosmsPhoneNumber: "Phone number (for Polish recipient You can skip area codes)", promosmsSMSSender: "SMS Sender Name : Pre-registred name or one of defaults: InfoSMS, SMS Info, MaxSMS, INFO, SMS", - "Feishu WebHookUrl": "Feishu WebHookUrl", + "Feishu WebHookUrl": "Feishu WebHookURL", matrixHomeserverURL: "Homeserver URL (with http(s):// and optionally port)", - "Internal Room Id": "Internal Room Id", + "Internal Room Id": "Internal Room ID", matrixDesc1: "You can find the internal room ID by looking in the advanced section of the room settings in your Matrix client. It should look like !QMdRCpUIfLwsfjxye6:home.server.", matrixDesc2: "It is highly recommended you create a new user and do not use your own Matrix user's access token as it will allow full access to your account and all the rooms you joined. Instead, create a new user and only invite it to the room that you want to receive the notification in. You can get the access token by running {0}", // End notification form @@ -301,7 +301,9 @@ export default { BodyInvalidFormat: "The request body is not valid JSON: ", "Monitor History": "Monitor History:", clearDataOlderThan: "Keep monitor history data for {0} days.", + PasswordsDoNotMatch: "Passwords do not match.", records: "records", "One record": "One record", "Showing {from} to {to} of {count} records": "Showing {from} to {to} of {count} records", + steamApiKeyDescription: "For monitoring a Steam Game Server you need a Steam Web-API key. You can register your API key here: ", }; diff --git a/src/mixins/socket.js b/src/mixins/socket.js index 321e2d6..d7ac8bc 100644 --- a/src/mixins/socket.js +++ b/src/mixins/socket.js @@ -347,7 +347,7 @@ export default { let result = {}; let unknown = { - text: "Unknown", + text: this.$t("Unknown"), color: "secondary", }; @@ -358,17 +358,17 @@ export default { result[monitorID] = unknown; } else if (lastHeartBeat.status === 1) { result[monitorID] = { - text: "Up", + text: this.$t("Up"), color: "primary", }; } else if (lastHeartBeat.status === 0) { result[monitorID] = { - text: "Down", + text: this.$t("Down"), color: "danger", }; } else if (lastHeartBeat.status === 2) { result[monitorID] = { - text: "Pending", + text: this.$t("Pending"), color: "warning", }; } else { diff --git a/src/pages/Details.vue b/src/pages/Details.vue index d38d8f8..1363aa2 100644 --- a/src/pages/Details.vue +++ b/src/pages/Details.vue @@ -41,7 +41,7 @@ {{ $t("checkEverySecond", [ monitor.interval ]) }}
- {{ $t(status.text) }} + {{ status.text }}
diff --git a/src/pages/EditMonitor.vue b/src/pages/EditMonitor.vue index fb95230..a763a42 100644 --- a/src/pages/EditMonitor.vue +++ b/src/pages/EditMonitor.vue @@ -29,6 +29,9 @@ + @@ -64,18 +67,20 @@ - -
+ +
- -
+ + +
+