From 59d10062ca5957459e0cda53c0468c1514ace590 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sun, 22 Jun 2025 14:49:24 +0200 Subject: [PATCH 01/43] chore: remove fluff from PR-template (#5941) --- .github/ISSUE_TEMPLATE/ask_for_help.yml | 2 +- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/ISSUE_TEMPLATE/feature_request.yml | 2 +- .github/ISSUE_TEMPLATE/security_issue.yml | 2 +- .github/PULL_REQUEST_TEMPLATE.md | 55 +++++----------------- 5 files changed, 17 insertions(+), 46 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/ask_for_help.yml b/.github/ISSUE_TEMPLATE/ask_for_help.yml index 45bd046e5..2156c5be0 100644 --- a/.github/ISSUE_TEMPLATE/ask_for_help.yml +++ b/.github/ISSUE_TEMPLATE/ask_for_help.yml @@ -3,7 +3,7 @@ name: ❓ Ask for help description: | Submit any question related to Uptime Kuma #title: "[Help]" -labels: ["help", "P3-low"] +labels: ["help"] body: - type: markdown attributes: diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 31cd6faf6..d0330c70a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -3,7 +3,7 @@ name: 🐛 Bug Report description: | Submit a bug report to help us improve #title: "[Bug]" -labels: ["bug", "P2-medium"] +labels: ["bug"] body: - type: markdown attributes: diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index c9ec4d093..4e1be15e1 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -3,7 +3,7 @@ name: 🚀 Feature Request description: | Submit a proposal for a new feature # title: "[Feature]" -labels: ["feature-request", "P3-low"] +labels: ["feature-request"] body: - type: markdown attributes: diff --git a/.github/ISSUE_TEMPLATE/security_issue.yml b/.github/ISSUE_TEMPLATE/security_issue.yml index d49c0aaf5..247073102 100644 --- a/.github/ISSUE_TEMPLATE/security_issue.yml +++ b/.github/ISSUE_TEMPLATE/security_issue.yml @@ -3,7 +3,7 @@ name: 🛡️ Security Issue description: | Notify Louis Lam about a security concern. Please do NOT include any sensitive details in this issue. # title: "Security Issue" -labels: ["security", "P1-high"] +labels: ["security"] assignees: [louislam] body: - type: markdown diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index f639c395e..dade3e76f 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,10 +1,10 @@ -**⚠️ Please Note: We do not accept all types of pull requests, and we want to ensure we don’t waste your time. Before submitting, make sure you have read our pull request guidelines: [Pull Request Rules](https://github.com/louislam/uptime-kuma/blob/master/CONTRIBUTING.md#can-i-create-a-pull-request-for-uptime-kuma)** - ## ❗ Important Announcement
Click here for more details:

+**⚠️ Please Note: We do not accept all types of pull requests, and we want to ensure we don’t waste your time. Before submitting, make sure you have read our pull request guidelines: [Pull Request Rules](https://github.com/louislam/uptime-kuma/blob/master/CONTRIBUTING.md#can-i-create-a-pull-request-for-uptime-kuma)** + ### 🚧 Temporary Delay in Feature Requests and Pull Request Reviews **At this time, we may be slower to respond to new feature requests and review pull requests. Existing requests and PRs will remain in the backlog but may not be prioritized immediately.** @@ -26,16 +26,22 @@ We appreciate your patience and understanding as we continue to improve Uptime K ## 📋 Overview -Provide a clear summary of the purpose and scope of this pull request: + - **What problem does this pull request address?** - - Please provide a detailed explanation here. - - **What features or functionality does this pull request introduce or enhance?** - - Please provide a detailed explanation here. +## 🔗 Related Issues + + + +- Relates to #issue-number +- Resolves #issue-number + ## 🔄 Changes ### 🛠️ Type of change @@ -52,19 +58,7 @@ Provide a clear summary of the purpose and scope of this pull request: - [ ] 🔧 Other (please specify): - Provide additional details here. -## 🔗 Related Issues - - - -- Relates to #issue-number -- Resolves #issue-number -- Fixes #issue-number - -## 📄 Checklist * +## 📄 Checklist @@ -97,26 +91,3 @@ If not, remove this section. | `DOWN` | ![Before](image-link) | ![After](image-link) | | Certificate-expiry | ![Before](image-link) | ![After](image-link) | | Testing | ![Before](image-link) | ![After](image-link) | - -## ℹ️ Additional Context - -Provide any relevant details to assist reviewers in understanding the changes. - -
Click here for more details: -

- -**Key Considerations**: - -- **Design decisions** – Key choices or trade-offs made during development. -- **Alternative solutions** – Approaches considered but not implemented, along with reasons. -- **Relevant links** – Specifications, discussions, or resources that provide context. -- **Dependencies** – Related pull requests or issues that must be resolved before merging. -- **Additional context** – Any other details that may help reviewers understand the changes. - -Provide details here - -## 💬 Requested Feedback - - - -- `Mention documents needing feedback here` From b55d6e8911ea6ee5a7bdddc9f3106b6f5bade698 Mon Sep 17 00:00:00 2001 From: Louis Lam Date: Mon, 23 Jun 2025 15:24:49 +0800 Subject: [PATCH 02/43] Improve the experience of testing pull requests (#5942) --- docker/dockerfile | 4 ++++ extra/checkout-pr.js | 33 -------------------------------- extra/checkout-pr.mjs | 34 +++++++++++++++++++++++++++++++++ extra/kuma-pr/index.mjs | 26 +++++++++++++++++++++++++ extra/kuma-pr/package.json | 8 ++++++++ extra/kuma-pr/pr-lib.mjs | 39 ++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 7 files changed, 112 insertions(+), 34 deletions(-) delete mode 100644 extra/checkout-pr.js create mode 100644 extra/checkout-pr.mjs create mode 100644 extra/kuma-pr/index.mjs create mode 100644 extra/kuma-pr/package.json create mode 100644 extra/kuma-pr/pr-lib.mjs diff --git a/docker/dockerfile b/docker/dockerfile index d55f94f61..e2a301e7b 100644 --- a/docker/dockerfile +++ b/docker/dockerfile @@ -79,6 +79,10 @@ USER node RUN git config --global user.email "no-reply@no-reply.com" RUN git config --global user.name "PR Tester" RUN git clone https://github.com/louislam/uptime-kuma.git . + +# Hide the warning when running in detached head state +RUN git config --global advice.detachedHead false + RUN npm ci EXPOSE 3000 3001 diff --git a/extra/checkout-pr.js b/extra/checkout-pr.js deleted file mode 100644 index 0328770b1..000000000 --- a/extra/checkout-pr.js +++ /dev/null @@ -1,33 +0,0 @@ -const childProcess = require("child_process"); - -if (!process.env.UPTIME_KUMA_GH_REPO) { - console.error("Please set a repo to the environment variable 'UPTIME_KUMA_GH_REPO' (e.g. mhkarimi1383:goalert-notification)"); - process.exit(1); -} - -let inputArray = process.env.UPTIME_KUMA_GH_REPO.split(":"); - -if (inputArray.length !== 2) { - console.error("Invalid format. Please set a repo to the environment variable 'UPTIME_KUMA_GH_REPO' (e.g. mhkarimi1383:goalert-notification)"); -} - -let name = inputArray[0]; -let branch = inputArray[1]; - -console.log("Checkout pr"); - -// Checkout the pr -let result = childProcess.spawnSync("git", [ "remote", "add", name, `https://github.com/${name}/uptime-kuma` ]); - -console.log(result.stdout.toString()); -console.error(result.stderr.toString()); - -result = childProcess.spawnSync("git", [ "fetch", name, branch ]); - -console.log(result.stdout.toString()); -console.error(result.stderr.toString()); - -result = childProcess.spawnSync("git", [ "checkout", `${name}/${branch}`, "--force" ]); - -console.log(result.stdout.toString()); -console.error(result.stderr.toString()); diff --git a/extra/checkout-pr.mjs b/extra/checkout-pr.mjs new file mode 100644 index 000000000..653664477 --- /dev/null +++ b/extra/checkout-pr.mjs @@ -0,0 +1,34 @@ +import childProcess from "child_process"; +import { parsePrName } from "./kuma-pr/pr-lib.mjs"; + +let { name, branch } = parsePrName(process.env.UPTIME_KUMA_GH_REPO); + +console.log(`Checking out PR from ${name}:${branch}`); + +// Checkout the pr +let result = childProcess.spawnSync("git", [ "remote", "add", name, `https://github.com/${name}/uptime-kuma` ], { + stdio: "inherit" +}); + +if (result.status !== 0) { + console.error("Failed to add remote repository."); + process.exit(1); +} + +result = childProcess.spawnSync("git", [ "fetch", name, branch ], { + stdio: "inherit" +}); + +if (result.status !== 0) { + console.error("Failed to fetch the branch."); + process.exit(1); +} + +result = childProcess.spawnSync("git", [ "checkout", `${name}/${branch}`, "--force" ], { + stdio: "inherit" +}); + +if (result.status !== 0) { + console.error("Failed to checkout the branch."); + process.exit(1); +} diff --git a/extra/kuma-pr/index.mjs b/extra/kuma-pr/index.mjs new file mode 100644 index 000000000..bcda9d335 --- /dev/null +++ b/extra/kuma-pr/index.mjs @@ -0,0 +1,26 @@ +#!/usr/bin/env node +import { spawn } from "child_process"; +import { parsePrName } from "./pr-lib.mjs"; + +const prName = process.argv[2]; + +// Pre-check the prName here, so testers don't need to wait until the Docker image is pulled to see the error. +try { + parsePrName(prName); +} catch (error) { + console.error(error.message); + process.exit(1); +} + +spawn("docker", [ + "run", + "--rm", + "-it", + "-p", "3000:3000", + "-p", "3001:3001", + "--pull", "always", + "-e", `UPTIME_KUMA_GH_REPO=${prName}`, + "louislam/uptime-kuma:pr-test2" +], { + stdio: "inherit", +}); diff --git a/extra/kuma-pr/package.json b/extra/kuma-pr/package.json new file mode 100644 index 000000000..16f30b160 --- /dev/null +++ b/extra/kuma-pr/package.json @@ -0,0 +1,8 @@ +{ + "name": "kuma-pr", + "version": "1.0.0", + "type": "module", + "bin": { + "kuma-pr": "./index.mjs" + } +} diff --git a/extra/kuma-pr/pr-lib.mjs b/extra/kuma-pr/pr-lib.mjs new file mode 100644 index 000000000..1cb5050bf --- /dev/null +++ b/extra/kuma-pr/pr-lib.mjs @@ -0,0 +1,39 @@ +/** + * Parse : to an object. + * @param {string} prName : + * @returns {object} An object with name and branch properties. + */ +export function parsePrName(prName) { + let name = "louislam"; + let branch; + + const errorMessage = "Please set a repo to the environment variable 'UPTIME_KUMA_GH_REPO' (e.g. mhkarimi1383:goalert-notification)"; + + if (!prName) { + throw new Error(errorMessage); + } + + prName = prName.trim(); + if (prName === "") { + throw new Error(errorMessage); + } + + let inputArray = prName.split(":"); + + // Just realized that owner's prs are not prefixed with "louislam:" + if (inputArray.length === 1) { + branch = inputArray[0]; + + } else if (inputArray.length === 2) { + name = inputArray[0]; + branch = inputArray[1]; + + } else { + throw new Error("Invalid format. The format is like this: mhkarimi1383:goalert-notification"); + } + + return { + name, + branch + }; +} diff --git a/package.json b/package.json index 16837fa8a..97b7bc339 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "release-nightly": "node ./extra/release/nightly.mjs", "git-remove-tag": "git tag -d", "build-dist-and-restart": "npm run build && npm run start-server-dev", - "start-pr-test": "node extra/checkout-pr.js && npm install && npm run dev", + "start-pr-test": "node extra/checkout-pr.mjs && npm install && npm run dev", "build-healthcheck-armv7": "cross-env GOOS=linux GOARCH=arm GOARM=7 go build -x -o ./extra/healthcheck-armv7 ./extra/healthcheck.go", "deploy-demo-server": "node extra/deploy-demo-server.js", "sort-contributors": "node extra/sort-contributors.js", From 92f2484a8d9dbce171efad6eafe922e95bb2e83d Mon Sep 17 00:00:00 2001 From: Louis Lam Date: Mon, 23 Jun 2025 17:56:39 +0800 Subject: [PATCH 03/43] Auto reply to PRs (#5943) Co-authored-by: Frank Elsinga --- .github/workflows/pr-reply.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/pr-reply.yml diff --git a/.github/workflows/pr-reply.yml b/.github/workflows/pr-reply.yml new file mode 100644 index 000000000..553774bf3 --- /dev/null +++ b/.github/workflows/pr-reply.yml @@ -0,0 +1,30 @@ +# Replys a message to all new PRs +# The message: +# - Say hello and thanks to the contributor +# - Mention maintainers will review the PR soon +# - To other people, show the testing pr command: npx kuma-pr +# - Also show the advanced usage link: https://github.com/louislam/uptime-kuma/wiki/Test-Pull-Requests +name: Reply to PRs +on: + pull_request: + types: [opened, reopened] +jobs: + reply: + runs-on: ubuntu-latest + steps: + - name: Reply to PR + uses: actions/github-script@v7 + with: + script: | + const pr = context.payload.pull_request; + const message = `Hello @${pr.user.login}, thank you for your contribution! :tada:\n` + + `The maintainers will review your PR soon.\n\n` + + `If anyone would like to help test this PR, you can use the command:\n` + + `\`\`\`bash\nnpx kuma-pr ${pr.user.login}:${pr.head.ref}\n\`\`\`\n\n` + + ` For advanced usage, please refer to our [wiki](https://github.com/louislam/uptime-kuma/wiki/Test-Pull-Requests) `; + await github.rest.issues.createComment({ + issue_number: pr.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: message + }); From 9e7ea4913aa6302da7ea36175f9318913291f12f Mon Sep 17 00:00:00 2001 From: Louis Lam Date: Mon, 23 Jun 2025 21:12:18 +0800 Subject: [PATCH 04/43] Fix auto pr reply (#5945) --- .github/workflows/pr-reply.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/pr-reply.yml b/.github/workflows/pr-reply.yml index 553774bf3..48752e641 100644 --- a/.github/workflows/pr-reply.yml +++ b/.github/workflows/pr-reply.yml @@ -8,6 +8,12 @@ name: Reply to PRs on: pull_request: types: [opened, reopened] + +permissions: + issues: write + pull-requests: write + contents: read + jobs: reply: runs-on: ubuntu-latest From 9976ef94af050f68945e1fc94620216ef3728756 Mon Sep 17 00:00:00 2001 From: mindsolo Date: Mon, 23 Jun 2025 16:38:01 +0300 Subject: [PATCH 05/43] feat: Add proxy clone functionality to settings (#5944) Co-authored-by: Frank Elsinga --- src/components/ProxyDialog.vue | 32 +++++++++++++++++++++++++++++ src/components/settings/Proxies.vue | 3 ++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/components/ProxyDialog.vue b/src/components/ProxyDialog.vue index 2f7ed7b61..aae635469 100644 --- a/src/components/ProxyDialog.vue +++ b/src/components/ProxyDialog.vue @@ -174,6 +174,38 @@ export default { this.modal.show(); }, + /** + * Show dialog to clone a proxy + * @param {number} proxyID ID of proxy to clone + * @returns {void} + */ + showClone(proxyID) { + if (proxyID) { + for (let proxy of this.$root.proxyList) { + if (proxy.id === proxyID) { + // Create a clone of the proxy data + this.proxy = { + protocol: proxy.protocol, + host: proxy.host, + port: proxy.port, + auth: proxy.auth, + username: proxy.username, + password: proxy.password, + active: proxy.active, + default: false, // Cloned proxy should not be default + applyExisting: false, + }; + break; + } + } + } + + // Set id to null to indicate this is a new proxy (clone) + this.id = null; + + this.modal.show(); + }, + /** * Submit form data for saving * @returns {void} diff --git a/src/components/settings/Proxies.vue b/src/components/settings/Proxies.vue index 4608f3aa4..de5b8d5a0 100644 --- a/src/components/settings/Proxies.vue +++ b/src/components/settings/Proxies.vue @@ -13,7 +13,8 @@
  • {{ proxy.host }}:{{ proxy.port }} ({{ proxy.protocol }}) {{ $t("Default") }}
    - {{ $t("Edit") }} + {{ $t("Edit") }} | + {{ $t("Clone") }}
  • From 10fd6ede1e016befd3fd2656553b362a2c74fb2a Mon Sep 17 00:00:00 2001 From: Louis Lam Date: Wed, 25 Jun 2025 13:39:00 +0800 Subject: [PATCH 06/43] [Eliminate Blocking] Docker monitor (#5927) --- server/docker.js | 18 +++++++++--------- server/model/monitor.js | 2 +- server/util-server.js | 15 +++++++++++++++ 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/server/docker.js b/server/docker.js index ee6051dfa..7ca5da562 100644 --- a/server/docker.js +++ b/server/docker.js @@ -1,10 +1,10 @@ const axios = require("axios"); const { R } = require("redbean-node"); const https = require("https"); -const fs = require("fs"); +const fsAsync = require("fs").promises; const path = require("path"); const Database = require("./database"); -const { axiosAbortSignal } = require("./util-server"); +const { axiosAbortSignal, fsExists } = require("./util-server"); class DockerHost { @@ -81,7 +81,7 @@ class DockerHost { options.socketPath = dockerHost.dockerDaemon; } else if (dockerHost.dockerType === "tcp") { options.baseURL = DockerHost.patchDockerURL(dockerHost.dockerDaemon); - options.httpsAgent = new https.Agent(DockerHost.getHttpsAgentOptions(dockerHost.dockerType, options.baseURL)); + options.httpsAgent = new https.Agent(await DockerHost.getHttpsAgentOptions(dockerHost.dockerType, options.baseURL)); } try { @@ -141,9 +141,9 @@ class DockerHost { * File names can also be overridden via 'DOCKER_TLS_FILE_NAME_(CA|KEY|CERT)'. * @param {string} dockerType i.e. "tcp" or "socket" * @param {string} url The docker host URL rewritten to https:// - * @returns {object} HTTP agent options + * @returns {Promise} HTTP agent options */ - static getHttpsAgentOptions(dockerType, url) { + static async getHttpsAgentOptions(dockerType, url) { let baseOptions = { maxCachedSessions: 0, rejectUnauthorized: true @@ -156,10 +156,10 @@ class DockerHost { let certPath = path.join(Database.dockerTLSDir, dirName, DockerHost.CertificateFileNameCert); let keyPath = path.join(Database.dockerTLSDir, dirName, DockerHost.CertificateFileNameKey); - if (dockerType === "tcp" && fs.existsSync(caPath) && fs.existsSync(certPath) && fs.existsSync(keyPath)) { - let ca = fs.readFileSync(caPath); - let key = fs.readFileSync(keyPath); - let cert = fs.readFileSync(certPath); + if (dockerType === "tcp" && await fsExists(caPath) && await fsExists(certPath) && await fsExists(keyPath)) { + let ca = await fsAsync.readFile(caPath); + let key = await fsAsync.readFile(keyPath); + let cert = await fsAsync.readFile(certPath); certOptions = { ca, key, diff --git a/server/model/monitor.js b/server/model/monitor.js index c9844a55d..c1db77e8b 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -746,7 +746,7 @@ class Monitor extends BeanModel { } else if (dockerHost._dockerType === "tcp") { options.baseURL = DockerHost.patchDockerURL(dockerHost._dockerDaemon); options.httpsAgent = new https.Agent( - DockerHost.getHttpsAgentOptions(dockerHost._dockerType, options.baseURL) + await DockerHost.getHttpsAgentOptions(dockerHost._dockerType, options.baseURL) ); } diff --git a/server/util-server.js b/server/util-server.js index 4cc833330..4da4be91b 100644 --- a/server/util-server.js +++ b/server/util-server.js @@ -23,6 +23,7 @@ const radiusClient = require("node-radius-client"); const redis = require("redis"); const oidc = require("openid-client"); const tls = require("tls"); +const { exists } = require("fs"); const { dictionaries: { @@ -1096,3 +1097,17 @@ module.exports.axiosAbortSignal = (timeoutMs) => { } } }; + +/** + * Async version of fs.existsSync + * @param {PathLike} path File path + * @returns {Promise} True if file exists, false otherwise + */ +function fsExists(path) { + return new Promise(function (resolve, reject) { + exists(path, function (exists) { + resolve(exists); + }); + }); +} +module.exports.fsExists = fsExists; From 5336b05a7fd78751396444a2788abcd921d93f5d Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sat, 28 Jun 2025 18:27:31 +0200 Subject: [PATCH 07/43] remove feature freeze messaging from templates (#5957) --- .github/ISSUE_TEMPLATE/feature_request.yml | 17 ++---------- .github/PULL_REQUEST_TEMPLATE.md | 31 +++++++--------------- 2 files changed, 11 insertions(+), 37 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 4e1be15e1..61d647a4f 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -8,23 +8,10 @@ body: - type: markdown attributes: value: | - ## ❗Important Announcement - - ### 🚧 Temporary Delay in Feature Requests and Pull Request Reviews - - **At this time, we may be slower to respond to new feature requests and review pull requests. Existing requests and PRs will remain in the backlog but may not be prioritized immediately.** - - - **Reason**: Our current focus is on addressing bugs, improving system performance, and implementing essential updates. This will help stabilize the project and ensure smoother management. - - **Impact**: While no new feature requests or pull requests are being outright rejected, there may be significant delays in reviews. We encourage the community to help by reviewing PRs or assisting other users in the meantime. - - **What You Can Do**: If you're interested in contributing, reviewing open PRs by following our [Review Guidelines](https://github.com/louislam/uptime-kuma/blob/master/.github/REVIEW_GUIDELINES.md) or offering help to other users is greatly appreciated. All feature requests and PRs will be revisited once the suspension period is lifted. - - We appreciate your patience and understanding as we continue to improve Uptime Kuma. - ### 🚫 Please Avoid Unnecessary Pinging of Maintainers - **We kindly ask you to refrain from pinging maintainers unless absolutely necessary. Pings are reserved for critical/urgent pull requests that require immediate attention.** - - **Why**: Reserving pings for urgent matters ensures maintainers can prioritize critical tasks effectively. + We kindly ask you to refrain from pinging maintainers unless absolutely necessary. + Pings are for critical/urgent pull requests that require immediate attention. - type: textarea id: related-issues validations: diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index dade3e76f..e351aa2e2 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,25 +1,13 @@ -## ❗ Important Announcement +## ❗ Important Announcements
    Click here for more details:

    **⚠️ Please Note: We do not accept all types of pull requests, and we want to ensure we don’t waste your time. Before submitting, make sure you have read our pull request guidelines: [Pull Request Rules](https://github.com/louislam/uptime-kuma/blob/master/CONTRIBUTING.md#can-i-create-a-pull-request-for-uptime-kuma)** -### 🚧 Temporary Delay in Feature Requests and Pull Request Reviews - -**At this time, we may be slower to respond to new feature requests and review pull requests. Existing requests and PRs will remain in the backlog but may not be prioritized immediately.** - -- **Reason**: Our current focus is on addressing bugs, improving system performance, and implementing essential updates. This will help stabilize the project and ensure smoother management. -- **Impact**: While no new feature requests or pull requests are being outright rejected, there may be significant delays in reviews. We encourage the community to help by reviewing PRs or assisting other users in the meantime. -- **What You Can Do**: If you're interested in contributing, reviewing open PRs by following our [Review Guidelines](https://github.com/louislam/uptime-kuma/blob/master/.github/REVIEW_GUIDELINES.md) or offering support to other users is greatly appreciated. All feature requests and PRs will be revisited once the suspension period is lifted. - -We appreciate your patience and understanding as we continue to improve Uptime Kuma. - ### 🚫 Please Avoid Unnecessary Pinging of Maintainers -**We kindly ask you to refrain from pinging maintainers unless absolutely necessary. Pings are reserved for critical/urgent pull requests that require immediate attention.** - -**Why**: Reserving pings for urgent matters ensures maintainers can prioritize critical tasks effectively. +We kindly ask you to refrain from pinging maintainers unless absolutely necessary. Pings are for critical/urgent pull requests that require immediate attention.

    @@ -33,18 +21,15 @@ We appreciate your patience and understanding as we continue to improve Uptime K - **What features or functionality does this pull request introduce or enhance?** - Please provide a detailed explanation here. -## 🔗 Related Issues - - Relates to #issue-number - Resolves #issue-number -## 🔄 Changes - -### 🛠️ Type of change +## 🛠️ Type of change @@ -63,6 +48,7 @@ Please link any GitHub issues or tasks that this pull request addresses. Use the - [ ] 🔍 My code adheres to the style guidelines of this project. +- [ ] 🦿 I have indicated where (if any) I used an LLM for the contributions - [ ] ✅ I ran ESLint and other code linters for modified files. - [ ] 🛠️ I have reviewed and tested my code. - [ ] 📝 I have commented my code, especially in hard-to-understand areas (e.g., using JSDoc for methods). @@ -76,10 +62,11 @@ Please link any GitHub issues or tasks that this pull request addresses. Use the ## 📷 Screenshots or Visual Changes - **UI Modifications**: Highlight any changes made to the user interface. From 9506b3a16be54334e4d2f3f683e780b92471ca87 Mon Sep 17 00:00:00 2001 From: Ryan Hartje Date: Sun, 29 Jun 2025 19:37:41 -0500 Subject: [PATCH 08/43] feat: Add optional audience for http-monitors via the oauth2 client credentials flow (#5950) Co-authored-by: Frank Elsinga --- .../2025-06-24-0000-add-audience-to-oauth.js | 12 ++++++++++++ server/model/monitor.js | 3 ++- server/server.js | 1 + server/util-server.js | 17 +++++++++++------ src/lang/en.json | 2 ++ src/pages/EditMonitor.vue | 4 ++++ 6 files changed, 32 insertions(+), 7 deletions(-) create mode 100644 db/knex_migrations/2025-06-24-0000-add-audience-to-oauth.js diff --git a/db/knex_migrations/2025-06-24-0000-add-audience-to-oauth.js b/db/knex_migrations/2025-06-24-0000-add-audience-to-oauth.js new file mode 100644 index 000000000..6666ed9c8 --- /dev/null +++ b/db/knex_migrations/2025-06-24-0000-add-audience-to-oauth.js @@ -0,0 +1,12 @@ +exports.up = function (knex) { + return knex.schema + .alterTable("monitor", function (table) { + table.string("oauth_audience").nullable().defaultTo(null); + }); +}; + +exports.down = function (knex) { + return knex.schema.alterTable("monitor", function (table) { + table.string("oauth_audience").alter(); + }); +}; diff --git a/server/model/monitor.js b/server/model/monitor.js index c1db77e8b..3be8267c9 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -181,6 +181,7 @@ class Monitor extends BeanModel { oauth_client_secret: this.oauth_client_secret, oauth_token_url: this.oauth_token_url, oauth_scopes: this.oauth_scopes, + oauth_audience: this.oauth_audience, oauth_auth_method: this.oauth_auth_method, pushToken: this.pushToken, databaseConnectionString: this.databaseConnectionString, @@ -1746,7 +1747,7 @@ class Monitor extends BeanModel { */ async makeOidcTokenClientCredentialsRequest() { log.debug("monitor", `[${this.name}] The oauth access-token undefined or expired. Requesting a new token`); - const oAuthAccessToken = await getOidcTokenClientCredentials(this.oauth_token_url, this.oauth_client_id, this.oauth_client_secret, this.oauth_scopes, this.oauth_auth_method); + const oAuthAccessToken = await getOidcTokenClientCredentials(this.oauth_token_url, this.oauth_client_id, this.oauth_client_secret, this.oauth_scopes, this.oauth_audience, this.oauth_auth_method); if (this.oauthAccessToken?.expires_at) { log.debug("monitor", `[${this.name}] Obtained oauth access-token. Expires at ${new Date(this.oauthAccessToken?.expires_at * 1000)}`); } else { diff --git a/server/server.js b/server/server.js index 5b2f41a2e..b7025464b 100644 --- a/server/server.js +++ b/server/server.js @@ -802,6 +802,7 @@ let needSetup = false; bean.oauth_auth_method = monitor.oauth_auth_method; bean.oauth_token_url = monitor.oauth_token_url; bean.oauth_scopes = monitor.oauth_scopes; + bean.oauth_audience = monitor.oauth_audience; bean.tlsCa = monitor.tlsCa; bean.tlsCert = monitor.tlsCert; bean.tlsKey = monitor.tlsKey; diff --git a/server/util-server.js b/server/util-server.js index 4da4be91b..d4a37970d 100644 --- a/server/util-server.js +++ b/server/util-server.js @@ -58,7 +58,7 @@ exports.initJWTSecret = async () => { }; /** - * Decodes a jwt and returns the payload portion without verifying the jqt. + * Decodes a jwt and returns the payload portion without verifying the jwt. * @param {string} jwt The input jwt as a string * @returns {object} Decoded jwt payload object */ @@ -67,15 +67,16 @@ exports.decodeJwt = (jwt) => { }; /** - * Gets a Access Token form a oidc/oauth2 provider - * @param {string} tokenEndpoint The token URI form the auth service provider + * Gets an Access Token from an oidc/oauth2 provider + * @param {string} tokenEndpoint The token URI from the auth service provider * @param {string} clientId The oidc/oauth application client id * @param {string} clientSecret The oidc/oauth application client secret - * @param {string} scope The scope the for which the token should be issued for - * @param {string} authMethod The method on how to sent the credentials. Default client_secret_basic + * @param {string} scope The scope(s) for which the token should be issued for + * @param {string} audience The audience for which the token should be issued for + * @param {string} authMethod The method used to send the credentials. Default client_secret_basic * @returns {Promise} TokenSet promise if the token request was successful */ -exports.getOidcTokenClientCredentials = async (tokenEndpoint, clientId, clientSecret, scope, authMethod = "client_secret_basic") => { +exports.getOidcTokenClientCredentials = async (tokenEndpoint, clientId, clientSecret, scope, audience, authMethod = "client_secret_basic") => { const oauthProvider = new oidc.Issuer({ token_endpoint: tokenEndpoint }); let client = new oauthProvider.Client({ client_id: clientId, @@ -91,6 +92,10 @@ exports.getOidcTokenClientCredentials = async (tokenEndpoint, clientId, clientSe if (scope) { grantParams.scope = scope; } + + if (audience) { + grantParams.audience = audience; + } return await client.grant(grantParams); }; diff --git a/src/lang/en.json b/src/lang/en.json index a979edcc2..b6449371b 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -1022,6 +1022,8 @@ "Client ID": "Client ID", "Client Secret": "Client Secret", "OAuth Scope": "OAuth Scope", + "OAuth Audience": "OAuth Audience", + "Optional: The audience to request the JWT for": "Optional: The audience to request the JWT for", "Optional: Space separated list of scopes": "Optional: Space separated list of scopes", "Go back to home page.": "Go back to home page.", "No tags found.": "No tags found.", diff --git a/src/pages/EditMonitor.vue b/src/pages/EditMonitor.vue index 0d628895d..1b7af4184 100644 --- a/src/pages/EditMonitor.vue +++ b/src/pages/EditMonitor.vue @@ -1025,6 +1025,10 @@ +
    + + +
    + + From d490285a447c4401e9986f6dbed3995454042fb5 Mon Sep 17 00:00:00 2001 From: yumeiyin <155420652+yumeiyin@users.noreply.github.com> Date: Mon, 14 Jul 2025 16:08:53 +0800 Subject: [PATCH 43/43] chore: fix some minor issues in comments (#5984) Signed-off-by: yumeiyin --- server/model/monitor.js | 2 +- server/notification-providers/promosms.js | 2 +- server/socket-handlers/api-key-socket-handler.js | 2 +- server/uptime-calculator.js | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/server/model/monitor.js b/server/model/monitor.js index 3be8267c9..0ddfa924c 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -1314,7 +1314,7 @@ class Monitor extends BeanModel { /** * Send a notification about a monitor * @param {boolean} isFirstBeat Is this beat the first of this monitor? - * @param {Monitor} monitor The monitor to send a notificaton about + * @param {Monitor} monitor The monitor to send a notification about * @param {Bean} bean Status information about monitor * @returns {void} */ diff --git a/server/notification-providers/promosms.js b/server/notification-providers/promosms.js index 05334e902..36b7ecb33 100644 --- a/server/notification-providers/promosms.js +++ b/server/notification-providers/promosms.js @@ -15,7 +15,7 @@ class PromoSMS extends NotificationProvider { notification.promosmsAllowLongSMS = false; } - //TODO: Add option for enabling special characters. It will decrese message max length from 160 to 70 chars. + //TODO: Add option for enabling special characters. It will decrease message max length from 160 to 70 chars. //Lets remove non ascii char let cleanMsg = msg.replace(/[^\x00-\x7F]/g, ""); diff --git a/server/socket-handlers/api-key-socket-handler.js b/server/socket-handlers/api-key-socket-handler.js index d88151294..d49ac086b 100644 --- a/server/socket-handlers/api-key-socket-handler.js +++ b/server/socket-handlers/api-key-socket-handler.js @@ -27,7 +27,7 @@ module.exports.apiKeySocketHandler = (socket) => { log.debug("apikeys", "Added API Key"); log.debug("apikeys", key); - // Append key ID and prefix to start of key seperated by _, used to get + // Append key ID and prefix to start of key separated by _, used to get // correct hash when validating key. let formattedKey = "uk" + bean.id + "_" + clearKey; await sendAPIKeyList(socket); diff --git a/server/uptime-calculator.js b/server/uptime-calculator.js index 71d1d458c..48f7d80ae 100644 --- a/server/uptime-calculator.js +++ b/server/uptime-calculator.js @@ -582,7 +582,7 @@ class UptimeCalculator { let totalPing = 0; let endTimestamp; - // Get the eariest timestamp of the required period based on the type + // Get the earliest timestamp of the required period based on the type switch (type) { case "day": endTimestamp = key - 86400 * (num - 1); @@ -710,7 +710,7 @@ class UptimeCalculator { let endTimestamp; - // Get the eariest timestamp of the required period based on the type + // Get the earliest timestamp of the required period based on the type switch (type) { case "day": endTimestamp = key - 86400 * (num - 1);