diff --git a/.dockerignore b/.dockerignore index 4a63437a..4ce0e13a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -28,6 +28,8 @@ SECURITY.md tsconfig.json .env /tmp +/babel.config.js +/ecosystem.config.js ### .gitignore content (commented rules are duplicated) @@ -42,4 +44,6 @@ dist-ssr #!/data/.gitkeep #.vscode + + ### End of .gitignore content diff --git a/.eslintrc.js b/.eslintrc.js index b0934d6d..4dae1432 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,4 +1,9 @@ module.exports = { + ignorePatterns: [ + "test/*", + "server/modules/apicache/*", + "src/util.js" + ], root: true, env: { browser: true, @@ -17,39 +22,47 @@ module.exports = { requireConfigFile: false, }, rules: { - "linebreak-style": ["error", "unix"], - "camelcase": ["warn", { + "yoda": "error", + eqeqeq: [ "warn", "smart" ], + "linebreak-style": [ "error", "unix" ], + "camelcase": [ "warn", { "properties": "never", "ignoreImports": true }], - // override/add rules settings here, such as: - // 'vue/no-unused-vars': 'error' - "no-unused-vars": "warn", + "no-unused-vars": [ "warn", { + "args": "none" + }], indent: [ "error", 4, { - ignoredNodes: ["TemplateLiteral"], + ignoredNodes: [ "TemplateLiteral" ], SwitchCase: 1, }, ], - quotes: ["warn", "double"], - semi: "warn", - "vue/html-indent": ["warn", 4], // default: 2 + quotes: [ "warn", "double" ], + semi: "error", + "vue/html-indent": [ "warn", 4 ], // default: 2 "vue/max-attributes-per-line": "off", "vue/singleline-html-element-content-newline": "off", "vue/html-self-closing": "off", + "vue/require-component-is": "off", // not allow is="style" https://github.com/vuejs/eslint-plugin-vue/issues/462#issuecomment-430234675 "vue/attribute-hyphenation": "off", // This change noNL to "no-n-l" unexpectedly - "no-multi-spaces": ["error", { + "no-multi-spaces": [ "error", { ignoreEOLComments: true, }], - "space-before-function-paren": ["error", { + "array-bracket-spacing": [ "warn", "always", { + "singleValue": true, + "objectsInArrays": false, + "arraysInArrays": false + }], + "space-before-function-paren": [ "error", { "anonymous": "always", "named": "never", "asyncArrow": "always" }], "curly": "error", - "object-curly-spacing": ["error", "always"], + "object-curly-spacing": [ "error", "always" ], "object-curly-newline": "off", "object-property-newline": "error", "comma-spacing": "error", @@ -60,36 +73,36 @@ module.exports = { "space-infix-ops": "warn", "arrow-spacing": "warn", "no-trailing-spaces": "warn", - "no-constant-condition": ["error", { + "no-constant-condition": [ "error", { "checkLoops": false, }], "space-before-blocks": "warn", //'no-console': 'warn', "no-extra-boolean-cast": "off", - "no-multiple-empty-lines": ["warn", { + "no-multiple-empty-lines": [ "warn", { "max": 1, "maxBOF": 0, }], - "lines-between-class-members": ["warn", "always", { + "lines-between-class-members": [ "warn", "always", { exceptAfterSingleLine: true, }], "no-unneeded-ternary": "error", - "array-bracket-newline": ["error", "consistent"], - "eol-last": ["error", "always"], + "array-bracket-newline": [ "error", "consistent" ], + "eol-last": [ "error", "always" ], //'prefer-template': 'error', - "comma-dangle": ["warn", "only-multiline"], - "no-empty": ["error", { + "comma-dangle": [ "warn", "only-multiline" ], + "no-empty": [ "error", { "allowEmptyCatch": true }], "no-control-regex": "off", - "one-var": ["error", "never"], - "max-statements-per-line": ["error", { "max": 1 }] + "one-var": [ "error", "never" ], + "max-statements-per-line": [ "error", { "max": 1 }] }, "overrides": [ { "files": [ "src/languages/*.js", "src/icon.js" ], "rules": { - "comma-dangle": ["error", "always-multiline"], + "comma-dangle": [ "error", "always-multiline" ], } }, diff --git a/.github/workflows/auto-test.yml b/.github/workflows/auto-test.yml index e01c02ce..269e3085 100644 --- a/.github/workflows/auto-test.yml +++ b/.github/workflows/auto-test.yml @@ -20,6 +20,7 @@ jobs: # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: + - run: git config --global core.autocrlf false # Mainly for Windows - uses: actions/checkout@v2 - name: Use Node.js ${{ matrix.node-version }} diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000..521a9f7c --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +legacy-peer-deps=true diff --git a/.stylelintrc b/.stylelintrc index aad673db..52301b54 100644 --- a/.stylelintrc +++ b/.stylelintrc @@ -1,9 +1,13 @@ { "extends": "stylelint-config-standard", + "customSyntax": "postcss-html", "rules": { "indentation": 4, "no-descending-specificity": null, "selector-list-comma-newline-after": null, - "declaration-empty-line-before": null + "declaration-empty-line-before": null, + "alpha-value-notation": "number", + "color-function-notation": "legacy", + "shorthand-property-no-redundant-values": null } } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ff47b90b..1e6f7dfa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -44,6 +44,8 @@ My long story here: https://www.reddit.com/r/UptimeKuma/comments/t1t6or/comment/ ### Recommended Pull Request Guideline +Before deep into coding, disscussion first is preferred. Creating an empty pull request for disscussion would be recommended. + 1. Fork the project 1. Clone your fork repo to local 1. Create a new branch @@ -53,6 +55,7 @@ My long story here: https://www.reddit.com/r/UptimeKuma/comments/t1t6or/comment/ 1. Create a pull request: https://github.com/louislam/uptime-kuma/compare 1. Write a proper description 1. Click "Change to draft" +1. Discussion #### ❌ Won't Merge diff --git a/README.md b/README.md index 3d32ac8c..ae7566aa 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,6 @@ VPS is sponsored by Uptime Kuma sponsors on [Open Collective](https://opencollec ### 🐳 Docker ```bash -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 ``` @@ -47,7 +46,10 @@ Browse to http://localhost:3001 after starting. ### 💪🏻 Non-Docker -Required Tools: Node.js >= 14, git and pm2. +Required Tools: +- [Node.js](https://nodejs.org/en/download/) >= 14 +- [Git](https://git-scm.com/downloads) +- [pm2](https://pm2.keymetrics.io/) - For run in background ```bash # Update your npm to the latest version @@ -67,11 +69,19 @@ npm install pm2 -g && pm2 install pm2-logrotate # Start Server pm2 start server/server.js --name uptime-kuma + +``` +Browse to http://localhost:3001 after starting. + +More useful PM2 Commands + +```bash # If you want to see the current console output pm2 monit -``` -Browse to http://localhost:3001 after starting. +# If you want to add it to startup +pm2 save && pm2 startup +``` ### Advanced Installation @@ -99,7 +109,7 @@ https://github.com/louislam/uptime-kuma/projects/1 Thank you so much! (GitHub Sponsors will be updated manually. OpenCollective sponsors will be updated automatically, the list will be cached by GitHub though. It may need some time to be updated) - + ## 🖼 More Screenshots @@ -144,10 +154,17 @@ https://www.reddit.com/r/UptimeKuma/ ## Contribute +### Test Beta Version + +Check out the latest beta release here: https://github.com/louislam/uptime-kuma/releases + +### Bug Reports / Feature Requests If you want to report a bug or request a new feature. Free feel to open a [new issue](https://github.com/louislam/uptime-kuma/issues). +## Translations If you want to translate Uptime Kuma into your language, please read: https://github.com/louislam/uptime-kuma/tree/master/src/languages -If you want to modify Uptime Kuma, this guideline may be useful for you: https://github.com/louislam/uptime-kuma/blob/master/CONTRIBUTING.md +Feel free to correct my grammar in this README, source code, or wiki, as my mother language is not English and my grammar is not that great. -Unfortunately, English proofreading is needed too because my grammar is not that great. Feel free to correct my grammar in this README, source code, or wiki. +## Pull Requests +If you want to modify Uptime Kuma, this guideline may be useful for you: https://github.com/louislam/uptime-kuma/blob/master/CONTRIBUTING.md diff --git a/babel.config.js b/babel.config.js index d2ad8213..6bb8a01a 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,11 +1,11 @@ const config = {}; if (process.env.TEST_FRONTEND) { - config.presets = ["@babel/preset-env"]; + config.presets = [ "@babel/preset-env" ]; } if (process.env.TEST_BACKEND) { - config.plugins = ["babel-plugin-rewire"]; + config.plugins = [ "babel-plugin-rewire" ]; } module.exports = config; diff --git a/config/vite.config.js b/config/vite.config.js index a9701d42..9fdc5fab 100644 --- a/config/vite.config.js +++ b/config/vite.config.js @@ -10,15 +10,15 @@ export default defineConfig({ plugins: [ vue(), legacy({ - targets: ["ie > 11"], - additionalLegacyPolyfills: ["regenerator-runtime/runtime"] + targets: [ "ie > 11" ], + additionalLegacyPolyfills: [ "regenerator-runtime/runtime" ] }) ], css: { postcss: { "parser": postCssScss, "map": false, - "plugins": [postcssRTLCSS] + "plugins": [ postcssRTLCSS ] } }, }); diff --git a/db/patch-added-mqtt-monitor.sql b/db/patch-added-mqtt-monitor.sql new file mode 100644 index 00000000..02b0b09d --- /dev/null +++ b/db/patch-added-mqtt-monitor.sql @@ -0,0 +1,16 @@ +-- You should not modify if this have pushed to Github, unless it does serious wrong with the db. +BEGIN TRANSACTION; + +ALTER TABLE monitor + ADD mqtt_topic TEXT; + +ALTER TABLE monitor + ADD mqtt_success_message VARCHAR(255); + +ALTER TABLE monitor + ADD mqtt_username VARCHAR(255); + +ALTER TABLE monitor + ADD mqtt_password VARCHAR(255); + +COMMIT; diff --git a/db/patch-monitor-expiry-notification.sql b/db/patch-monitor-expiry-notification.sql new file mode 100644 index 00000000..7a330014 --- /dev/null +++ b/db/patch-monitor-expiry-notification.sql @@ -0,0 +1,7 @@ +-- You should not modify if this have pushed to Github, unless it does serious wrong with the db. +BEGIN TRANSACTION; + +ALTER TABLE monitor + ADD expiry_notification BOOLEAN default 1; + +COMMIT; diff --git a/db/patch-proxy.sql b/db/patch-proxy.sql new file mode 100644 index 00000000..41897b1e --- /dev/null +++ b/db/patch-proxy.sql @@ -0,0 +1,23 @@ +-- You should not modify if this have pushed to Github, unless it does serious wrong with the db. +BEGIN TRANSACTION; + +CREATE TABLE proxy ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + user_id INT NOT NULL, + protocol VARCHAR(10) NOT NULL, + host VARCHAR(255) NOT NULL, + port SMALLINT NOT NULL, + auth BOOLEAN NOT NULL, + username VARCHAR(255) NULL, + password VARCHAR(255) NULL, + active BOOLEAN NOT NULL DEFAULT 1, + 'default' BOOLEAN NOT NULL DEFAULT 0, + created_date DATETIME DEFAULT (DATETIME('now')) NOT NULL +); + +ALTER TABLE monitor ADD COLUMN proxy_id INTEGER REFERENCES proxy(id); + +CREATE INDEX proxy_id ON monitor (proxy_id); +CREATE INDEX proxy_user_id ON proxy (user_id); + +COMMIT; diff --git a/db/patch-status-page-footer-css.sql b/db/patch-status-page-footer-css.sql new file mode 100644 index 00000000..413918f1 --- /dev/null +++ b/db/patch-status-page-footer-css.sql @@ -0,0 +1,6 @@ +-- You should not modify if this have pushed to Github, unless it does serious wrong with the db. +BEGIN TRANSACTION; +ALTER TABLE status_page ADD footer_text TEXT; +ALTER TABLE status_page ADD custom_css TEXT; +ALTER TABLE status_page ADD show_powered_by BOOLEAN NOT NULL DEFAULT 1; +COMMIT; diff --git a/docker/debian-base.dockerfile b/docker/debian-base.dockerfile index 9a8c759b..62889dc9 100644 --- a/docker/debian-base.dockerfile +++ b/docker/debian-base.dockerfile @@ -1,8 +1,11 @@ # DON'T UPDATE TO node:14-bullseye-slim, see #372. # If the image changed, the second stage image should be changed too FROM node:16-buster-slim +ARG TARGETPLATFORM + WORKDIR /app +# Install Curl # Install Apprise, add sqlite3 cli for debugging in the future, iputils-ping for ping, util-linux for setpriv # Stupid python3 and python3-pip actually install a lot of useless things into Debian, specify --no-install-recommends to skip them, make the base even smaller than alpine! RUN apt update && \ @@ -10,3 +13,14 @@ RUN apt update && \ sqlite3 iputils-ping util-linux dumb-init && \ pip3 --no-cache-dir install apprise==0.9.7 && \ rm -rf /var/lib/apt/lists/* + +# Install cloudflared +# dpkg --add-architecture arm: cloudflared do not provide armhf, this is workaround. Read more: https://github.com/cloudflare/cloudflared/issues/583 +COPY extra/download-cloudflared.js ./extra/download-cloudflared.js +RUN node ./extra/download-cloudflared.js $TARGETPLATFORM && \ + dpkg --add-architecture arm && \ + apt update && \ + apt --yes --no-install-recommends install ./cloudflared.deb && \ + rm -rf /var/lib/apt/lists/* && \ + rm -f cloudflared.deb + diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index ba22bd24..a6499ef9 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -5,9 +5,10 @@ version: '3.3' services: uptime-kuma: - image: louislam/uptime-kuma + image: louislam/uptime-kuma:1 container_name: uptime-kuma volumes: - ./uptime-kuma:/app/data ports: - 3001:3001 + restart: always diff --git a/ecosystem.config.js b/ecosystem.config.js index 5f403400..bff3451f 100644 --- a/ecosystem.config.js +++ b/ecosystem.config.js @@ -1,6 +1,6 @@ module.exports = { - apps: [{ - name: "uptime-kuma", - script: "./server/server.js", - }] -} + apps: [{ + name: "uptime-kuma", + script: "./server/server.js", + }] +}; diff --git a/extra/beta/update-version.js b/extra/beta/update-version.js index aa75562d..b8de95df 100644 --- a/extra/beta/update-version.js +++ b/extra/beta/update-version.js @@ -1,20 +1,14 @@ const pkg = require("../../package.json"); const fs = require("fs"); -const child_process = require("child_process"); +const childProcess = require("child_process"); const util = require("../../src/util"); util.polyfill(); -const oldVersion = pkg.version; const version = process.env.VERSION; console.log("Beta Version: " + version); -if (!oldVersion || oldVersion.includes("-beta.")) { - console.error("Error: old version should not be a beta version?"); - process.exit(1); -} - if (!version || !version.includes("-beta.")) { console.error("invalid version, beta version only"); process.exit(1); @@ -37,7 +31,7 @@ if (! exists) { function commit(version) { let msg = "Update to " + version; - let res = child_process.spawnSync("git", ["commit", "-m", msg, "-a"]); + let res = childProcess.spawnSync("git", [ "commit", "-m", msg, "-a" ]); let stdout = res.stdout.toString().trim(); console.log(stdout); @@ -45,15 +39,15 @@ function commit(version) { throw new Error("commit error"); } - res = child_process.spawnSync("git", ["push", "origin", "master"]); + res = childProcess.spawnSync("git", [ "push", "origin", "master" ]); console.log(res.stdout.toString().trim()); } function tag(version) { - let res = child_process.spawnSync("git", ["tag", version]); + let res = childProcess.spawnSync("git", [ "tag", version ]); console.log(res.stdout.toString().trim()); - res = child_process.spawnSync("git", ["push", "origin", version]); + res = childProcess.spawnSync("git", [ "push", "origin", version ]); console.log(res.stdout.toString().trim()); } @@ -62,15 +56,7 @@ function tagExists(version) { throw new Error("invalid version"); } - let res = child_process.spawnSync("git", ["tag", "-l", version]); + let res = childProcess.spawnSync("git", [ "tag", "-l", version ]); return res.stdout.toString().trim() === version; } - -function safeDelete(dir) { - if (fs.existsSync(dir)) { - fs.rmdirSync(dir, { - recursive: true, - }); - } -} diff --git a/extra/close-incorrect-issue.js b/extra/close-incorrect-issue.js index a15a5da3..ae38bccc 100644 --- a/extra/close-incorrect-issue.js +++ b/extra/close-incorrect-issue.js @@ -29,7 +29,7 @@ const github = require("@actions/github"); owner: issue.owner, repo: issue.repo, issue_number: issue.number, - labels: ["invalid-format"] + labels: [ "invalid-format" ] }); // Add the issue closing comment diff --git a/extra/download-cloudflared.js b/extra/download-cloudflared.js new file mode 100644 index 00000000..41519b7c --- /dev/null +++ b/extra/download-cloudflared.js @@ -0,0 +1,44 @@ +// + +const http = require("https"); // or 'https' for https:// URLs +const fs = require("fs"); + +const platform = process.argv[2]; + +if (!platform) { + console.error("No platform??"); + process.exit(1); +} + +let arch = null; + +if (platform === "linux/amd64") { + arch = "amd64"; +} else if (platform === "linux/arm64") { + arch = "arm64"; +} else if (platform === "linux/arm/v7") { + arch = "arm"; +} else { + console.error("Invalid platform?? " + platform); +} + +const file = fs.createWriteStream("cloudflared.deb"); +get("https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-" + arch + ".deb"); + +function get(url) { + http.get(url, function (res) { + if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) { + console.log("Redirect to " + res.headers.location); + get(res.headers.location); + } else if (res.statusCode >= 200 && res.statusCode < 300) { + res.pipe(file); + + res.on("end", function () { + console.log("Downloaded"); + }); + } else { + console.error(res.statusCode); + process.exit(1); + } + }); +} diff --git a/extra/download-dist.js b/extra/download-dist.js index dc64166c..b04beec7 100644 --- a/extra/download-dist.js +++ b/extra/download-dist.js @@ -4,6 +4,7 @@ const tar = require("tar"); const packageJSON = require("../package.json"); const fs = require("fs"); +const rmSync = require("./fs-rmSync.js"); const version = packageJSON.version; const filename = "dist.tar.gz"; @@ -11,6 +12,12 @@ const filename = "dist.tar.gz"; const url = `https://github.com/louislam/uptime-kuma/releases/download/${version}/${filename}`; download(url); +/** + * Downloads the latest version of the dist from a GitHub release. + * @param {string} url The URL to download from. + * + * Generated by Trelent + */ function download(url) { console.log(url); @@ -21,7 +28,7 @@ function download(url) { if (fs.existsSync("./dist")) { if (fs.existsSync("./dist-backup")) { - fs.rmdirSync("./dist-backup", { + rmSync("./dist-backup", { recursive: true }); } @@ -35,7 +42,7 @@ function download(url) { tarStream.on("close", () => { if (fs.existsSync("./dist-backup")) { - fs.rmdirSync("./dist-backup", { + rmSync("./dist-backup", { recursive: true }); } diff --git a/extra/fs-rmSync.js b/extra/fs-rmSync.js new file mode 100644 index 00000000..aa45b6dc --- /dev/null +++ b/extra/fs-rmSync.js @@ -0,0 +1,23 @@ +const fs = require("fs"); +/** + * Detect if `fs.rmSync` is available + * to avoid the runtime deprecation warning triggered for using `fs.rmdirSync` with `{ recursive: true }` in Node.js v16, + * or the `recursive` property removing completely in the future Node.js version. + * See the link below. + * + * @todo Once we drop the support for Node.js v14 (or at least versions before v14.14.0), we can safely replace this function with `fs.rmSync`, since `fs.rmSync` was add in Node.js v14.14.0 and currently we supports all the Node.js v14 versions that include the versions before the v14.14.0, and this function have almost the same signature with `fs.rmSync`. + * @link https://nodejs.org/docs/latest-v16.x/api/deprecations.html#dep0147-fsrmdirpath--recursive-true- the deprecation infomation of `fs.rmdirSync` + * @link https://nodejs.org/docs/latest-v16.x/api/fs.html#fsrmsyncpath-options the document of `fs.rmSync` + * @param {fs.PathLike} path Valid types for path values in "fs". + * @param {fs.RmDirOptions} [options] options for `fs.rmdirSync`, if `fs.rmSync` is available and property `recursive` is true, it will automatically have property `force` with value `true`. + */ +const rmSync = (path, options) => { + if (typeof fs.rmSync === "function") { + if (options.recursive) { + options.force = true; + } + return fs.rmSync(path, options); + } + return fs.rmdirSync(path, options); +}; +module.exports = rmSync; diff --git a/extra/mark-as-nightly.js b/extra/mark-as-nightly.js index 0316596b..a55fd98f 100644 --- a/extra/mark-as-nightly.js +++ b/extra/mark-as-nightly.js @@ -4,21 +4,21 @@ const util = require("../src/util"); util.polyfill(); -const oldVersion = pkg.version -const newVersion = oldVersion + "-nightly" +const oldVersion = pkg.version; +const newVersion = oldVersion + "-nightly"; -console.log("Old Version: " + oldVersion) -console.log("New Version: " + newVersion) +console.log("Old Version: " + oldVersion); +console.log("New Version: " + newVersion); if (newVersion) { // Process package.json - pkg.version = newVersion - pkg.scripts.setup = pkg.scripts.setup.replaceAll(oldVersion, newVersion) - pkg.scripts["build-docker"] = pkg.scripts["build-docker"].replaceAll(oldVersion, newVersion) - fs.writeFileSync("package.json", JSON.stringify(pkg, null, 4) + "\n") + pkg.version = newVersion; + pkg.scripts.setup = pkg.scripts.setup.replaceAll(oldVersion, newVersion); + pkg.scripts["build-docker"] = pkg.scripts["build-docker"].replaceAll(oldVersion, newVersion); + fs.writeFileSync("package.json", JSON.stringify(pkg, null, 4) + "\n"); // Process README.md if (fs.existsSync("README.md")) { - fs.writeFileSync("README.md", fs.readFileSync("README.md", "utf8").replaceAll(oldVersion, newVersion)) + fs.writeFileSync("README.md", fs.readFileSync("README.md", "utf8").replaceAll(oldVersion, newVersion)); } } diff --git a/extra/reset-password.js b/extra/reset-password.js index 1b48dffd..8036a456 100644 --- a/extra/reset-password.js +++ b/extra/reset-password.js @@ -1,11 +1,10 @@ console.log("== Uptime Kuma Reset Password Tool =="); -console.log("Loading the database"); - const Database = require("../server/database"); const { R } = require("redbean-node"); const readline = require("readline"); const { initJWTSecret } = require("../server/util-server"); +const User = require("../server/model/user"); const args = require("args-parser")(process.argv); const rl = readline.createInterface({ input: process.stdin, @@ -13,8 +12,9 @@ const rl = readline.createInterface({ }); const main = async () => { + console.log("Connecting the database"); Database.init(args); - await Database.connect(); + await Database.connect(false, false, true); try { // No need to actually reset the password for testing, just make sure no connection problem. It is ok for now. @@ -31,7 +31,7 @@ const main = async () => { let confirmPassword = await question("Confirm New Password: "); if (password === confirmPassword) { - await user.resetPassword(password); + await User.resetPassword(user.id, password); // Reset all sessions by reset jwt secret await initJWTSecret(); diff --git a/extra/simple-dns-server.js b/extra/simple-dns-server.js index 5e5745f0..376dbdd0 100644 --- a/extra/simple-dns-server.js +++ b/extra/simple-dns-server.js @@ -26,7 +26,7 @@ server.on("request", (request, send, rinfo) => { ttl: 300, address: "1.2.3.4" }); - } if (question.type === Packet.TYPE.AAAA) { + } else if (question.type === Packet.TYPE.AAAA) { response.answers.push({ name: question.name, type: question.type, diff --git a/extra/simple-mqtt-server.js b/extra/simple-mqtt-server.js new file mode 100644 index 00000000..238d2772 --- /dev/null +++ b/extra/simple-mqtt-server.js @@ -0,0 +1,50 @@ +const { log } = require("../src/util"); + +const mqttUsername = "louis1"; +const mqttPassword = "!@#$LLam"; + +class SimpleMqttServer { + aedes = require("aedes")(); + server = require("net").createServer(this.aedes.handle); + + constructor(port) { + this.port = port; + } + + start() { + this.server.listen(this.port, () => { + console.log("server started and listening on port ", this.port); + }); + } +} + +let server1 = new SimpleMqttServer(10000); + +server1.aedes.authenticate = function (client, username, password, callback) { + if (username && password) { + console.log(password.toString("utf-8")); + callback(null, username === mqttUsername && password.toString("utf-8") === mqttPassword); + } else { + callback(null, false); + } +}; + +server1.aedes.on("subscribe", (subscriptions, client) => { + console.log(subscriptions); + + for (let s of subscriptions) { + if (s.topic === "test") { + server1.aedes.publish({ + topic: "test", + payload: Buffer.from("ok"), + }, (error) => { + if (error) { + log.error("mqtt_server", error); + } + }); + } + } + +}); + +server1.start(); diff --git a/extra/update-language-files/index.js b/extra/update-language-files/index.js index 7ba30cc0..e449fe34 100644 --- a/extra/update-language-files/index.js +++ b/extra/update-language-files/index.js @@ -3,6 +3,7 @@ import fs from "fs"; import path from "path"; import util from "util"; +import rmSync from "../fs-rmSync.js"; // https://stackoverflow.com/questions/13786160/copy-folder-recursively-in-node-js /** @@ -30,7 +31,7 @@ console.log("Arguments:", process.argv); const baseLangCode = process.argv[2] || "en"; console.log("Base Lang: " + baseLangCode); if (fs.existsSync("./languages")) { - fs.rmdirSync("./languages", { recursive: true }); + rmSync("./languages", { recursive: true }); } copyRecursiveSync("../../src/languages", "./languages"); @@ -40,7 +41,7 @@ const files = fs.readdirSync("./languages"); console.log("Files:", files); for (const file of files) { - if (!file.endsWith(".js")) { + if (! file.endsWith(".js")) { console.log("Skipping " + file); continue; } @@ -82,5 +83,5 @@ for (const file of files) { fs.writeFileSync(`../../src/languages/${file}`, code); } -fs.rmdirSync("./languages", { recursive: true }); +rmSync("./languages", { recursive: true }); console.log("Done. Fixing formatting by ESLint..."); diff --git a/extra/update-version.js b/extra/update-version.js index 8f3562a5..f17ad200 100644 --- a/extra/update-version.js +++ b/extra/update-version.js @@ -1,6 +1,6 @@ const pkg = require("../package.json"); const fs = require("fs"); -const child_process = require("child_process"); +const childProcess = require("child_process"); const util = require("../src/util"); util.polyfill(); @@ -32,10 +32,16 @@ if (! exists) { console.log("version exists"); } +/** + * Updates the version number in package.json and commits it to git. + * @param {string} version - The new version number + * + * Generated by Trelent + */ function commit(version) { let msg = "Update to " + version; - let res = child_process.spawnSync("git", ["commit", "-m", msg, "-a"]); + let res = childProcess.spawnSync("git", [ "commit", "-m", msg, "-a" ]); let stdout = res.stdout.toString().trim(); console.log(stdout); @@ -45,17 +51,22 @@ function commit(version) { } function tag(version) { - let res = child_process.spawnSync("git", ["tag", version]); + let res = childProcess.spawnSync("git", [ "tag", version ]); console.log(res.stdout.toString().trim()); } +/** + * Checks if a given version is already tagged in the git repository. + * @param {string} version - The version to check for. + * + * Generated by Trelent + */ function tagExists(version) { if (! version) { throw new Error("invalid version"); } - let res = child_process.spawnSync("git", ["tag", "-l", version]); + let res = childProcess.spawnSync("git", [ "tag", "-l", version ]); return res.stdout.toString().trim() === version; } - diff --git a/extra/update-wiki-version.js b/extra/update-wiki-version.js index 10631c33..d0f10561 100644 --- a/extra/update-wiki-version.js +++ b/extra/update-wiki-version.js @@ -1,4 +1,4 @@ -const child_process = require("child_process"); +const childProcess = require("child_process"); const fs = require("fs"); const newVersion = process.env.VERSION; @@ -16,23 +16,23 @@ function updateWiki(newVersion) { safeDelete(wikiDir); - child_process.spawnSync("git", ["clone", "https://github.com/louislam/uptime-kuma.wiki.git", wikiDir]); + childProcess.spawnSync("git", [ "clone", "https://github.com/louislam/uptime-kuma.wiki.git", wikiDir ]); let content = fs.readFileSync(howToUpdateFilename).toString(); // Replace the version: https://regex101.com/r/hmj2Bc/1 content = content.replace(/(git checkout )([^\s]+)/, `$1${newVersion}`); fs.writeFileSync(howToUpdateFilename, content); - child_process.spawnSync("git", ["add", "-A"], { + childProcess.spawnSync("git", [ "add", "-A" ], { cwd: wikiDir, }); - child_process.spawnSync("git", ["commit", "-m", `Update to ${newVersion}`], { + childProcess.spawnSync("git", [ "commit", "-m", `Update to ${newVersion}` ], { cwd: wikiDir, }); console.log("Pushing to Github"); - child_process.spawnSync("git", ["push"], { + childProcess.spawnSync("git", [ "push" ], { cwd: wikiDir, }); diff --git a/package-lock.json b/package-lock.json index 1d30ce07..e581fd54 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,19 @@ { "name": "uptime-kuma", - "version": "1.12.1", + "version": "1.15.0-beta.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "uptime-kuma", - "version": "1.12.1", + "version": "1.15.0-beta.0", "license": "MIT", "dependencies": { "@fortawesome/fontawesome-svg-core": "~1.2.36", "@fortawesome/free-regular-svg-icons": "~5.15.4", "@fortawesome/free-solid-svg-icons": "~5.15.4", "@fortawesome/vue-fontawesome": "~3.0.0-5", - "@louislam/sqlite3": "~6.0.1", + "@louislam/sqlite3": "~15.0.3", "@popperjs/core": "~2.10.2", "args-parser": "~1.3.0", "axios": "~0.26.1", @@ -32,21 +32,27 @@ "favico.js": "^0.3.10", "form-data": "~4.0.0", "http-graceful-shutdown": "~3.1.7", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", "iconv-lite": "^0.6.3", "jsonwebtoken": "~8.5.1", "jwt-decode": "^3.1.2", "limiter": "^2.1.0", + "mqtt": "^4.2.8", + "node-cloudflared-tunnel": "~1.0.9", "nodemailer": "~6.6.5", "notp": "~2.0.3", "password-hash": "~1.2.2", "postcss-rtlcss": "~3.4.1", "postcss-scss": "~4.0.3", + "prismjs": "^1.27.0", "prom-client": "~13.2.0", "prometheus-api-metrics": "~3.2.1", "qrcode": "~1.5.0", "redbean-node": "0.1.3", "socket.io": "~4.4.1", "socket.io-client": "~4.4.1", + "socks-proxy-agent": "^6.1.1", "tar": "^6.1.11", "tcp-ping": "~0.1.1", "thirty-two": "~1.0.2", @@ -59,19 +65,21 @@ "vue-i18n": "~9.1.9", "vue-image-crop-upload": "~3.0.3", "vue-multiselect": "~3.0.0-alpha.2", + "vue-prism-editor": "^2.0.0-alpha.2", "vue-qrcode": "~1.0.0", "vue-router": "~4.0.14", "vue-toastification": "~2.0.0-rc.5", "vuedraggable": "~4.1.0" }, "devDependencies": { - "@actions/github": "~5.0.0", + "@actions/github": "~5.0.1", "@babel/eslint-parser": "~7.15.8", "@babel/preset-env": "^7.15.8", "@types/bootstrap": "~5.1.9", "@vitejs/plugin-legacy": "~1.6.4", "@vitejs/plugin-vue": "~1.9.4", "@vue/compiler-sfc": "~3.2.31", + "aedes": "^0.46.3", "babel-plugin-rewire": "~1.2.0", "core-js": "~3.18.3", "cross-env": "~7.0.3", @@ -80,7 +88,8 @@ "eslint-plugin-vue": "~7.18.0", "jest": "~27.2.5", "jest-puppeteer": "~6.0.3", - "npm-check-updates": "^12.5.4", + "npm-check-updates": "^12.5.5", + "postcss-html": "^1.3.1", "puppeteer": "~13.1.3", "sass": "~1.42.1", "stylelint": "~14.2.0", @@ -93,15 +102,15 @@ } }, "node_modules/@actions/github": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.0.tgz", - "integrity": "sha512-QvE9eAAfEsS+yOOk0cylLBIO/d6WyWIOvsxxzdrPFaud39G6BOkUwScXZn1iBzQzHyu9SBkkLSWlohDWdsasAQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.1.tgz", + "integrity": "sha512-JZGyPM9ektb8NVTTI/2gfJ9DL7Rk98tQ7OVyTlgTuaQroariRBsOnzjy0I2EarX4xUZpK88YyO503fhmjFdyAg==", "dev": true, "dependencies": { "@actions/http-client": "^1.0.11", - "@octokit/core": "^3.4.0", - "@octokit/plugin-paginate-rest": "^2.13.3", - "@octokit/plugin-rest-endpoint-methods": "^5.1.1" + "@octokit/core": "^3.6.0", + "@octokit/plugin-paginate-rest": "^2.17.0", + "@octokit/plugin-rest-endpoint-methods": "^5.13.0" } }, "node_modules/@actions/http-client": { @@ -1864,7 +1873,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "devOptional": true + "dev": true }, "node_modules/@hapi/hoek": { "version": "9.2.1", @@ -2668,19 +2677,20 @@ } }, "node_modules/@louislam/sqlite3": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@louislam/sqlite3/-/sqlite3-6.0.1.tgz", - "integrity": "sha512-QGLj5bjQ+O4YSPj/qxtEAArbIqW9wNzBUamlIcRbvFjFiNokItwdubqL2Gl5iX0q1mUn3Z6NoFO1rrAZ/qqlsA==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@louislam/sqlite3/-/sqlite3-15.0.3.tgz", + "integrity": "sha512-rCH6PIaa+TgBzpTRnqBKUa4H/5G2hIk5ukYK5rXxK+8hVGykRin3UMGzGejrPzIKzDnZGByIF0XD4ndi6lprRQ==", "hasInstallScript": true, "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.7", - "node-addon-api": "^3.0.0" + "@mapbox/node-pre-gyp": "^1.0.0", + "node-addon-api": "^4.2.0", + "tar": "^6.1.11" }, "optionalDependencies": { - "node-gyp": "^8.4.1" + "node-gyp": "^7.1.2" }, "peerDependencies": { - "node-gyp": "8.x" + "node-gyp": "7.x" }, "peerDependenciesMeta": { "node-gyp": { @@ -2689,14 +2699,14 @@ } }, "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.8.tgz", - "integrity": "sha512-CMGKi28CF+qlbXh26hDe6NxCd7amqeAzEqnS6IHeO6LoaKyM/n+Xw3HT1COdq8cuioOdlKdqn/hCmqPUOMOywg==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz", + "integrity": "sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==", "dependencies": { - "detect-libc": "^1.0.3", + "detect-libc": "^2.0.0", "https-proxy-agent": "^5.0.0", "make-dir": "^3.1.0", - "node-fetch": "^2.6.5", + "node-fetch": "^2.6.7", "nopt": "^5.0.0", "npmlog": "^5.0.1", "rimraf": "^3.0.2", @@ -2756,31 +2766,6 @@ "node": ">= 8" } }, - "node_modules/@npmcli/fs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", - "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", - "devOptional": true, - "dependencies": { - "@gar/promisify": "^1.0.1", - "semver": "^7.3.5" - } - }, - "node_modules/@npmcli/fs/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "devOptional": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@npmcli/git": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-3.0.0.tgz", @@ -2802,9 +2787,9 @@ } }, "node_modules/@npmcli/git/node_modules/lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", "dev": true, "engines": { "node": ">=12" @@ -2857,7 +2842,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", - "devOptional": true, + "dev": true, "dependencies": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" @@ -2896,13 +2881,17 @@ "node": "^12.13.0 || ^14.15.0 || >=16" } }, - "node_modules/@npmcli/run-script/node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "node_modules/@npmcli/run-script/node_modules/@npmcli/fs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.0.tgz", + "integrity": "sha512-DmfBvNXGaetMxj9LTp8NAN9vEidXURrf5ZTslQzEAi/6GbW+4yjaLFQc6Tue5cpZ9Frlk4OBo/Snf1Bh/S7qTQ==", "dev": true, + "dependencies": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + }, "engines": { - "node": ">= 10" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/@npmcli/run-script/node_modules/are-we-there-yet": { @@ -2919,18 +2908,18 @@ } }, "node_modules/@npmcli/run-script/node_modules/cacache": { - "version": "16.0.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.2.tgz", - "integrity": "sha512-Q17j7s8X81i/QYVrKVQ/qwWGT+pYLfpTcZ+X+p/Qw9FULy9JEfb2FECYTTt6mPV6A/vk92nRZ80ncpKxiGTrIA==", + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.3.tgz", + "integrity": "sha512-eC7wYodNCVb97kuHGk5P+xZsvUJHkhSEOyNwkenqQPAsOtrTjvWOE5vSPNBpz9d8X3acIf6w2Ub5s4rvOCTs4g==", "dev": true, "dependencies": { - "@npmcli/fs": "^1.0.0", + "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^1.1.2", "chownr": "^2.0.0", "fs-minipass": "^2.1.0", "glob": "^7.2.0", "infer-owner": "^1.0.4", - "lru-cache": "^7.5.1", + "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", @@ -2944,22 +2933,22 @@ "unique-filename": "^1.1.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/@npmcli/run-script/node_modules/cacache/node_modules/lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", "dev": true, "engines": { "node": ">=12" } }, "node_modules/@npmcli/run-script/node_modules/gauge": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.3.tgz", - "integrity": "sha512-ICw1DhAwMtb22rYFwEHgJcx1JCwJGv3x6G0OQUq56Nge+H4Q8JEwr8iveS0XFlsUNSI67F5ffMGK25bK4Pmskw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", "dev": true, "dependencies": { "aproba": "^1.0.3 || ^2.0.0", @@ -2972,36 +2961,22 @@ "wide-align": "^1.1.5" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" - } - }, - "node_modules/@npmcli/run-script/node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/@npmcli/run-script/node_modules/make-fetch-happen": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.0.6.tgz", - "integrity": "sha512-4Gfh6lV3TLXmj7qz79hBFuvVqjYSMW6v2+sxtdX4LFQU0rK3V/txRjE0DoZb7X0IF3t9f8NO3CxPSWlvdckhVA==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.1.1.tgz", + "integrity": "sha512-3/mCljDQNjmrP7kl0vhS5WVlV+TvSKoZaFhdiYV7MOijEnrhrjaVnqbp/EY/7S+fhUB2KpH7j8c1iRsIOs+kjw==", "dev": true, "dependencies": { "agentkeepalive": "^4.2.1", - "cacache": "^16.0.0", + "cacache": "^16.0.2", "http-cache-semantics": "^4.1.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", - "lru-cache": "^7.5.1", + "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-fetch": "^2.0.3", @@ -3013,22 +2988,22 @@ "ssri": "^8.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/@npmcli/run-script/node_modules/make-fetch-happen/node_modules/lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", "dev": true, "engines": { "node": ">=12" } }, "node_modules/@npmcli/run-script/node_modules/minipass-fetch": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.0.3.tgz", - "integrity": "sha512-VA+eiiUtaIvpQJXISwE3OiMvQwAWrgKb97F0aXlCS1Ahikr8fEQq8m3Hf7Kv9KT3nokuHigJKsDMB6atU04olQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.0.tgz", + "integrity": "sha512-H9U4UVBGXEyyWJnqYDCLp1PwD8XIkJ4akNHp1aGVI+2Ym7wQMlxDKi4IB4JbmyU+pl9pEs/cVrK6cOuvmbK4Sg==", "dev": true, "dependencies": { "minipass": "^3.1.6", @@ -3036,7 +3011,7 @@ "minizlib": "^2.1.2" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" }, "optionalDependencies": { "encoding": "^0.1.13" @@ -3217,9 +3192,9 @@ } }, "node_modules/@sideway/address": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.3.tgz", - "integrity": "sha512-8ncEUtmnTsMmL7z1YPB47kPUq7LpKWJNFPsRzHiIajGC5uXlWGn+AmkYPcHNl8S4tcEGx+cnORnNYaw2wvL+LQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", + "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", "dev": true, "dependencies": { "@hapi/hoek": "^9.0.0" @@ -3290,12 +3265,11 @@ } }, "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "devOptional": true, + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "engines": { - "node": ">= 6" + "node": ">= 10" } }, "node_modules/@types/accepts": { @@ -3507,9 +3481,9 @@ } }, "node_modules/@types/lodash": { - "version": "4.14.180", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.180.tgz", - "integrity": "sha512-XOKXa1KIxtNXgASAnwj7cnttJxS4fksBRywK/9LzRV5YxrF80BXZIGeQSuoESQ/VkUj30Ae0+YcuHc15wJCB2g==" + "version": "4.14.181", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.181.tgz", + "integrity": "sha512-n3tyKthHJbkiWhDZs3DkhkCzt2MexYHXlX0td5iMplyfwketaOeKboEVBqzceH7juqvEg3q5oUoBFxSLu7zFag==" }, "node_modules/@types/mime": { "version": "1.3.2", @@ -3523,9 +3497,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "17.0.22", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.22.tgz", - "integrity": "sha512-8FwbVoG4fy+ykY86XCAclKZDORttqE5/s7dyWZKLXTdv3vRy5HozBEinG5IqhvPXXzIZEcTVbuHlQEI6iuwcmw==" + "version": "17.0.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", + "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", @@ -3706,9 +3680,9 @@ } }, "node_modules/@vue/devtools-api": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.1.3.tgz", - "integrity": "sha512-79InfO2xHv+WHIrH1bHXQUiQD/wMls9qBk6WVwGCbdwP7/3zINtvqPNMtmSHXsIKjvUAHc8L0ouOj6ZQQRmcXg==" + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.1.4.tgz", + "integrity": "sha512-IiA0SvDrJEgXvVxjNkHPFfDx6SXw0b/TUkqMcDZWNg9fnCAHbTpoo59YfJ9QLFkwa3raau5vSlRVzMSLDnfdtQ==" }, "node_modules/@vue/reactivity": { "version": "3.2.31", @@ -3829,6 +3803,68 @@ "node": ">=0.4.0" } }, + "node_modules/aedes": { + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/aedes/-/aedes-0.46.3.tgz", + "integrity": "sha512-i3B+H74uNRhlqcs/JdrMp7e3daz4Cwls0x4yLcfjGXz2tIwnxhF6od4m86O6yyNdz/Gg3jfY3q0sc/Cz8qzg6g==", + "dev": true, + "dependencies": { + "aedes-packet": "^2.3.1", + "aedes-persistence": "^8.1.3", + "bulk-write-stream": "^2.0.1", + "end-of-stream": "^1.4.4", + "fastfall": "^1.5.1", + "fastparallel": "^2.4.1", + "fastseries": "^2.0.0", + "hyperid": "^3.0.0", + "mqemitter": "^4.5.0", + "mqtt-packet": "^7.1.2", + "readable-stream": "^3.6.0", + "retimer": "^3.0.0", + "reusify": "^1.0.4", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/aedes-packet": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/aedes-packet/-/aedes-packet-2.3.1.tgz", + "integrity": "sha512-LqBd57uc2rui2RbjycW17dylglejG26mM4ewVXGNDnVp/SUHFVEgm7d1HTmYrnSkSCNoHti042qgcTwv/F+BtQ==", + "dev": true, + "dependencies": { + "mqtt-packet": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/aedes-persistence": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/aedes-persistence/-/aedes-persistence-8.1.3.tgz", + "integrity": "sha512-VMCjEV+2g1TNJb/IlDEUy6SP9crT+QUhe2xc6UjyqrFNBNgTvHmOefXY7FxWrwmR2QA02vwg3+5p/JXkyg/Dkw==", + "dev": true, + "dependencies": { + "aedes-packet": "^2.3.1", + "from2": "^2.3.0", + "qlobber": "^5.0.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/aedes/node_modules/mqtt-packet": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-7.1.2.tgz", + "integrity": "sha512-FFZbcZ2omsf4c5TxEQfcX9hI+JzDpDKPT46OmeIBpVA7+t32ey25UNqlqNXTmeZOr5BLsSIERpQQLsFWJS94SQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.2", + "debug": "^4.1.1", + "process-nextick-args": "^2.0.1" + } + }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -3844,7 +3880,7 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz", "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==", - "devOptional": true, + "dev": true, "dependencies": { "debug": "^4.1.0", "depd": "^1.1.2", @@ -3858,7 +3894,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "devOptional": true, + "dev": true, "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -3871,7 +3907,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, + "devOptional": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -4012,6 +4048,24 @@ "node": ">=0.10.0" } }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "optional": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "optional": true, + "engines": { + "node": ">=0.8" + } + }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -4031,6 +4085,21 @@ "resolved": "https://registry.npmjs.org/await-lock/-/await-lock-2.1.0.tgz", "integrity": "sha512-t7Zm5YGgEEc/3eYAicF32m/TNvL+XOeYZy9CvBUeJY/szM7frLolFylhrlZNWV/ohWhcUXygrBGjYmoQdxF4CQ==" }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "optional": true + }, "node_modules/axios": { "version": "0.26.1", "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", @@ -4295,7 +4364,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, "funding": [ { "type": "github", @@ -4335,6 +4403,15 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "optional": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, "node_modules/bcryptjs": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", @@ -4364,7 +4441,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -4638,7 +4714,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, "funding": [ { "type": "github", @@ -4675,14 +4750,41 @@ "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "node_modules/builtins": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", - "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", - "dev": true + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.0.tgz", + "integrity": "sha512-aizhtbxgT1Udg0Fj6GssXshAVK+nxbtCV+1OtTrMNy67jffDFBY6CUBAkhO4owbleAx6fdbnWdpsmmcXydbzNw==", + "dev": true, + "dependencies": { + "semver": "^7.0.0" + } + }, + "node_modules/builtins/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/bulk-write-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bulk-write-stream/-/bulk-write-stream-2.0.1.tgz", + "integrity": "sha512-XWOLjgHtpDasHfwM8oO4df1JoZwa7/OwTsXDzh4rUTo+9CowzeOFBZz43w+H14h1fyq+xl28tVIBrdjcjj4Gug==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } }, "node_modules/bytes": { "version": "3.1.2", @@ -4692,35 +4794,6 @@ "node": ">= 0.8" } }, - "node_modules/cacache": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", - "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", - "optional": true, - "dependencies": { - "@npmcli/fs": "^1.0.0", - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/cacheable-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", @@ -4811,9 +4884,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001319", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001319.tgz", - "integrity": "sha512-xjlIAFHucBRSMUo1kb5D4LYgcN1M45qdKP++lhqowDpwJwGkpIRTt5qQqnhxjj1vHcI7nrJxWhCC1ATrCEBTcw==", + "version": "1.0.30001323", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001323.tgz", + "integrity": "sha512-e4BF2RlCVELKx8+RmklSEIVub1TWrmdhvA5kEUueummz1XyySW0DVk+3x9HyhU9MuWTa2BhqLgEuEmUwASAdCA==", "dev": true, "funding": [ { @@ -4826,6 +4899,12 @@ } ] }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "optional": true + }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -4930,7 +5009,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "devOptional": true, + "dev": true, "engines": { "node": ">=6" } @@ -5029,6 +5108,15 @@ "node": ">= 0.12.0" } }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/collect-v8-coverage": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", @@ -5112,6 +5200,23 @@ "node": ">= 6" } }, + "node_modules/commist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz", + "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==", + "dependencies": { + "leven": "^2.1.0", + "minimist": "^1.1.0" + } + }, + "node_modules/commist/node_modules/leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/compare-versions": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", @@ -5127,6 +5232,20 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "engines": [ + "node >= 6.0" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, "node_modules/configstore": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", @@ -5230,6 +5349,12 @@ "semver": "bin/semver.js" } }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "devOptional": true + }, "node_modules/cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", @@ -5366,6 +5491,18 @@ "node": ">=0.8" } }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/data-urls": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", @@ -5535,14 +5672,11 @@ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "bin": { - "detect-libc": "bin/detect-libc.js" - }, + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", "engines": { - "node": ">=0.10" + "node": ">=8" } }, "node_modules/detect-newline": { @@ -5604,6 +5738,41 @@ "node": ">=6.0.0" } }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, "node_modules/domexception": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", @@ -5625,24 +5794,74 @@ "node": ">=8" } }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "dev": true, "dependencies": { - "is-obj": "^2.0.0" + "domelementtype": "^2.2.0" }, "engines": { - "node": ">=8" + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "node_modules/duplexer3": { - "version": "0.1.4", + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/duplexer3": { + "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", "dev": true }, + "node_modules/duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "optional": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -5657,9 +5876,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "node_modules/electron-to-chromium": { - "version": "1.4.89", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.89.tgz", - "integrity": "sha512-z1Axg0Fu54fse8wN4fd+GAINdU5mJmLtcl6bqIcYyzNVGONcfHAeeJi88KYMQVKalhXlYuVPzKkFIU5VD0raUw==", + "version": "1.4.103", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.103.tgz", + "integrity": "sha512-c/uKWR1Z/W30Wy/sx3dkZoj4BijbXX85QKWu9jJfjho3LBAXNEGAEW3oWiGb+dotA6C6BzCTxL2/aLes7jlUeg==", "dev": true }, "node_modules/emittery": { @@ -5696,6 +5915,7 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, "optional": true, "dependencies": { "iconv-lite": "^0.6.2" @@ -5705,7 +5925,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "dependencies": { "once": "^1.4.0" } @@ -5809,6 +6028,18 @@ "node": ">=8.6" } }, + "node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -5822,7 +6053,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "devOptional": true + "dev": true }, "node_modules/error-ex": { "version": "1.3.2", @@ -6715,6 +6946,12 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "optional": true + }, "node_modules/extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", @@ -6750,11 +6987,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "engines": [ + "node >=0.6.0" + ], + "optional": true + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "devOptional": true }, "node_modules/fast-glob": { "version": "3.2.11", @@ -6776,7 +7022,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "devOptional": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -6796,6 +7042,28 @@ "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", "dev": true }, + "node_modules/fastfall": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/fastfall/-/fastfall-1.5.1.tgz", + "integrity": "sha1-P+4DMxpJ0dObPN96XpzWb0dee5Q=", + "dev": true, + "dependencies": { + "reusify": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fastparallel": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/fastparallel/-/fastparallel-2.4.1.tgz", + "integrity": "sha512-qUmhxPgNHmvRjZKBFUNI0oZuuH9OlSIOXmJ98lhKPxMZZ7zS/Fi0wRHOihDSz0R1YiIOjxzOY4bq65YTcdBi2Q==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4", + "xtend": "^4.0.2" + } + }, "node_modules/fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -6805,6 +7073,12 @@ "reusify": "^1.0.4" } }, + "node_modules/fastseries": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fastseries/-/fastseries-2.0.0.tgz", + "integrity": "sha512-XBU9RXeoYc2/VnvMhplAxEmZLfIk7cvTBu+xwoBuTI8pL19E03cmca17QQycKIdxgwCeFA/a4u27gv1h3ya5LQ==", + "dev": true + }, "node_modules/favico.js": { "version": "0.3.10", "resolved": "https://registry.npmjs.org/favico.js/-/favico.js-0.3.10.tgz", @@ -7068,6 +7342,15 @@ "node": ">=0.10.0" } }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "optional": true, + "engines": { + "node": "*" + } + }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -7106,6 +7389,46 @@ "node": ">= 0.6" } }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/from2/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/from2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/from2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -7250,6 +7573,15 @@ "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.2.5.tgz", "integrity": "sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA==" }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, "node_modules/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -7429,6 +7761,29 @@ "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "devOptional": true }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "optional": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -7489,6 +7844,15 @@ "node": ">=8" } }, + "node_modules/help-me": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-3.0.0.tgz", + "integrity": "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==", + "dependencies": { + "glob": "^7.1.6", + "readable-stream": "^3.6.0" + } + }, "node_modules/homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -7502,15 +7866,24 @@ } }, "node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.0.0.tgz", + "integrity": "sha512-rRnjWu0Bxj+nIfUOkz0695C0H6tRrN5iYIzYejb0tDEefe2AekHu/U5Kn9pEie5vsJqpNQU02az7TGSH3qpz4Q==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" + "lru-cache": "^7.5.1" }, "engines": { - "node": ">=10" + "node": "^12.13.0 || ^14.15.0 || >=16" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", + "dev": true, + "engines": { + "node": ">=12" } }, "node_modules/html-encoding-sniffer": { @@ -7540,11 +7913,30 @@ "node": ">=8" } }, + "node_modules/htmlparser2": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", + "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.2", + "domutils": "^2.8.0", + "entities": "^3.0.1" + } + }, "node_modules/http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "devOptional": true + "dev": true }, "node_modules/http-errors": { "version": "1.8.1", @@ -7573,12 +7965,11 @@ } }, "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "devOptional": true, + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "dependencies": { - "@tootallnate/once": "1", + "@tootallnate/once": "2", "agent-base": "6", "debug": "4" }, @@ -7586,6 +7977,21 @@ "node": ">= 6" } }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", @@ -7619,11 +8025,21 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", - "devOptional": true, + "dev": true, "dependencies": { "ms": "^2.0.0" } }, + "node_modules/hyperid": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hyperid/-/hyperid-3.0.1.tgz", + "integrity": "sha512-I+tl7TS5nsoVhkxqX1rS3Qmqlq44eoPUcgPthW8v3IW8CvWL7lwtd6HQbkDUMrBKJTG0vgEaRsjT35imW/D+9Q==", + "dev": true, + "dependencies": { + "uuid": "^8.3.2", + "uuid-parse": "^1.1.0" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -7639,7 +8055,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, "funding": [ { "type": "github", @@ -7724,7 +8139,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.8.19" } @@ -7733,7 +8148,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "devOptional": true, + "dev": true, "engines": { "node": ">=8" } @@ -7742,7 +8157,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "devOptional": true + "dev": true }, "node_modules/inflight": { "version": "1.0.6", @@ -7775,8 +8190,7 @@ "node_modules/ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "devOptional": true + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" }, "node_modules/ipaddr.js": { "version": "1.9.1", @@ -7936,7 +8350,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=", - "devOptional": true + "dev": true }, "node_modules/is-npm": { "version": "5.0.0", @@ -8042,7 +8456,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "devOptional": true }, "node_modules/is-valid-path": { "version": "0.1.1", @@ -8070,6 +8484,12 @@ "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", "dev": true }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "devOptional": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -8085,6 +8505,12 @@ "node": ">=0.10.0" } }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "optional": true + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", @@ -10068,6 +10494,11 @@ "@sideway/pinpoint": "^2.0.0" } }, + "node_modules/js-sdsl": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-2.1.4.tgz", + "integrity": "sha512-/Ew+CJWHNddr7sjwgxaVeIORIH4AMVC9dy0hPf540ZGMVgS9d3ajwuVdyhDt6/QUvT8ATjR3yuYBKsS79F+H4A==" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -10087,6 +10518,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, "node_modules/jsdom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", @@ -10133,6 +10570,15 @@ } } }, + "node_modules/jsdom/node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/jsdom/node_modules/acorn": { "version": "8.7.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", @@ -10159,6 +10605,20 @@ "node": ">= 6" } }, + "node_modules/jsdom/node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -10192,11 +10652,17 @@ "jju": "^1.1.0" } }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "optional": true + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "devOptional": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -10204,6 +10670,12 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "optional": true + }, "node_modules/json5": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", @@ -10260,6 +10732,21 @@ "semver": "bin/semver" } }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "optional": true, + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/just-performance": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/just-performance/-/just-performance-4.3.0.tgz", @@ -10692,33 +11179,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-fetch-happen": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", - "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", - "optional": true, - "dependencies": { - "agentkeepalive": "^4.1.3", - "cacache": "^15.2.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^6.0.0", - "minipass": "^3.1.3", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^1.3.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.2", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^6.0.0", - "ssri": "^8.0.0" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -10784,6 +11244,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/meow/node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/meow/node_modules/normalize-package-data": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", @@ -10874,13 +11346,13 @@ } }, "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" @@ -10957,8 +11429,7 @@ "node_modules/minimist": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "node_modules/minimist-options": { "version": "4.1.0", @@ -10998,7 +11469,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "devOptional": true, + "dev": true, "dependencies": { "minipass": "^3.0.0" }, @@ -11006,28 +11477,11 @@ "node": ">= 8" } }, - "node_modules/minipass-fetch": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", - "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", - "optional": true, - "dependencies": { - "minipass": "^3.1.0", - "minipass-sized": "^1.0.3", - "minizlib": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "optionalDependencies": { - "encoding": "^0.1.12" - } - }, "node_modules/minipass-flush": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "devOptional": true, + "dev": true, "dependencies": { "minipass": "^3.0.0" }, @@ -11049,7 +11503,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "devOptional": true, + "dev": true, "dependencies": { "minipass": "^3.0.0" }, @@ -11061,7 +11515,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "devOptional": true, + "dev": true, "dependencies": { "minipass": "^3.0.0" }, @@ -11120,6 +11574,61 @@ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "dev": true }, + "node_modules/mqemitter": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/mqemitter/-/mqemitter-4.5.0.tgz", + "integrity": "sha512-Mp/zytFeIv6piJQkEKnncHcP4R/ErJc5C7dfonkhkNUT2LA/nTayrfNxbipp3M5iCJUTQSUtzfQAQA3XVcKz6w==", + "dev": true, + "dependencies": { + "fastparallel": "^2.3.0", + "qlobber": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mqtt": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.3.7.tgz", + "integrity": "sha512-ew3qwG/TJRorTz47eW46vZ5oBw5MEYbQZVaEji44j5lAUSQSqIEoul7Kua/BatBW0H0kKQcC9kwUHa1qzaWHSw==", + "dependencies": { + "commist": "^1.0.0", + "concat-stream": "^2.0.0", + "debug": "^4.1.1", + "duplexify": "^4.1.1", + "help-me": "^3.0.0", + "inherits": "^2.0.3", + "lru-cache": "^6.0.0", + "minimist": "^1.2.5", + "mqtt-packet": "^6.8.0", + "number-allocator": "^1.0.9", + "pump": "^3.0.0", + "readable-stream": "^3.6.0", + "reinterval": "^1.1.0", + "rfdc": "^1.3.0", + "split2": "^3.1.0", + "ws": "^7.5.5", + "xtend": "^4.0.2" + }, + "bin": { + "mqtt": "bin/mqtt.js", + "mqtt_pub": "bin/pub.js", + "mqtt_sub": "bin/sub.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mqtt-packet": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", + "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", + "dependencies": { + "bl": "^4.0.2", + "debug": "^4.1.1", + "process-nextick-args": "^2.0.1" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -11131,9 +11640,9 @@ "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==" }, "node_modules/nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.2.tgz", + "integrity": "sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -11156,9 +11665,17 @@ } }, "node_modules/node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + }, + "node_modules/node-cloudflared-tunnel": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/node-cloudflared-tunnel/-/node-cloudflared-tunnel-1.0.9.tgz", + "integrity": "sha512-d0mhIM5P2ldE2yHChehC6EvnpFCkifWRzWrW81gVWdcCWqNcyISXuDdOYzRW5mwmjWuT6WNtLJoGQ84uqS4EmA==", + "dependencies": { + "command-exists": "^1.2.9" + } }, "node_modules/node-fetch": { "version": "2.6.7", @@ -11199,20 +11716,20 @@ } }, "node_modules/node-gyp": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz", - "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", + "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", "optional": true, "dependencies": { "env-paths": "^2.2.0", "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^9.1.0", + "graceful-fs": "^4.2.3", "nopt": "^5.0.0", - "npmlog": "^6.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", + "semver": "^7.3.2", + "tar": "^6.0.2", "which": "^2.0.2" }, "bin": { @@ -11222,57 +11739,96 @@ "node": ">= 10.12.0" } }, + "node_modules/node-gyp/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-gyp/node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "optional": true + }, "node_modules/node-gyp/node_modules/are-we-there-yet": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz", - "integrity": "sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", "optional": true, "dependencies": { "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "readable-stream": "^2.0.6" } }, "node_modules/node-gyp/node_modules/gauge": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.3.tgz", - "integrity": "sha512-ICw1DhAwMtb22rYFwEHgJcx1JCwJGv3x6G0OQUq56Nge+H4Q8JEwr8iveS0XFlsUNSI67F5ffMGK25bK4Pmskw==", + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "optional": true, "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/node-gyp/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "optional": true, + "dependencies": { + "number-is-nan": "^1.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": ">=0.10.0" } }, "node_modules/node-gyp/node_modules/npmlog": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.1.tgz", - "integrity": "sha512-BTHDvY6nrRHuRfyjt1MAufLxYdVXZfd099H4+i1f0lPywNQyI4foeNXJRObB/uy+TYqUW0vAD9gbdSOXPst7Eg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "optional": true, "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.0", - "set-blocking": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, + "node_modules/node-gyp/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/node-gyp/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true + }, "node_modules/node-gyp/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "optional": true, "dependencies": { "lru-cache": "^6.0.0" @@ -11284,6 +11840,41 @@ "node": ">=10" } }, + "node_modules/node-gyp/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/node-gyp/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "optional": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-gyp/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -11333,27 +11924,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16" } }, - "node_modules/normalize-package-data/node_modules/hosted-git-info": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.0.0.tgz", - "integrity": "sha512-rRnjWu0Bxj+nIfUOkz0695C0H6tRrN5iYIzYejb0tDEefe2AekHu/U5Kn9pEie5vsJqpNQU02az7TGSH3qpz4Q==", - "dev": true, - "dependencies": { - "lru-cache": "^7.5.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" - } - }, - "node_modules/normalize-package-data/node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, "node_modules/normalize-package-data/node_modules/semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -11411,9 +11981,9 @@ } }, "node_modules/npm-check-updates": { - "version": "12.5.4", - "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-12.5.4.tgz", - "integrity": "sha512-4+27zaTdieWgvPLaCZ/A6Q2WC1cYVcrc2SqVmLFYgkWBrKw1QkwpeV16FSvkFGZr3OdFyr7Dpjw8JRn4H2QxFw==", + "version": "12.5.5", + "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-12.5.5.tgz", + "integrity": "sha512-7LH6KN6F1fZMtY4zNYAQPpJU1ToxZ6sSCxk948vrLIz97aNqmPLSX72MrmbOWwpyBgLCPbFJWY/k3zE18pmxfw==", "dev": true, "dependencies": { "chalk": "^4.1.2", @@ -11425,7 +11995,7 @@ "fp-and-or": "^0.1.3", "get-stdin": "^8.0.0", "globby": "^11.0.4", - "hosted-git-info": "^4.1.0", + "hosted-git-info": "^5.0.0", "json-parse-helpfulerror": "^1.0.3", "jsonlines": "^0.1.1", "libnpmconfig": "^1.2.1", @@ -11664,38 +12234,17 @@ "dev": true }, "node_modules/npm-package-arg": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-9.0.1.tgz", - "integrity": "sha512-Xs9wznfEAmZAR61qsYH3iN24V/qMYYkvAR5CRQNMvC6PjN2fHtO8y9XP/xdp5K+Icx+u1wMBMgWRPCmAEChSog==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-9.0.2.tgz", + "integrity": "sha512-v/miORuX8cndiOheW8p2moNuPJ7QhcFh9WGlTorruG8hXSA23vMTEp5hTCmDxic0nD8KHhj/NQgFuySD3GYY3g==", "dev": true, "dependencies": { "hosted-git-info": "^5.0.0", "semver": "^7.3.5", - "validate-npm-package-name": "^3.0.0" + "validate-npm-package-name": "^4.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" - } - }, - "node_modules/npm-package-arg/node_modules/hosted-git-info": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.0.0.tgz", - "integrity": "sha512-rRnjWu0Bxj+nIfUOkz0695C0H6tRrN5iYIzYejb0tDEefe2AekHu/U5Kn9pEie5vsJqpNQU02az7TGSH3qpz4Q==", - "dev": true, - "dependencies": { - "lru-cache": "^7.5.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" - } - }, - "node_modules/npm-package-arg/node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", - "dev": true, - "engines": { - "node": ">=12" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/npm-package-arg/node_modules/semver": { @@ -11762,45 +12311,49 @@ } }, "node_modules/npm-registry-fetch": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-13.0.1.tgz", - "integrity": "sha512-Ak+LXVtSrCLOdscFW/apUw67OPNph8waHsPKM9UOJosL7i59EF5XoSWQMEsXEOeifM9Bb4/2+WrQC4t/pd8DGg==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-13.1.0.tgz", + "integrity": "sha512-TIYL5X8CcwDhbFMXFDShNcpG6OMCYK6VzvSr6MUWP20tCU2DJ4ao2qQg3DT+3Pet8mO6/cgbZpon4LMh3duYLg==", "dev": true, "dependencies": { - "make-fetch-happen": "^10.0.3", + "make-fetch-happen": "^10.0.6", "minipass": "^3.1.6", - "minipass-fetch": "^2.0.1", + "minipass-fetch": "^2.0.3", "minipass-json-stream": "^1.0.1", "minizlib": "^2.1.2", - "npm-package-arg": "^9.0.0", + "npm-package-arg": "^9.0.1", "proc-log": "^2.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/npm-registry-fetch/node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "node_modules/npm-registry-fetch/node_modules/@npmcli/fs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.0.tgz", + "integrity": "sha512-DmfBvNXGaetMxj9LTp8NAN9vEidXURrf5ZTslQzEAi/6GbW+4yjaLFQc6Tue5cpZ9Frlk4OBo/Snf1Bh/S7qTQ==", "dev": true, + "dependencies": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + }, "engines": { - "node": ">= 10" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/npm-registry-fetch/node_modules/cacache": { - "version": "16.0.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.2.tgz", - "integrity": "sha512-Q17j7s8X81i/QYVrKVQ/qwWGT+pYLfpTcZ+X+p/Qw9FULy9JEfb2FECYTTt6mPV6A/vk92nRZ80ncpKxiGTrIA==", + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.3.tgz", + "integrity": "sha512-eC7wYodNCVb97kuHGk5P+xZsvUJHkhSEOyNwkenqQPAsOtrTjvWOE5vSPNBpz9d8X3acIf6w2Ub5s4rvOCTs4g==", "dev": true, "dependencies": { - "@npmcli/fs": "^1.0.0", + "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^1.1.2", "chownr": "^2.0.0", "fs-minipass": "^2.1.0", "glob": "^7.2.0", "infer-owner": "^1.0.4", - "lru-cache": "^7.5.1", + "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", @@ -11814,45 +12367,31 @@ "unique-filename": "^1.1.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" - } - }, - "node_modules/npm-registry-fetch/node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/npm-registry-fetch/node_modules/lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", "dev": true, "engines": { "node": ">=12" } }, "node_modules/npm-registry-fetch/node_modules/make-fetch-happen": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.0.6.tgz", - "integrity": "sha512-4Gfh6lV3TLXmj7qz79hBFuvVqjYSMW6v2+sxtdX4LFQU0rK3V/txRjE0DoZb7X0IF3t9f8NO3CxPSWlvdckhVA==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.1.1.tgz", + "integrity": "sha512-3/mCljDQNjmrP7kl0vhS5WVlV+TvSKoZaFhdiYV7MOijEnrhrjaVnqbp/EY/7S+fhUB2KpH7j8c1iRsIOs+kjw==", "dev": true, "dependencies": { "agentkeepalive": "^4.2.1", - "cacache": "^16.0.0", + "cacache": "^16.0.2", "http-cache-semantics": "^4.1.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", - "lru-cache": "^7.5.1", + "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-fetch": "^2.0.3", @@ -11864,13 +12403,13 @@ "ssri": "^8.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/npm-registry-fetch/node_modules/minipass-fetch": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.0.3.tgz", - "integrity": "sha512-VA+eiiUtaIvpQJXISwE3OiMvQwAWrgKb97F0aXlCS1Ahikr8fEQq8m3Hf7Kv9KT3nokuHigJKsDMB6atU04olQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.0.tgz", + "integrity": "sha512-H9U4UVBGXEyyWJnqYDCLp1PwD8XIkJ4akNHp1aGVI+2Ym7wQMlxDKi4IB4JbmyU+pl9pEs/cVrK6cOuvmbK4Sg==", "dev": true, "dependencies": { "minipass": "^3.1.6", @@ -11878,12 +12417,39 @@ "minizlib": "^2.1.2" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" }, "optionalDependencies": { "encoding": "^0.1.13" } }, + "node_modules/npm-registry-fetch/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-registry-fetch/node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -11907,6 +12473,24 @@ "set-blocking": "^2.0.0" } }, + "node_modules/number-allocator": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.10.tgz", + "integrity": "sha512-K4AvNGKo9lP6HqsZyfSr9KDaqnwFzW203inhQEOwFrmFaYevpdX4VNwdOLk197aHujzbT//z6pCBrCOUYSM5iw==", + "dependencies": { + "debug": "^4.3.1", + "js-sdsl": "^2.1.2" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/numbered": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/numbered/-/numbered-1.1.0.tgz", @@ -11918,6 +12502,15 @@ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "optional": true, + "engines": { + "node": "*" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -12059,7 +12652,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "devOptional": true, + "dev": true, "dependencies": { "aggregate-error": "^3.0.0" }, @@ -12153,19 +12746,32 @@ "node": "^12.13.0 || ^14.15.0 || >=16" } }, + "node_modules/pacote/node_modules/@npmcli/fs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.0.tgz", + "integrity": "sha512-DmfBvNXGaetMxj9LTp8NAN9vEidXURrf5ZTslQzEAi/6GbW+4yjaLFQc6Tue5cpZ9Frlk4OBo/Snf1Bh/S7qTQ==", + "dev": true, + "dependencies": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/pacote/node_modules/cacache": { - "version": "16.0.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.2.tgz", - "integrity": "sha512-Q17j7s8X81i/QYVrKVQ/qwWGT+pYLfpTcZ+X+p/Qw9FULy9JEfb2FECYTTt6mPV6A/vk92nRZ80ncpKxiGTrIA==", + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.3.tgz", + "integrity": "sha512-eC7wYodNCVb97kuHGk5P+xZsvUJHkhSEOyNwkenqQPAsOtrTjvWOE5vSPNBpz9d8X3acIf6w2Ub5s4rvOCTs4g==", "dev": true, "dependencies": { - "@npmcli/fs": "^1.0.0", + "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^1.1.2", "chownr": "^2.0.0", "fs-minipass": "^2.1.0", "glob": "^7.2.0", "infer-owner": "^1.0.4", - "lru-cache": "^7.5.1", + "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", @@ -12179,18 +12785,45 @@ "unique-filename": "^1.1.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/pacote/node_modules/lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", "dev": true, "engines": { "node": ">=12" } }, + "node_modules/pacote/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pacote/node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -12327,6 +12960,12 @@ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", "dev": true }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "optional": true + }, "node_modules/pg-connection-string": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", @@ -12409,6 +13048,20 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-html": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.3.1.tgz", + "integrity": "sha512-SJ7iRw+IngyZv3Z9lChlZU30a9y9MZjZZcoUJmx0T/nKE9S+hetJ8fAv/MRu4bPnGDsXhVlaFs5+umpK3yaaQQ==", + "dev": true, + "dependencies": { + "htmlparser2": "^7.1.2", + "postcss": "^8.4.0", + "postcss-safe-parser": "^6.0.0" + }, + "engines": { + "node": "^12 || >=14" + } + }, "node_modules/postcss-media-query-parser": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", @@ -12467,9 +13120,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.9", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz", - "integrity": "sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ==", + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -12529,15 +13182,28 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/prismjs": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz", + "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==", + "engines": { + "node": ">=6" + } + }, "node_modules/proc-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-2.0.0.tgz", - "integrity": "sha512-I/35MfCX2H8jBUhKN8JB8nmqvQo/nKdrBodBY7L3RhDSPPyvOHwLYNmPuhwuJq7a7C3vgFKWGQM+ecPStcvOHA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-2.0.1.tgz", + "integrity": "sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==", "dev": true, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -12586,13 +13252,13 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "devOptional": true + "dev": true }, "node_modules/promise-retry": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "devOptional": true, + "dev": true, "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" @@ -12641,13 +13307,12 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true + "devOptional": true }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -12657,7 +13322,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6" } @@ -12742,6 +13407,15 @@ } } }, + "node_modules/qlobber": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/qlobber/-/qlobber-5.0.3.tgz", + "integrity": "sha512-wW4GTZPePyh0RgOsM18oDyOUlXfurVRgoNyJfS+y7VWPyd0GYhQp5T2tycZFZjonH+hngxIfklGJhTP/ghidgQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/qrcode": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.0.tgz", @@ -13267,6 +13941,11 @@ "jsesc": "bin/jsesc" } }, + "node_modules/reinterval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", + "integrity": "sha1-M2Hs+jymwYKDOA3Qu5VG85D17Oc=" + }, "node_modules/remote-git-tags": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/remote-git-tags/-/remote-git-tags-3.0.0.tgz", @@ -13276,6 +13955,84 @@ "node": ">=8" } }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "optional": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "optional": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "optional": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/request/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "optional": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "optional": true, + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -13375,11 +14132,17 @@ "lowercase-keys": "^1.0.0" } }, + "node_modules/retimer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/retimer/-/retimer-3.0.0.tgz", + "integrity": "sha512-WKE0j11Pa0ZJI5YIk0nflGI7SQsfl2ljihVy7ogh7DeQSeYAUi0ubZ/yEueGtDfUPk6GH5LRw1hBdLq4IwUBWA==", + "dev": true + }, "node_modules/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "devOptional": true, + "dev": true, "engines": { "node": ">= 4" } @@ -13394,6 +14157,11 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -13799,7 +14567,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "devOptional": true, "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" @@ -13871,7 +14638,6 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", - "devOptional": true, "dependencies": { "ip": "^1.1.5", "smart-buffer": "^4.2.0" @@ -13885,7 +14651,6 @@ "version": "6.1.1", "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz", "integrity": "sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew==", - "devOptional": true, "dependencies": { "agent-base": "^6.0.2", "debug": "^4.3.1", @@ -14002,17 +14767,50 @@ "specificity": "bin/specificity" } }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dependencies": { + "readable-stream": "^3.0.0" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "node_modules/sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "optional": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ssri": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "devOptional": true, + "dev": true, "dependencies": { "minipass": "^3.1.1" }, @@ -14049,6 +14847,11 @@ "node": ">= 0.6" } }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -14382,9 +15185,9 @@ } }, "node_modules/table/node_modules/ajv": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz", - "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", @@ -14650,6 +15453,24 @@ "node": ">=0.6.11 <=0.7.0 || >=0.7.3" } }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "optional": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -14695,6 +15516,11 @@ "node": ">= 0.6" } }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", @@ -14771,7 +15597,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "devOptional": true, + "dev": true, "dependencies": { "unique-slug": "^2.0.0" } @@ -14780,7 +15606,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "devOptional": true, + "dev": true, "dependencies": { "imurmurhash": "^0.1.4" } @@ -14946,7 +15772,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, + "devOptional": true, "dependencies": { "punycode": "^2.1.0" } @@ -14976,6 +15802,21 @@ "node": ">= 0.4.0" } }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/uuid-parse": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/uuid-parse/-/uuid-parse-1.1.0.tgz", + "integrity": "sha512-OdmXxA8rDsQ7YpNVbKSJkNzTw2I+S5WsbMDnCtIWSQaosNAcWtFuI/YK1TjzUI6nbkgiqEyh8gWngfcv8Asd9A==", + "dev": true + }, "node_modules/v-pagination-3": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/v-pagination-3/-/v-pagination-3-0.1.7.tgz", @@ -15026,12 +15867,15 @@ } }, "node_modules/validate-npm-package-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", - "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz", + "integrity": "sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==", "dev": true, "dependencies": { - "builtins": "^1.0.3" + "builtins": "^5.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/vary": { @@ -15042,6 +15886,26 @@ "node": ">= 0.8" } }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "engines": [ + "node >=0.6.0" + ], + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "optional": true + }, "node_modules/vite": { "version": "2.6.14", "resolved": "https://registry.npmjs.org/vite/-/vite-2.6.14.tgz", @@ -15245,6 +16109,17 @@ "npm": ">= 3.0.0" } }, + "node_modules/vue-prism-editor": { + "version": "2.0.0-alpha.2", + "resolved": "https://registry.npmjs.org/vue-prism-editor/-/vue-prism-editor-2.0.0-alpha.2.tgz", + "integrity": "sha512-Gu42ba9nosrE+gJpnAEuEkDMqG9zSUysIR8SdXUw8MQKDjBnnNR9lHC18uOr/ICz7yrA/5c7jHJr9lpElODC7w==", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, "node_modules/vue-qrcode": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/vue-qrcode/-/vue-qrcode-1.0.0.tgz", @@ -15525,7 +16400,6 @@ "version": "7.5.7", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", - "dev": true, "engines": { "node": ">=8.3.0" }, @@ -15571,6 +16445,14 @@ "node": ">=0.4.0" } }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -15667,15 +16549,15 @@ }, "dependencies": { "@actions/github": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.0.tgz", - "integrity": "sha512-QvE9eAAfEsS+yOOk0cylLBIO/d6WyWIOvsxxzdrPFaud39G6BOkUwScXZn1iBzQzHyu9SBkkLSWlohDWdsasAQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.1.tgz", + "integrity": "sha512-JZGyPM9ektb8NVTTI/2gfJ9DL7Rk98tQ7OVyTlgTuaQroariRBsOnzjy0I2EarX4xUZpK88YyO503fhmjFdyAg==", "dev": true, "requires": { "@actions/http-client": "^1.0.11", - "@octokit/core": "^3.4.0", - "@octokit/plugin-paginate-rest": "^2.13.3", - "@octokit/plugin-rest-endpoint-methods": "^5.1.1" + "@octokit/core": "^3.6.0", + "@octokit/plugin-paginate-rest": "^2.17.0", + "@octokit/plugin-rest-endpoint-methods": "^5.13.0" } }, "@actions/http-client": { @@ -16902,7 +17784,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "devOptional": true + "dev": true }, "@hapi/hoek": { "version": "9.2.1", @@ -17520,24 +18402,25 @@ } }, "@louislam/sqlite3": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@louislam/sqlite3/-/sqlite3-6.0.1.tgz", - "integrity": "sha512-QGLj5bjQ+O4YSPj/qxtEAArbIqW9wNzBUamlIcRbvFjFiNokItwdubqL2Gl5iX0q1mUn3Z6NoFO1rrAZ/qqlsA==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@louislam/sqlite3/-/sqlite3-15.0.3.tgz", + "integrity": "sha512-rCH6PIaa+TgBzpTRnqBKUa4H/5G2hIk5ukYK5rXxK+8hVGykRin3UMGzGejrPzIKzDnZGByIF0XD4ndi6lprRQ==", "requires": { - "@mapbox/node-pre-gyp": "^1.0.7", - "node-addon-api": "^3.0.0", - "node-gyp": "^8.4.1" + "@mapbox/node-pre-gyp": "^1.0.0", + "node-addon-api": "^4.2.0", + "node-gyp": "^7.1.2", + "tar": "^6.1.11" } }, "@mapbox/node-pre-gyp": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.8.tgz", - "integrity": "sha512-CMGKi28CF+qlbXh26hDe6NxCd7amqeAzEqnS6IHeO6LoaKyM/n+Xw3HT1COdq8cuioOdlKdqn/hCmqPUOMOywg==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz", + "integrity": "sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==", "requires": { - "detect-libc": "^1.0.3", + "detect-libc": "^2.0.0", "https-proxy-agent": "^5.0.0", "make-dir": "^3.1.0", - "node-fetch": "^2.6.5", + "node-fetch": "^2.6.7", "nopt": "^5.0.0", "npmlog": "^5.0.1", "rimraf": "^3.0.2", @@ -17581,27 +18464,6 @@ "fastq": "^1.6.0" } }, - "@npmcli/fs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", - "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", - "devOptional": true, - "requires": { - "@gar/promisify": "^1.0.1", - "semver": "^7.3.5" - }, - "dependencies": { - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "devOptional": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, "@npmcli/git": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-3.0.0.tgz", @@ -17620,9 +18482,9 @@ }, "dependencies": { "lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", "dev": true }, "semver": { @@ -17661,7 +18523,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", - "devOptional": true, + "dev": true, "requires": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" @@ -17694,11 +18556,15 @@ "read-package-json-fast": "^2.0.3" }, "dependencies": { - "@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true + "@npmcli/fs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.0.tgz", + "integrity": "sha512-DmfBvNXGaetMxj9LTp8NAN9vEidXURrf5ZTslQzEAi/6GbW+4yjaLFQc6Tue5cpZ9Frlk4OBo/Snf1Bh/S7qTQ==", + "dev": true, + "requires": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + } }, "are-we-there-yet": { "version": "3.0.0", @@ -17711,18 +18577,18 @@ } }, "cacache": { - "version": "16.0.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.2.tgz", - "integrity": "sha512-Q17j7s8X81i/QYVrKVQ/qwWGT+pYLfpTcZ+X+p/Qw9FULy9JEfb2FECYTTt6mPV6A/vk92nRZ80ncpKxiGTrIA==", + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.3.tgz", + "integrity": "sha512-eC7wYodNCVb97kuHGk5P+xZsvUJHkhSEOyNwkenqQPAsOtrTjvWOE5vSPNBpz9d8X3acIf6w2Ub5s4rvOCTs4g==", "dev": true, "requires": { - "@npmcli/fs": "^1.0.0", + "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^1.1.2", "chownr": "^2.0.0", "fs-minipass": "^2.1.0", "glob": "^7.2.0", "infer-owner": "^1.0.4", - "lru-cache": "^7.5.1", + "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", @@ -17737,17 +18603,17 @@ }, "dependencies": { "lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", "dev": true } } }, "gauge": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.3.tgz", - "integrity": "sha512-ICw1DhAwMtb22rYFwEHgJcx1JCwJGv3x6G0OQUq56Nge+H4Q8JEwr8iveS0XFlsUNSI67F5ffMGK25bK4Pmskw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", "dev": true, "requires": { "aproba": "^1.0.3 || ^2.0.0", @@ -17760,30 +18626,19 @@ "wide-align": "^1.1.5" } }, - "http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "requires": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - } - }, "make-fetch-happen": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.0.6.tgz", - "integrity": "sha512-4Gfh6lV3TLXmj7qz79hBFuvVqjYSMW6v2+sxtdX4LFQU0rK3V/txRjE0DoZb7X0IF3t9f8NO3CxPSWlvdckhVA==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.1.1.tgz", + "integrity": "sha512-3/mCljDQNjmrP7kl0vhS5WVlV+TvSKoZaFhdiYV7MOijEnrhrjaVnqbp/EY/7S+fhUB2KpH7j8c1iRsIOs+kjw==", "dev": true, "requires": { "agentkeepalive": "^4.2.1", - "cacache": "^16.0.0", + "cacache": "^16.0.2", "http-cache-semantics": "^4.1.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", - "lru-cache": "^7.5.1", + "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-fetch": "^2.0.3", @@ -17796,17 +18651,17 @@ }, "dependencies": { "lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", "dev": true } } }, "minipass-fetch": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.0.3.tgz", - "integrity": "sha512-VA+eiiUtaIvpQJXISwE3OiMvQwAWrgKb97F0aXlCS1Ahikr8fEQq8m3Hf7Kv9KT3nokuHigJKsDMB6atU04olQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.0.tgz", + "integrity": "sha512-H9U4UVBGXEyyWJnqYDCLp1PwD8XIkJ4akNHp1aGVI+2Ym7wQMlxDKi4IB4JbmyU+pl9pEs/cVrK6cOuvmbK4Sg==", "dev": true, "requires": { "encoding": "^0.1.13", @@ -17967,9 +18822,9 @@ "integrity": "sha512-IXf3XA7+XyN7CP9gGh/XB0UxVMlvARGEgGXLubFICsUMGz6Q+DU+i4gGlpOxTjKvXjkJDJC8YdqdKkDj9qZHEQ==" }, "@sideway/address": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.3.tgz", - "integrity": "sha512-8ncEUtmnTsMmL7z1YPB47kPUq7LpKWJNFPsRzHiIajGC5uXlWGn+AmkYPcHNl8S4tcEGx+cnORnNYaw2wvL+LQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", + "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", "dev": true, "requires": { "@hapi/hoek": "^9.0.0" @@ -18031,10 +18886,9 @@ } }, "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "devOptional": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==" }, "@types/accepts": { "version": "1.3.5", @@ -18245,9 +19099,9 @@ } }, "@types/lodash": { - "version": "4.14.180", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.180.tgz", - "integrity": "sha512-XOKXa1KIxtNXgASAnwj7cnttJxS4fksBRywK/9LzRV5YxrF80BXZIGeQSuoESQ/VkUj30Ae0+YcuHc15wJCB2g==" + "version": "4.14.181", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.181.tgz", + "integrity": "sha512-n3tyKthHJbkiWhDZs3DkhkCzt2MexYHXlX0td5iMplyfwketaOeKboEVBqzceH7juqvEg3q5oUoBFxSLu7zFag==" }, "@types/mime": { "version": "1.3.2", @@ -18261,9 +19115,9 @@ "dev": true }, "@types/node": { - "version": "17.0.22", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.22.tgz", - "integrity": "sha512-8FwbVoG4fy+ykY86XCAclKZDORttqE5/s7dyWZKLXTdv3vRy5HozBEinG5IqhvPXXzIZEcTVbuHlQEI6iuwcmw==" + "version": "17.0.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", + "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" }, "@types/normalize-package-data": { "version": "2.4.1", @@ -18427,9 +19281,9 @@ } }, "@vue/devtools-api": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.1.3.tgz", - "integrity": "sha512-79InfO2xHv+WHIrH1bHXQUiQD/wMls9qBk6WVwGCbdwP7/3zINtvqPNMtmSHXsIKjvUAHc8L0ouOj6ZQQRmcXg==" + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.1.4.tgz", + "integrity": "sha512-IiA0SvDrJEgXvVxjNkHPFfDx6SXw0b/TUkqMcDZWNg9fnCAHbTpoo59YfJ9QLFkwa3raau5vSlRVzMSLDnfdtQ==" }, "@vue/reactivity": { "version": "3.2.31", @@ -18532,6 +19386,61 @@ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true }, + "aedes": { + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/aedes/-/aedes-0.46.3.tgz", + "integrity": "sha512-i3B+H74uNRhlqcs/JdrMp7e3daz4Cwls0x4yLcfjGXz2tIwnxhF6od4m86O6yyNdz/Gg3jfY3q0sc/Cz8qzg6g==", + "dev": true, + "requires": { + "aedes-packet": "^2.3.1", + "aedes-persistence": "^8.1.3", + "bulk-write-stream": "^2.0.1", + "end-of-stream": "^1.4.4", + "fastfall": "^1.5.1", + "fastparallel": "^2.4.1", + "fastseries": "^2.0.0", + "hyperid": "^3.0.0", + "mqemitter": "^4.5.0", + "mqtt-packet": "^7.1.2", + "readable-stream": "^3.6.0", + "retimer": "^3.0.0", + "reusify": "^1.0.4", + "uuid": "^8.3.2" + }, + "dependencies": { + "mqtt-packet": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-7.1.2.tgz", + "integrity": "sha512-FFZbcZ2omsf4c5TxEQfcX9hI+JzDpDKPT46OmeIBpVA7+t32ey25UNqlqNXTmeZOr5BLsSIERpQQLsFWJS94SQ==", + "dev": true, + "requires": { + "bl": "^4.0.2", + "debug": "^4.1.1", + "process-nextick-args": "^2.0.1" + } + } + } + }, + "aedes-packet": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/aedes-packet/-/aedes-packet-2.3.1.tgz", + "integrity": "sha512-LqBd57uc2rui2RbjycW17dylglejG26mM4ewVXGNDnVp/SUHFVEgm7d1HTmYrnSkSCNoHti042qgcTwv/F+BtQ==", + "dev": true, + "requires": { + "mqtt-packet": "^6.3.0" + } + }, + "aedes-persistence": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/aedes-persistence/-/aedes-persistence-8.1.3.tgz", + "integrity": "sha512-VMCjEV+2g1TNJb/IlDEUy6SP9crT+QUhe2xc6UjyqrFNBNgTvHmOefXY7FxWrwmR2QA02vwg3+5p/JXkyg/Dkw==", + "dev": true, + "requires": { + "aedes-packet": "^2.3.1", + "from2": "^2.3.0", + "qlobber": "^5.0.3" + } + }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -18544,7 +19453,7 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz", "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==", - "devOptional": true, + "dev": true, "requires": { "debug": "^4.1.0", "depd": "^1.1.2", @@ -18555,7 +19464,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "devOptional": true, + "dev": true, "requires": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -18565,7 +19474,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, + "devOptional": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -18672,6 +19581,21 @@ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, + "asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "optional": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "optional": true + }, "astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -18688,6 +19612,18 @@ "resolved": "https://registry.npmjs.org/await-lock/-/await-lock-2.1.0.tgz", "integrity": "sha512-t7Zm5YGgEEc/3eYAicF32m/TNvL+XOeYZy9CvBUeJY/szM7frLolFylhrlZNWV/ohWhcUXygrBGjYmoQdxF4CQ==" }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "optional": true + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "optional": true + }, "axios": { "version": "0.26.1", "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", @@ -18902,8 +19838,7 @@ "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "base64id": { "version": "2.0.0", @@ -18925,6 +19860,15 @@ } } }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "optional": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, "bcryptjs": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", @@ -18951,7 +19895,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, "requires": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -19155,7 +20098,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, "requires": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -19175,46 +20117,43 @@ "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "builtins": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", - "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", - "dev": true + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.0.tgz", + "integrity": "sha512-aizhtbxgT1Udg0Fj6GssXshAVK+nxbtCV+1OtTrMNy67jffDFBY6CUBAkhO4owbleAx6fdbnWdpsmmcXydbzNw==", + "dev": true, + "requires": { + "semver": "^7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "bulk-write-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bulk-write-stream/-/bulk-write-stream-2.0.1.tgz", + "integrity": "sha512-XWOLjgHtpDasHfwM8oO4df1JoZwa7/OwTsXDzh4rUTo+9CowzeOFBZz43w+H14h1fyq+xl28tVIBrdjcjj4Gug==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } }, "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" }, - "cacache": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", - "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", - "optional": true, - "requires": { - "@npmcli/fs": "^1.0.0", - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - } - }, "cacheable-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", @@ -19280,11 +20219,17 @@ } }, "caniuse-lite": { - "version": "1.0.30001319", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001319.tgz", - "integrity": "sha512-xjlIAFHucBRSMUo1kb5D4LYgcN1M45qdKP++lhqowDpwJwGkpIRTt5qQqnhxjj1vHcI7nrJxWhCC1ATrCEBTcw==", + "version": "1.0.30001323", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001323.tgz", + "integrity": "sha512-e4BF2RlCVELKx8+RmklSEIVub1TWrmdhvA5kEUueummz1XyySW0DVk+3x9HyhU9MuWTa2BhqLgEuEmUwASAdCA==", "dev": true }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "optional": true + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -19365,7 +20310,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "devOptional": true + "dev": true }, "cli-boxes": { "version": "2.2.1", @@ -19441,6 +20386,12 @@ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "optional": true + }, "collect-v8-coverage": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", @@ -19512,6 +20463,22 @@ "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", "dev": true }, + "commist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz", + "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==", + "requires": { + "leven": "^2.1.0", + "minimist": "^1.1.0" + }, + "dependencies": { + "leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=" + } + } + }, "compare-versions": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", @@ -19527,6 +20494,17 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, "configstore": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", @@ -19610,6 +20588,12 @@ } } }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "devOptional": true + }, "cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", @@ -19715,6 +20699,15 @@ "fs-exists-sync": "^0.1.0" } }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "optional": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, "data-urls": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", @@ -19850,9 +20843,9 @@ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==" }, "detect-newline": { "version": "3.1.0", @@ -19901,6 +20894,31 @@ "esutils": "^2.0.2" } }, + "dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "dependencies": { + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true + } + } + }, + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true + }, "domexception": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", @@ -19918,6 +20936,26 @@ } } }, + "domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, "dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -19933,6 +20971,27 @@ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", "dev": true }, + "duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "requires": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "optional": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, "ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -19947,9 +21006,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.4.89", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.89.tgz", - "integrity": "sha512-z1Axg0Fu54fse8wN4fd+GAINdU5mJmLtcl6bqIcYyzNVGONcfHAeeJi88KYMQVKalhXlYuVPzKkFIU5VD0raUw==", + "version": "1.4.103", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.103.tgz", + "integrity": "sha512-c/uKWR1Z/W30Wy/sx3dkZoj4BijbXX85QKWu9jJfjho3LBAXNEGAEW3oWiGb+dotA6C6BzCTxL2/aLes7jlUeg==", "dev": true }, "emittery": { @@ -19977,6 +21036,7 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, "optional": true, "requires": { "iconv-lite": "^0.6.2" @@ -19986,7 +21046,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "requires": { "once": "^1.4.0" } @@ -20055,6 +21114,12 @@ "ansi-colors": "^4.1.1" } }, + "entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true + }, "env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -20065,7 +21130,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "devOptional": true + "dev": true }, "error-ex": { "version": "1.3.2", @@ -20697,6 +21762,12 @@ "basic-auth": "^2.0.1" } }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "optional": true + }, "extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", @@ -20720,11 +21791,17 @@ } } }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "optional": true + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "devOptional": true }, "fast-glob": { "version": "3.2.11", @@ -20743,7 +21820,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "devOptional": true }, "fast-levenshtein": { "version": "2.0.6", @@ -20763,6 +21840,25 @@ "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", "dev": true }, + "fastfall": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/fastfall/-/fastfall-1.5.1.tgz", + "integrity": "sha1-P+4DMxpJ0dObPN96XpzWb0dee5Q=", + "dev": true, + "requires": { + "reusify": "^1.0.0" + } + }, + "fastparallel": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/fastparallel/-/fastparallel-2.4.1.tgz", + "integrity": "sha512-qUmhxPgNHmvRjZKBFUNI0oZuuH9OlSIOXmJ98lhKPxMZZ7zS/Fi0wRHOihDSz0R1YiIOjxzOY4bq65YTcdBi2Q==", + "dev": true, + "requires": { + "reusify": "^1.0.4", + "xtend": "^4.0.2" + } + }, "fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -20772,6 +21868,12 @@ "reusify": "^1.0.4" } }, + "fastseries": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fastseries/-/fastseries-2.0.0.tgz", + "integrity": "sha512-XBU9RXeoYc2/VnvMhplAxEmZLfIk7cvTBu+xwoBuTI8pL19E03cmca17QQycKIdxgwCeFA/a4u27gv1h3ya5LQ==", + "dev": true + }, "favico.js": { "version": "0.3.10", "resolved": "https://registry.npmjs.org/favico.js/-/favico.js-0.3.10.tgz", @@ -20974,6 +22076,12 @@ "for-in": "^1.0.1" } }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "optional": true + }, "form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -21000,6 +22108,48 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -21104,6 +22254,15 @@ "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.2.5.tgz", "integrity": "sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA==" }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "optional": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, "glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -21246,6 +22405,22 @@ "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "devOptional": true }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "optional": true + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "optional": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, "hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -21288,6 +22463,15 @@ "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", "dev": true }, + "help-me": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-3.0.0.tgz", + "integrity": "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==", + "requires": { + "glob": "^7.1.6", + "readable-stream": "^3.6.0" + } + }, "homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -21298,12 +22482,20 @@ } }, "hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.0.0.tgz", + "integrity": "sha512-rRnjWu0Bxj+nIfUOkz0695C0H6tRrN5iYIzYejb0tDEefe2AekHu/U5Kn9pEie5vsJqpNQU02az7TGSH3qpz4Q==", "dev": true, "requires": { - "lru-cache": "^6.0.0" + "lru-cache": "^7.5.1" + }, + "dependencies": { + "lru-cache": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", + "dev": true + } } }, "html-encoding-sniffer": { @@ -21327,11 +22519,23 @@ "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==", "dev": true }, + "htmlparser2": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", + "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.2", + "domutils": "^2.8.0", + "entities": "^3.0.1" + } + }, "http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "devOptional": true + "dev": true }, "http-errors": { "version": "1.8.1", @@ -21354,16 +22558,26 @@ } }, "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "devOptional": true, + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "requires": { - "@tootallnate/once": "1", + "@tootallnate/once": "2", "agent-base": "6", "debug": "4" } }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "optional": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, "https-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", @@ -21391,11 +22605,21 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", - "devOptional": true, + "dev": true, "requires": { "ms": "^2.0.0" } }, + "hyperid": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hyperid/-/hyperid-3.0.1.tgz", + "integrity": "sha512-I+tl7TS5nsoVhkxqX1rS3Qmqlq44eoPUcgPthW8v3IW8CvWL7lwtd6HQbkDUMrBKJTG0vgEaRsjT35imW/D+9Q==", + "dev": true, + "requires": { + "uuid": "^8.3.2", + "uuid-parse": "^1.1.0" + } + }, "iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -21407,8 +22631,7 @@ "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "ignore": { "version": "4.0.6", @@ -21455,19 +22678,19 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "devOptional": true + "dev": true }, "indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "devOptional": true + "dev": true }, "infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "devOptional": true + "dev": true }, "inflight": { "version": "1.0.6", @@ -21497,8 +22720,7 @@ "ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "devOptional": true + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" }, "ipaddr.js": { "version": "1.9.1", @@ -21620,7 +22842,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=", - "devOptional": true + "dev": true }, "is-npm": { "version": "5.0.0", @@ -21693,7 +22915,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "devOptional": true }, "is-valid-path": { "version": "0.1.1", @@ -21715,6 +22937,12 @@ "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", "dev": true }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "devOptional": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -21727,6 +22955,12 @@ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "optional": true + }, "istanbul-lib-coverage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", @@ -23218,6 +24452,11 @@ "@sideway/pinpoint": "^2.0.0" } }, + "js-sdsl": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-2.1.4.tgz", + "integrity": "sha512-/Ew+CJWHNddr7sjwgxaVeIORIH4AMVC9dy0hPf540ZGMVgS9d3ajwuVdyhDt6/QUvT8ATjR3yuYBKsS79F+H4A==" + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -23234,6 +24473,12 @@ "esprima": "^4.0.0" } }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, "jsdom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", @@ -23269,6 +24514,12 @@ "xml-name-validator": "^3.0.0" }, "dependencies": { + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, "acorn": { "version": "8.7.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", @@ -23285,6 +24536,17 @@ "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } } } }, @@ -23315,11 +24577,17 @@ "jju": "^1.1.0" } }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "optional": true + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "devOptional": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -23327,6 +24595,12 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "optional": true + }, "json5": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", @@ -23369,6 +24643,18 @@ } } }, + "jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "optional": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, "just-performance": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/just-performance/-/just-performance-4.3.0.tgz", @@ -23720,30 +25006,6 @@ "semver": "^6.0.0" } }, - "make-fetch-happen": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", - "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", - "optional": true, - "requires": { - "agentkeepalive": "^4.1.3", - "cacache": "^15.2.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^6.0.0", - "minipass": "^3.1.3", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^1.3.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.2", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^6.0.0", - "ssri": "^8.0.0" - } - }, "makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -23790,6 +25052,15 @@ "yargs-parser": "^20.2.3" }, "dependencies": { + "hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, "normalize-package-data": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", @@ -23858,13 +25129,13 @@ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" }, "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" } }, "mime": { @@ -23914,8 +25185,7 @@ "minimist": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "minimist-options": { "version": "4.1.0", @@ -23948,28 +25218,16 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "devOptional": true, + "dev": true, "requires": { "minipass": "^3.0.0" } }, - "minipass-fetch": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", - "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", - "optional": true, - "requires": { - "encoding": "^0.1.12", - "minipass": "^3.1.0", - "minipass-sized": "^1.0.3", - "minizlib": "^2.0.0" - } - }, "minipass-flush": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "devOptional": true, + "dev": true, "requires": { "minipass": "^3.0.0" } @@ -23988,7 +25246,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "devOptional": true, + "dev": true, "requires": { "minipass": "^3.0.0" } @@ -23997,7 +25255,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "devOptional": true, + "dev": true, "requires": { "minipass": "^3.0.0" } @@ -24040,6 +25298,50 @@ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "dev": true }, + "mqemitter": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/mqemitter/-/mqemitter-4.5.0.tgz", + "integrity": "sha512-Mp/zytFeIv6piJQkEKnncHcP4R/ErJc5C7dfonkhkNUT2LA/nTayrfNxbipp3M5iCJUTQSUtzfQAQA3XVcKz6w==", + "dev": true, + "requires": { + "fastparallel": "^2.3.0", + "qlobber": "^5.0.0" + } + }, + "mqtt": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.3.7.tgz", + "integrity": "sha512-ew3qwG/TJRorTz47eW46vZ5oBw5MEYbQZVaEji44j5lAUSQSqIEoul7Kua/BatBW0H0kKQcC9kwUHa1qzaWHSw==", + "requires": { + "commist": "^1.0.0", + "concat-stream": "^2.0.0", + "debug": "^4.1.1", + "duplexify": "^4.1.1", + "help-me": "^3.0.0", + "inherits": "^2.0.3", + "lru-cache": "^6.0.0", + "minimist": "^1.2.5", + "mqtt-packet": "^6.8.0", + "number-allocator": "^1.0.9", + "pump": "^3.0.0", + "readable-stream": "^3.6.0", + "reinterval": "^1.1.0", + "rfdc": "^1.3.0", + "split2": "^3.1.0", + "ws": "^7.5.5", + "xtend": "^4.0.2" + } + }, + "mqtt-packet": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", + "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", + "requires": { + "bl": "^4.0.2", + "debug": "^4.1.1", + "process-nextick-args": "^2.0.1" + } + }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -24051,9 +25353,9 @@ "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==" }, "nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==" + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.2.tgz", + "integrity": "sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==" }, "natural-compare": { "version": "1.4.0", @@ -24067,9 +25369,17 @@ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, "node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + }, + "node-cloudflared-tunnel": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/node-cloudflared-tunnel/-/node-cloudflared-tunnel-1.0.9.tgz", + "integrity": "sha512-d0mhIM5P2ldE2yHChehC6EvnpFCkifWRzWrW81gVWdcCWqNcyISXuDdOYzRW5mwmjWuT6WNtLJoGQ84uqS4EmA==", + "requires": { + "command-exists": "^1.2.9" + } }, "node-fetch": { "version": "2.6.7", @@ -24101,69 +25411,140 @@ } }, "node-gyp": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz", - "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", + "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", "optional": true, "requires": { "env-paths": "^2.2.0", "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^9.1.0", + "graceful-fs": "^4.2.3", "nopt": "^5.0.0", - "npmlog": "^6.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", + "semver": "^7.3.2", + "tar": "^6.0.2", "which": "^2.0.2" }, "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "optional": true + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "optional": true + }, "are-we-there-yet": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz", - "integrity": "sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "optional": true, "requires": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" } }, - "gauge": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.3.tgz", - "integrity": "sha512-ICw1DhAwMtb22rYFwEHgJcx1JCwJGv3x6G0OQUq56Nge+H4Q8JEwr8iveS0XFlsUNSI67F5ffMGK25bK4Pmskw==", + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "optional": true, "requires": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" + "number-is-nan": "^1.0.0" } }, "npmlog": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.1.tgz", - "integrity": "sha512-BTHDvY6nrRHuRfyjt1MAufLxYdVXZfd099H4+i1f0lPywNQyI4foeNXJRObB/uy+TYqUW0vAD9gbdSOXPst7Eg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "optional": true, "requires": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.0", - "set-blocking": "^2.0.0" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true + }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "optional": true, "requires": { "lru-cache": "^6.0.0" } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } } } }, @@ -24204,23 +25585,6 @@ "validate-npm-package-license": "^3.0.4" }, "dependencies": { - "hosted-git-info": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.0.0.tgz", - "integrity": "sha512-rRnjWu0Bxj+nIfUOkz0695C0H6tRrN5iYIzYejb0tDEefe2AekHu/U5Kn9pEie5vsJqpNQU02az7TGSH3qpz4Q==", - "dev": true, - "requires": { - "lru-cache": "^7.5.1" - }, - "dependencies": { - "lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", - "dev": true - } - } - }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -24265,9 +25629,9 @@ } }, "npm-check-updates": { - "version": "12.5.4", - "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-12.5.4.tgz", - "integrity": "sha512-4+27zaTdieWgvPLaCZ/A6Q2WC1cYVcrc2SqVmLFYgkWBrKw1QkwpeV16FSvkFGZr3OdFyr7Dpjw8JRn4H2QxFw==", + "version": "12.5.5", + "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-12.5.5.tgz", + "integrity": "sha512-7LH6KN6F1fZMtY4zNYAQPpJU1ToxZ6sSCxk948vrLIz97aNqmPLSX72MrmbOWwpyBgLCPbFJWY/k3zE18pmxfw==", "dev": true, "requires": { "chalk": "^4.1.2", @@ -24279,7 +25643,7 @@ "fp-and-or": "^0.1.3", "get-stdin": "^8.0.0", "globby": "^11.0.4", - "hosted-git-info": "^4.1.0", + "hosted-git-info": "^5.0.0", "json-parse-helpfulerror": "^1.0.3", "jsonlines": "^0.1.1", "libnpmconfig": "^1.2.1", @@ -24449,33 +25813,16 @@ "dev": true }, "npm-package-arg": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-9.0.1.tgz", - "integrity": "sha512-Xs9wznfEAmZAR61qsYH3iN24V/qMYYkvAR5CRQNMvC6PjN2fHtO8y9XP/xdp5K+Icx+u1wMBMgWRPCmAEChSog==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-9.0.2.tgz", + "integrity": "sha512-v/miORuX8cndiOheW8p2moNuPJ7QhcFh9WGlTorruG8hXSA23vMTEp5hTCmDxic0nD8KHhj/NQgFuySD3GYY3g==", "dev": true, "requires": { "hosted-git-info": "^5.0.0", "semver": "^7.3.5", - "validate-npm-package-name": "^3.0.0" + "validate-npm-package-name": "^4.0.0" }, "dependencies": { - "hosted-git-info": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.0.0.tgz", - "integrity": "sha512-rRnjWu0Bxj+nIfUOkz0695C0H6tRrN5iYIzYejb0tDEefe2AekHu/U5Kn9pEie5vsJqpNQU02az7TGSH3qpz4Q==", - "dev": true, - "requires": { - "lru-cache": "^7.5.1" - }, - "dependencies": { - "lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", - "dev": true - } - } - }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -24523,39 +25870,43 @@ } }, "npm-registry-fetch": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-13.0.1.tgz", - "integrity": "sha512-Ak+LXVtSrCLOdscFW/apUw67OPNph8waHsPKM9UOJosL7i59EF5XoSWQMEsXEOeifM9Bb4/2+WrQC4t/pd8DGg==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-13.1.0.tgz", + "integrity": "sha512-TIYL5X8CcwDhbFMXFDShNcpG6OMCYK6VzvSr6MUWP20tCU2DJ4ao2qQg3DT+3Pet8mO6/cgbZpon4LMh3duYLg==", "dev": true, "requires": { - "make-fetch-happen": "^10.0.3", + "make-fetch-happen": "^10.0.6", "minipass": "^3.1.6", - "minipass-fetch": "^2.0.1", + "minipass-fetch": "^2.0.3", "minipass-json-stream": "^1.0.1", "minizlib": "^2.1.2", - "npm-package-arg": "^9.0.0", + "npm-package-arg": "^9.0.1", "proc-log": "^2.0.0" }, "dependencies": { - "@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true + "@npmcli/fs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.0.tgz", + "integrity": "sha512-DmfBvNXGaetMxj9LTp8NAN9vEidXURrf5ZTslQzEAi/6GbW+4yjaLFQc6Tue5cpZ9Frlk4OBo/Snf1Bh/S7qTQ==", + "dev": true, + "requires": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + } }, "cacache": { - "version": "16.0.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.2.tgz", - "integrity": "sha512-Q17j7s8X81i/QYVrKVQ/qwWGT+pYLfpTcZ+X+p/Qw9FULy9JEfb2FECYTTt6mPV6A/vk92nRZ80ncpKxiGTrIA==", + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.3.tgz", + "integrity": "sha512-eC7wYodNCVb97kuHGk5P+xZsvUJHkhSEOyNwkenqQPAsOtrTjvWOE5vSPNBpz9d8X3acIf6w2Ub5s4rvOCTs4g==", "dev": true, "requires": { - "@npmcli/fs": "^1.0.0", + "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^1.1.2", "chownr": "^2.0.0", "fs-minipass": "^2.1.0", "glob": "^7.2.0", "infer-owner": "^1.0.4", - "lru-cache": "^7.5.1", + "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", @@ -24569,36 +25920,25 @@ "unique-filename": "^1.1.1" } }, - "http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "requires": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - } - }, "lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", "dev": true }, "make-fetch-happen": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.0.6.tgz", - "integrity": "sha512-4Gfh6lV3TLXmj7qz79hBFuvVqjYSMW6v2+sxtdX4LFQU0rK3V/txRjE0DoZb7X0IF3t9f8NO3CxPSWlvdckhVA==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.1.1.tgz", + "integrity": "sha512-3/mCljDQNjmrP7kl0vhS5WVlV+TvSKoZaFhdiYV7MOijEnrhrjaVnqbp/EY/7S+fhUB2KpH7j8c1iRsIOs+kjw==", "dev": true, "requires": { "agentkeepalive": "^4.2.1", - "cacache": "^16.0.0", + "cacache": "^16.0.2", "http-cache-semantics": "^4.1.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", - "lru-cache": "^7.5.1", + "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-fetch": "^2.0.3", @@ -24611,9 +25951,9 @@ } }, "minipass-fetch": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.0.3.tgz", - "integrity": "sha512-VA+eiiUtaIvpQJXISwE3OiMvQwAWrgKb97F0aXlCS1Ahikr8fEQq8m3Hf7Kv9KT3nokuHigJKsDMB6atU04olQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.0.tgz", + "integrity": "sha512-H9U4UVBGXEyyWJnqYDCLp1PwD8XIkJ4akNHp1aGVI+2Ym7wQMlxDKi4IB4JbmyU+pl9pEs/cVrK6cOuvmbK4Sg==", "dev": true, "requires": { "encoding": "^0.1.13", @@ -24621,6 +25961,26 @@ "minipass-sized": "^1.0.3", "minizlib": "^2.1.2" } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } + } } } }, @@ -24644,6 +26004,21 @@ "set-blocking": "^2.0.0" } }, + "number-allocator": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.10.tgz", + "integrity": "sha512-K4AvNGKo9lP6HqsZyfSr9KDaqnwFzW203inhQEOwFrmFaYevpdX4VNwdOLk197aHujzbT//z6pCBrCOUYSM5iw==", + "requires": { + "debug": "^4.3.1", + "js-sdsl": "^2.1.2" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "optional": true + }, "numbered": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/numbered/-/numbered-1.1.0.tgz", @@ -24655,6 +26030,12 @@ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "optional": true + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -24754,7 +26135,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "devOptional": true, + "dev": true, "requires": { "aggregate-error": "^3.0.0" } @@ -24821,19 +26202,29 @@ "tar": "^6.1.11" }, "dependencies": { + "@npmcli/fs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.0.tgz", + "integrity": "sha512-DmfBvNXGaetMxj9LTp8NAN9vEidXURrf5ZTslQzEAi/6GbW+4yjaLFQc6Tue5cpZ9Frlk4OBo/Snf1Bh/S7qTQ==", + "dev": true, + "requires": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + } + }, "cacache": { - "version": "16.0.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.2.tgz", - "integrity": "sha512-Q17j7s8X81i/QYVrKVQ/qwWGT+pYLfpTcZ+X+p/Qw9FULy9JEfb2FECYTTt6mPV6A/vk92nRZ80ncpKxiGTrIA==", + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.3.tgz", + "integrity": "sha512-eC7wYodNCVb97kuHGk5P+xZsvUJHkhSEOyNwkenqQPAsOtrTjvWOE5vSPNBpz9d8X3acIf6w2Ub5s4rvOCTs4g==", "dev": true, "requires": { - "@npmcli/fs": "^1.0.0", + "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^1.1.2", "chownr": "^2.0.0", "fs-minipass": "^2.1.0", "glob": "^7.2.0", "infer-owner": "^1.0.4", - "lru-cache": "^7.5.1", + "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", @@ -24848,10 +26239,30 @@ } }, "lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } + } } } }, @@ -24952,6 +26363,12 @@ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", "dev": true }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "optional": true + }, "pg-connection-string": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", @@ -25003,6 +26420,17 @@ "source-map-js": "^1.0.2" } }, + "postcss-html": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.3.1.tgz", + "integrity": "sha512-SJ7iRw+IngyZv3Z9lChlZU30a9y9MZjZZcoUJmx0T/nKE9S+hetJ8fAv/MRu4bPnGDsXhVlaFs5+umpK3yaaQQ==", + "dev": true, + "requires": { + "htmlparser2": "^7.1.2", + "postcss": "^8.4.0", + "postcss-safe-parser": "^6.0.0" + } + }, "postcss-media-query-parser": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", @@ -25035,9 +26463,9 @@ "integrity": "sha512-j4KxzWovfdHsyxwl1BxkUal/O4uirvHgdzMKS1aWJBAV0qh2qj5qAZqpeBfVUYGWv+4iK9Az7SPyZ4fyNju1uA==" }, "postcss-selector-parser": { - "version": "6.0.9", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz", - "integrity": "sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ==", + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", "dev": true, "requires": { "cssesc": "^3.0.0", @@ -25081,12 +26509,22 @@ } } }, + "prismjs": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz", + "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==" + }, "proc-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-2.0.0.tgz", - "integrity": "sha512-I/35MfCX2H8jBUhKN8JB8nmqvQo/nKdrBodBY7L3RhDSPPyvOHwLYNmPuhwuJq7a7C3vgFKWGQM+ecPStcvOHA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-2.0.1.tgz", + "integrity": "sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==", "dev": true }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -25128,13 +26566,13 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "devOptional": true + "dev": true }, "promise-retry": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "devOptional": true, + "dev": true, "requires": { "err-code": "^2.0.2", "retry": "^0.12.0" @@ -25174,13 +26612,12 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true + "devOptional": true }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -25190,7 +26627,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "devOptional": true }, "pupa": { "version": "2.1.1", @@ -25244,6 +26681,12 @@ } } }, + "qlobber": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/qlobber/-/qlobber-5.0.3.tgz", + "integrity": "sha512-wW4GTZPePyh0RgOsM18oDyOUlXfurVRgoNyJfS+y7VWPyd0GYhQp5T2tycZFZjonH+hngxIfklGJhTP/ghidgQ==", + "dev": true + }, "qrcode": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.0.tgz", @@ -25660,12 +27103,80 @@ } } }, + "reinterval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", + "integrity": "sha1-M2Hs+jymwYKDOA3Qu5VG85D17Oc=" + }, "remote-git-tags": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/remote-git-tags/-/remote-git-tags-3.0.0.tgz", "integrity": "sha512-C9hAO4eoEsX+OXA4rla66pXZQ+TLQ8T9dttgQj18yuKlPMTVkIkdYXvlMC55IuUsIkV6DpmQYi10JKFLaU+l7w==", "dev": true }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "optional": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "optional": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "optional": true + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "optional": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "optional": true + } + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -25740,11 +27251,17 @@ "lowercase-keys": "^1.0.0" } }, + "retimer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/retimer/-/retimer-3.0.0.tgz", + "integrity": "sha512-WKE0j11Pa0ZJI5YIk0nflGI7SQsfl2ljihVy7ogh7DeQSeYAUi0ubZ/yEueGtDfUPk6GH5LRw1hBdLq4IwUBWA==", + "dev": true + }, "retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "devOptional": true + "dev": true }, "reusify": { "version": "1.0.4", @@ -25752,6 +27269,11 @@ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true }, + "rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -26045,8 +27567,7 @@ "smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "devOptional": true + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" }, "socket.io": { "version": "4.4.1", @@ -26104,7 +27625,6 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", - "devOptional": true, "requires": { "ip": "^1.1.5", "smart-buffer": "^4.2.0" @@ -26114,7 +27634,6 @@ "version": "6.1.1", "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz", "integrity": "sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew==", - "devOptional": true, "requires": { "agent-base": "^6.0.2", "debug": "^4.3.1", @@ -26215,17 +27734,42 @@ "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==", "dev": true }, + "split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "requires": { + "readable-stream": "^3.0.0" + } + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "optional": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, "ssri": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "devOptional": true, + "dev": true, "requires": { "minipass": "^3.1.1" } @@ -26252,6 +27796,11 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -26510,9 +28059,9 @@ }, "dependencies": { "ajv": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz", - "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -26727,6 +28276,21 @@ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", "dev": true }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "optional": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -26757,6 +28321,11 @@ "mime-types": "~2.1.24" } }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, "typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", @@ -26814,7 +28383,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "devOptional": true, + "dev": true, "requires": { "unique-slug": "^2.0.0" } @@ -26823,7 +28392,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "devOptional": true, + "dev": true, "requires": { "imurmurhash": "^0.1.4" } @@ -26946,7 +28515,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, + "devOptional": true, "requires": { "punycode": "^2.1.0" } @@ -26970,6 +28539,18 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true + }, + "uuid-parse": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/uuid-parse/-/uuid-parse-1.1.0.tgz", + "integrity": "sha512-OdmXxA8rDsQ7YpNVbKSJkNzTw2I+S5WsbMDnCtIWSQaosNAcWtFuI/YK1TjzUI6nbkgiqEyh8gWngfcv8Asd9A==", + "dev": true + }, "v-pagination-3": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/v-pagination-3/-/v-pagination-3-0.1.7.tgz", @@ -27016,12 +28597,12 @@ } }, "validate-npm-package-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", - "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz", + "integrity": "sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==", "dev": true, "requires": { - "builtins": "^1.0.3" + "builtins": "^5.0.0" } }, "vary": { @@ -27029,6 +28610,25 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "optional": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "optional": true + } + } + }, "vite": { "version": "2.6.14", "resolved": "https://registry.npmjs.org/vite/-/vite-2.6.14.tgz", @@ -27151,6 +28751,11 @@ "resolved": "https://registry.npmjs.org/vue-multiselect/-/vue-multiselect-3.0.0-alpha.2.tgz", "integrity": "sha512-Xp9fGJECns45v+v8jXbCIsAkCybYkEg0lNwr7Z6HDUSMyx2TEIK2giipPE+qXiShEc1Ipn+ZtttH2iq9hwXP4Q==" }, + "vue-prism-editor": { + "version": "2.0.0-alpha.2", + "resolved": "https://registry.npmjs.org/vue-prism-editor/-/vue-prism-editor-2.0.0-alpha.2.tgz", + "integrity": "sha512-Gu42ba9nosrE+gJpnAEuEkDMqG9zSUysIR8SdXUw8MQKDjBnnNR9lHC18uOr/ICz7yrA/5c7jHJr9lpElODC7w==" + }, "vue-qrcode": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/vue-qrcode/-/vue-qrcode-1.0.0.tgz", @@ -27369,8 +28974,7 @@ "ws": { "version": "7.5.7", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", - "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", - "dev": true + "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==" }, "xdg-basedir": { "version": "4.0.0", @@ -27395,6 +28999,11 @@ "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==" }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index 134271c0..4d94d0e4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "uptime-kuma", - "version": "1.13.1", + "version": "1.15.0-beta.0", "license": "MIT", "repository": { "type": "git", @@ -13,6 +13,7 @@ "install-legacy": "npm install --legacy-peer-deps", "update-legacy": "npm update --legacy-peer-deps", "lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .", + "lint-fix:js": "eslint --ext \".js,.vue\" --fix --ignore-path .gitignore .", "lint:style": "stylelint \"**/*.{vue,css,scss}\" --ignore-path .gitignore", "lint": "npm run lint:js && npm run lint:style", "dev": "vite --host --config ./config/vite.config.js", @@ -20,7 +21,7 @@ "start-server": "node server/server.js", "start-server-dev": "cross-env NODE_ENV=development node server/server.js", "build": "vite build --config ./config/vite.config.js", - "test": "node test/prepare-test-server.js && node server/server.js --port=3002 --data-dir=./data/test/ --test", + "test": "npm run lint && node test/prepare-test-server.js && node server/server.js --port=3002 --data-dir=./data/test/ --test", "test-with-build": "npm run build && npm test", "jest": "node test/prepare-jest.js && npm run jest-frontend && npm run jest-backend", "jest-frontend": "cross-env TEST_FRONTEND=1 jest --config=./config/jest-frontend.config.js", @@ -36,7 +37,7 @@ "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 -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:upload-artifact --build-arg VERSION --build-arg GITHUB_TOKEN --target upload-artifact . --progress plain", - "setup": "git checkout 1.13.1 && npm ci --production && npm run download-dist", + "setup": "git checkout 1.14.0 && npm ci --production && npm run download-dist", "download-dist": "node extra/download-dist.js", "mark-as-nightly": "node extra/mark-as-nightly.js", "reset-password": "node extra/reset-password.js", @@ -48,6 +49,7 @@ "test-install-script-ubuntu1604": "npm run compile-install-script && docker build --progress plain -f test/test_install_script/ubuntu1604.dockerfile .", "test-nodejs16": "docker build --progress plain -f test/ubuntu-nodejs16.dockerfile .", "simple-dns-server": "node extra/simple-dns-server.js", + "simple-mqtt-server": "node extra/simple-mqtt-server.js", "update-language-files-with-base-lang": "cd extra/update-language-files && node index.js %npm_config_base_lang% && eslint ../../src/languages/**.js --fix", "update-language-files": "cd extra/update-language-files && node index.js && eslint ../../src/languages/**.js --fix", "ncu-patch": "npm-check-updates -u -t patch", @@ -60,7 +62,7 @@ "@fortawesome/free-regular-svg-icons": "~5.15.4", "@fortawesome/free-solid-svg-icons": "~5.15.4", "@fortawesome/vue-fontawesome": "~3.0.0-5", - "@louislam/sqlite3": "~6.0.1", + "@louislam/sqlite3": "~15.0.3", "@popperjs/core": "~2.10.2", "args-parser": "~1.3.0", "axios": "~0.26.1", @@ -79,21 +81,27 @@ "favico.js": "^0.3.10", "form-data": "~4.0.0", "http-graceful-shutdown": "~3.1.7", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", "iconv-lite": "^0.6.3", "jsonwebtoken": "~8.5.1", "jwt-decode": "^3.1.2", "limiter": "^2.1.0", + "mqtt": "^4.2.8", + "node-cloudflared-tunnel": "~1.0.9", "nodemailer": "~6.6.5", "notp": "~2.0.3", "password-hash": "~1.2.2", "postcss-rtlcss": "~3.4.1", "postcss-scss": "~4.0.3", + "prismjs": "^1.27.0", "prom-client": "~13.2.0", "prometheus-api-metrics": "~3.2.1", "qrcode": "~1.5.0", "redbean-node": "0.1.3", "socket.io": "~4.4.1", "socket.io-client": "~4.4.1", + "socks-proxy-agent": "^6.1.1", "tar": "^6.1.11", "tcp-ping": "~0.1.1", "thirty-two": "~1.0.2", @@ -106,19 +114,21 @@ "vue-i18n": "~9.1.9", "vue-image-crop-upload": "~3.0.3", "vue-multiselect": "~3.0.0-alpha.2", + "vue-prism-editor": "^2.0.0-alpha.2", "vue-qrcode": "~1.0.0", "vue-router": "~4.0.14", "vue-toastification": "~2.0.0-rc.5", "vuedraggable": "~4.1.0" }, "devDependencies": { - "@actions/github": "~5.0.0", + "@actions/github": "~5.0.1", "@babel/eslint-parser": "~7.15.8", "@babel/preset-env": "^7.15.8", "@types/bootstrap": "~5.1.9", "@vitejs/plugin-legacy": "~1.6.4", "@vitejs/plugin-vue": "~1.9.4", "@vue/compiler-sfc": "~3.2.31", + "aedes": "^0.46.3", "babel-plugin-rewire": "~1.2.0", "core-js": "~3.18.3", "cross-env": "~7.0.3", @@ -127,7 +137,8 @@ "eslint-plugin-vue": "~7.18.0", "jest": "~27.2.5", "jest-puppeteer": "~6.0.3", - "npm-check-updates": "^12.5.4", + "npm-check-updates": "^12.5.5", + "postcss-html": "^1.3.1", "puppeteer": "~13.1.3", "sass": "~1.42.1", "stylelint": "~14.2.0", diff --git a/server/2fa.js b/server/2fa.js index bc8145cf..f8d700bf 100644 --- a/server/2fa.js +++ b/server/2fa.js @@ -1,4 +1,3 @@ -const { checkLogin } = require("./util-server"); const { R } = require("redbean-node"); class TwoFA { diff --git a/server/auth.js b/server/auth.js index 1196f94d..d9412ae3 100644 --- a/server/auth.js +++ b/server/auth.js @@ -2,7 +2,6 @@ const basicAuth = require("express-basic-auth"); const passwordHash = require("./password-hash"); const { R } = require("redbean-node"); const { setting } = require("./util-server"); -const { debug } = require("../src/util"); const { loginRateLimiter } = require("./rate-limiter"); /** @@ -12,6 +11,10 @@ const { loginRateLimiter } = require("./rate-limiter"); * @returns {Promise} */ exports.login = async function (username, password) { + if (typeof username !== "string" || typeof password !== "string") { + return null; + } + let user = await R.findOne("user", " username = ? AND active = 1 ", [ username, ]); @@ -30,6 +33,13 @@ exports.login = async function (username, password) { return null; }; +/** + * A function that checks if a user is logged in. + * @param {string} username The username of the user to check for. + * @param {function} callback The callback to call when done, with an error and result parameter. + * + * Generated by Trelent + */ function myAuthorizer(username, password, callback) { // Login Rate Limit loginRateLimiter.pass(null, 0).then((pass) => { diff --git a/server/check-version.js b/server/check-version.js index f3b15e84..c9d87c96 100644 --- a/server/check-version.js +++ b/server/check-version.js @@ -17,7 +17,7 @@ exports.startInterval = () => { res.data.slow = "1000.0.0"; } - if (!await setting("checkUpdate")) { + if (await setting("checkUpdate") === false) { return; } diff --git a/server/client.js b/server/client.js index c7b3bc16..31b10e84 100644 --- a/server/client.js +++ b/server/client.js @@ -7,6 +7,12 @@ const { io } = require("./server"); const { setting } = require("./util-server"); const checkVersion = require("./check-version"); +/** + * Send a list of notifications to the user. + * @param {Socket} socket The socket object that is connected to the client. + * + * Generated by Trelent + */ async function sendNotificationList(socket) { const timeLogger = new TimeLogger(); @@ -83,6 +89,29 @@ async function sendImportantHeartbeatList(socket, monitorID, toUser = false, ove } +/** + * Delivers proxy list + * + * @param socket + * @return {Promise} + */ +async function sendProxyList(socket) { + const timeLogger = new TimeLogger(); + + const list = await R.find("proxy", " user_id = ? ", [ socket.userID ]); + io.to(socket.userID).emit("proxyList", list.map(bean => bean.export())); + + timeLogger.print("Send Proxy List"); + + return list; +} + +/** + * Emits the version information to the client. + * @param {Socket} socket The socket object that is connected to the client. + * + * Generated by Trelent + */ async function sendInfo(socket) { socket.emit("info", { version: checkVersion.version, @@ -95,6 +124,6 @@ module.exports = { sendNotificationList, sendImportantHeartbeatList, sendHeartbeatList, - sendInfo + sendProxyList, + sendInfo, }; - diff --git a/server/database.js b/server/database.js index 5cd57c9d..099d15d5 100644 --- a/server/database.js +++ b/server/database.js @@ -1,7 +1,7 @@ const fs = require("fs"); const { R } = require("redbean-node"); const { setSetting, setting } = require("./util-server"); -const { debug, sleep } = require("../src/util"); +const { log, sleep } = require("../src/util"); const dayjs = require("dayjs"); const knex = require("knex"); @@ -54,6 +54,10 @@ class Database { "patch-notification_sent_history.sql": true, "patch-monitor-basic-auth.sql": true, "patch-status-page.sql": true, + "patch-proxy.sql": true, + "patch-monitor-expiry-notification.sql": true, + "patch-status-page-footer-css.sql": true, + "patch-added-mqtt-monitor.sql": true, } /** @@ -78,10 +82,10 @@ class Database { fs.mkdirSync(Database.uploadDir, { recursive: true }); } - console.log(`Data Dir: ${Database.dataDir}`); + log.info("db", `Data Dir: ${Database.dataDir}`); } - static async connect(testMode = false) { + static async connect(testMode = false, autoloadModels = true, noLog = false) { const acquireConnectionTimeout = 120 * 1000; const Dialect = require("knex/lib/dialects/sqlite3/index.js"); @@ -111,7 +115,10 @@ class Database { // Auto map the model to a bean object R.freeze(true); - await R.autoloadModels("./server/model"); + + if (autoloadModels) { + await R.autoloadModels("./server/model"); + } await R.exec("PRAGMA foreign_keys = ON"); if (testMode) { @@ -124,10 +131,17 @@ class Database { await R.exec("PRAGMA cache_size = -12000"); await R.exec("PRAGMA auto_vacuum = FULL"); - console.log("SQLite config:"); - console.log(await R.getAll("PRAGMA journal_mode")); - console.log(await R.getAll("PRAGMA cache_size")); - console.log("SQLite Version: " + await R.getCell("SELECT sqlite_version()")); + // This ensures that an operating system crash or power failure will not corrupt the database. + // FULL synchronous is very safe, but it is also slower. + // Read more: https://sqlite.org/pragma.html#pragma_synchronous + await R.exec("PRAGMA synchronous = FULL"); + + if (!noLog) { + log.info("db", "SQLite config:"); + log.info("db", await R.getAll("PRAGMA journal_mode")); + log.info("db", await R.getAll("PRAGMA cache_size")); + log.info("db", "SQLite Version: " + await R.getCell("SELECT sqlite_version()")); + } } static async patch() { @@ -137,15 +151,15 @@ class Database { version = 0; } - console.info("Your database version: " + version); - console.info("Latest database version: " + this.latestVersion); + log.info("db", "Your database version: " + version); + log.info("db", "Latest database version: " + this.latestVersion); if (version === this.latestVersion) { - console.info("Database patch not needed"); + log.info("db", "Database patch not needed"); } else if (version > this.latestVersion) { - console.info("Warning: Database version is newer than expected"); + log.info("db", "Warning: Database version is newer than expected"); } else { - console.info("Database patch is needed"); + log.info("db", "Database patch is needed"); this.backup(version); @@ -153,17 +167,17 @@ class Database { try { for (let i = version + 1; i <= this.latestVersion; i++) { const sqlFile = `./db/patch${i}.sql`; - console.info(`Patching ${sqlFile}`); + log.info("db", `Patching ${sqlFile}`); await Database.importSQLFile(sqlFile); - console.info(`Patched ${sqlFile}`); + log.info("db", `Patched ${sqlFile}`); await setSetting("database_version", i); } } catch (ex) { await Database.close(); - console.error(ex); - 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"); + log.error("db", ex); + log.error("db", "Start Uptime-Kuma failed due to issue patching the database"); + log.error("db", "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); @@ -179,15 +193,15 @@ class Database { * @returns {Promise} */ static async patch2() { - console.log("Database Patch 2.0 Process"); + log.info("db", "Database Patch 2.0 Process"); let databasePatchedFiles = await setting("databasePatchedFiles"); if (! databasePatchedFiles) { databasePatchedFiles = {}; } - debug("Patched files:"); - debug(databasePatchedFiles); + log.debug("db", "Patched files:"); + log.debug("db", databasePatchedFiles); try { for (let sqlFilename in this.patchList) { @@ -195,15 +209,15 @@ class Database { } if (this.patched) { - console.log("Database Patched Successfully"); + log.info("db", "Database Patched Successfully"); } } catch (ex) { await Database.close(); - console.error(ex); - 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"); + log.error("db", ex); + log.error("db", "Start Uptime-Kuma failed due to issue patching the database"); + log.error("db", "Please submit the bug report if you still encounter the problem after restart: https://github.com/louislam/uptime-kuma/issues"); this.restore(); @@ -290,16 +304,16 @@ class Database { let value = this.patchList[sqlFilename]; if (! value) { - console.log(sqlFilename + " skip"); + log.info("db", sqlFilename + " skip"); return; } // Check if patched if (! databasePatchedFiles[sqlFilename]) { - console.log(sqlFilename + " is not patched"); + log.info("db", sqlFilename + " is not patched"); if (value.parents) { - console.log(sqlFilename + " need parents"); + log.info("db", sqlFilename + " need parents"); for (let parentSQLFilename of value.parents) { await this.patch2Recursion(parentSQLFilename, databasePatchedFiles); } @@ -307,14 +321,14 @@ class Database { this.backup(dayjs().format("YYYYMMDDHHmmss")); - console.log(sqlFilename + " is patching"); + log.info("db", sqlFilename + " is patching"); this.patched = true; await this.importSQLFile("./db/" + sqlFilename); databasePatchedFiles[sqlFilename] = true; - console.log(sqlFilename + " was patched successfully"); + log.info("db", sqlFilename + " was patched successfully"); } else { - debug(sqlFilename + " is already patched, skip"); + log.debug("db", sqlFilename + " is already patched, skip"); } } @@ -366,7 +380,7 @@ class Database { }; process.addListener("unhandledRejection", listener); - console.log("Closing the database"); + log.info("db", "Closing the database"); while (true) { Database.noReject = true; @@ -376,10 +390,10 @@ class Database { if (Database.noReject) { break; } else { - console.log("Waiting to close the database"); + log.info("db", "Waiting to close the database"); } } - console.log("SQLite closed"); + log.info("db", "SQLite closed"); process.removeListener("unhandledRejection", listener); } @@ -391,7 +405,7 @@ class Database { */ static backup(version) { if (! this.backupPath) { - console.info("Backing up the database"); + log.info("db", "Backing up the database"); this.backupPath = this.dataDir + "kuma.db.bak" + version; fs.copyFileSync(Database.path, this.backupPath); @@ -414,7 +428,7 @@ class Database { */ static restore() { if (this.backupPath) { - console.error("Patching the database failed!!! Restoring the backup"); + log.error("db", "Patching the database failed!!! Restoring the backup"); const shmPath = Database.path + "-shm"; const walPath = Database.path + "-wal"; @@ -433,7 +447,7 @@ class Database { fs.unlinkSync(walPath); } } catch (e) { - console.log("Restore failed; you may need to restore the backup manually"); + log.error("db", "Restore failed; you may need to restore the backup manually"); process.exit(1); } @@ -449,14 +463,14 @@ class Database { } } else { - console.log("Nothing to restore"); + log.info("db", "Nothing to restore"); } } static getSize() { - debug("Database.getSize()"); + log.debug("db", "Database.getSize()"); let stats = fs.statSync(Database.path); - debug(stats); + log.debug("db", stats); return stats.size; } diff --git a/server/image-data-uri.js b/server/image-data-uri.js index 3ccaab7d..fbff9340 100644 --- a/server/image-data-uri.js +++ b/server/image-data-uri.js @@ -3,12 +3,19 @@ Modified with 0 dependencies */ let fs = require("fs"); +const { log } = require("../src/util"); let ImageDataURI = (() => { + /** + * @param {string} dataURI - A string that is a valid Data URI. + * @returns {?Object} An object with properties "imageType" and "dataBase64". The former is the image type, e.g., "png", and the latter is a base64 encoded string of the image's binary data. If it fails to parse, returns null instead of an object. + * + * Generated by Trelent + */ function decode(dataURI) { if (!/data:image\//.test(dataURI)) { - console.log("ImageDataURI :: Error :: It seems that it is not an Image Data URI. Couldn't match \"data:image/\""); + log.error("image-data-uri", "It seems that it is not an Image Data URI. Couldn't match \"data:image/\""); return null; } @@ -20,9 +27,16 @@ let ImageDataURI = (() => { }; } + /** + * @param {Buffer} data - The image data to be encoded. + * @param {String} mediaType - The type of the image, e.g., "image/png". + * @returns {String|null} A string representing the base64-encoded version of the given Buffer object or null if an error occurred. + * + * Generated by Trelent + */ function encode(data, mediaType) { if (!data || !mediaType) { - console.log("ImageDataURI :: Error :: Missing some of the required params: data, mediaType "); + log.error("image-data-uri", "Missing some of the required params: data, mediaType"); return null; } @@ -33,6 +47,13 @@ let ImageDataURI = (() => { return dataImgBase64; } + /** + * Converts a data URI to a file path. + * @param {string} dataURI The Data URI of the image. + * @param {string} [filePath] The path where the image will be saved, defaults to "./". + * + * Generated by Trelent + */ function outputFile(dataURI, filePath) { filePath = filePath || "./"; return new Promise((resolve, reject) => { diff --git a/server/jobs.js b/server/jobs.js index 0469d5ca..739e867d 100644 --- a/server/jobs.js +++ b/server/jobs.js @@ -1,7 +1,8 @@ const path = require("path"); const Bree = require("bree"); const { SHARE_ENV } = require("worker_threads"); - +const { log } = require("../src/util"); +let bree; const jobs = [ { name: "clear-old-data", @@ -10,7 +11,7 @@ const jobs = [ ]; const initBackgroundJobs = function (args) { - const bree = new Bree({ + bree = new Bree({ root: path.resolve("server", "jobs"), jobs, worker: { @@ -18,7 +19,7 @@ const initBackgroundJobs = function (args) { workerData: args, }, workerMessageHandler: (message) => { - console.log("[Background Job]:", message); + log.info("jobs", message); } }); @@ -26,6 +27,13 @@ const initBackgroundJobs = function (args) { return bree; }; +const stopBackgroundJobs = function () { + if (bree) { + bree.stop(); + } +}; + module.exports = { - initBackgroundJobs + initBackgroundJobs, + stopBackgroundJobs }; diff --git a/server/jobs/clear-old-data.js b/server/jobs/clear-old-data.js index 7c368014..0ec5ffa5 100644 --- a/server/jobs/clear-old-data.js +++ b/server/jobs/clear-old-data.js @@ -30,7 +30,7 @@ const DEFAULT_KEEP_PERIOD = 180; try { await R.exec( "DELETE FROM heartbeat WHERE time < DATETIME('now', '-' || ? || ' days') ", - [parsedPeriod] + [ parsedPeriod ] ); } catch (e) { log(`Failed to clear old data: ${e.message}`); diff --git a/server/jobs/util-worker.js b/server/jobs/util-worker.js index 9426840d..f122e682 100644 --- a/server/jobs/util-worker.js +++ b/server/jobs/util-worker.js @@ -9,7 +9,7 @@ const log = function (any) { }; const exit = function (error) { - if (error && error != 0) { + if (error && error !== 0) { process.exit(error); } else { if (parentPort) { diff --git a/server/model/monitor.js b/server/model/monitor.js index 628f17a6..2abf4be3 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -6,11 +6,12 @@ dayjs.extend(utc); 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, setting, errorLog } = require("../util-server"); +const { log, UP, DOWN, PENDING, flipStatus, TimeLogger } = require("../../src/util"); +const { tcping, ping, dnsResolve, checkCertificate, checkStatusCode, getTotalClientInRoom, setting, errorLog, mqttAsync } = require("../util-server"); const { R } = require("redbean-node"); const { BeanModel } = require("redbean-node/dist/bean-model"); const { Notification } = require("../notification"); +const { Proxy } = require("../proxy"); const { demoMode } = require("../config"); const version = require("../../package.json").version; const apicache = require("../modules/apicache"); @@ -41,7 +42,7 @@ class Monitor extends BeanModel { /** * Return an object that ready to parse to JSON */ - async toJSON() { + async toJSON(includeSensitiveData = true) { let notificationIDList = {}; @@ -55,15 +56,11 @@ class Monitor extends BeanModel { const tags = await this.getTags(); - return { + let data = { id: this.id, name: this.name, url: this.url, method: this.method, - body: this.body, - headers: this.headers, - basic_auth_user: this.basic_auth_user, - basic_auth_pass: this.basic_auth_pass, hostname: this.hostname, port: this.port, maxretries: this.maxretries, @@ -73,6 +70,7 @@ class Monitor extends BeanModel { interval: this.interval, retryInterval: this.retryInterval, keyword: this.keyword, + expiryNotification: this.isEnabledExpiryNotification(), ignoreTls: this.getIgnoreTls(), upsideDown: this.isUpsideDown(), maxredirects: this.maxredirects, @@ -80,14 +78,31 @@ class Monitor extends BeanModel { dns_resolve_type: this.dns_resolve_type, dns_resolve_server: this.dns_resolve_server, dns_last_result: this.dns_last_result, - pushToken: this.pushToken, + proxyId: this.proxy_id, notificationIDList, tags: tags, + mqttUsername: this.mqttUsername, + mqttPassword: this.mqttPassword, + mqttTopic: this.mqttTopic, + mqttSuccessMessage: this.mqttSuccessMessage }; + + if (includeSensitiveData) { + data = { + ...data, + headers: this.headers, + body: this.body, + basic_auth_user: this.basic_auth_user, + basic_auth_pass: this.basic_auth_pass, + pushToken: this.pushToken, + }; + } + + return data; } async getTags() { - return await R.getAll("SELECT mt.*, tag.name, tag.color FROM monitor_tag mt JOIN tag ON mt.tag_id = tag.id WHERE mt.monitor_id = ?", [this.id]); + return await R.getAll("SELECT mt.*, tag.name, tag.color FROM monitor_tag mt JOIN tag ON mt.tag_id = tag.id WHERE mt.monitor_id = ?", [ this.id ]); } /** @@ -99,6 +114,10 @@ class Monitor extends BeanModel { return Buffer.from(user + ":" + pass).toString("base64"); } + isEnabledExpiryNotification() { + return Boolean(this.expiryNotification); + } + /** * Parse to boolean * @returns {boolean} @@ -144,7 +163,7 @@ class Monitor extends BeanModel { // undefined if not https let tlsInfo = undefined; - if (! previousBeat) { + if (!previousBeat) { previousBeat = await R.findOne("heartbeat", " monitor_id = ? ORDER BY time DESC", [ this.id, ]); @@ -162,7 +181,7 @@ class Monitor extends BeanModel { } // Duration - if (! isFirstBeat) { + if (!isFirstBeat) { bean.duration = dayjs(bean.time).diff(dayjs(previousBeat.time), "second"); } else { bean.duration = 0; @@ -181,7 +200,12 @@ class Monitor extends BeanModel { }; } - debug(`[${this.name}] Prepare Options for axios`); + const httpsAgentOptions = { + maxCachedSessions: 0, // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940) + rejectUnauthorized: !this.getIgnoreTls(), + }; + + log.debug("monitor", `[${this.name}] Prepare Options for axios`); const options = { url: this.url, @@ -194,17 +218,33 @@ class Monitor extends BeanModel { ...(this.headers ? JSON.parse(this.headers) : {}), ...(basicAuthHeader), }, - 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()); }, }; - debug(`[${this.name}] Axios Request`); + if (this.proxy_id) { + const proxy = await R.load("proxy", this.proxy_id); + + if (proxy && proxy.active) { + const { httpAgent, httpsAgent } = Proxy.createAgents(proxy, { + httpsAgentOptions: httpsAgentOptions, + }); + + options.proxy = false; + options.httpAgent = httpAgent; + options.httpsAgent = httpsAgent; + } + } + + if (!options.httpsAgent) { + options.httpsAgent = new https.Agent(httpsAgentOptions); + } + + log.debug("monitor", `[${this.name}] Axios Options: ${JSON.stringify(options)}`); + log.debug("monitor", `[${this.name}] Axios Request`); + let res = await axios.request(options); bean.msg = `${res.status} - ${res.statusText}`; bean.ping = dayjs().valueOf() - startTime; @@ -212,29 +252,30 @@ class Monitor extends BeanModel { // Check certificate if https is used let certInfoStartTime = dayjs().valueOf(); if (this.getUrl()?.protocol === "https:") { - debug(`[${this.name}] Check cert`); + log.debug("monitor", `[${this.name}] Check cert`); try { let tlsInfoObject = checkCertificate(res); tlsInfo = await this.updateTlsInfo(tlsInfoObject); - if (!this.getIgnoreTls()) { - debug(`[${this.name}] call sendCertNotification`); + if (!this.getIgnoreTls() && this.isEnabledExpiryNotification()) { + log.debug("monitor", `[${this.name}] call sendCertNotification`); await this.sendCertNotification(tlsInfoObject); } } catch (e) { if (e.message !== "No TLS certificate in response") { - console.error(e.message); + log.error("monitor", "Caught error"); + log.error("monitor", e.message); } } } if (process.env.TIMELOGGER === "1") { - debug("Cert Info Query Time: " + (dayjs().valueOf() - certInfoStartTime) + "ms"); + log.debug("monitor", "Cert Info Query Time: " + (dayjs().valueOf() - certInfoStartTime) + "ms"); } - if (process.env.UPTIME_KUMA_LOG_RESPONSE_BODY_MONITOR_ID == this.id) { - console.log(res.data); + if (process.env.UPTIME_KUMA_LOG_RESPONSE_BODY_MONITOR_ID === this.id) { + log.info("monitor", res.data); } if (this.type === "http") { @@ -273,24 +314,24 @@ class Monitor extends BeanModel { let dnsRes = await dnsResolve(this.hostname, this.dns_resolve_server, this.dns_resolve_type); bean.ping = dayjs().valueOf() - startTime; - if (this.dns_resolve_type == "A" || this.dns_resolve_type == "AAAA" || this.dns_resolve_type == "TXT") { + if (this.dns_resolve_type === "A" || this.dns_resolve_type === "AAAA" || this.dns_resolve_type === "TXT") { dnsMessage += "Records: "; dnsMessage += dnsRes.join(" | "); - } else if (this.dns_resolve_type == "CNAME" || this.dns_resolve_type == "PTR") { + } else if (this.dns_resolve_type === "CNAME" || this.dns_resolve_type === "PTR") { dnsMessage = dnsRes[0]; - } else if (this.dns_resolve_type == "CAA") { + } else if (this.dns_resolve_type === "CAA") { dnsMessage = dnsRes[0].issue; - } else if (this.dns_resolve_type == "MX") { + } else if (this.dns_resolve_type === "MX") { dnsRes.forEach(record => { dnsMessage += `Hostname: ${record.exchange} - Priority: ${record.priority} | `; }); dnsMessage = dnsMessage.slice(0, -2); - } else if (this.dns_resolve_type == "NS") { + } else if (this.dns_resolve_type === "NS") { dnsMessage += "Servers: "; dnsMessage += dnsRes.join(" | "); - } else if (this.dns_resolve_type == "SOA") { + } else if (this.dns_resolve_type === "SOA") { dnsMessage += `NS-Name: ${dnsRes.nsname} | Hostmaster: ${dnsRes.hostmaster} | Serial: ${dnsRes.serial} | Refresh: ${dnsRes.refresh} | Retry: ${dnsRes.retry} | Expire: ${dnsRes.expire} | MinTTL: ${dnsRes.minttl}`; - } else if (this.dns_resolve_type == "SRV") { + } else if (this.dns_resolve_type === "SRV") { dnsRes.forEach(record => { dnsMessage += `Name: ${record.name} | Port: ${record.port} | Priority: ${record.priority} | Weight: ${record.weight} | `; }); @@ -314,7 +355,7 @@ class Monitor extends BeanModel { time ]); - debug("heartbeatCount" + heartbeatCount + " " + time); + log.debug("monitor", "heartbeatCount" + heartbeatCount + " " + time); if (heartbeatCount <= 0) { // Fix #922, since previous heartbeat could be inserted by api, it should get from database @@ -345,7 +386,7 @@ class Monitor extends BeanModel { }, httpsAgent: new https.Agent({ maxCachedSessions: 0, // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940) - rejectUnauthorized: ! this.getIgnoreTls(), + rejectUnauthorized: !this.getIgnoreTls(), }), maxRedirects: this.maxredirects, validateStatus: (status) => { @@ -367,7 +408,14 @@ class Monitor extends BeanModel { } else { throw new Error("Server not found on Steam"); } - + } else if (this.type === "mqtt") { + bean.msg = await mqttAsync(this.hostname, this.mqttTopic, this.mqttSuccessMessage, { + port: this.port, + username: this.mqttUsername, + password: this.mqttPassword, + interval: this.interval, + }); + bean.status = UP; } else { bean.msg = "Unknown Monitor Type"; bean.status = PENDING; @@ -398,7 +446,7 @@ class Monitor extends BeanModel { } } - debug(`[${this.name}] Check isImportant`); + log.debug("monitor", `[${this.name}] Check isImportant`); let isImportant = Monitor.isImportantBeat(isFirstBeat, previousBeat?.status, bean.status); // Mark as important if status changed, ignore pending pings, @@ -406,11 +454,11 @@ class Monitor extends BeanModel { if (isImportant) { bean.important = true; - debug(`[${this.name}] sendNotification`); + log.debug("monitor", `[${this.name}] sendNotification`); await Monitor.sendNotification(isFirstBeat, this, bean); // Clear Status Page Cache - debug(`[${this.name}] apicache clear`); + log.debug("monitor", `[${this.name}] apicache clear`); apicache.clear(); } else { @@ -418,33 +466,33 @@ class Monitor extends BeanModel { } if (bean.status === UP) { - console.info(`Monitor #${this.id} '${this.name}': Successful Response: ${bean.ping} ms | Interval: ${beatInterval} seconds | Type: ${this.type}`); + log.info("monitor", `Monitor #${this.id} '${this.name}': Successful Response: ${bean.ping} ms | Interval: ${beatInterval} seconds | Type: ${this.type}`); } else if (bean.status === PENDING) { if (this.retryInterval > 0) { beatInterval = this.retryInterval; } - console.warn(`Monitor #${this.id} '${this.name}': Pending: ${bean.msg} | Max retries: ${this.maxretries} | Retry: ${retries} | Retry Interval: ${beatInterval} seconds | Type: ${this.type}`); + log.warn("monitor", `Monitor #${this.id} '${this.name}': Pending: ${bean.msg} | Max retries: ${this.maxretries} | Retry: ${retries} | Retry Interval: ${beatInterval} seconds | Type: ${this.type}`); } else { - console.warn(`Monitor #${this.id} '${this.name}': Failing: ${bean.msg} | Interval: ${beatInterval} seconds | Type: ${this.type}`); + log.warn("monitor", `Monitor #${this.id} '${this.name}': Failing: ${bean.msg} | Interval: ${beatInterval} seconds | Type: ${this.type}`); } - debug(`[${this.name}] Send to socket`); + log.debug("monitor", `[${this.name}] Send to socket`); io.to(this.user_id).emit("heartbeat", bean.toJSON()); Monitor.sendStats(io, this.id, this.user_id); - debug(`[${this.name}] Store`); + log.debug("monitor", `[${this.name}] Store`); await R.store(bean); - debug(`[${this.name}] prometheus.update`); + log.debug("monitor", `[${this.name}] prometheus.update`); prometheus.update(bean, tlsInfo); previousBeat = bean; if (! this.isStop) { - debug(`[${this.name}] SetTimeout for next check.`); + log.debug("monitor", `[${this.name}] SetTimeout for next check.`); this.heartbeatInterval = setTimeout(safeBeat, beatInterval * 1000); } else { - console.log(`[${this.name}] isStop = true, no next check.`); + log.info("monitor", `[${this.name}] isStop = true, no next check.`); } }; @@ -455,10 +503,10 @@ class Monitor extends BeanModel { } catch (e) { console.trace(e); errorLog(e, false); - console.error("Please report to https://github.com/louislam/uptime-kuma/issues"); + log.error("monitor", "Please report to https://github.com/louislam/uptime-kuma/issues"); if (! this.isStop) { - console.log("Try to restart the monitor"); + log.info("monitor", "Try to restart the monitor"); this.heartbeatInterval = setTimeout(safeBeat, this.interval * 1000); } } @@ -505,41 +553,41 @@ class Monitor extends BeanModel { * @returns {Promise} */ async updateTlsInfo(checkCertificateResult) { - let tls_info_bean = await R.findOne("monitor_tls_info", "monitor_id = ?", [ + let tlsInfoBean = await R.findOne("monitor_tls_info", "monitor_id = ?", [ this.id, ]); - if (tls_info_bean == null) { - tls_info_bean = R.dispense("monitor_tls_info"); - tls_info_bean.monitor_id = this.id; + if (tlsInfoBean == null) { + tlsInfoBean = R.dispense("monitor_tls_info"); + tlsInfoBean.monitor_id = this.id; } else { // Clear sent history if the cert changed. try { - let oldCertInfo = JSON.parse(tls_info_bean.info_json); + let oldCertInfo = JSON.parse(tlsInfoBean.info_json); let isValidObjects = oldCertInfo && oldCertInfo.certInfo && checkCertificateResult && checkCertificateResult.certInfo; if (isValidObjects) { if (oldCertInfo.certInfo.fingerprint256 !== checkCertificateResult.certInfo.fingerprint256) { - debug("Resetting sent_history"); + log.debug("monitor", "Resetting sent_history"); await R.exec("DELETE FROM notification_sent_history WHERE type = 'certificate' AND monitor_id = ?", [ this.id ]); } else { - debug("No need to reset sent_history"); - debug(oldCertInfo.certInfo.fingerprint256); - debug(checkCertificateResult.certInfo.fingerprint256); + log.debug("monitor", "No need to reset sent_history"); + log.debug("monitor", oldCertInfo.certInfo.fingerprint256); + log.debug("monitor", checkCertificateResult.certInfo.fingerprint256); } } else { - debug("Not valid object"); + log.debug("monitor", "Not valid object"); } } catch (e) { } } - tls_info_bean.info_json = JSON.stringify(checkCertificateResult); - await R.store(tls_info_bean); + tlsInfoBean.info_json = JSON.stringify(checkCertificateResult); + await R.store(tlsInfoBean); return checkCertificateResult; } @@ -553,7 +601,7 @@ class Monitor extends BeanModel { await Monitor.sendUptime(24 * 30, io, monitorID, userID); await Monitor.sendCertInfo(io, monitorID, userID); } else { - debug("No clients in the room, no need to send stats"); + log.debug("monitor", "No clients in the room, no need to send stats"); } } @@ -580,11 +628,11 @@ class Monitor extends BeanModel { } static async sendCertInfo(io, monitorID, userID) { - let tls_info = await R.findOne("monitor_tls_info", "monitor_id = ?", [ + let tlsInfo = await R.findOne("monitor_tls_info", "monitor_id = ?", [ monitorID, ]); - if (tls_info != null) { - io.to(userID).emit("certInfo", monitorID, tls_info.info_json); + if (tlsInfo != null) { + io.to(userID).emit("certInfo", monitorID, tlsInfo.info_json); } } @@ -646,7 +694,7 @@ class Monitor extends BeanModel { } else { // Handle new monitor with only one beat, because the beat's duration = 0 - let status = parseInt(await R.getCell("SELECT `status` FROM heartbeat WHERE monitor_id = ?", [ monitorID ])); + let status = parseInt(await R.getCell("SELECT `status` FROM heartbeat WHERE monitor_id = ?", [monitorID])); if (status === UP) { uptime = 1; @@ -698,10 +746,10 @@ class Monitor extends BeanModel { for (let notification of notificationList) { try { - await Notification.send(JSON.parse(notification.config), msg, await monitor.toJSON(), bean.toJSON()); + await Notification.send(JSON.parse(notification.config), msg, await monitor.toJSON(false), bean.toJSON()); } catch (e) { - console.error("Cannot send notification to " + notification.name); - console.log(e); + log.error("monitor", "Cannot send notification to " + notification.name); + log.error("monitor", e); } } } @@ -718,7 +766,7 @@ class Monitor extends BeanModel { if (tlsInfoObject && tlsInfoObject.certInfo && tlsInfoObject.certInfo.daysRemaining) { const notificationList = await Monitor.getNotificationList(this); - debug("call sendCertNotificationByTargetDays"); + log.debug("monitor", "call sendCertNotificationByTargetDays"); await this.sendCertNotificationByTargetDays(tlsInfoObject.certInfo.daysRemaining, 21, notificationList); await this.sendCertNotificationByTargetDays(tlsInfoObject.certInfo.daysRemaining, 14, notificationList); await this.sendCertNotificationByTargetDays(tlsInfoObject.certInfo.daysRemaining, 7, notificationList); @@ -728,7 +776,7 @@ class Monitor extends BeanModel { async sendCertNotificationByTargetDays(daysRemaining, targetDays, notificationList) { if (daysRemaining > targetDays) { - debug(`No need to send cert notification. ${daysRemaining} > ${targetDays}`); + log.debug("monitor", `No need to send cert notification. ${daysRemaining} > ${targetDays}`); return; } @@ -742,21 +790,21 @@ class Monitor extends BeanModel { // Sent already, no need to send again if (row) { - debug("Sent already, no need to send again"); + log.debug("monitor", "Sent already, no need to send again"); return; } let sent = false; - debug("Send certificate notification"); + log.debug("monitor", "Send certificate notification"); for (let notification of notificationList) { try { - debug("Sending to " + notification.name); + log.debug("monitor", "Sending to " + notification.name); await Notification.send(JSON.parse(notification.config), `[${this.name}][${this.url}] Certificate will be expired in ${daysRemaining} days`); sent = true; } catch (e) { - console.error("Cannot send cert notification to " + notification.name); - console.error(e); + log.error("monitor", "Cannot send cert notification to " + notification.name); + log.error("monitor", e); } } @@ -768,7 +816,7 @@ class Monitor extends BeanModel { ]); } } else { - debug("No notification, no need to send cert notification"); + log.debug("monitor", "No notification, no need to send cert notification"); } } diff --git a/server/model/proxy.js b/server/model/proxy.js new file mode 100644 index 00000000..7ddec434 --- /dev/null +++ b/server/model/proxy.js @@ -0,0 +1,21 @@ +const { BeanModel } = require("redbean-node/dist/bean-model"); + +class Proxy extends BeanModel { + toJSON() { + return { + id: this._id, + userId: this._user_id, + protocol: this._protocol, + host: this._host, + port: this._port, + auth: !!this._auth, + username: this._username, + password: this._password, + active: !!this._active, + default: !!this._default, + createdDate: this._created_date, + }; + } +} + +module.exports = Proxy; diff --git a/server/model/status_page.js b/server/model/status_page.js index 6f763f58..b1befc25 100644 --- a/server/model/status_page.js +++ b/server/model/status_page.js @@ -3,6 +3,20 @@ const { R } = require("redbean-node"); class StatusPage extends BeanModel { + static domainMappingList = { }; + + /** + * Return object like this: { "test-uptime.kuma.pet": "default" } + * @returns {Promise} + */ + static async loadDomainMappingList() { + StatusPage.domainMappingList = await R.getAssoc(` + SELECT domain, slug + FROM status_page, status_page_cname + WHERE status_page.id = status_page_cname.status_page_id + `); + } + static async sendStatusPageList(io, socket) { let result = {}; @@ -16,6 +30,57 @@ class StatusPage extends BeanModel { return list; } + async updateDomainNameList(domainNameList) { + + if (!Array.isArray(domainNameList)) { + throw new Error("Invalid array"); + } + + let trx = await R.begin(); + + await trx.exec("DELETE FROM status_page_cname WHERE status_page_id = ?", [ + this.id, + ]); + + try { + for (let domain of domainNameList) { + if (typeof domain !== "string") { + throw new Error("Invalid domain"); + } + + if (domain.trim() === "") { + continue; + } + + // If the domain name is used in another status page, delete it + await trx.exec("DELETE FROM status_page_cname WHERE domain = ?", [ + domain, + ]); + + let mapping = trx.dispense("status_page_cname"); + mapping.status_page_id = this.id; + mapping.domain = domain; + await trx.store(mapping); + } + await trx.commit(); + } catch (error) { + await trx.rollback(); + throw error; + } + } + + getDomainNameList() { + let domainList = []; + for (let domain in StatusPage.domainMappingList) { + let s = StatusPage.domainMappingList[domain]; + + if (this.slug === s) { + domainList.push(domain); + } + } + return domainList; + } + async toJSON() { return { id: this.id, @@ -26,6 +91,10 @@ class StatusPage extends BeanModel { theme: this.theme, published: !!this.published, showTags: !!this.show_tags, + domainNameList: this.getDomainNameList(), + customCSS: this.custom_css, + footerText: this.footer_text, + showPoweredBy: !!this.show_powered_by, }; } @@ -38,6 +107,9 @@ class StatusPage extends BeanModel { theme: this.theme, published: !!this.published, showTags: !!this.show_tags, + customCSS: this.custom_css, + footerText: this.footer_text, + showPoweredBy: !!this.show_powered_by, }; } diff --git a/server/model/user.js b/server/model/user.js index d1d3d200..b243f87f 100644 --- a/server/model/user.js +++ b/server/model/user.js @@ -5,17 +5,29 @@ const { R } = require("redbean-node"); class User extends BeanModel { /** - * Direct execute, no need R.store() + * + * Fix #1510, as in the context reset-password.js, there is no auto model mapping. Call this static function instead. + * @param userID * @param newPassword * @returns {Promise} */ - async resetPassword(newPassword) { + static async resetPassword(userID, newPassword) { await R.exec("UPDATE `user` SET password = ? WHERE id = ? ", [ passwordHash.generate(newPassword), - this.id + userID ]); + } + + /** + * + * @param newPassword + * @returns {Promise} + */ + async resetPassword(newPassword) { + await User.resetPassword(this.id, newPassword); this.password = newPassword; } + } module.exports = User; diff --git a/server/modules/apicache/apicache.js b/server/modules/apicache/apicache.js index 22d1fed7..25f0a54f 100644 --- a/server/modules/apicache/apicache.js +++ b/server/modules/apicache/apicache.js @@ -68,6 +68,15 @@ function ApiCache() { instances.push(this); this.id = instances.length; + /** + * Logs a message to the console if the `DEBUG` environment variable is set. + * @param {string} a - The first argument to log. + * @param {string} b - The second argument to log. + * @param {string} c - The third argument to log. + * @param {string} d - The fourth argument to log, and so on... (optional) + * + * Generated by Trelent + */ function debug(a, b, c, d) { let arr = ["\x1b[36m[apicache]\x1b[0m", a, b, c, d].filter(function (arg) { return arg !== undefined; @@ -77,6 +86,13 @@ function ApiCache() { return (globalOptions.debug || debugEnv) && console.log.apply(null, arr); } + /** + * Returns true if the given request and response should be logged. + * @param {Object} request The HTTP request object. + * @param {Object} response The HTTP response object. + * + * Generated by Trelent + */ function shouldCacheResponse(request, response, toggle) { let opt = globalOptions; let codes = opt.statusCodes; @@ -99,6 +115,12 @@ function ApiCache() { return true; } + /** + * Adds a key to the index. + * @param {string} key The key to add. + * + * Generated by Trelent + */ function addIndexEntries(key, req) { let groupName = req.apicacheGroup; @@ -111,6 +133,13 @@ function ApiCache() { index.all.unshift(key); } + /** + * Returns a new object containing only the whitelisted headers. + * @param {Object} headers The original object of header names and values. + * @param {Array.} globalOptions.headerWhitelist An array of strings representing the whitelisted header names to keep in the output object. + * + * Generated by Trelent + */ function filterBlacklistedHeaders(headers) { return Object.keys(headers) .filter(function (key) { @@ -122,6 +151,12 @@ function ApiCache() { }, {}); } + /** + * @param {Object} headers The response headers to filter. + * @returns {Object} A new object containing only the whitelisted response headers. + * + * Generated by Trelent + */ function createCacheObject(status, headers, data, encoding) { return { status: status, @@ -132,6 +167,14 @@ function ApiCache() { }; } + /** + * Sets a cache value for the given key. + * @param {string} key The cache key to set. + * @param {*} value The cache value to set. + * @param {number} duration How long in milliseconds the cached response should be valid for (defaults to 1 hour). + * + * Generated by Trelent + */ function cacheResponse(key, value, duration) { let redis = globalOptions.redisClient; let expireCallback = globalOptions.events.expire; @@ -154,6 +197,12 @@ function ApiCache() { }, Math.min(duration, 2147483647)); } + /** + * Appends content to the response. + * @param {string|Buffer} content The content to append. + * + * Generated by Trelent + */ function accumulateContent(res, content) { if (content) { if (typeof content == "string") { @@ -179,6 +228,13 @@ function ApiCache() { } } + /** + * Monkeypatches the response object to add cache control headers and create a cache object. + * @param {Object} req - The request object. + * @param {Object} res - The response object. + * + * Generated by Trelent + */ function makeResponseCacheable(req, res, next, key, duration, strDuration, toggle) { // monkeypatch res.end to create cache object res._apicache = { @@ -245,6 +301,13 @@ function ApiCache() { next(); } + /** + * @param {Request} request + * @param {Response} response + * @returns {boolean|undefined} true if the request should be cached, false otherwise. If undefined, defaults to true. + * + * Generated by Trelent + */ function sendCachedResponse(request, response, cacheObject, toggle, next, duration) { if (toggle && !toggle(request, response)) { return next(); @@ -365,6 +428,13 @@ function ApiCache() { return this.getIndex(); }; + /** + * Converts a duration string to an integer number of milliseconds. + * @param {string} duration - The string to convert. + * @returns {number} The converted value in milliseconds, or the defaultDuration if it can't be parsed. + * + * Generated by Trelent + */ function parseDuration(duration, defaultDuration) { if (typeof duration === "number") { return duration; diff --git a/server/notification-providers/alerta.js b/server/notification-providers/alerta.js index e692b57b..2b85d67a 100644 --- a/server/notification-providers/alerta.js +++ b/server/notification-providers/alerta.js @@ -14,7 +14,7 @@ class Alerta extends NotificationProvider { let config = { headers: { "Content-Type": "application/json;charset=UTF-8", - "Authorization": "Key " + notification.alertaapiKey, + "Authorization": "Key " + notification.alertaApiKey, } }; let data = { @@ -40,17 +40,17 @@ class Alerta extends NotificationProvider { await axios.post(alertaUrl, postData, config); } else { let datadup = Object.assign( { - correlate: ["service_up", "service_down"], + correlate: [ "service_up", "service_down" ], event: monitorJSON["type"], group: "uptimekuma-" + monitorJSON["type"], resource: monitorJSON["name"], }, data ); - if (heartbeatJSON["status"] == DOWN) { + if (heartbeatJSON["status"] === DOWN) { datadup.severity = notification.alertaAlertState; // critical datadup.text = "Service " + monitorJSON["type"] + " is down."; await axios.post(alertaUrl, datadup, config); - } else if (heartbeatJSON["status"] == UP) { + } else if (heartbeatJSON["status"] === UP) { datadup.severity = notification.alertaRecoverState; // cleaned datadup.text = "Service " + monitorJSON["type"] + " is up."; await axios.post(alertaUrl, datadup, config); diff --git a/server/notification-providers/aliyun-sms.js b/server/notification-providers/aliyun-sms.js index 6a206320..9a14240c 100644 --- a/server/notification-providers/aliyun-sms.js +++ b/server/notification-providers/aliyun-sms.js @@ -64,7 +64,7 @@ class AliyunSMS extends NotificationProvider { }; let result = await axios(config); - if (result.data.Message == "OK") { + if (result.data.Message === "OK") { return true; } return false; diff --git a/server/notification-providers/apprise.js b/server/notification-providers/apprise.js index fdcd8d61..2d795d4e 100644 --- a/server/notification-providers/apprise.js +++ b/server/notification-providers/apprise.js @@ -1,12 +1,12 @@ const NotificationProvider = require("./notification-provider"); -const child_process = require("child_process"); +const childProcess = require("child_process"); class Apprise extends NotificationProvider { name = "apprise"; async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { - let s = child_process.spawnSync("apprise", [ "-vv", "-b", msg, notification.appriseURL]) + let s = childProcess.spawnSync("apprise", [ "-vv", "-b", msg, notification.appriseURL ]); let output = (s.stdout) ? s.stdout.toString() : "ERROR: maybe apprise not found"; @@ -16,7 +16,7 @@ class Apprise extends NotificationProvider { return "Sent Successfully"; } - throw new Error(output) + throw new Error(output); } else { return "No output from apprise"; } diff --git a/server/notification-providers/bark.js b/server/notification-providers/bark.js index 4ebe978a..8920c295 100644 --- a/server/notification-providers/bark.js +++ b/server/notification-providers/bark.js @@ -21,31 +21,26 @@ class Bark extends NotificationProvider { name = "Bark"; async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { - try { - var barkEndpoint = notification.barkEndpoint; + let barkEndpoint = notification.barkEndpoint; - // check if the endpoint has a "/" suffix, if so, delete it first - if (barkEndpoint.endsWith("/")) { - barkEndpoint = barkEndpoint.substring(0, barkEndpoint.length - 1); - } - - if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] == UP) { - let title = "UptimeKuma Monitor Up"; - return await this.postNotification(title, msg, barkEndpoint); - } + // check if the endpoint has a "/" suffix, if so, delete it first + if (barkEndpoint.endsWith("/")) { + barkEndpoint = barkEndpoint.substring(0, barkEndpoint.length - 1); + } - if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] == DOWN) { - let title = "UptimeKuma Monitor Down"; - return await this.postNotification(title, msg, barkEndpoint); - } + if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] === UP) { + let title = "UptimeKuma Monitor Up"; + return await this.postNotification(title, msg, barkEndpoint); + } - if (msg != null) { - let title = "UptimeKuma Message"; - return await this.postNotification(title, msg, barkEndpoint); - } + if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] === DOWN) { + let title = "UptimeKuma Monitor Down"; + return await this.postNotification(title, msg, barkEndpoint); + } - } catch (error) { - throw error; + if (msg != null) { + let title = "UptimeKuma Message"; + return await this.postNotification(title, msg, barkEndpoint); } } diff --git a/server/notification-providers/clicksendsms.js b/server/notification-providers/clicksendsms.js index 74e2f4c5..e66b982c 100644 --- a/server/notification-providers/clicksendsms.js +++ b/server/notification-providers/clicksendsms.js @@ -12,7 +12,7 @@ class ClickSendSMS extends NotificationProvider { let config = { headers: { "Content-Type": "application/json", - "Authorization": "Basic " + Buffer.from(notification.clicksendsmsLogin + ":" + notification.clicksendsmsPassword).toString('base64'), + "Authorization": "Basic " + Buffer.from(notification.clicksendsmsLogin + ":" + notification.clicksendsmsPassword).toString("base64"), "Accept": "text/json", } }; diff --git a/server/notification-providers/dingding.js b/server/notification-providers/dingding.js index cf08f14b..ef7dba0d 100644 --- a/server/notification-providers/dingding.js +++ b/server/notification-providers/dingding.js @@ -50,7 +50,7 @@ class DingDing extends NotificationProvider { }; let result = await axios(config); - if (result.data.errmsg == "ok") { + if (result.data.errmsg === "ok") { return true; } return false; diff --git a/server/notification-providers/discord.js b/server/notification-providers/discord.js index 881ad211..dd63e74b 100644 --- a/server/notification-providers/discord.js +++ b/server/notification-providers/discord.js @@ -17,8 +17,8 @@ class Discord extends NotificationProvider { let discordtestdata = { username: discordDisplayName, content: msg, - } - await axios.post(notification.discordWebhookUrl, discordtestdata) + }; + await axios.post(notification.discordWebhookUrl, discordtestdata); return okMsg; } @@ -35,7 +35,7 @@ class Discord extends NotificationProvider { } // If heartbeatJSON is not null, we go into the normal alerting loop. - if (heartbeatJSON["status"] == DOWN) { + if (heartbeatJSON["status"] === DOWN) { let discorddowndata = { username: discordDisplayName, embeds: [{ @@ -61,16 +61,16 @@ class Discord extends NotificationProvider { }, ], }], - } + }; if (notification.discordPrefixMessage) { discorddowndata.content = notification.discordPrefixMessage; } - await axios.post(notification.discordWebhookUrl, discorddowndata) + await axios.post(notification.discordWebhookUrl, discorddowndata); return okMsg; - } else if (heartbeatJSON["status"] == UP) { + } else if (heartbeatJSON["status"] === UP) { let discordupdata = { username: discordDisplayName, embeds: [{ @@ -96,17 +96,17 @@ class Discord extends NotificationProvider { }, ], }], - } + }; if (notification.discordPrefixMessage) { discordupdata.content = notification.discordPrefixMessage; } - await axios.post(notification.discordWebhookUrl, discordupdata) + await axios.post(notification.discordWebhookUrl, discordupdata); return okMsg; } } catch (error) { - this.throwGeneralAxiosError(error) + this.throwGeneralAxiosError(error); } } diff --git a/server/notification-providers/feishu.js b/server/notification-providers/feishu.js index 05fc9c18..73781ca4 100644 --- a/server/notification-providers/feishu.js +++ b/server/notification-providers/feishu.js @@ -21,7 +21,7 @@ class Feishu extends NotificationProvider { return okMsg; } - if (heartbeatJSON["status"] == DOWN) { + if (heartbeatJSON["status"] === DOWN) { let downdata = { msg_type: "post", content: { @@ -48,7 +48,7 @@ class Feishu extends NotificationProvider { return okMsg; } - if (heartbeatJSON["status"] == UP) { + if (heartbeatJSON["status"] === UP) { let updata = { msg_type: "post", content: { diff --git a/server/notification-providers/google-chat.js b/server/notification-providers/google-chat.js index 6fb32428..02cb4823 100644 --- a/server/notification-providers/google-chat.js +++ b/server/notification-providers/google-chat.js @@ -13,11 +13,11 @@ class GoogleChat extends NotificationProvider { try { // Google Chat message formatting: https://developers.google.com/chat/api/guides/message-formats/basic - let textMsg = '' + let textMsg = ""; if (heartbeatJSON && heartbeatJSON.status === UP) { - textMsg = `✅ Application is back online\n`; + textMsg = "✅ Application is back online\n"; } else if (heartbeatJSON && heartbeatJSON.status === DOWN) { - textMsg = `🔴 Application went down\n`; + textMsg = "🔴 Application went down\n"; } if (monitorJSON && monitorJSON.name) { diff --git a/server/notification-providers/gorush.js b/server/notification-providers/gorush.js index 58da5525..6d756e46 100644 --- a/server/notification-providers/gorush.js +++ b/server/notification-providers/gorush.js @@ -18,7 +18,7 @@ class Gorush extends NotificationProvider { let data = { "notifications": [ { - "tokens": [notification.gorushDeviceToken], + "tokens": [ notification.gorushDeviceToken ], "platform": platformMapping[notification.gorushPlatform], "message": msg, // Optional diff --git a/server/notification-providers/gotify.js b/server/notification-providers/gotify.js index 08526189..0c524493 100644 --- a/server/notification-providers/gotify.js +++ b/server/notification-providers/gotify.js @@ -15,7 +15,7 @@ class Gotify extends NotificationProvider { "message": msg, "priority": notification.gotifyPriority || 8, "title": "Uptime-Kuma", - }) + }); return okMsg; diff --git a/server/notification-providers/line.js b/server/notification-providers/line.js index 327696ed..e594e174 100644 --- a/server/notification-providers/line.js +++ b/server/notification-providers/line.js @@ -25,9 +25,9 @@ class Line extends NotificationProvider { "text": "Test Successful!" } ] - } - await axios.post(lineAPIUrl, testMessage, config) - } else if (heartbeatJSON["status"] == DOWN) { + }; + await axios.post(lineAPIUrl, testMessage, config); + } else if (heartbeatJSON["status"] === DOWN) { let downMessage = { "to": notification.lineUserID, "messages": [ @@ -36,9 +36,9 @@ class Line extends NotificationProvider { "text": "UptimeKuma Alert: [🔴 Down]\n" + "Name: " + monitorJSON["name"] + " \n" + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"] } ] - } - await axios.post(lineAPIUrl, downMessage, config) - } else if (heartbeatJSON["status"] == UP) { + }; + await axios.post(lineAPIUrl, downMessage, config); + } else if (heartbeatJSON["status"] === UP) { let upMessage = { "to": notification.lineUserID, "messages": [ @@ -47,12 +47,12 @@ class Line extends NotificationProvider { "text": "UptimeKuma Alert: [✅ Up]\n" + "Name: " + monitorJSON["name"] + " \n" + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"] } ] - } - await axios.post(lineAPIUrl, upMessage, config) + }; + await axios.post(lineAPIUrl, upMessage, config); } return okMsg; } catch (error) { - this.throwGeneralAxiosError(error) + this.throwGeneralAxiosError(error); } } } diff --git a/server/notification-providers/lunasea.js b/server/notification-providers/lunasea.js index c41f400e..b53f3241 100644 --- a/server/notification-providers/lunasea.js +++ b/server/notification-providers/lunasea.js @@ -8,38 +8,38 @@ class LunaSea extends NotificationProvider { async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { let okMsg = "Sent Successfully."; - let lunaseadevice = "https://notify.lunasea.app/v1/custom/device/" + notification.lunaseaDevice + let lunaseadevice = "https://notify.lunasea.app/v1/custom/device/" + notification.lunaseaDevice; try { if (heartbeatJSON == null) { let testdata = { "title": "Uptime Kuma Alert", "body": "Testing Successful.", - } - await axios.post(lunaseadevice, testdata) + }; + await axios.post(lunaseadevice, testdata); return okMsg; } - if (heartbeatJSON["status"] == DOWN) { + if (heartbeatJSON["status"] === DOWN) { let downdata = { "title": "UptimeKuma Alert: " + monitorJSON["name"], "body": "[🔴 Down] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"], - } - await axios.post(lunaseadevice, downdata) + }; + await axios.post(lunaseadevice, downdata); return okMsg; } - if (heartbeatJSON["status"] == UP) { + if (heartbeatJSON["status"] === UP) { let updata = { "title": "UptimeKuma Alert: " + monitorJSON["name"], "body": "[✅ Up] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"], - } - await axios.post(lunaseadevice, updata) + }; + await axios.post(lunaseadevice, updata); return okMsg; } } catch (error) { - this.throwGeneralAxiosError(error) + this.throwGeneralAxiosError(error); } } diff --git a/server/notification-providers/matrix.js b/server/notification-providers/matrix.js index c1054fce..915c772d 100644 --- a/server/notification-providers/matrix.js +++ b/server/notification-providers/matrix.js @@ -1,7 +1,7 @@ const NotificationProvider = require("./notification-provider"); const axios = require("axios"); const Crypto = require("crypto"); -const { debug } = require("../../src/util"); +const { log } = require("../../src/util"); class Matrix extends NotificationProvider { name = "matrix"; @@ -17,11 +17,11 @@ class Matrix extends NotificationProvider { .slice(0, size) ); - debug("Random String: " + randomString); + log.debug("notification", "Random String: " + randomString); const roomId = encodeURIComponent(notification.internalRoomId); - debug("Matrix Room ID: " + roomId); + log.debug("notification", "Matrix Room ID: " + roomId); try { let config = { diff --git a/server/notification-providers/mattermost.js b/server/notification-providers/mattermost.js index c2ffc23b..2076ad21 100644 --- a/server/notification-providers/mattermost.js +++ b/server/notification-providers/mattermost.js @@ -15,16 +15,21 @@ class Mattermost extends NotificationProvider { let mattermostTestData = { username: mattermostUserName, text: msg, - } - await axios.post(notification.mattermostWebhookUrl, mattermostTestData) + }; + await axios.post(notification.mattermostWebhookUrl, mattermostTestData); return okMsg; } - const mattermostChannel = notification.mattermostchannel.toLowerCase(); + let mattermostChannel; + + if (typeof notification.mattermostchannel === "string") { + mattermostChannel = notification.mattermostchannel.toLowerCase(); + } + const mattermostIconEmoji = notification.mattermosticonemo; const mattermostIconUrl = notification.mattermosticonurl; - if (heartbeatJSON["status"] == DOWN) { + if (heartbeatJSON["status"] === DOWN) { let mattermostdowndata = { username: mattermostUserName, text: "Uptime Kuma Alert", @@ -68,7 +73,7 @@ class Mattermost extends NotificationProvider { mattermostdowndata ); return okMsg; - } else if (heartbeatJSON["status"] == UP) { + } else if (heartbeatJSON["status"] === UP) { let mattermostupdata = { username: mattermostUserName, text: "Uptime Kuma Alert", diff --git a/server/notification-providers/notification-provider.js b/server/notification-providers/notification-provider.js index 61c6242d..87687baa 100644 --- a/server/notification-providers/notification-provider.js +++ b/server/notification-providers/notification-provider.js @@ -25,11 +25,11 @@ class NotificationProvider { if (typeof error.response.data === "string") { msg += error.response.data; } else { - msg += JSON.stringify(error.response.data) + msg += JSON.stringify(error.response.data); } } - throw new Error(msg) + throw new Error(msg); } } diff --git a/server/notification-providers/octopush.js b/server/notification-providers/octopush.js index 9d77aa5b..0eda940b 100644 --- a/server/notification-providers/octopush.js +++ b/server/notification-providers/octopush.js @@ -10,7 +10,7 @@ class Octopush extends NotificationProvider { try { // Default - V2 - if (notification.octopushVersion == 2 || !notification.octopushVersion) { + if (notification.octopushVersion === 2 || !notification.octopushVersion) { let config = { headers: { "api-key": notification.octopushAPIKey, @@ -30,14 +30,14 @@ class Octopush extends NotificationProvider { "purpose": "alert", "sender": notification.octopushSenderName }; - await axios.post("https://api.octopush.com/v1/public/sms-campaign/send", data, config) - } else if (notification.octopushVersion == 1) { + await axios.post("https://api.octopush.com/v1/public/sms-campaign/send", data, config); + } else if (notification.octopushVersion === 1) { let data = { "user_login": notification.octopushDMLogin, "api_key": notification.octopushDMAPIKey, "sms_recipients": notification.octopushDMPhoneNumber, "sms_sender": notification.octopushDMSenderName, - "sms_type": (notification.octopushDMSMSType == "sms_premium") ? "FR" : "XXX", + "sms_type": (notification.octopushDMSMSType === "sms_premium") ? "FR" : "XXX", "transactional": "1", //octopush not supporting non ascii char "sms_text": msg.replace(/[^\x00-\x7F]/g, ""), @@ -49,7 +49,7 @@ class Octopush extends NotificationProvider { }, params: data }; - await axios.post("https://www.octopush-dm.com/api/sms/json", {}, config) + await axios.post("https://www.octopush-dm.com/api/sms/json", {}, config); } else { throw new Error("Unknown Octopush version!"); } diff --git a/server/notification-providers/onebot.js b/server/notification-providers/onebot.js new file mode 100644 index 00000000..6c62eccb --- /dev/null +++ b/server/notification-providers/onebot.js @@ -0,0 +1,45 @@ +const NotificationProvider = require("./notification-provider"); +const axios = require("axios"); + +class OneBot extends NotificationProvider { + + name = "OneBot"; + + async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { + let okMsg = "Sent Successfully."; + try { + let httpAddr = notification.httpAddr; + if (!httpAddr.startsWith("http")) { + httpAddr = "http://" + httpAddr; + } + if (!httpAddr.endsWith("/")) { + httpAddr += "/"; + } + let onebotAPIUrl = httpAddr + "send_msg"; + let config = { + headers: { + "Content-Type": "application/json", + "Authorization": "Bearer " + notification.accessToken, + } + }; + let pushText = "UptimeKuma Alert: " + msg; + let data = { + "auto_escape": true, + "message": pushText, + }; + if (notification.msgType === "group") { + data["message_type"] = "group"; + data["group_id"] = notification.recieverId; + } else { + data["message_type"] = "private"; + data["user_id"] = notification.recieverId; + } + await axios.post(onebotAPIUrl, data, config); + return okMsg; + } catch (error) { + this.throwGeneralAxiosError(error); + } + } +} + +module.exports = OneBot; diff --git a/server/notification-providers/promosms.js b/server/notification-providers/promosms.js index 362ef714..4f7e8f90 100644 --- a/server/notification-providers/promosms.js +++ b/server/notification-providers/promosms.js @@ -12,7 +12,7 @@ class PromoSMS extends NotificationProvider { let config = { headers: { "Content-Type": "application/json", - "Authorization": "Basic " + Buffer.from(notification.promosmsLogin + ":" + notification.promosmsPassword).toString('base64'), + "Authorization": "Basic " + Buffer.from(notification.promosmsLogin + ":" + notification.promosmsPassword).toString("base64"), "Accept": "text/json", } }; @@ -30,7 +30,7 @@ class PromoSMS extends NotificationProvider { let error = "Something gone wrong. Api returned " + resp.data.response.status + "."; this.throwGeneralAxiosError(error); } - + return okMsg; } catch (error) { this.throwGeneralAxiosError(error); diff --git a/server/notification-providers/pushbullet.js b/server/notification-providers/pushbullet.js index c7b824a2..7f7a1c8d 100644 --- a/server/notification-providers/pushbullet.js +++ b/server/notification-providers/pushbullet.js @@ -23,26 +23,26 @@ class Pushbullet extends NotificationProvider { "type": "note", "title": "Uptime Kuma Alert", "body": "Testing Successful.", - } - await axios.post(pushbulletUrl, testdata, config) - } else if (heartbeatJSON["status"] == DOWN) { + }; + await axios.post(pushbulletUrl, testdata, config); + } else if (heartbeatJSON["status"] === DOWN) { let downdata = { "type": "note", "title": "UptimeKuma Alert: " + monitorJSON["name"], "body": "[🔴 Down] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"], - } - await axios.post(pushbulletUrl, downdata, config) - } else if (heartbeatJSON["status"] == UP) { + }; + await axios.post(pushbulletUrl, downdata, config); + } else if (heartbeatJSON["status"] === UP) { let updata = { "type": "note", "title": "UptimeKuma Alert: " + monitorJSON["name"], "body": "[✅ Up] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"], - } - await axios.post(pushbulletUrl, updata, config) + }; + await axios.post(pushbulletUrl, updata, config); } return okMsg; } catch (error) { - this.throwGeneralAxiosError(error) + this.throwGeneralAxiosError(error); } } } diff --git a/server/notification-providers/pushdeer.js b/server/notification-providers/pushdeer.js new file mode 100644 index 00000000..bbd83f4b --- /dev/null +++ b/server/notification-providers/pushdeer.js @@ -0,0 +1,52 @@ +const NotificationProvider = require("./notification-provider"); +const axios = require("axios"); +const { DOWN, UP } = require("../../src/util"); + +class PushDeer extends NotificationProvider { + + name = "PushDeer"; + + async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { + let okMsg = "Sent Successfully."; + let pushdeerlink = "https://api2.pushdeer.com/message/push"; + + let valid = msg != null && monitorJSON != null && heartbeatJSON != null; + + let title; + if (valid && heartbeatJSON.status === UP) { + title = "## Uptime Kuma: " + monitorJSON.name + " up"; + } else if (valid && heartbeatJSON.status === DOWN) { + title = "## Uptime Kuma: " + monitorJSON.name + " down"; + } else { + title = "## Uptime Kuma Message"; + } + + let data = { + "pushkey": notification.pushdeerKey, + "text": title, + "desp": msg.replace(/\n/g, "\n\n"), + "type": "markdown", + }; + + try { + let res = await axios.post(pushdeerlink, data); + + if ("error" in res.data) { + let error = res.data.error; + this.throwGeneralAxiosError(error); + } + if (res.data.content.result.length === 0) { + let error = "Invalid PushDeer key"; + this.throwGeneralAxiosError(error); + } else if (JSON.parse(res.data.content.result[0]).success !== "ok") { + let error = "Unknown error"; + this.throwGeneralAxiosError(error); + } + return okMsg; + } catch (error) { + this.throwGeneralAxiosError(error); + } + } +} + +module.exports = PushDeer; diff --git a/server/notification-providers/pushy.js b/server/notification-providers/pushy.js index 2bb89934..1d6e7f32 100644 --- a/server/notification-providers/pushy.js +++ b/server/notification-providers/pushy.js @@ -19,10 +19,10 @@ class Pushy extends NotificationProvider { "badge": 1, "sound": "ping.aiff" } - }) + }); return okMsg; } catch (error) { - this.throwGeneralAxiosError(error) + this.throwGeneralAxiosError(error); } } } diff --git a/server/notification-providers/rocket-chat.js b/server/notification-providers/rocket-chat.js index 25b0b945..fb48ce1a 100644 --- a/server/notification-providers/rocket-chat.js +++ b/server/notification-providers/rocket-chat.js @@ -2,7 +2,7 @@ const NotificationProvider = require("./notification-provider"); const axios = require("axios"); const Slack = require("./slack"); const { setting } = require("../util-server"); -const { getMonitorRelativeURL, UP, DOWN } = require("../../src/util"); +const { getMonitorRelativeURL, DOWN } = require("../../src/util"); class RocketChat extends NotificationProvider { diff --git a/server/notification-providers/signal.js b/server/notification-providers/signal.js index fee65754..677208ee 100644 --- a/server/notification-providers/signal.js +++ b/server/notification-providers/signal.js @@ -16,10 +16,10 @@ class Signal extends NotificationProvider { }; let config = {}; - await axios.post(notification.signalURL, data, config) + await axios.post(notification.signalURL, data, config); return okMsg; } catch (error) { - this.throwGeneralAxiosError(error) + this.throwGeneralAxiosError(error); } } } diff --git a/server/notification-providers/smtp.js b/server/notification-providers/smtp.js index d85ee88c..a6a0cc01 100644 --- a/server/notification-providers/smtp.js +++ b/server/notification-providers/smtp.js @@ -1,6 +1,6 @@ const nodemailer = require("nodemailer"); const NotificationProvider = require("./notification-provider"); -const { DOWN, UP } = require("../../src/util"); +const { DOWN } = require("../../src/util"); class SMTP extends NotificationProvider { diff --git a/server/notification-providers/techulus-push.js b/server/notification-providers/techulus-push.js index f844d17c..751ff4c3 100644 --- a/server/notification-providers/techulus-push.js +++ b/server/notification-providers/techulus-push.js @@ -12,10 +12,10 @@ class TechulusPush extends NotificationProvider { await axios.post(`https://push.techulus.com/api/v1/notify/${notification.pushAPIKey}`, { "title": "Uptime-Kuma", "body": msg, - }) + }); return okMsg; } catch (error) { - this.throwGeneralAxiosError(error) + this.throwGeneralAxiosError(error); } } } diff --git a/server/notification-providers/telegram.js b/server/notification-providers/telegram.js index 54d33bfb..2b057622 100644 --- a/server/notification-providers/telegram.js +++ b/server/notification-providers/telegram.js @@ -14,12 +14,12 @@ class Telegram extends NotificationProvider { chat_id: notification.telegramChatID, text: msg, }, - }) + }); return okMsg; } catch (error) { - let msg = (error.response.data.description) ? error.response.data.description : "Error without description" - throw new Error(msg) + let msg = (error.response.data.description) ? error.response.data.description : "Error without description"; + throw new Error(msg); } } } diff --git a/server/notification-providers/webhook.js b/server/notification-providers/webhook.js index 9cb361f3..d4933cf0 100644 --- a/server/notification-providers/webhook.js +++ b/server/notification-providers/webhook.js @@ -24,17 +24,17 @@ class Webhook extends NotificationProvider { config = { headers: finalData.getHeaders(), - } + }; } else { finalData = data; } - await axios.post(notification.webhookURL, finalData, config) + await axios.post(notification.webhookURL, finalData, config); return okMsg; } catch (error) { - this.throwGeneralAxiosError(error) + this.throwGeneralAxiosError(error); } } diff --git a/server/notification-providers/wecom.js b/server/notification-providers/wecom.js index 7ba8c378..deca278c 100644 --- a/server/notification-providers/wecom.js +++ b/server/notification-providers/wecom.js @@ -26,10 +26,10 @@ class WeCom extends NotificationProvider { composeMessage(heartbeatJSON, msg) { let title; - if (msg != null && heartbeatJSON != null && heartbeatJSON['status'] == UP) { + if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] === UP) { title = "UptimeKuma Monitor Up"; } - if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] == DOWN) { + if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] === DOWN) { title = "UptimeKuma Monitor Down"; } if (msg != null) { diff --git a/server/notification.js b/server/notification.js index 30f83b0e..842e0e2f 100644 --- a/server/notification.js +++ b/server/notification.js @@ -24,19 +24,22 @@ const Feishu = require("./notification-providers/feishu"); const AliyunSms = require("./notification-providers/aliyun-sms"); const DingDing = require("./notification-providers/dingding"); const Bark = require("./notification-providers/bark"); +const { log } = require("../src/util"); const SerwerSMS = require("./notification-providers/serwersms"); const Stackfield = require("./notification-providers/stackfield"); const WeCom = require("./notification-providers/wecom"); const GoogleChat = require("./notification-providers/google-chat"); const Gorush = require("./notification-providers/gorush"); const Alerta = require("./notification-providers/alerta"); +const OneBot = require("./notification-providers/onebot"); +const PushDeer = require("./notification-providers/pushdeer"); class Notification { providerList = {}; static init() { - console.log("Prepare Notification Providers"); + log.info("notification", "Prepare Notification Providers"); this.providerList = {}; @@ -72,6 +75,8 @@ class Notification { new GoogleChat(), new Gorush(), new Alerta(), + new OneBot(), + new PushDeer(), ]; for (let item of list) { @@ -104,27 +109,27 @@ class Notification { } static async save(notification, notificationID, userID) { - let bean + let bean; if (notificationID) { bean = await R.findOne("notification", " id = ? AND user_id = ? ", [ notificationID, userID, - ]) + ]); if (! bean) { - throw new Error("notification not found") + throw new Error("notification not found"); } } else { - bean = R.dispense("notification") + bean = R.dispense("notification"); } bean.name = notification.name; bean.user_id = userID; bean.config = JSON.stringify(notification); bean.is_default = notification.isDefault || false; - await R.store(bean) + await R.store(bean); if (notification.applyExisting) { await applyNotificationEveryMonitor(bean.id, userID); @@ -137,13 +142,13 @@ class Notification { let bean = await R.findOne("notification", " id = ? AND user_id = ? ", [ notificationID, userID, - ]) + ]); if (! bean) { - throw new Error("notification not found") + throw new Error("notification not found"); } - await R.trash(bean) + await R.trash(bean); } static checkApprise() { @@ -154,6 +159,13 @@ class Notification { } +/** + * Adds a new monitor to the database. + * @param {number} userID The ID of the user that owns this monitor. + * @param {string} name The name of this monitor. + * + * Generated by Trelent + */ async function applyNotificationEveryMonitor(notificationID, userID) { let monitors = await R.getAll("SELECT id FROM monitor WHERE user_id = ?", [ userID @@ -163,17 +175,17 @@ async function applyNotificationEveryMonitor(notificationID, userID) { let checkNotification = await R.findOne("monitor_notification", " monitor_id = ? AND notification_id = ? ", [ monitors[i].id, notificationID, - ]) + ]); if (! checkNotification) { let relation = R.dispense("monitor_notification"); relation.monitor_id = monitors[i].id; relation.notification_id = notificationID; - await R.store(relation) + await R.store(relation); } } } module.exports = { Notification, -} +}; diff --git a/server/password-hash.js b/server/password-hash.js index 91e5e1ad..a42b4df0 100644 --- a/server/password-hash.js +++ b/server/password-hash.js @@ -4,20 +4,20 @@ const saltRounds = 10; exports.generate = function (password) { return bcrypt.hashSync(password, saltRounds); -} +}; exports.verify = function (password, hash) { if (isSHA1(hash)) { - return passwordHashOld.verify(password, hash) + return passwordHashOld.verify(password, hash); } return bcrypt.compareSync(password, hash); -} +}; function isSHA1(hash) { - return (typeof hash === "string" && hash.startsWith("sha1")) + return (typeof hash === "string" && hash.startsWith("sha1")); } exports.needRehash = function (hash) { return isSHA1(hash); -} +}; diff --git a/server/ping-lite.js b/server/ping-lite.js index 0075e80b..5f15b6d3 100644 --- a/server/ping-lite.js +++ b/server/ping-lite.js @@ -8,6 +8,13 @@ const util = require("./util-server"); module.exports = Ping; +/** + * @param {string} host - The host to ping + * @param {object} [options] - Options for the ping command + * @param {array|string} [options.args] - Arguments to pass to the ping command + * + * Generated by Trelent + */ function Ping(host, options) { if (!host) { throw new Error("You must specify a host to ping!"); @@ -125,6 +132,11 @@ Ping.prototype.send = function (callback) { } }); + /** + * @param {Function} callback + * + * Generated by Trelent + */ function onEnd() { let stdout = this.stdout._stdout; let stderr = this.stderr._stderr; diff --git a/server/prometheus.js b/server/prometheus.js index 86ad381b..fe0896f6 100644 --- a/server/prometheus.js +++ b/server/prometheus.js @@ -1,4 +1,5 @@ const PrometheusClient = require("prom-client"); +const { log } = require("../src/util"); const commonLabels = [ "monitor_name", @@ -8,24 +9,24 @@ const commonLabels = [ "monitor_port", ]; -const monitor_cert_days_remaining = new PrometheusClient.Gauge({ +const monitorCertDaysRemaining = new PrometheusClient.Gauge({ name: "monitor_cert_days_remaining", help: "The number of days remaining until the certificate expires", labelNames: commonLabels }); -const monitor_cert_is_valid = new PrometheusClient.Gauge({ +const monitorCertIsValid = new PrometheusClient.Gauge({ name: "monitor_cert_is_valid", help: "Is the certificate still valid? (1 = Yes, 0= No)", labelNames: commonLabels }); -const monitor_response_time = new PrometheusClient.Gauge({ +const monitorResponseTime = new PrometheusClient.Gauge({ name: "monitor_response_time", help: "Monitor Response Time (ms)", labelNames: commonLabels }); -const monitor_status = new PrometheusClient.Gauge({ +const monitorStatus = new PrometheusClient.Gauge({ name: "monitor_status", help: "Monitor Status (1 = UP, 0= DOWN)", labelNames: commonLabels @@ -48,50 +49,54 @@ class Prometheus { if (typeof tlsInfo !== "undefined") { try { - let is_valid = 0; - if (tlsInfo.valid == true) { - is_valid = 1; + let isValid; + if (tlsInfo.valid === true) { + isValid = 1; } else { - is_valid = 0; + isValid = 0; } - monitor_cert_is_valid.set(this.monitorLabelValues, is_valid); + monitorCertIsValid.set(this.monitorLabelValues, isValid); } catch (e) { - console.error(e); + log.error("prometheus", "Caught error"); + log.error("prometheus", e); } try { if (tlsInfo.certInfo != null) { - monitor_cert_days_remaining.set(this.monitorLabelValues, tlsInfo.certInfo.daysRemaining); + monitorCertDaysRemaining.set(this.monitorLabelValues, tlsInfo.certInfo.daysRemaining); } } catch (e) { - console.error(e); + log.error("prometheus", "Caught error"); + log.error("prometheus", e); } } try { - monitor_status.set(this.monitorLabelValues, heartbeat.status); + monitorStatus.set(this.monitorLabelValues, heartbeat.status); } catch (e) { - console.error(e); + log.error("prometheus", "Caught error"); + log.error("prometheus", e); } try { if (typeof heartbeat.ping === "number") { - monitor_response_time.set(this.monitorLabelValues, heartbeat.ping); + monitorResponseTime.set(this.monitorLabelValues, heartbeat.ping); } else { // Is it good? - monitor_response_time.set(this.monitorLabelValues, -1); + monitorResponseTime.set(this.monitorLabelValues, -1); } } catch (e) { - console.error(e); + log.error("prometheus", "Caught error"); + log.error("prometheus", e); } } remove() { try { - monitor_cert_days_remaining.remove(this.monitorLabelValues); - monitor_cert_is_valid.remove(this.monitorLabelValues); - monitor_response_time.remove(this.monitorLabelValues); - monitor_status.remove(this.monitorLabelValues); + monitorCertDaysRemaining.remove(this.monitorLabelValues); + monitorCertIsValid.remove(this.monitorLabelValues); + monitorResponseTime.remove(this.monitorLabelValues); + monitorStatus.remove(this.monitorLabelValues); } catch (e) { console.error(e); } diff --git a/server/proxy.js b/server/proxy.js new file mode 100644 index 00000000..3de6425c --- /dev/null +++ b/server/proxy.js @@ -0,0 +1,187 @@ +const { R } = require("redbean-node"); +const HttpProxyAgent = require("http-proxy-agent"); +const HttpsProxyAgent = require("https-proxy-agent"); +const SocksProxyAgent = require("socks-proxy-agent"); +const { debug } = require("../src/util"); +const server = require("./server"); + +class Proxy { + + static SUPPORTED_PROXY_PROTOCOLS = [ "http", "https", "socks", "socks5", "socks4" ] + + /** + * Saves and updates given proxy entity + * + * @param proxy + * @param proxyID + * @param userID + * @return {Promise} + */ + static async save(proxy, proxyID, userID) { + let bean; + + if (proxyID) { + bean = await R.findOne("proxy", " id = ? AND user_id = ? ", [ proxyID, userID ]); + + if (!bean) { + throw new Error("proxy not found"); + } + + } else { + bean = R.dispense("proxy"); + } + + // Make sure given proxy protocol is supported + if (!this.SUPPORTED_PROXY_PROTOCOLS.includes(proxy.protocol)) { + throw new Error(` + Unsupported proxy protocol "${proxy.protocol}. + Supported protocols are ${this.SUPPORTED_PROXY_PROTOCOLS.join(", ")}."` + ); + } + + // When proxy is default update deactivate old default proxy + if (proxy.default) { + await R.exec("UPDATE proxy SET `default` = 0 WHERE `default` = 1"); + } + + bean.user_id = userID; + bean.protocol = proxy.protocol; + bean.host = proxy.host; + bean.port = proxy.port; + bean.auth = proxy.auth; + bean.username = proxy.username; + bean.password = proxy.password; + bean.active = proxy.active || true; + bean.default = proxy.default || false; + + await R.store(bean); + + if (proxy.applyExisting) { + await applyProxyEveryMonitor(bean.id, userID); + } + + return bean; + } + + /** + * Deletes proxy with given id and removes it from monitors + * + * @param proxyID + * @param userID + * @return {Promise} + */ + static async delete(proxyID, userID) { + const bean = await R.findOne("proxy", " id = ? AND user_id = ? ", [ proxyID, userID ]); + + if (!bean) { + throw new Error("proxy not found"); + } + + // Delete removed proxy from monitors if exists + await R.exec("UPDATE monitor SET proxy_id = null WHERE proxy_id = ?", [ proxyID ]); + + // Delete proxy from list + await R.trash(bean); + } + + /** + * Create HTTP and HTTPS agents related with given proxy bean object + * + * @param proxy proxy bean object + * @param options http and https agent options + * @return {{httpAgent: Agent, httpsAgent: Agent}} + */ + static createAgents(proxy, options) { + const { httpAgentOptions, httpsAgentOptions } = options || {}; + let agent; + let httpAgent; + let httpsAgent; + + const proxyOptions = { + protocol: proxy.protocol, + host: proxy.host, + port: proxy.port, + }; + + if (proxy.auth) { + proxyOptions.auth = `${proxy.username}:${proxy.password}`; + } + + debug(`Proxy Options: ${JSON.stringify(proxyOptions)}`); + debug(`HTTP Agent Options: ${JSON.stringify(httpAgentOptions)}`); + debug(`HTTPS Agent Options: ${JSON.stringify(httpsAgentOptions)}`); + + switch (proxy.protocol) { + case "http": + case "https": + httpAgent = new HttpProxyAgent({ + ...httpAgentOptions || {}, + ...proxyOptions + }); + + httpsAgent = new HttpsProxyAgent({ + ...httpsAgentOptions || {}, + ...proxyOptions, + }); + break; + case "socks": + case "socks5": + case "socks4": + agent = new SocksProxyAgent({ + ...httpAgentOptions, + ...httpsAgentOptions, + ...proxyOptions, + }); + + httpAgent = agent; + httpsAgent = agent; + break; + + default: throw new Error(`Unsupported proxy protocol provided. ${proxy.protocol}`); + } + + return { + httpAgent, + httpsAgent + }; + } + + /** + * Reload proxy settings for current monitors + * @returns {Promise} + */ + static async reloadProxy() { + let updatedList = await R.getAssoc("SELECT id, proxy_id FROM monitor"); + + for (let monitorID in server.monitorList) { + let monitor = server.monitorList[monitorID]; + + if (updatedList[monitorID]) { + monitor.proxy_id = updatedList[monitorID].proxy_id; + } + } + } +} + +/** + * Applies given proxy id to monitors + * + * @param proxyID + * @param userID + * @return {Promise} + */ +async function applyProxyEveryMonitor(proxyID, userID) { + // Find all monitors with id and proxy id + const monitors = await R.getAll("SELECT id, proxy_id FROM monitor WHERE user_id = ?", [ userID ]); + + // Update proxy id not match with given proxy id + for (const monitor of monitors) { + if (monitor.proxy_id !== proxyID) { + await R.exec("UPDATE monitor SET proxy_id = ? WHERE id = ?", [ proxyID, monitor.id ]); + } + } +} + +module.exports = { + Proxy, +}; diff --git a/server/rate-limiter.js b/server/rate-limiter.js index 0bacc14c..f58f16cb 100644 --- a/server/rate-limiter.js +++ b/server/rate-limiter.js @@ -1,5 +1,5 @@ const { RateLimiter } = require("limiter"); -const { debug } = require("../src/util"); +const { log } = require("../src/util"); class KumaRateLimiter { constructor(config) { @@ -9,7 +9,7 @@ class KumaRateLimiter { async pass(callback, num = 1) { const remainingRequests = await this.removeTokens(num); - debug("Rate Limit (remainingRequests):" + remainingRequests); + log.info("rate-limit", "remaining requests: " + remainingRequests); if (remainingRequests < 0) { if (callback) { callback({ @@ -34,6 +34,14 @@ const loginRateLimiter = new KumaRateLimiter({ errorMessage: "Too frequently, try again later." }); +const twoFaRateLimiter = new KumaRateLimiter({ + tokensPerInterval: 30, + interval: "minute", + fireImmediately: true, + errorMessage: "Too frequently, try again later." +}); + module.exports = { - loginRateLimiter + loginRateLimiter, + twoFaRateLimiter, }; diff --git a/server/routers/api-router.js b/server/routers/api-router.js index ad887084..51aa5f3f 100644 --- a/server/routers/api-router.js +++ b/server/routers/api-router.js @@ -1,20 +1,30 @@ let express = require("express"); -const { allowDevAllOrigin, getSettings, setting } = require("../util-server"); +const { allowDevAllOrigin } = require("../util-server"); const { R } = require("redbean-node"); const server = require("../server"); const apicache = require("../modules/apicache"); const Monitor = require("../model/monitor"); const dayjs = require("dayjs"); -const { UP, flipStatus, debug } = require("../../src/util"); +const { UP, flipStatus, log } = require("../../src/util"); const StatusPage = require("../model/status_page"); let router = express.Router(); let cache = apicache.middleware; let io = server.io; -router.get("/api/entry-page", async (_, response) => { +router.get("/api/entry-page", async (request, response) => { allowDevAllOrigin(response); - response.json(server.entryPage); + + let result = { }; + + if (request.hostname in StatusPage.domainMappingList) { + result.type = "statusPageMatchedDomain"; + result.statusPageSlug = StatusPage.domainMappingList[request.hostname]; + } else { + result.type = "entryPage"; + result.entryPage = server.entryPage; + } + response.json(result); }); router.get("/api/push/:pushToken", async (request, response) => { @@ -52,8 +62,8 @@ router.get("/api/push/:pushToken", async (request, response) => { duration = dayjs(bean.time).diff(dayjs(previousHeartbeat.time), "second"); } - debug("PreviousStatus: " + previousStatus); - debug("Current Status: " + status); + log.debug("router", "PreviousStatus: " + previousStatus); + log.debug("router", "Current Status: " + status); bean.important = Monitor.isImportantBeat(isFirstBeat, previousStatus, status); bean.monitor_id = monitor.id; @@ -114,7 +124,7 @@ router.get("/api/status-page/:slug", cache("5 minutes"), async (request, respons // Public Group List const publicGroupList = []; const showTags = !!statusPage.show_tags; - debug("Show Tags???" + showTags); + const list = await R.find("group", " public = 1 AND status_page_id = ? ORDER BY weight ", [ statusPage.id ]); @@ -185,14 +195,6 @@ router.get("/api/status-page/heartbeat/:slug", cache("1 minutes"), async (reques } }); -/** - * Default is published - * @returns {Promise} - */ -async function isPublished() { - return true; -} - function send403(res, msg = "") { res.status(403).json({ "status": "fail", diff --git a/server/server.js b/server/server.js index f3e8db0f..7d6ee42b 100644 --- a/server/server.js +++ b/server/server.js @@ -11,89 +11,115 @@ if (nodeVersion < requiredVersion) { } const args = require("args-parser")(process.argv); -const { sleep, debug, getRandomInt, genSecret } = require("../src/util"); +const { sleep, log, getRandomInt, genSecret, debug, isDev } = require("../src/util"); const config = require("./config"); -debug(args); +log.info("server", "Welcome to Uptime Kuma"); +log.debug("server", "Arguments"); +log.debug("server", args); if (! process.env.NODE_ENV) { process.env.NODE_ENV = "production"; } -console.log("Node Env: " + process.env.NODE_ENV); +log.info("server", "Node Env: " + process.env.NODE_ENV); -console.log("Importing Node libraries"); +log.info("server", "Importing Node libraries"); const fs = require("fs"); const http = require("http"); const https = require("https"); -console.log("Importing 3rd-party libraries"); -debug("Importing express"); +log.info("server", "Importing 3rd-party libraries"); +log.debug("server", "Importing express"); const express = require("express"); -debug("Importing socket.io"); +log.debug("server", "Importing socket.io"); const { Server } = require("socket.io"); -debug("Importing redbean-node"); +log.debug("server", "Importing redbean-node"); const { R } = require("redbean-node"); -debug("Importing jsonwebtoken"); +log.debug("server", "Importing jsonwebtoken"); const jwt = require("jsonwebtoken"); -debug("Importing http-graceful-shutdown"); +log.debug("server", "Importing http-graceful-shutdown"); const gracefulShutdown = require("http-graceful-shutdown"); -debug("Importing prometheus-api-metrics"); +log.debug("server", "Importing prometheus-api-metrics"); const prometheusAPIMetrics = require("prometheus-api-metrics"); -debug("Importing compare-versions"); +log.debug("server", "Importing compare-versions"); const compareVersions = require("compare-versions"); const { passwordStrength } = require("check-password-strength"); -debug("Importing 2FA Modules"); +log.debug("server", "Importing 2FA Modules"); const notp = require("notp"); const base32 = require("thirty-two"); -console.log("Importing this project modules"); -debug("Importing Monitor"); +/** + * `module.exports` (alias: `server`) should be inside this class, in order to avoid circular dependency issue. + * @type {UptimeKumaServer} + */ +class UptimeKumaServer { + /** + * Main monitor list + * @type {{}} + */ + monitorList = {}; + entryPage = "dashboard"; + + async sendMonitorList(socket) { + let list = await getMonitorJSONList(socket.userID); + io.to(socket.userID).emit("monitorList", list); + return list; + } +} + +const server = module.exports = new UptimeKumaServer(); + +log.info("server", "Importing this project modules"); +log.debug("server", "Importing Monitor"); const Monitor = require("./model/monitor"); -debug("Importing Settings"); -const { getSettings, setSettings, setting, initJWTSecret, checkLogin, startUnitTest, FBSD, errorLog } = require("./util-server"); +log.debug("server", "Importing Settings"); +const { getSettings, setSettings, setting, initJWTSecret, checkLogin, startUnitTest, FBSD, errorLog, doubleCheckPassword } = require("./util-server"); -debug("Importing Notification"); +log.debug("server", "Importing Notification"); const { Notification } = require("./notification"); Notification.init(); -debug("Importing Database"); +log.debug("server", "Importing Proxy"); +const { Proxy } = require("./proxy"); + +log.debug("server", "Importing Database"); const Database = require("./database"); -debug("Importing Background Jobs"); -const { initBackgroundJobs } = require("./jobs"); -const { loginRateLimiter } = require("./rate-limiter"); +log.debug("server", "Importing Background Jobs"); +const { initBackgroundJobs, stopBackgroundJobs } = require("./jobs"); +const { loginRateLimiter, twoFaRateLimiter } = require("./rate-limiter"); const { basicAuth } = require("./auth"); const { login } = require("./auth"); const passwordHash = require("./password-hash"); const checkVersion = require("./check-version"); -console.info("Version: " + checkVersion.version); +log.info("server", "Version: " + checkVersion.version); // 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 || args.host; - // Also read HOST if not FreeBSD, as HOST is a system environment variable in FreeBSD -if (!hostname && !FBSD) { - hostname = process.env.HOST; -} +let hostEnv = FBSD ? null : process.env.HOST; +let hostname = args.host || process.env.UPTIME_KUMA_HOST || hostEnv; if (hostname) { - console.log("Custom hostname: " + hostname); + log.info("server", "Custom hostname: " + hostname); } -const port = parseInt(process.env.UPTIME_KUMA_PORT || process.env.PORT || args.port || 3001); +const port = [ args.port, process.env.UPTIME_KUMA_PORT, process.env.PORT, 3001 ] + .map(portValue => parseInt(portValue)) + .find(portValue => !isNaN(portValue)); // 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; +const sslKey = args["ssl-key"] || process.env.UPTIME_KUMA_SSL_KEY || process.env.SSL_KEY || undefined; +const sslCert = args["ssl-cert"] || process.env.UPTIME_KUMA_SSL_CERT || process.env.SSL_CERT || undefined; +const disableFrameSameOrigin = args["disable-frame-sameorigin"] || !!process.env.UPTIME_KUMA_DISABLE_FRAME_SAMEORIGIN || false; +const cloudflaredToken = args["cloudflared-token"] || process.env.UPTIME_KUMA_CLOUDFLARED_TOKEN || undefined; // 2FA / notp verification defaults -const twofa_verification_opts = { +const twoFAVerifyOptions = { "window": 1, "time": 30 }; @@ -105,34 +131,36 @@ const twofa_verification_opts = { const testMode = !!args["test"] || false; if (config.demoMode) { - console.log("==== Demo Mode ===="); + log.info("server", "==== Demo Mode ===="); } -console.log("Creating express and socket.io instance"); +log.info("server", "Creating express and socket.io instance"); const app = express(); -let server; +let httpServer; if (sslKey && sslCert) { - console.log("Server Type: HTTPS"); - server = https.createServer({ + log.info("server", "Server Type: HTTPS"); + httpServer = https.createServer({ key: fs.readFileSync(sslKey), cert: fs.readFileSync(sslCert) }, app); } else { - console.log("Server Type: HTTP"); - server = http.createServer(app); + log.info("server", "Server Type: HTTP"); + httpServer = http.createServer(app); } -const io = new Server(server); +const io = new Server(httpServer); module.exports.io = io; // Must be after io instantiation -const { sendNotificationList, sendHeartbeatList, sendImportantHeartbeatList, sendInfo } = require("./client"); +const { sendNotificationList, sendHeartbeatList, sendImportantHeartbeatList, sendInfo, sendProxyList } = require("./client"); const { statusPageSocketHandler } = require("./socket-handlers/status-page-socket-handler"); const databaseSocketHandler = require("./socket-handlers/database-socket-handler"); const TwoFA = require("./2fa"); const StatusPage = require("./model/status_page"); +const { cloudflaredSocketHandler, autoStart: cloudflaredAutoStart, stop: cloudflaredStop } = require("./socket-handlers/cloudflared-socket-handler"); +const { proxySocketHandler } = require("./socket-handlers/proxy-socket-handler"); app.use(express.json()); @@ -147,6 +175,7 @@ app.use(function (req, res, next) { /** * Total WebSocket client connected to server currently, no actual use + * * @type {number} */ let totalClient = 0; @@ -157,12 +186,6 @@ let totalClient = 0; */ let jwtSecret = null; -/** - * Main monitor list - * @type {{}} - */ -let monitorList = {}; - /** * Show Setup Page * @type {boolean} @@ -180,34 +203,45 @@ try { } catch (e) { // "dist/index.html" is not necessary for development if (process.env.NODE_ENV !== "development") { - console.error("Error: Cannot find 'dist/index.html', did you install correctly?"); + log.error("server", "Error: Cannot find 'dist/index.html', did you install correctly?"); process.exit(1); } } -exports.entryPage = "dashboard"; - (async () => { Database.init(args); await initDatabase(testMode); exports.entryPage = await setting("entryPage"); + await StatusPage.loadDomainMappingList(); - console.log("Adding route"); + log.info("server", "Adding route"); // *************************** // Normal Router here // *************************** // Entry Page - app.get("/", async (_request, response) => { - if (exports.entryPage && exports.entryPage.startsWith("statusPage-")) { + app.get("/", async (request, response) => { + debug(`Request Domain: ${request.hostname}`); + + if (request.hostname in StatusPage.domainMappingList) { + debug("This is a status page domain"); + response.send(indexHTML); + } else if (exports.entryPage && exports.entryPage.startsWith("statusPage-")) { response.redirect("/status/" + exports.entryPage.replace("statusPage-", "")); } else { response.redirect("/dashboard"); } }); + if (isDev) { + app.post("/test-webhook", async (request, response) => { + log.debug("test", request.body); + response.send("OK"); + }); + } + // Robots.txt app.get("/robots.txt", async (_request, response) => { let txt = "User-agent: *\nDisallow:"; @@ -246,7 +280,7 @@ exports.entryPage = "dashboard"; } }); - console.log("Adding socket handler"); + log.info("server", "Adding socket handler"); io.on("connection", async (socket) => { sendInfo(socket); @@ -254,7 +288,7 @@ exports.entryPage = "dashboard"; totalClient++; if (needSetup) { - console.log("Redirect to setup page"); + log.info("server", "Redirect to setup page"); socket.emit("setup"); } @@ -267,33 +301,40 @@ exports.entryPage = "dashboard"; // *************************** socket.on("loginByToken", async (token, callback) => { + log.info("auth", `Login by token. IP=${getClientIp(socket)}`); try { let decoded = jwt.verify(token, jwtSecret); - console.log("Username from JWT: " + decoded.username); + log.info("auth", "Username from JWT: " + decoded.username); let user = await R.findOne("user", " username = ? AND active = 1 ", [ decoded.username, ]); if (user) { - debug("afterLogin"); - + log.debug("auth", "afterLogin"); afterLogin(socket, user); + log.debug("auth", "afterLogin ok"); - debug("afterLogin ok"); + log.info("auth", `Successfully logged in user ${decoded.username}. IP=${getClientIp(socket)}`); callback({ ok: true, }); } else { + + log.info("auth", `Inactive or deleted user ${decoded.username}. IP=${getClientIp(socket)}`); + callback({ ok: false, msg: "The user is inactive or deleted.", }); } } catch (error) { + + log.error("auth", `Invalid token. IP=${getClientIp(socket)}`); + callback({ ok: false, msg: "Invalid token.", @@ -303,10 +344,20 @@ exports.entryPage = "dashboard"; }); socket.on("login", async (data, callback) => { - console.log("Login"); + log.info("auth", `Login by username + password. IP=${getClientIp(socket)}`); + + // Checking + if (typeof callback !== "function") { + return; + } + + if (!data) { + return; + } // Login Rate Limit if (! await loginRateLimiter.pass(callback)) { + log.info("auth", `Too many failed requests for user ${data.username}. IP=${getClientIp(socket)}`); return; } @@ -315,6 +366,9 @@ exports.entryPage = "dashboard"; if (user) { if (user.twofa_status == 0) { afterLogin(socket, user); + + log.info("auth", `Successfully logged in user ${data.username}. IP=${getClientIp(socket)}`); + callback({ ok: true, token: jwt.sign({ @@ -324,13 +378,16 @@ exports.entryPage = "dashboard"; } if (user.twofa_status == 1 && !data.token) { + + log.info("auth", `2FA token required for user ${data.username}. IP=${getClientIp(socket)}`); + callback({ tokenRequired: true, }); } if (data.token) { - let verify = notp.totp.verify(data.token, user.twofa_secret, twofa_verification_opts); + let verify = notp.totp.verify(data.token, user.twofa_secret, twoFAVerifyOptions); if (user.twofa_last_token !== data.token && verify) { afterLogin(socket, user); @@ -340,6 +397,8 @@ exports.entryPage = "dashboard"; socket.userID, ]); + log.info("auth", `Successfully logged in user ${data.username}. IP=${getClientIp(socket)}`); + callback({ ok: true, token: jwt.sign({ @@ -347,6 +406,9 @@ exports.entryPage = "dashboard"; }, jwtSecret), }); } else { + + log.warn("auth", `Invalid token provided for user ${data.username}. IP=${getClientIp(socket)}`); + callback({ ok: false, msg: "Invalid Token!", @@ -354,6 +416,9 @@ exports.entryPage = "dashboard"; } } } else { + + log.warn("auth", `Incorrect username or password for user ${data.username}. IP=${getClientIp(socket)}`); + callback({ ok: false, msg: "Incorrect username or password.", @@ -363,14 +428,27 @@ exports.entryPage = "dashboard"; }); socket.on("logout", async (callback) => { + // Rate Limit + if (! await loginRateLimiter.pass(callback)) { + return; + } + socket.leave(socket.userID); socket.userID = null; - callback(); + + if (typeof callback === "function") { + callback(); + } }); - socket.on("prepare2FA", async (callback) => { + socket.on("prepare2FA", async (currentPassword, callback) => { try { + if (! await twoFaRateLimiter.pass(callback)) { + return; + } + checkLogin(socket); + await doubleCheckPassword(socket, currentPassword); let user = await R.findOne("user", " id = ? AND active = 1 ", [ socket.userID, @@ -405,73 +483,104 @@ exports.entryPage = "dashboard"; } catch (error) { callback({ ok: false, - msg: "Error while trying to prepare 2FA.", + msg: error.message, }); } }); - socket.on("save2FA", async (callback) => { + socket.on("save2FA", async (currentPassword, callback) => { try { + if (! await twoFaRateLimiter.pass(callback)) { + return; + } + checkLogin(socket); + await doubleCheckPassword(socket, currentPassword); await R.exec("UPDATE `user` SET twofa_status = 1 WHERE id = ? ", [ socket.userID, ]); + log.info("auth", `Saved 2FA token. IP=${getClientIp(socket)}`); + callback({ ok: true, msg: "2FA Enabled.", }); } catch (error) { + + log.error("auth", `Error changing 2FA token. IP=${getClientIp(socket)}`); + callback({ ok: false, - msg: "Error while trying to change 2FA.", + msg: error.message, }); } }); - socket.on("disable2FA", async (callback) => { + socket.on("disable2FA", async (currentPassword, callback) => { try { + if (! await twoFaRateLimiter.pass(callback)) { + return; + } + checkLogin(socket); + await doubleCheckPassword(socket, currentPassword); await TwoFA.disable2FA(socket.userID); + log.info("auth", `Disabled 2FA token. IP=${getClientIp(socket)}`); + callback({ ok: true, msg: "2FA Disabled.", }); } catch (error) { + + log.error("auth", `Error disabling 2FA token. IP=${getClientIp(socket)}`); + callback({ ok: false, - msg: "Error while trying to change 2FA.", + msg: error.message, }); } }); - socket.on("verifyToken", async (token, callback) => { - let user = await R.findOne("user", " id = ? AND active = 1 ", [ - socket.userID, - ]); + socket.on("verifyToken", async (token, currentPassword, callback) => { + try { + checkLogin(socket); + await doubleCheckPassword(socket, currentPassword); - let verify = notp.totp.verify(token, user.twofa_secret, twofa_verification_opts); + let user = await R.findOne("user", " id = ? AND active = 1 ", [ + socket.userID, + ]); - if (user.twofa_last_token !== token && verify) { - callback({ - ok: true, - valid: true, - }); - } else { + let verify = notp.totp.verify(token, user.twofa_secret, twoFAVerifyOptions); + + if (user.twofa_last_token !== token && verify) { + callback({ + ok: true, + valid: true, + }); + } else { + callback({ + ok: false, + msg: "Invalid Token.", + valid: false, + }); + } + + } catch (error) { callback({ ok: false, - msg: "Invalid Token.", - valid: false, + msg: error.message, }); } }); socket.on("twoFAStatus", async (callback) => { - checkLogin(socket); - try { + checkLogin(socket); + let user = await R.findOne("user", " id = ? AND active = 1 ", [ socket.userID, ]); @@ -488,9 +597,10 @@ exports.entryPage = "dashboard"; }); } } catch (error) { + console.log(error); callback({ ok: false, - msg: "Error while trying to get 2FA status.", + msg: error.message, }); } }); @@ -551,9 +661,11 @@ exports.entryPage = "dashboard"; await updateMonitorNotification(bean.id, notificationIDList); - await sendMonitorList(socket); + await server.sendMonitorList(socket); await startMonitor(socket.userID, bean.id); + log.info("monitor", `Added Monitor: ${monitor.id} User ID: ${socket.userID}`); + callback({ ok: true, msg: "Added Successfully.", @@ -561,6 +673,9 @@ exports.entryPage = "dashboard"; }); } catch (e) { + + log.error("monitor", `Error adding Monitor: ${monitor.id} User ID: ${socket.userID}`); + callback({ ok: false, msg: e.message, @@ -580,7 +695,7 @@ exports.entryPage = "dashboard"; } // Reset Prometheus labels - monitorList[monitor.id]?.prometheus()?.remove(); + server.monitorList[monitor.id]?.prometheus()?.remove(); bean.name = monitor.name; bean.type = monitor.type; @@ -597,12 +712,18 @@ exports.entryPage = "dashboard"; bean.port = monitor.port; bean.keyword = monitor.keyword; bean.ignoreTls = monitor.ignoreTls; + bean.expiryNotification = monitor.expiryNotification; bean.upsideDown = monitor.upsideDown; bean.maxredirects = monitor.maxredirects; bean.accepted_statuscodes_json = JSON.stringify(monitor.accepted_statuscodes); bean.dns_resolve_type = monitor.dns_resolve_type; bean.dns_resolve_server = monitor.dns_resolve_server; bean.pushToken = monitor.pushToken; + bean.proxyId = Number.isInteger(monitor.proxyId) ? monitor.proxyId : null; + bean.mqttUsername = monitor.mqttUsername; + bean.mqttPassword = monitor.mqttPassword; + bean.mqttTopic = monitor.mqttTopic; + bean.mqttSuccessMessage = monitor.mqttSuccessMessage; await R.store(bean); @@ -612,7 +733,7 @@ exports.entryPage = "dashboard"; await restartMonitor(socket.userID, bean.id); } - await sendMonitorList(socket); + await server.sendMonitorList(socket); callback({ ok: true, @@ -621,7 +742,7 @@ exports.entryPage = "dashboard"; }); } catch (e) { - console.error(e); + log.error("monitor", e); callback({ ok: false, msg: e.message, @@ -632,12 +753,12 @@ exports.entryPage = "dashboard"; socket.on("getMonitorList", async (callback) => { try { checkLogin(socket); - await sendMonitorList(socket); + await server.sendMonitorList(socket); callback({ ok: true, }); } catch (e) { - console.error(e); + log.error("monitor", e); callback({ ok: false, msg: e.message, @@ -649,7 +770,7 @@ exports.entryPage = "dashboard"; try { checkLogin(socket); - console.log(`Get Monitor: ${monitorID} User ID: ${socket.userID}`); + log.info("monitor", `Get Monitor: ${monitorID} User ID: ${socket.userID}`); let bean = await R.findOne("monitor", " id = ? AND user_id = ? ", [ monitorID, @@ -673,7 +794,7 @@ exports.entryPage = "dashboard"; try { checkLogin(socket); - console.log(`Get Monitor Beats: ${monitorID} User ID: ${socket.userID}`); + log.info("monitor", `Get Monitor Beats: ${monitorID} User ID: ${socket.userID}`); if (period == null) { throw new Error("Invalid period."); @@ -706,7 +827,7 @@ exports.entryPage = "dashboard"; try { checkLogin(socket); await startMonitor(socket.userID, monitorID); - await sendMonitorList(socket); + await server.sendMonitorList(socket); callback({ ok: true, @@ -725,7 +846,7 @@ exports.entryPage = "dashboard"; try { checkLogin(socket); await pauseMonitor(socket.userID, monitorID); - await sendMonitorList(socket); + await server.sendMonitorList(socket); callback({ ok: true, @@ -744,11 +865,11 @@ exports.entryPage = "dashboard"; try { checkLogin(socket); - console.log(`Delete Monitor: ${monitorID} User ID: ${socket.userID}`); + log.info("manage", `Delete Monitor: ${monitorID} User ID: ${socket.userID}`); - if (monitorID in monitorList) { - monitorList[monitorID].stop(); - delete monitorList[monitorID]; + if (monitorID in server.monitorList) { + server.monitorList[monitorID].stop(); + delete server.monitorList[monitorID]; } await R.exec("DELETE FROM monitor WHERE id = ? AND user_id = ? ", [ @@ -761,7 +882,7 @@ exports.entryPage = "dashboard"; msg: "Deleted Successfully.", }); - await sendMonitorList(socket); + await server.sendMonitorList(socket); // Clear heartbeat list on client await sendImportantHeartbeatList(socket, monitorID, true, true); @@ -939,21 +1060,13 @@ exports.entryPage = "dashboard"; throw new Error("Password is too weak. It should contain alphabetic and numeric characters. It must be at least 6 characters in length."); } - let user = await R.findOne("user", " id = ? AND active = 1 ", [ - socket.userID, - ]); - - if (user && passwordHash.verify(password.currentPassword, user.password)) { + let user = await doubleCheckPassword(socket, password.currentPassword); + await user.resetPassword(password.newPassword); - user.resetPassword(password.newPassword); - - callback({ - ok: true, - msg: "Password has been updated successfully.", - }); - } else { - throw new Error("Incorrect current password"); - } + callback({ + ok: true, + msg: "Password has been updated successfully.", + }); } catch (e) { callback({ @@ -980,10 +1093,14 @@ exports.entryPage = "dashboard"; } }); - socket.on("setSettings", async (data, callback) => { + socket.on("setSettings", async (data, currentPassword, callback) => { try { checkLogin(socket); + if (data.disableAuth) { + await doubleCheckPassword(socket, currentPassword); + } + await setSettings("general", data); exports.entryPage = data.entryPage; @@ -1080,9 +1197,10 @@ exports.entryPage = "dashboard"; let backupData = JSON.parse(uploadedJSON); - console.log(`Importing Backup, User ID: ${socket.userID}, Version: ${backupData.version}`); + log.info("manage", `Importing Backup, User ID: ${socket.userID}, Version: ${backupData.version}`); let notificationListData = backupData.notificationList; + let proxyListData = backupData.proxyList; let monitorListData = backupData.monitorList; let version17x = compareVersions.compare(backupData.version, "1.7.0", ">="); @@ -1090,8 +1208,8 @@ exports.entryPage = "dashboard"; // If the import option is "overwrite" it'll clear most of the tables, except "settings" and "user" if (importHandle == "overwrite") { // Stops every monitor first, so it doesn't execute any heartbeat while importing - for (let id in monitorList) { - let monitor = monitorList[id]; + for (let id in server.monitorList) { + let monitor = server.monitorList[id]; await monitor.stop(); } await R.exec("DELETE FROM heartbeat"); @@ -1101,6 +1219,7 @@ exports.entryPage = "dashboard"; await R.exec("DELETE FROM monitor_tag"); await R.exec("DELETE FROM tag"); await R.exec("DELETE FROM monitor"); + await R.exec("DELETE FROM proxy"); } // Only starts importing if the backup file contains at least one notification @@ -1120,6 +1239,24 @@ exports.entryPage = "dashboard"; } } + // Only starts importing if the backup file contains at least one proxy + if (proxyListData && proxyListData.length >= 1) { + const proxies = await R.findAll("proxy"); + + // Loop over proxy list and save proxies + for (const proxy of proxyListData) { + const exists = proxies.find(item => item.id === proxy.id); + + // Do not process when proxy already exists in import handle is skip and keep + if ([ "skip", "keep" ].includes(importHandle) && !exists) { + return; + } + + // Save proxy as new entry if exists update exists one + await Proxy.save(proxy, exists ? proxy.id : undefined, proxy.userId); + } + } + // Only starts importing if the backup file contains at least one monitor if (monitorListData.length >= 1) { // Get every existing monitor name and puts them in one simple string @@ -1169,6 +1306,7 @@ exports.entryPage = "dashboard"; dns_resolve_type: monitorListData[i].dns_resolve_type, dns_resolve_server: monitorListData[i].dns_resolve_server, notificationIDList: {}, + proxy_id: monitorListData[i].proxy_id || null, }; if (monitorListData[i].pushToken) { @@ -1234,7 +1372,7 @@ exports.entryPage = "dashboard"; } await sendNotificationList(socket); - await sendMonitorList(socket); + await server.sendMonitorList(socket); } callback({ @@ -1254,7 +1392,7 @@ exports.entryPage = "dashboard"; try { checkLogin(socket); - console.log(`Clear Events Monitor: ${monitorID} User ID: ${socket.userID}`); + log.info("manage", `Clear Events Monitor: ${monitorID} User ID: ${socket.userID}`); await R.exec("UPDATE heartbeat SET msg = ?, important = ? WHERE monitor_id = ? ", [ "", @@ -1280,7 +1418,7 @@ exports.entryPage = "dashboard"; try { checkLogin(socket); - console.log(`Clear Heartbeats Monitor: ${monitorID} User ID: ${socket.userID}`); + log.info("manage", `Clear Heartbeats Monitor: ${monitorID} User ID: ${socket.userID}`); await R.exec("DELETE FROM heartbeat WHERE monitor_id = ?", [ monitorID @@ -1304,7 +1442,7 @@ exports.entryPage = "dashboard"; try { checkLogin(socket); - console.log(`Clear Statistics User ID: ${socket.userID}`); + log.info("manage", `Clear Statistics User ID: ${socket.userID}`); await R.exec("DELETE FROM heartbeat"); @@ -1322,37 +1460,39 @@ exports.entryPage = "dashboard"; // Status Page Socket Handler for admin only statusPageSocketHandler(socket); + cloudflaredSocketHandler(socket); databaseSocketHandler(socket); + proxySocketHandler(socket); - debug("added all socket handlers"); + log.debug("server", "added all socket handlers"); // *************************** // Better do anything after added all socket handlers here // *************************** - debug("check auto login"); + log.debug("auth", "check auto login"); if (await setting("disableAuth")) { - console.log("Disabled Auth: auto login to admin"); + log.info("auth", "Disabled Auth: auto login to admin"); afterLogin(socket, await R.findOne("user")); socket.emit("autoLogin"); } else { - debug("need auth"); + log.debug("auth", "need auth"); } }); - console.log("Init the server"); + log.info("server", "Init the server"); - server.once("error", async (err) => { + httpServer.once("error", async (err) => { console.error("Cannot listen: " + err.message); - await Database.close(); + await shutdownFunction(); }); - server.listen(port, hostname, () => { + httpServer.listen(port, hostname, () => { if (hostname) { - console.log(`Listening on ${hostname}:${port}`); + log.info("server", `Listening on ${hostname}:${port}`); } else { - console.log(`Listening on ${port}`); + log.info("server", `Listening on ${port}`); } startMonitors(); checkVersion.startInterval(); @@ -1364,8 +1504,18 @@ exports.entryPage = "dashboard"; initBackgroundJobs(args); + // Start cloudflared at the end if configured + await cloudflaredAutoStart(cloudflaredToken); + })(); +/** + * Adds or removes notifications from a monitor. + * @param {number} monitorID The ID of the monitor to add/remove notifications from. + * @param {Array.} notificationIDList An array of IDs for the notifications to add/remove. + * + * Generated by Trelent + */ async function updateMonitorNotification(monitorID, notificationIDList) { await R.exec("DELETE FROM monitor_notification WHERE monitor_id = ? ", [ monitorID, @@ -1381,6 +1531,13 @@ async function updateMonitorNotification(monitorID, notificationIDList) { } } +/** + * This function checks if the user owns a monitor with the given ID. + * @param {number} monitorID - The ID of the monitor to check ownership for. + * @param {number} userID - The ID of the user who is trying to access this data. + * + * Generated by Trelent + */ async function checkOwner(userID, monitorID) { let row = await R.getRow("SELECT id FROM monitor WHERE id = ? AND user_id = ? ", [ monitorID, @@ -1392,18 +1549,17 @@ async function checkOwner(userID, monitorID) { } } -async function sendMonitorList(socket) { - let list = await getMonitorJSONList(socket.userID); - io.to(socket.userID).emit("monitorList", list); - return list; -} - +/** + * This function is used to send the heartbeat list of a monitor. + * @param {Socket} socket - The socket object that will be used to send the data. + */ async function afterLogin(socket, user) { socket.userID = user.id; socket.join(user.id); - let monitorList = await sendMonitorList(socket); + let monitorList = await server.sendMonitorList(socket); sendNotificationList(socket); + sendProxyList(socket); await sleep(500); @@ -1422,6 +1578,13 @@ async function afterLogin(socket, user) { } } +/** + * Get a list of monitors for the given user. + * @param {string} userID - The ID of the user to get monitors for. + * @returns {Promise} A promise that resolves to an object with monitor IDs as keys and monitor objects as values. + * + * Generated by Trelent + */ async function getMonitorJSONList(userID) { let result = {}; @@ -1436,15 +1599,20 @@ async function getMonitorJSONList(userID) { return result; } +/** + * Connect to the database and patch it if necessary. + * + * Generated by Trelent + */ async function initDatabase(testMode = false) { if (! fs.existsSync(Database.path)) { - console.log("Copying Database"); + log.info("server", "Copying Database"); fs.copyFileSync(Database.templatePath, Database.path); } - console.log("Connecting to the Database"); + log.info("server", "Connecting to the Database"); await Database.connect(testMode); - console.log("Connected"); + log.info("server", "Connected"); // Patch the database await Database.patch(); @@ -1454,26 +1622,33 @@ async function initDatabase(testMode = false) { ]); if (! jwtSecretBean) { - console.log("JWT secret is not found, generate one."); + log.info("server", "JWT secret is not found, generate one."); jwtSecretBean = await initJWTSecret(); - console.log("Stored JWT secret into database"); + log.info("server", "Stored JWT secret into database"); } else { - console.log("Load JWT secret from database."); + log.info("server", "Load JWT secret from database."); } // If there is no record in user table, it is a new Uptime Kuma instance, need to setup if ((await R.count("user")) === 0) { - console.log("No user, need setup"); + log.info("server", "No user, need setup"); needSetup = true; } jwtSecret = jwtSecretBean.value; } +/** + * Resume a monitor. + * @param {string} userID - The ID of the user who owns the monitor. + * @param {string} monitorID - The ID of the monitor to resume. + * + * Generated by Trelent + */ async function startMonitor(userID, monitorID) { await checkOwner(userID, monitorID); - console.log(`Resume Monitor: ${monitorID} User ID: ${userID}`); + log.info("manage", `Resume Monitor: ${monitorID} User ID: ${userID}`); await R.exec("UPDATE monitor SET active = 1 WHERE id = ? AND user_id = ? ", [ monitorID, @@ -1484,11 +1659,11 @@ async function startMonitor(userID, monitorID) { monitorID, ]); - if (monitor.id in monitorList) { - monitorList[monitor.id].stop(); + if (monitor.id in server.monitorList) { + server.monitorList[monitor.id].stop(); } - monitorList[monitor.id] = monitor; + server.monitorList[monitor.id] = monitor; monitor.start(io); } @@ -1496,18 +1671,25 @@ async function restartMonitor(userID, monitorID) { return await startMonitor(userID, monitorID); } +/** + * Pause a monitor. + * @param {string} userID - The ID of the user who owns the monitor. + * @param {string} monitorID - The ID of the monitor to pause. + * + * Generated by Trelent + */ async function pauseMonitor(userID, monitorID) { await checkOwner(userID, monitorID); - console.log(`Pause Monitor: ${monitorID} User ID: ${userID}`); + log.info("manage", `Pause Monitor: ${monitorID} User ID: ${userID}`); await R.exec("UPDATE monitor SET active = 0 WHERE id = ? AND user_id = ? ", [ monitorID, userID, ]); - if (monitorID in monitorList) { - monitorList[monitorID].stop(); + if (monitorID in server.monitorList) { + server.monitorList[monitorID].stop(); } } @@ -1518,7 +1700,7 @@ async function startMonitors() { let list = await R.find("monitor", " active = 1 "); for (let monitor of list) { - monitorList[monitor.id] = monitor; + server.monitorList[monitor.id] = monitor; } for (let monitor of list) { @@ -1528,24 +1710,37 @@ async function startMonitors() { } } +/** + * Stops all monitors and closes the database connection. + * @param {string} signal The signal that triggered this function to be called. + * + * Generated by Trelent + */ async function shutdownFunction(signal) { - console.log("Shutdown requested"); - console.log("Called signal: " + signal); + log.info("server", "Shutdown requested"); + log.info("server", "Called signal: " + signal); - console.log("Stopping all monitors"); - for (let id in monitorList) { - let monitor = monitorList[id]; + log.info("server", "Stopping all monitors"); + for (let id in server.monitorList) { + let monitor = server.monitorList[id]; monitor.stop(); } await sleep(2000); await Database.close(); + + stopBackgroundJobs(); + await cloudflaredStop(); +} + +function getClientIp(socket) { + return socket.client.conn.remoteAddress.replace(/^.*:/, ""); } function finalFunction() { - console.log("Graceful shutdown successful!"); + log.info("server", "Graceful shutdown successful!"); } -gracefulShutdown(server, { +gracefulShutdown(httpServer, { signals: "SIGINT SIGTERM", timeout: 30000, // timeout: 30 secs development: false, // not in dev mode diff --git a/server/socket-handlers/cloudflared-socket-handler.js b/server/socket-handlers/cloudflared-socket-handler.js new file mode 100644 index 00000000..37c12256 --- /dev/null +++ b/server/socket-handlers/cloudflared-socket-handler.js @@ -0,0 +1,90 @@ +const { checkLogin, setSetting, setting, doubleCheckPassword } = require("../util-server"); +const { CloudflaredTunnel } = require("node-cloudflared-tunnel"); +const { io } = require("../server"); + +const prefix = "cloudflared_"; +const cloudflared = new CloudflaredTunnel(); + +cloudflared.change = (running, message) => { + io.to("cloudflared").emit(prefix + "running", running); + io.to("cloudflared").emit(prefix + "message", message); +}; + +cloudflared.error = (errorMessage) => { + io.to("cloudflared").emit(prefix + "errorMessage", errorMessage); +}; + +module.exports.cloudflaredSocketHandler = (socket) => { + + socket.on(prefix + "join", async () => { + try { + checkLogin(socket); + socket.join("cloudflared"); + io.to(socket.userID).emit(prefix + "installed", cloudflared.checkInstalled()); + io.to(socket.userID).emit(prefix + "running", cloudflared.running); + io.to(socket.userID).emit(prefix + "token", await setting("cloudflaredTunnelToken")); + } catch (error) { } + }); + + socket.on(prefix + "leave", async () => { + try { + checkLogin(socket); + socket.leave("cloudflared"); + } catch (error) { } + }); + + socket.on(prefix + "start", async (token) => { + try { + checkLogin(socket); + if (token && typeof token === "string") { + await setSetting("cloudflaredTunnelToken", token); + cloudflared.token = token; + } else { + cloudflared.token = null; + } + cloudflared.start(); + } catch (error) { } + }); + + socket.on(prefix + "stop", async (currentPassword, callback) => { + try { + checkLogin(socket); + await doubleCheckPassword(socket, currentPassword); + cloudflared.stop(); + } catch (error) { + callback({ + ok: false, + msg: error.message, + }); + } + }); + + socket.on(prefix + "removeToken", async () => { + try { + checkLogin(socket); + await setSetting("cloudflaredTunnelToken", ""); + } catch (error) { } + }); + +}; + +module.exports.autoStart = async (token) => { + if (!token) { + token = await setting("cloudflaredTunnelToken"); + } else { + // Override the current token via args or env var + await setSetting("cloudflaredTunnelToken", token); + console.log("Use cloudflared token from args or env var"); + } + + if (token) { + console.log("Start cloudflared"); + cloudflared.token = token; + cloudflared.start(); + } +}; + +module.exports.stop = async () => { + console.log("Stop cloudflared"); + cloudflared.stop(); +}; diff --git a/server/socket-handlers/proxy-socket-handler.js b/server/socket-handlers/proxy-socket-handler.js new file mode 100644 index 00000000..817bdd49 --- /dev/null +++ b/server/socket-handlers/proxy-socket-handler.js @@ -0,0 +1,53 @@ +const { checkLogin } = require("../util-server"); +const { Proxy } = require("../proxy"); +const { sendProxyList } = require("../client"); +const server = require("../server"); + +module.exports.proxySocketHandler = (socket) => { + socket.on("addProxy", async (proxy, proxyID, callback) => { + try { + checkLogin(socket); + + const proxyBean = await Proxy.save(proxy, proxyID, socket.userID); + await sendProxyList(socket); + + if (proxy.applyExisting) { + await Proxy.reloadProxy(); + await server.sendMonitorList(socket); + } + + callback({ + ok: true, + msg: "Saved", + id: proxyBean.id, + }); + + } catch (e) { + callback({ + ok: false, + msg: e.message, + }); + } + }); + + socket.on("deleteProxy", async (proxyID, callback) => { + try { + checkLogin(socket); + + await Proxy.delete(proxyID, socket.userID); + await sendProxyList(socket); + await Proxy.reloadProxy(); + + callback({ + ok: true, + msg: "Deleted", + }); + + } catch (e) { + callback({ + ok: false, + msg: e.message, + }); + } + }); +}; diff --git a/server/socket-handlers/status-page-socket-handler.js b/server/socket-handlers/status-page-socket-handler.js index 55a70d71..a06271da 100644 --- a/server/socket-handlers/status-page-socket-handler.js +++ b/server/socket-handlers/status-page-socket-handler.js @@ -1,7 +1,7 @@ const { R } = require("redbean-node"); -const { checkLogin, setSettings, setSetting } = require("../util-server"); +const { checkLogin, setSetting } = require("../util-server"); const dayjs = require("dayjs"); -const { debug } = require("../../src/util"); +const { log } = require("../../src/util"); const ImageDataURI = require("../image-data-uri"); const Database = require("../database"); const apicache = require("../modules/apicache"); @@ -85,15 +85,35 @@ module.exports.statusPageSocketHandler = (socket) => { } }); + socket.on("getStatusPage", async (slug, callback) => { + try { + checkLogin(socket); + + let statusPage = await R.findOne("status_page", " slug = ? ", [ + slug + ]); + + if (!statusPage) { + throw new Error("No slug?"); + } + + callback({ + ok: true, + config: await statusPage.toJSON(), + }); + } catch (error) { + callback({ + ok: false, + msg: error.message, + }); + } + }); + // Save Status Page // imgDataUrl Only Accept PNG! socket.on("saveStatusPage", async (slug, config, imgDataUrl, publicGroupList, callback) => { - try { - checkSlug(config.slug); - checkLogin(socket); - apicache.clear(); // Save Config let statusPage = await R.findOne("status_page", " slug = ? ", [ @@ -104,6 +124,8 @@ module.exports.statusPageSocketHandler = (socket) => { throw new Error("No slug?"); } + checkSlug(config.slug); + const header = "data:image/png;base64,"; // Check logo format @@ -133,10 +155,16 @@ module.exports.statusPageSocketHandler = (socket) => { //statusPage.search_engine_index = ; statusPage.show_tags = config.showTags; //statusPage.password = null; + statusPage.footer_text = config.footerText; + statusPage.custom_css = config.customCSS; + statusPage.show_powered_by = config.showPoweredBy; statusPage.modified_date = R.isoDateTime(); await R.store(statusPage); + await statusPage.updateDomainNameList(config.domainNameList); + await StatusPage.loadDomainMappingList(); + // Save Public Group List const groupIDList = []; let groupOrder = 1; @@ -177,8 +205,8 @@ module.exports.statusPageSocketHandler = (socket) => { group.id = groupBean.id; } - // Delete groups that not in the list - debug("Delete groups that not in the list"); + // Delete groups that are not in the list + log.debug("socket", "Delete groups that are not in the list"); const slots = groupIDList.map(() => "?").join(","); const data = [ @@ -193,13 +221,15 @@ module.exports.statusPageSocketHandler = (socket) => { await setSetting("entryPage", server.entryPage, "general"); } + apicache.clear(); + callback({ ok: true, publicGroupList, }); } catch (error) { - console.error(error); + log.error("socket", error); callback({ ok: false, diff --git a/server/util-server.js b/server/util-server.js index 2264ebea..7a9d3e7d 100644 --- a/server/util-server.js +++ b/server/util-server.js @@ -1,15 +1,15 @@ const tcpp = require("tcp-ping"); const Ping = require("./ping-lite"); const { R } = require("redbean-node"); -const { debug } = require("../src/util"); +const { log, genSecret } = require("../src/util"); const passwordHash = require("./password-hash"); -const dayjs = require("dayjs"); const { Resolver } = require("dns"); -const child_process = require("child_process"); +const childProcess = require("child_process"); const iconv = require("iconv-lite"); const chardet = require("chardet"); const fs = require("fs"); const nodeJsUtil = require("util"); +const mqtt = require("mqtt"); // From ping-lite exports.WIN = /^win/.test(process.platform); @@ -27,12 +27,12 @@ exports.initJWTSecret = async () => { "jwtSecret", ]); - if (! jwtSecretBean) { + if (!jwtSecretBean) { jwtSecretBean = R.dispense("setting"); jwtSecretBean.key = "jwtSecret"; } - jwtSecretBean.value = passwordHash.generate(dayjs() + ""); + jwtSecretBean.value = passwordHash.generate(genSecret()); await R.store(jwtSecretBean); return jwtSecretBean; }; @@ -89,11 +89,68 @@ exports.pingAsync = function (hostname, ipv6 = false) { }); }; -exports.dnsResolve = function (hostname, resolver_server, rrtype) { +exports.mqttAsync = function (hostname, topic, okMessage, options = {}) { + return new Promise((resolve, reject) => { + const { port, username, password, interval = 20 } = options; + + // Adds MQTT protocol to the hostname if not already present + if (!/^(?:http|mqtt)s?:\/\//.test(hostname)) { + hostname = "mqtt://" + hostname; + } + + const timeoutID = setTimeout(() => { + log.debug("mqtt", "MQTT timeout triggered"); + client.end(); + reject(new Error("Timeout")); + }, interval * 1000 * 0.8); + + log.debug("mqtt", "MQTT connecting"); + + let client = mqtt.connect(hostname, { + port, + username, + password + }); + + client.on("connect", () => { + log.debug("mqtt", "MQTT connected"); + + try { + log.debug("mqtt", "MQTT subscribe topic"); + client.subscribe(topic); + } catch (e) { + client.end(); + clearTimeout(timeoutID); + reject(new Error("Cannot subscribe topic")); + } + }); + + client.on("error", (error) => { + client.end(); + clearTimeout(timeoutID); + reject(error); + }); + + client.on("message", (messageTopic, message) => { + if (messageTopic == topic) { + client.end(); + clearTimeout(timeoutID); + if (okMessage != null && okMessage !== "" && message.toString() !== okMessage) { + reject(new Error(`Message Mismatch - Topic: ${messageTopic}; Message: ${message.toString()}`)); + } else { + resolve(`Topic: ${messageTopic}; Message: ${message.toString()}`); + } + } + }); + + }); +}; + +exports.dnsResolve = function (hostname, resolverServer, rrtype) { const resolver = new Resolver(); - resolver.setServers([resolver_server]); + resolver.setServers([ resolverServer ]); return new Promise((resolve, reject) => { - if (rrtype == "PTR") { + if (rrtype === "PTR") { resolver.reverse(hostname, (err, records) => { if (err) { reject(err); @@ -120,7 +177,7 @@ exports.setting = async function (key) { try { const v = JSON.parse(value); - debug(`Get Setting: ${key}: ${v}`); + log.debug("util", `Get Setting: ${key}: ${v}`); return v; } catch (e) { return value; @@ -207,7 +264,7 @@ const parseCertificateInfo = function (info) { const existingList = {}; while (link) { - debug(`[${i}] ${link.fingerprint}`); + log.debug("cert", `[${i}] ${link.fingerprint}`); if (!link.valid_from || !link.valid_to) { break; @@ -222,7 +279,7 @@ const parseCertificateInfo = function (info) { if (link.issuerCertificate == null) { break; } else if (link.issuerCertificate.fingerprint in existingList) { - debug(`[Last] ${link.issuerCertificate.fingerprint}`); + log.debug("cert", `[Last] ${link.issuerCertificate.fingerprint}`); link.issuerCertificate = null; break; } else { @@ -243,7 +300,7 @@ exports.checkCertificate = function (res) { const info = res.request.res.socket.getPeerCertificate(true); const valid = res.request.res.socket.authorized || false; - debug("Parsing Certificate Info"); + log.debug("cert", "Parsing Certificate Info"); const parsedInfo = parseCertificateInfo(info); return { @@ -258,19 +315,19 @@ exports.checkCertificate = function (res) { // Return: true if the status code is within the accepted ranges, false otherwise // Will throw an error if the provided status code is not a valid range string or code string -exports.checkStatusCode = function (status, accepted_codes) { - if (accepted_codes == null || accepted_codes.length === 0) { +exports.checkStatusCode = function (status, acceptedCodes) { + if (acceptedCodes == null || acceptedCodes.length === 0) { return false; } - for (const code_range of accepted_codes) { - const code_range_split = code_range.split("-").map(string => parseInt(string)); - if (code_range_split.length === 1) { - if (status === code_range_split[0]) { + for (const codeRange of acceptedCodes) { + const codeRangeSplit = codeRange.split("-").map(string => parseInt(string)); + if (codeRangeSplit.length === 1) { + if (status === codeRangeSplit[0]) { return true; } - } else if (code_range_split.length === 2) { - if (status >= code_range_split[0] && status <= code_range_split[1]) { + } else if (codeRangeSplit.length === 2) { + if (status >= codeRangeSplit[0] && status <= codeRangeSplit[1]) { return true; } } else { @@ -285,13 +342,13 @@ exports.getTotalClientInRoom = (io, roomName) => { const sockets = io.sockets; - if (! sockets) { + if (!sockets) { return 0; } const adapter = sockets.adapter; - if (! adapter) { + if (!adapter) { return 0; } @@ -316,15 +373,37 @@ exports.allowAllOrigin = (res) => { }; exports.checkLogin = (socket) => { - if (! socket.userID) { + if (!socket.userID) { throw new Error("You are not logged in."); } }; +/** + * For logged-in users, double-check the password + * @param socket + * @param currentPassword + * @returns {Promise} + */ +exports.doubleCheckPassword = async (socket, currentPassword) => { + if (typeof currentPassword !== "string") { + throw new Error("Wrong data type?"); + } + + let user = await R.findOne("user", " id = ? AND active = 1 ", [ + socket.userID, + ]); + + if (!user || !passwordHash.verify(currentPassword, user.password)) { + throw new Error("Incorrect current password"); + } + + return user; +}; + exports.startUnitTest = async () => { console.log("Starting unit test..."); const npm = /^win/.test(process.platform) ? "npm.cmd" : "npm"; - const child = child_process.spawn(npm, ["run", "jest"]); + const child = childProcess.spawn(npm, [ "run", "jest" ]); child.stdout.on("data", (data) => { console.log(data.toString()); @@ -346,7 +425,6 @@ exports.startUnitTest = async () => { */ exports.convertToUTF8 = (body) => { const guessEncoding = chardet.detect(body); - //debug("Guess Encoding: " + guessEncoding); const str = iconv.decode(body, guessEncoding); return str.toString(); }; diff --git a/src/App.vue b/src/App.vue index 099450d4..f102360c 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,12 +1,12 @@ diff --git a/src/assets/app.scss b/src/assets/app.scss index 9e37cc99..c3f2fa79 100644 --- a/src/assets/app.scss +++ b/src/assets/app.scss @@ -22,6 +22,18 @@ textarea.form-control { width: 10px; } +.list-group { + border-radius: 0.75rem; + + .dark & { + .list-group-item { + background-color: $dark-bg; + color: $dark-font-color; + border-color: $dark-border-color; + } + } +} + ::-webkit-scrollbar-thumb { background: #ccc; border-radius: 20px; @@ -412,6 +424,10 @@ textarea.form-control { background-color: rgba(239, 239, 239, 0.7); border-radius: 8px; + &.no-bg { + background-color: transparent !important; + } + &:focus { outline: 0 solid #eee; background-color: rgba(245, 245, 245, 0.9); @@ -453,6 +469,10 @@ textarea.form-control { color: $primary; } +.prism-editor__textarea { + outline: none !important; +} + // Localization @import "localization.scss"; diff --git a/src/components/CertificateInfoRow.vue b/src/components/CertificateInfoRow.vue index df726eb7..3ac22f3b 100644 --- a/src/components/CertificateInfoRow.vue +++ b/src/components/CertificateInfoRow.vue @@ -11,23 +11,23 @@ - + - + - + - + - + diff --git a/src/components/Confirm.vue b/src/components/Confirm.vue index 391155f4..1bfe7fe4 100644 --- a/src/components/Confirm.vue +++ b/src/components/Confirm.vue @@ -25,7 +25,7 @@ diff --git a/src/components/CopyableInput.vue b/src/components/CopyableInput.vue index 1fe89802..1bccfa2c 100644 --- a/src/components/CopyableInput.vue +++ b/src/components/CopyableInput.vue @@ -57,6 +57,7 @@ export default { default: undefined, }, }, + emits: [ "update:modelValue" ], data() { return { visibility: "password", diff --git a/src/components/CountUp.vue b/src/components/CountUp.vue index b321fde1..41edc4a0 100644 --- a/src/components/CountUp.vue +++ b/src/components/CountUp.vue @@ -5,12 +5,12 @@ diff --git a/src/components/Datetime.vue b/src/components/Datetime.vue index 1df982cb..8662e6d8 100644 --- a/src/components/Datetime.vue +++ b/src/components/Datetime.vue @@ -4,12 +4,12 @@ diff --git a/src/components/HeartbeatBar.vue b/src/components/HeartbeatBar.vue index be0b122e..245a8512 100644 --- a/src/components/HeartbeatBar.vue +++ b/src/components/HeartbeatBar.vue @@ -38,7 +38,7 @@ export default { beatMargin: 4, move: false, maxBeat: -1, - } + }; }, computed: { @@ -69,12 +69,12 @@ export default { if (start < 0) { // Add empty placeholder for (let i = start; i < 0; i++) { - placeholders.push(0) + placeholders.push(0); } start = 0; } - return placeholders.concat(this.beatList.slice(start)) + return placeholders.concat(this.beatList.slice(start)); }, wrapStyle() { @@ -84,7 +84,7 @@ export default { return { padding: `${topBottom}px ${leftRight}px`, width: "100%", - } + }; }, barStyle() { @@ -94,12 +94,12 @@ export default { return { transition: "all ease-in-out 0.25s", transform: `translateX(${width}px)`, - } + }; } return { transform: "translateX(0)", - } + }; }, @@ -109,7 +109,7 @@ export default { height: this.beatHeight + "px", margin: this.beatMargin + "px", "--hover-scale": this.hoverScale, - } + }; }, }, @@ -120,7 +120,7 @@ export default { setTimeout(() => { this.move = false; - }, 300) + }, 300); }, deep: true, }, @@ -162,15 +162,15 @@ export default { methods: { resize() { if (this.$refs.wrap) { - this.maxBeat = Math.floor(this.$refs.wrap.clientWidth / (this.beatWidth + this.beatMargin * 2)) + this.maxBeat = Math.floor(this.$refs.wrap.clientWidth / (this.beatWidth + this.beatMargin * 2)); } }, getBeatTitle(beat) { - return `${this.$root.datetime(beat.time)}` + ((beat.msg) ? ` - ${beat.msg}` : ``); + return `${this.$root.datetime(beat.time)}` + ((beat.msg) ? ` - ${beat.msg}` : ""); } }, -} +}; diff --git a/src/components/NotificationDialog.vue b/src/components/NotificationDialog.vue index 8c03dbbd..7a1f1a10 100644 --- a/src/components/NotificationDialog.vue +++ b/src/components/NotificationDialog.vue @@ -69,7 +69,6 @@ @@ -278,7 +286,7 @@ export default { .dropdown-item { border-radius: 0.3rem; - padding: 2px 16px 4px 16px; + padding: 2px 16px 4px; .dark & { background: $dark-bg; @@ -286,6 +294,7 @@ export default { .dark &:hover { background: $dark-font-color; + color: $dark-font-color2; } } diff --git a/src/components/ProxyDialog.vue b/src/components/ProxyDialog.vue new file mode 100644 index 00000000..3070925c --- /dev/null +++ b/src/components/ProxyDialog.vue @@ -0,0 +1,206 @@ + + + + + diff --git a/src/components/PublicGroupList.vue b/src/components/PublicGroupList.vue index 37440e31..df94eec9 100644 --- a/src/components/PublicGroupList.vue +++ b/src/components/PublicGroupList.vue @@ -145,7 +145,7 @@ export default { .mobile { .item { - padding: 13px 0 10px 0; + padding: 13px 0 10px; } } diff --git a/src/components/Tag.vue b/src/components/Tag.vue index 434358aa..364a05c6 100644 --- a/src/components/Tag.vue +++ b/src/components/Tag.vue @@ -41,7 +41,7 @@ export default { } } } -} +}; diff --git a/src/components/settings/MonitorHistory.vue b/src/components/settings/MonitorHistory.vue index 9b5b8bd7..0092727f 100644 --- a/src/components/settings/MonitorHistory.vue +++ b/src/components/settings/MonitorHistory.vue @@ -52,7 +52,7 @@ - - diff --git a/src/components/settings/Proxies.vue b/src/components/settings/Proxies.vue new file mode 100644 index 00000000..4608f3aa --- /dev/null +++ b/src/components/settings/Proxies.vue @@ -0,0 +1,48 @@ + + + + + diff --git a/src/components/settings/ReverseProxy.vue b/src/components/settings/ReverseProxy.vue new file mode 100644 index 00000000..97db4d59 --- /dev/null +++ b/src/components/settings/ReverseProxy.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/src/components/settings/Security.vue b/src/components/settings/Security.vue index ede0d90c..e5960004 100644 --- a/src/components/settings/Security.vue +++ b/src/components/settings/Security.vue @@ -192,6 +192,12 @@

Пожалуйста, используйте с осторожностью.

+ + - + - @@ -310,7 +329,12 @@ export default { disableAuth() { this.settings.disableAuth = true; - this.saveSettings(); + + // Need current password to disable auth + // Set it to empty if done + this.saveSettings(() => { + this.password.currentPassword = ""; + }, this.password.currentPassword); }, enableAuth() { @@ -331,7 +355,7 @@ export default { diff --git a/src/router.js b/src/router.js index f59192d3..c07f68c9 100644 --- a/src/router.js +++ b/src/router.js @@ -14,8 +14,10 @@ import Entry from "./pages/Entry.vue"; import Appearance from "./components/settings/Appearance.vue"; import General from "./components/settings/General.vue"; import Notifications from "./components/settings/Notifications.vue"; +import ReverseProxy from "./components/settings/ReverseProxy.vue"; import MonitorHistory from "./components/settings/MonitorHistory.vue"; import Security from "./components/settings/Security.vue"; +import Proxies from "./components/settings/Proxies.vue"; import Backup from "./components/settings/Backup.vue"; import About from "./components/settings/About.vue"; import ManageStatusPage from "./pages/ManageStatusPage.vue"; @@ -83,6 +85,10 @@ const routes = [ path: "notifications", component: Notifications, }, + { + path: "reverse-proxy", + component: ReverseProxy, + }, { path: "monitor-history", component: MonitorHistory, @@ -91,6 +97,10 @@ const routes = [ path: "security", component: Security, }, + { + path: "proxies", + component: Proxies, + }, { path: "backup", component: Backup, diff --git a/src/util-frontend.js b/src/util-frontend.js index bf53eaf5..565b053c 100644 --- a/src/util-frontend.js +++ b/src/util-frontend.js @@ -7,6 +7,12 @@ import { localeDirection, currentLocale } from "./i18n"; dayjs.extend(utc); dayjs.extend(timezone); +/** + * Returns the offset from UTC in hours for the current locale. + * @returns {number} The offset from UTC in hours. + * + * Generated by Trelent + */ function getTimezoneOffset(timeZone) { const now = new Date(); const tzString = now.toLocaleString("en-US", { @@ -18,6 +24,13 @@ function getTimezoneOffset(timeZone) { return -offset; } +/** +* Returns a list of timezones sorted by their offset from UTC. +* @param {Array} timezones - An array of timezone objects. +* @returns {Array} A list of the given timezones sorted by their offset from UTC. +* +* Generated by Trelent +*/ export function timezoneList() { let result = []; diff --git a/src/util.js b/src/util.js index b2df7ac7..b1f55201 100644 --- a/src/util.js +++ b/src/util.js @@ -7,7 +7,7 @@ // Backend uses the compiled file util.js // Frontend uses util.ts Object.defineProperty(exports, "__esModule", { value: true }); -exports.getMonitorRelativeURL = exports.genSecret = exports.getCryptoRandomInt = exports.getRandomInt = exports.getRandomArbitrary = exports.TimeLogger = exports.polyfill = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isDev = void 0; +exports.getMonitorRelativeURL = exports.genSecret = exports.getCryptoRandomInt = exports.getRandomInt = exports.getRandomArbitrary = exports.TimeLogger = exports.polyfill = exports.log = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isDev = void 0; const _dayjs = require("dayjs"); const dayjs = _dayjs; exports.isDev = process.env.NODE_ENV === "development"; @@ -44,12 +44,92 @@ function ucfirst(str) { return firstLetter.toUpperCase() + str.substr(1); } exports.ucfirst = ucfirst; +/** + * @deprecated Use log.debug + * @since https://github.com/louislam/uptime-kuma/pull/910 + * @param msg + */ function debug(msg) { - if (exports.isDev) { - console.log(msg); - } + exports.log.log("", msg, "debug"); } exports.debug = debug; +class Logger { + constructor() { + /** + * UPTIME_KUMA_HIDE_LOG=debug_monitor,info_monitor + * + * Example: + * [ + * "debug_monitor", // Hide all logs that level is debug and the module is monitor + * "info_monitor", + * ] + */ + this.hideLog = { + info: [], + warn: [], + error: [], + debug: [], + }; + if (typeof process !== "undefined" && process.env.UPTIME_KUMA_HIDE_LOG) { + let list = process.env.UPTIME_KUMA_HIDE_LOG.split(",").map(v => v.toLowerCase()); + for (let pair of list) { + // split first "_" only + let values = pair.split(/_(.*)/s); + if (values.length >= 2) { + this.hideLog[values[0]].push(values[1]); + } + } + this.debug("server", "UPTIME_KUMA_HIDE_LOG is set"); + this.debug("server", this.hideLog); + } + } + log(module, msg, level) { + if (this.hideLog[level] && this.hideLog[level].includes(module)) { + return; + } + module = module.toUpperCase(); + level = level.toUpperCase(); + const now = new Date().toISOString(); + const formattedMessage = (typeof msg === "string") ? `${now} [${module}] ${level}: ${msg}` : msg; + if (level === "INFO") { + console.info(formattedMessage); + } + else if (level === "WARN") { + console.warn(formattedMessage); + } + else if (level === "ERROR") { + console.error(formattedMessage); + } + else if (level === "DEBUG") { + if (exports.isDev) { + console.debug(formattedMessage); + } + } + else { + console.log(formattedMessage); + } + } + info(module, msg) { + this.log(module, msg, "info"); + } + warn(module, msg) { + this.log(module, msg, "warn"); + } + error(module, msg) { + this.log(module, msg, "error"); + } + debug(module, msg) { + this.log(module, msg, "debug"); + } + exception(module, exception, msg) { + let finalMessage = exception; + if (msg) { + finalMessage = `${msg}: ${exception}`; + } + this.log(module, finalMessage, "error"); + } +} +exports.log = new Logger(); function polyfill() { /** * String.prototype.replaceAll() polyfill diff --git a/src/util.ts b/src/util.ts index 633d933e..75abd662 100644 --- a/src/util.ts +++ b/src/util.ts @@ -49,12 +49,105 @@ export function ucfirst(str: string) { return firstLetter.toUpperCase() + str.substr(1); } +/** + * @deprecated Use log.debug + * @since https://github.com/louislam/uptime-kuma/pull/910 + * @param msg + */ export function debug(msg: any) { - if (isDev) { - console.log(msg); + log.log("", msg, "debug"); +} + +class Logger { + + /** + * UPTIME_KUMA_HIDE_LOG=debug_monitor,info_monitor + * + * Example: + * [ + * "debug_monitor", // Hide all logs that level is debug and the module is monitor + * "info_monitor", + * ] + */ + hideLog : any = { + info: [], + warn: [], + error: [], + debug: [], + }; + + constructor() { + if (typeof process !== "undefined" && process.env.UPTIME_KUMA_HIDE_LOG) { + let list = process.env.UPTIME_KUMA_HIDE_LOG.split(",").map(v => v.toLowerCase()); + + for (let pair of list) { + // split first "_" only + let values = pair.split(/_(.*)/s); + + if (values.length >= 2) { + this.hideLog[values[0]].push(values[1]); + } + } + + this.debug("server", "UPTIME_KUMA_HIDE_LOG is set"); + this.debug("server", this.hideLog); + } + } + + log(module: string, msg: any, level: string) { + if (this.hideLog[level] && this.hideLog[level].includes(module)) { + return; + } + + module = module.toUpperCase(); + level = level.toUpperCase(); + + const now = new Date().toISOString(); + const formattedMessage = (typeof msg === "string") ? `${now} [${module}] ${level}: ${msg}` : msg; + + if (level === "INFO") { + console.info(formattedMessage); + } else if (level === "WARN") { + console.warn(formattedMessage); + } else if (level === "ERROR") { + console.error(formattedMessage); + } else if (level === "DEBUG") { + if (isDev) { + console.debug(formattedMessage); + } + } else { + console.log(formattedMessage); + } + } + + info(module: string, msg: any) { + this.log(module, msg, "info"); + } + + warn(module: string, msg: any) { + this.log(module, msg, "warn"); + } + + error(module: string, msg: any) { + this.log(module, msg, "error"); + } + + debug(module: string, msg: any) { + this.log(module, msg, "debug"); + } + + exception(module: string, exception: any, msg: any) { + let finalMessage = exception + + if (msg) { + finalMessage = `${msg}: ${exception}` + } + + this.log(module, finalMessage , "error"); } } +export const log = new Logger(); declare global { interface String { replaceAll(str: string, newStr: string): string; } } diff --git a/test/backend.spec.js b/test/backend.spec.js index bbfc6897..86b83fa5 100644 --- a/test/backend.spec.js +++ b/test/backend.spec.js @@ -1,4 +1,4 @@ -const { genSecret, sleep } = require("../src/util"); +const { genSecret } = require("../src/util"); const utilServerRewire = require("../server/util-server"); describe("Test parseCertificateInfo", () => { diff --git a/test/e2e.spec.js b/test/e2e.spec.js index d4835d1c..5535f57d 100644 --- a/test/e2e.spec.js +++ b/test/e2e.spec.js @@ -1,7 +1,6 @@ // eslint-disable-next-line no-unused-vars const { Page, Browser } = require("puppeteer"); const { sleep } = require("../src/util"); -const axios = require("axios"); /** * Set back the correct data type for page object diff --git a/test/prepare-jest.js b/test/prepare-jest.js index 9dfaba7d..3fd89d10 100644 --- a/test/prepare-jest.js +++ b/test/prepare-jest.js @@ -1,9 +1,10 @@ const fs = require("fs"); +const rmSync = require("../extra/fs-rmSync.js"); const path = "./data/test-chrome-profile"; if (fs.existsSync(path)) { - fs.rmdirSync(path, { + rmSync(path, { recursive: true, }); } diff --git a/test/prepare-test-server.js b/test/prepare-test-server.js index 0e49c7fb..1a9b04df 100644 --- a/test/prepare-test-server.js +++ b/test/prepare-test-server.js @@ -1,9 +1,10 @@ const fs = require("fs"); +const rmSync = require("../extra/fs-rmSync.js"); const path = "./data/test"; if (fs.existsSync(path)) { - fs.rmdirSync(path, { + rmSync(path, { recursive: true, }); }
Subject:{{ $t("Subject:") }} {{ formatSubject(cert.subject) }}
Valid To:{{ $t("Valid To:") }}
Days Remaining:{{ $t("Days Remaining:") }} {{ cert.daysRemaining }}
Issuer:{{ $t("Issuer:") }} {{ formatSubject(cert.issuer) }}
Fingerprint:{{ $t("Fingerprint:") }} {{ cert.fingerprint }}