From e72dfc3bfd0a0abc06beb8e216f4f49f427621c0 Mon Sep 17 00:00:00 2001 From: 7heMech <83923848+7heMech@users.noreply.github.com> Date: Wed, 4 Feb 2026 12:14:10 +0000 Subject: [PATCH 01/77] Add reuseport to improve performance and reduce packet drops --- backend/templates/stream.conf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/templates/stream.conf b/backend/templates/stream.conf index 3a10387b27..d365897ab7 100644 --- a/backend/templates/stream.conf +++ b/backend/templates/stream.conf @@ -5,8 +5,8 @@ {% if enabled %} {% if tcp_forwarding == 1 or tcp_forwarding == true -%} server { - listen {{ incoming_port }} {%- if certificate %} ssl {%- endif %}; - {% unless ipv6 -%} # {%- endunless -%} listen [::]:{{ incoming_port }} {%- if certificate %} ssl {%- endif %}; + listen {{ incoming_port }} reuseport {%- if certificate %} ssl {%- endif %}; + {% unless ipv6 -%} # {%- endunless -%} listen [::]:{{ incoming_port }} reuseport {%- if certificate %} ssl {%- endif %}; {%- include "_certificates_stream.conf" %} @@ -23,8 +23,8 @@ server { {% if udp_forwarding == 1 or udp_forwarding == true -%} server { - listen {{ incoming_port }} udp; - {% unless ipv6 -%} # {%- endunless -%} listen [::]:{{ incoming_port }} udp; + listen {{ incoming_port }} udp reuseport; + {% unless ipv6 -%} # {%- endunless -%} listen [::]:{{ incoming_port }} udp reuseport; proxy_pass {{ forwarding_host }}:{{ forwarding_port }}; From 46bf3274d811fd5ad02b7e0fbec587b73d4bc045 Mon Sep 17 00:00:00 2001 From: Yassine DAMIRI Date: Mon, 20 Apr 2026 01:00:43 +0200 Subject: [PATCH 02/77] fix: Changed order of escape to prevent RCE --- backend/setup.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/setup.js b/backend/setup.js index 84f42793ea..20d628ca97 100644 --- a/backend/setup.js +++ b/backend/setup.js @@ -123,8 +123,8 @@ const setupCertbotPlugins = async () => { // Escape single quotes and backslashes if (typeof certificate.meta.dns_provider_credentials === "string") { const escapedCredentials = certificate.meta.dns_provider_credentials - .replaceAll("'", "\\'") - .replaceAll("\\", "\\\\"); + .replaceAll("\\", "\\\\") + .replaceAll("'", "\\'"); const credentials_cmd = `[ -f '${credentials_loc}' ] || { mkdir -p /etc/letsencrypt/credentials 2> /dev/null; echo '${escapedCredentials}' > '${credentials_loc}' && chmod 600 '${credentials_loc}'; }`; promises.push(utils.exec(credentials_cmd)); } From 6629abed3250c5c82e2d1537a811f56f91c8f405 Mon Sep 17 00:00:00 2001 From: Yassine Damiri <54901715+Yasha-ops@users.noreply.github.com> Date: Mon, 1 Jun 2026 17:02:19 +0200 Subject: [PATCH 03/77] Use fs module for credential file operations Refactor (from the review) credential file handling to use fs module for directory creation and file writing --- backend/setup.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/backend/setup.js b/backend/setup.js index 20d628ca97..c46e5743e1 100644 --- a/backend/setup.js +++ b/backend/setup.js @@ -6,6 +6,7 @@ import certificateModel from "./models/certificate.js"; import settingModel from "./models/setting.js"; import userModel from "./models/user.js"; import userPermissionModel from "./models/user_permission.js"; +import fs from "fs"; export const isSetup = async () => { const row = await userModel.query().select("id").where("is_deleted", 0).first(); @@ -120,18 +121,14 @@ const setupCertbotPlugins = async () => { // Make sure credentials file exists const credentials_loc = `/etc/letsencrypt/credentials/credentials-${certificate.id}`; - // Escape single quotes and backslashes if (typeof certificate.meta.dns_provider_credentials === "string") { - const escapedCredentials = certificate.meta.dns_provider_credentials - .replaceAll("\\", "\\\\") - .replaceAll("'", "\\'"); - const credentials_cmd = `[ -f '${credentials_loc}' ] || { mkdir -p /etc/letsencrypt/credentials 2> /dev/null; echo '${escapedCredentials}' > '${credentials_loc}' && chmod 600 '${credentials_loc}'; }`; - promises.push(utils.exec(credentials_cmd)); + promises.push(fs.mkdir("/etc/letsencrypt/credentials", { recursive: true }) + .then(() => fs.writeFile(credentials_loc, certificate.meta.dns_provider_credentials, { mode: 0o600, flag: "wx" }))); } } return true; }); - + await installPlugins(plugins); if (promises.length) { From 62ed3300531d5ca7e321f5cb35678a6092a08e96 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jun 2026 13:57:48 +0000 Subject: [PATCH 04/77] Bump the prod-patch-updates group in /test with 2 updates Bumps the prod-patch-updates group in /test with 2 updates: [@cypress/grep](https://github.com/cypress-io/cypress) and [eslint](https://github.com/eslint/eslint). Updates `@cypress/grep` from 6.0.0 to 6.0.1 - [Release notes](https://github.com/cypress-io/cypress/releases) - [Changelog](https://github.com/cypress-io/cypress/blob/develop/CHANGELOG.md) - [Commits](https://github.com/cypress-io/cypress/compare/@cypress/grep-v6.0.0...@cypress/grep-v6.0.1) Updates `eslint` from 10.4.0 to 10.4.1 - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](https://github.com/eslint/eslint/compare/v10.4.0...v10.4.1) --- updated-dependencies: - dependency-name: "@cypress/grep" dependency-version: 6.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod-patch-updates - dependency-name: eslint dependency-version: 10.4.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod-patch-updates ... Signed-off-by: dependabot[bot] --- test/yarn.lock | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/test/yarn.lock b/test/yarn.lock index 0f41aea86c..ca6b6539ea 100644 --- a/test/yarn.lock +++ b/test/yarn.lock @@ -81,9 +81,9 @@ "@babel/helper-validator-identifier" "^7.29.7" "@cypress/grep@^6.0.0": - version "6.0.0" - resolved "https://registry.yarnpkg.com/@cypress/grep/-/grep-6.0.0.tgz#fcc5f42d0086464e2752c4d84ac563c3cd21eb77" - integrity sha512-n3PCeqt8OwmLFz310igbRUm3qDE5WJgM9LW+2ejdULfMu2Sudqg3UX8koC8/JU/+ZcJ5UbaQAap1Nbi0QvzXwA== + version "6.0.1" + resolved "https://registry.yarnpkg.com/@cypress/grep/-/grep-6.0.1.tgz#33fb03fd860f3cc4d3f4940c54ad2f6426d0dfea" + integrity sha512-nxTBNid7mKeDfM5thNPc4YH6q+1BoDKFwDLcJJLvosNbJ9WcsRZAU9F6gUQyS/BWhKmRWn+st3JdVtokk8aMSw== dependencies: debug "^4.3.4" find-test-names "^1.28.18" @@ -160,10 +160,10 @@ resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-3.0.5.tgz#88e9bf4d11d2b19c082e78ebe7ce88724a5eb091" integrity sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw== -"@eslint/plugin-kit@^0.7.1": - version "0.7.1" - resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.7.1.tgz#c4125fd015eceeb09b793109fdbcd4dd0a02d346" - integrity sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ== +"@eslint/plugin-kit@^0.7.2": + version "0.7.2" + resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz#4b0962f3f2c7ce8bc98b3ecfe34525c09d2cb729" + integrity sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A== dependencies: "@eslint/core" "^1.2.1" levn "^0.4.1" @@ -928,16 +928,16 @@ eslint-visitor-keys@^5.0.1: integrity sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA== eslint@^10.3.0: - version "10.4.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-10.4.0.tgz#d86b6c405de0f19f3318c47139b8cb6771b3f592" - integrity sha512-loXy6bWOoP3EP6JA7jo6p5jMpBJmHmsNZM5SFRHLdh1MGOPurMnNBj4ZlAbaqUAaQWbCr7jHV4P7gzAyryZWkQ== + version "10.4.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-10.4.1.tgz#f6640b176e0912246d9ddbf8fcfa5e8b7f02445a" + integrity sha512-AyIKhnOBuOAdueD7RB3xB+YeAWScb9jHsJBgH2Hcde8InP5JYhqrRR6iTMHyTEwgENK54Cp44e4v8BwNhsuHuw== dependencies: "@eslint-community/eslint-utils" "^4.8.0" "@eslint-community/regexpp" "^4.12.2" "@eslint/config-array" "^0.23.5" "@eslint/config-helpers" "^0.6.0" "@eslint/core" "^1.2.1" - "@eslint/plugin-kit" "^0.7.1" + "@eslint/plugin-kit" "^0.7.2" "@humanfs/node" "^0.16.6" "@humanwhocodes/module-importer" "^1.0.1" "@humanwhocodes/retry" "^0.4.2" From fc4a409292fcfd1f225db5b4de7ca0d39da3c156 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jun 2026 13:58:55 +0000 Subject: [PATCH 05/77] Bump the dev-patch-updates group in /frontend with 4 updates Bumps the dev-patch-updates group in /frontend with 4 updates: [@formatjs/cli](https://github.com/formatjs/formatjs), [tmp](https://github.com/raszi/node-tmp), [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) and [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest). Updates `@formatjs/cli` from 6.16.3 to 6.16.6 - [Release notes](https://github.com/formatjs/formatjs/releases) - [Commits](https://github.com/formatjs/formatjs/compare/@formatjs/cli@6.16.3...@formatjs/intl-datetimeformat@6.16.6) Updates `tmp` from 0.2.6 to 0.2.7 - [Changelog](https://github.com/raszi/node-tmp/blob/master/CHANGELOG.md) - [Commits](https://github.com/raszi/node-tmp/compare/v0.2.6...v0.2.7) Updates `vite` from 8.0.14 to 8.0.16 - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v8.0.16/packages/vite) Updates `vitest` from 4.1.7 to 4.1.8 - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md) - [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.8/packages/vitest) --- updated-dependencies: - dependency-name: "@formatjs/cli" dependency-version: 6.16.6 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: tmp dependency-version: 0.2.7 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: vite dependency-version: 8.0.16 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates - dependency-name: vitest dependency-version: 4.1.8 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-patch-updates ... Signed-off-by: dependabot[bot] --- frontend/package.json | 8 +- frontend/yarn.lock | 338 +++++++++++++++++++++--------------------- 2 files changed, 173 insertions(+), 173 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 769a2a7702..1fa055e355 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -41,7 +41,7 @@ }, "devDependencies": { "@biomejs/biome": "^2.4.15", - "@formatjs/cli": "^6.16.3", + "@formatjs/cli": "^6.16.6", "@tanstack/react-query-devtools": "^5.100.14", "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.9.1", @@ -57,10 +57,10 @@ "postcss": "^8.5.15", "postcss-simple-vars": "^7.0.1", "sass": "^1.100.0", - "tmp": "^0.2.6", + "tmp": "^0.2.7", "typescript": "6.0.3", - "vite": "^8.0.14", + "vite": "^8.0.16", "vite-plugin-checker": "^0.14.1", - "vitest": "^4.1.7" + "vitest": "^4.1.8" } } diff --git a/frontend/yarn.lock b/frontend/yarn.lock index d5f803762f..3c116af36a 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -276,35 +276,35 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.10.tgz#a2a1e3812d14525f725d011a73eceb41fef5bc1c" integrity sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ== -"@formatjs/cli-native-darwin-arm64@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@formatjs/cli-native-darwin-arm64/-/cli-native-darwin-arm64-1.1.0.tgz#c47df2ec7c1d27643900af77c474bd224b4587dc" - integrity sha512-ygEpFpmRjbAKanWaeto/eUItyuK18667mdDzpDg3CTzc15WYzjZKnwJNFUuPFvFA4hiod1tnhXT1eiXmc1wWNg== - -"@formatjs/cli-native-linux-arm64@1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@formatjs/cli-native-linux-arm64/-/cli-native-linux-arm64-1.2.0.tgz#3ddcafb006351417e82785b809a1ab1fbbb2c577" - integrity sha512-G6YuIVD8D6hZjnsD/aYZQ2qMHSve7IadEiXgKiDfFQBbyrkjDAlt6LDSqq4qnuv3WJ7/jAOn/An6n/bGyt0rLg== +"@formatjs/cli-native-darwin-arm64@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@formatjs/cli-native-darwin-arm64/-/cli-native-darwin-arm64-1.1.1.tgz#abf5d12040511bbb9225ae6835fb6107f3e7f866" + integrity sha512-G2IfmxwDN1kUMIbM9ec5HfJTNR89X11+U3bt4lewfrRqoHOc9bQAkkVHLsY8gNVLjyQIXch58Ewd+AAHkg6cag== -"@formatjs/cli-native-linux-x64@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@formatjs/cli-native-linux-x64/-/cli-native-linux-x64-1.1.0.tgz#1a3f01ea47f971a0dd0d7f49b98df237375862fa" - integrity sha512-AxORf5LR14HvXU4ov9gnhLrNIS2DYKqKMkRkprUhuh+ljba1riF05msK8KzslEPYQoeYKc5A0OZp57poh4xz/g== +"@formatjs/cli-native-linux-arm64@1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@formatjs/cli-native-linux-arm64/-/cli-native-linux-arm64-1.2.1.tgz#b55884c1bbe4c68a6545dd4e87e60e043c394c0e" + integrity sha512-dbafLt5p1wQi16QnTFuz6s5j5c8HcyRSw+gUp5xEtaQ9Ua2YKRu+YqlgsERg+ArTWN+ZTHIGu+0YymTvfTropA== -"@formatjs/cli-native-win32-x64@1.1.1": +"@formatjs/cli-native-linux-x64@1.1.1": version "1.1.1" - resolved "https://registry.yarnpkg.com/@formatjs/cli-native-win32-x64/-/cli-native-win32-x64-1.1.1.tgz#a911b22c8f5ccfe4aff5a00276ee4274f4b81079" - integrity sha512-2vYgm7dzAb7wA9KjOOJGxZiSShwBNK4dEmgiJ1lRpEIz6RKMZ6wBY4UVn03VdAv8djJ7r6RK4Xyd2ouGcbh9Bg== + resolved "https://registry.yarnpkg.com/@formatjs/cli-native-linux-x64/-/cli-native-linux-x64-1.1.1.tgz#e3439d454b6006537abc22130989f285d036426b" + integrity sha512-zi6eOPAc03fszPyiGCkmzBxjIxynDFflie9zgbyZIQgKV7MhXEmUmpGYeaTTDX903OFCJJ3ZvpajSTdZ7C7yeQ== -"@formatjs/cli@^6.16.3": - version "6.16.3" - resolved "https://registry.yarnpkg.com/@formatjs/cli/-/cli-6.16.3.tgz#728a17c1deaf1fec0ace554b2c72695f18253231" - integrity sha512-AN6uZR1xnl3V215HHJiKiA+DvNMrO/XfQ7hOyq3gXfHJwKSgLLQFtSFxw9A1O0SaGC2E2Kwo4mqwS1ZCLGe/qw== +"@formatjs/cli-native-win32-x64@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@formatjs/cli-native-win32-x64/-/cli-native-win32-x64-1.1.2.tgz#6cc2db043243d5215065d3548e7198233e342c0d" + integrity sha512-2TKatQRlDbVc+eJE4b9n0/+bsDg+DpS0kmHw7OYI1zGXhus4YqRPtlJnraazRmPlXtRNgvY/UYCPgBvX7DbYhw== + +"@formatjs/cli@^6.16.6": + version "6.16.6" + resolved "https://registry.yarnpkg.com/@formatjs/cli/-/cli-6.16.6.tgz#dcc47f28756eec01f59e3911f58407293ff9c65f" + integrity sha512-82l9wmeqvClrtI/8VQOcFVZQwZWYEiMI505hywngF+xr7ti94OQXg0gi3piYaQarfiIac2GSMibLQ2aQM5mJaA== optionalDependencies: - "@formatjs/cli-native-darwin-arm64" "1.1.0" - "@formatjs/cli-native-linux-arm64" "1.2.0" - "@formatjs/cli-native-linux-x64" "1.1.0" - "@formatjs/cli-native-win32-x64" "1.1.1" + "@formatjs/cli-native-darwin-arm64" "1.1.1" + "@formatjs/cli-native-linux-arm64" "1.2.1" + "@formatjs/cli-native-linux-x64" "1.1.1" + "@formatjs/cli-native-win32-x64" "1.1.2" "@formatjs/fast-memoize@3.1.5": version "3.1.5" @@ -372,10 +372,10 @@ dependencies: "@tybys/wasm-util" "^0.10.1" -"@oxc-project/types@=0.132.0": - version "0.132.0" - resolved "https://registry.yarnpkg.com/@oxc-project/types/-/types-0.132.0.tgz#d77243df4fe1a0a1e60e12ac6240fa898d2363ff" - integrity sha512-FESMOxil5Se014ui/Eq8fT5uHJo6nIRwH0PfJrZJXs6Gek3ZVFOrpUv3YIZT20m+extU98Hg1Ym72U58rlsxUQ== +"@oxc-project/types@=0.133.0": + version "0.133.0" + resolved "https://registry.yarnpkg.com/@oxc-project/types/-/types-0.133.0.tgz#2e282ef9e1d26e06b68ccd14b73f310a3b2cf7f8" + integrity sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA== "@parcel/watcher-android-arm64@2.5.6": version "2.5.6" @@ -507,84 +507,84 @@ uncontrollable "^8.0.4" warning "^4.0.3" -"@rolldown/binding-android-arm64@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.2.tgz#ebe1264e43ba5bb224c58c85e0ac238f87e5ad14" - integrity sha512-ZS4D1JPGn/MYQN/SYDWftIE/nVsM8j/AFOYEzAoOE2O3NktQOZru+/vYXGbR/qtdLdIfGCP0lcoJiYVzsEz+iQ== +"@rolldown/binding-android-arm64@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz#54ce8f8382213f4a314a0c2f7ba83f81ffeae592" + integrity sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw== -"@rolldown/binding-darwin-arm64@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.2.tgz#f972fb71bc03840629bee923babbb7048d14a5d0" - integrity sha512-vdFA9+C/rekyGce7WqHs/xoT0ioZEWaOFyZLIV1mEeNFaFDUQrPIo8Vs2GvJ6eetb3rzDUtUBgzto3ExpXJB3w== +"@rolldown/binding-darwin-arm64@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz#388fca1566c14c00c4b446fc3928630e7f0d95fc" + integrity sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA== -"@rolldown/binding-darwin-x64@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.2.tgz#da1c062c135e1e50067084be5ab8055cc1e05b29" - integrity sha512-BewSOwTHazv77DTYiAZXSqqKZ4KP/KonFisDMVU7PImxoWfB2aepnPhd2E4SWz3zDzYgDNbs6jBmTdgNnF02GA== +"@rolldown/binding-darwin-x64@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz#53f57de1f599ecf1db13823cfc88c18fb80954ad" + integrity sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg== -"@rolldown/binding-freebsd-x64@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.2.tgz#a4c8532072705ce597c0d75418513709b75b3f1d" - integrity sha512-m41o7M0YWtUdqk61Tb+jnKb2rN++iRdIASlExkUoKfIAH30DOHCB8fVLzSUpbWHHU8esmEioY62PxzexE8MBuA== +"@rolldown/binding-freebsd-x64@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz#6f3fdda1b7aeaac9d268a526804b4fb96e4e35f1" + integrity sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g== -"@rolldown/binding-linux-arm-gnueabihf@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.2.tgz#78f3bd274a1bab07356017d728b70289f04011c1" - integrity sha512-jcojB9H7W/jS29pMKWAK1N+fU99vXodHDTatS3b3y/XSOCiHo0kkA74pL3jJmkoQtYpOCxDvaKs1fo2Ij/1X5w== +"@rolldown/binding-linux-arm-gnueabihf@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz#d87a454bf585cc9676849377e91d6e375297326f" + integrity sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw== -"@rolldown/binding-linux-arm64-gnu@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.2.tgz#4dc530aed0b554762ffc1a5e4f016b8be495eea0" - integrity sha512-1jn6qDU5iiOgFgygDzKUuKP0maTi0/f1+sBLgvij/76C77Nm3ts6ufz9Bjg5q5dduxiUIxtq86JIoBvo1xQ4Ig== +"@rolldown/binding-linux-arm64-gnu@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz#419fd6bf612cf348f10528cbcd94ebab9607d8d1" + integrity sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw== -"@rolldown/binding-linux-arm64-musl@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.2.tgz#56043cdf4768ea3184bb08a3f45b24f183003877" - integrity sha512-QVLO/czFMdoMFSqlX3bcswcJNm/23r+qoa/jgtmFc/qEp6/jXmIkDjF/XIo8dPfGaiwy1xfQn8o77L79GeXFgw== +"@rolldown/binding-linux-arm64-musl@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz#fcc6918696bb76844877e1e4930a18fd0d374069" + integrity sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q== -"@rolldown/binding-linux-ppc64-gnu@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.2.tgz#92eba998d5cd9e4cfc8b95407b4b80f46dacadf4" - integrity sha512-hgO5Abm0w5UL6FEa2iFnZqo2KlK7TQ5QhV5x09hujBf7t5KzHQ1VmfPuTpqRy/rNlSxua3eWH374xxiVrP+lcA== +"@rolldown/binding-linux-ppc64-gnu@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz#32aecb7c8dae5d4f2a8cde57a058ec86991542f8" + integrity sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg== -"@rolldown/binding-linux-s390x-gnu@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.2.tgz#50b0e95dc3c22af1ecd1669ad7e6030e6860819e" - integrity sha512-fy8rXxuYEu602abC8MUNaPjYLIFzReOaEIEMKMUa0rFEUxNpVXhs15KSSQ4qlqSaM7B6rcj9rDZgADh/IGDzLQ== +"@rolldown/binding-linux-s390x-gnu@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz#bed9346ea81e6bb8b93cf11f5d88b77db890b763" + integrity sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg== -"@rolldown/binding-linux-x64-gnu@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.2.tgz#d9fd5af004a373a2d26a09ce8fb66bd0927cbc0b" - integrity sha512-0+bOkiQ779+r1WpoHOWHqncvyySci0vKph+myNDYb+im6meJAzHQXay6oEgnkHuUGouM1LKTZwqKpBow6Kj7CQ== +"@rolldown/binding-linux-x64-gnu@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz#64c2d26f75dffd9b5a1f97557a00ae77250c8cb7" + integrity sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg== -"@rolldown/binding-linux-x64-musl@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.2.tgz#c0ad80adf4d4df430d0ec309e97924db85065c3c" - integrity sha512-mjSkrzZK5Qsl0a9d1JgILOiuZOSDTVdKENcSXBoqbzSrspLR/4/IRVDo5wd2GgZjNss/viBFJdeq+j7qH2nypw== +"@rolldown/binding-linux-x64-musl@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz#5a45132e8a47659eeaaf3b540c2954a97c860ff3" + integrity sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow== -"@rolldown/binding-openharmony-arm64@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.2.tgz#341fc254ef7759f865bb219beb5cea6f5c9a44f6" - integrity sha512-1v5vHasdfQAZoEHakBV72LIFAC9JjnymsiKxp+GEr/ma3+NJCPSaYK+qavInOovJkgwFrs7GccX2d6IgDA3Z5w== +"@rolldown/binding-openharmony-arm64@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz#290513068c55e849dc8457a32afee1d7b0acb309" + integrity sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg== -"@rolldown/binding-wasm32-wasi@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.2.tgz#65f9389f74168fd54e67b12d0630fb90348051f0" - integrity sha512-mb1VobWn6NheziTk5/WEaR6AKVbrwT5sOi6C7zk3gy/pD1qtJfU1j4PgTo2NJnOtbL9Dl3Aeei8w9jJ7qC2jZQ== +"@rolldown/binding-wasm32-wasi@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz#3d9972dbf1a953d3c7afaa4a0f20ef2b2e39f31b" + integrity sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg== dependencies: "@emnapi/core" "1.10.0" "@emnapi/runtime" "1.10.0" "@napi-rs/wasm-runtime" "^1.1.4" -"@rolldown/binding-win32-arm64-msvc@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.2.tgz#17e80f3402308f12c76ff4172768d51715b522ac" - integrity sha512-SqKonF56vA/L2yHwHYcEp2P34URpOZ7d1fS635cTkpDnUtEGdUbhI6NzsPdqeSWvAAeGDrxjWjNmibDIdFf9/A== +"@rolldown/binding-win32-arm64-msvc@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz#a004ab607a16d6f03bcb555728ff888af75773ad" + integrity sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g== -"@rolldown/binding-win32-x64-msvc@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.2.tgz#875cfa37f26d11692dbe28b8331499c97aa99d1f" - integrity sha512-v7qRI7gXLRINcOGXt+7YmAZ6iFuyZVMIoXAxhd8oP+DR9dLfL9GfNIx7PLMxmhZdvq8waUJBQiWN9EKNy+TRBQ== +"@rolldown/binding-win32-x64-msvc@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz#e2a25b34691a1cc8a1209d7de709063026dd0cdb" + integrity sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA== "@rolldown/pluginutils@^1.0.0": version "1.0.1" @@ -873,63 +873,63 @@ dependencies: "@rolldown/pluginutils" "^1.0.0" -"@vitest/expect@4.1.7": - version "4.1.7" - resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-4.1.7.tgz#dc2918d51b54fa24ac5b4e7e802ef7440a11027f" - integrity sha512-1R+tw0ortHEbZDGMymm+pN7/AFQ/RkFFdtd7EN+VBpynKmLbP8A3rpEXdshBJ7+8hQ9zBJh/i1s0yKNtxAnU7w== +"@vitest/expect@4.1.8": + version "4.1.8" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-4.1.8.tgz#45154f1f8559f55c5281eb0dcb1ac37b581a87d8" + integrity sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ== dependencies: "@standard-schema/spec" "^1.1.0" "@types/chai" "^5.2.2" - "@vitest/spy" "4.1.7" - "@vitest/utils" "4.1.7" + "@vitest/spy" "4.1.8" + "@vitest/utils" "4.1.8" chai "^6.2.2" tinyrainbow "^3.1.0" -"@vitest/mocker@4.1.7": - version "4.1.7" - resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-4.1.7.tgz#05c5b42968b56057c40ea3e4546f3227cf1bf6fc" - integrity sha512-vY7nuamKgfvpA1Koa3oYIw/k7D6kZnpGyNMZW8loow2bsBYla1TFdqTaXncWdRn4pgwNs+90RhnXhJScDwQeJA== +"@vitest/mocker@4.1.8": + version "4.1.8" + resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-4.1.8.tgz#d006bfc5894a1af51e74deddef2535d6bd436b16" + integrity sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw== dependencies: - "@vitest/spy" "4.1.7" + "@vitest/spy" "4.1.8" estree-walker "^3.0.3" magic-string "^0.30.21" -"@vitest/pretty-format@4.1.7": - version "4.1.7" - resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-4.1.7.tgz#86b37ea96d4c5bd1357be66982e60a89a343c1bb" - integrity sha512-umgCarTOYQWIaDMvGDRZij+6b9oVeLIyJzfN+AS88e0ZOU3QTgNNSTtjQOpcvWr3np1N0j4WgZj+sb3oYBDscw== +"@vitest/pretty-format@4.1.8": + version "4.1.8" + resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-4.1.8.tgz#d9d2e248b900d7ad9556c4374fcdf1871c615193" + integrity sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA== dependencies: tinyrainbow "^3.1.0" -"@vitest/runner@4.1.7": - version "4.1.7" - resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-4.1.7.tgz#a7c465a76c0edc7deb1e8927dad452b71c5797b5" - integrity sha512-BapjmAQ2aI78WdMEfeUWivnfVzB+VPGwWRQcJE0OUq7qEeEcBsCSf+0T5iREBNE5nBb4wA5Ya0W6IA+sghdEFw== +"@vitest/runner@4.1.8": + version "4.1.8" + resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-4.1.8.tgz#4631808f3996359b74ccc3ca262990e14c295d50" + integrity sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg== dependencies: - "@vitest/utils" "4.1.7" + "@vitest/utils" "4.1.8" pathe "^2.0.3" -"@vitest/snapshot@4.1.7": - version "4.1.7" - resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-4.1.7.tgz#03ca7bed0cb3f2ce37de9feee7a159ba5d4893a4" - integrity sha512-ZacLzja+TmJeZ1h14xW2FB/WpeimUD3haBXQPyJqxvo8jQTmfeA8zv58mtjN2C7EHXZDYVcVYdYmAxjkWVvKCw== +"@vitest/snapshot@4.1.8": + version "4.1.8" + resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-4.1.8.tgz#37470135d64ea11bb2a839b1c6b7f5de7018f6ee" + integrity sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ== dependencies: - "@vitest/pretty-format" "4.1.7" - "@vitest/utils" "4.1.7" + "@vitest/pretty-format" "4.1.8" + "@vitest/utils" "4.1.8" magic-string "^0.30.21" pathe "^2.0.3" -"@vitest/spy@4.1.7": - version "4.1.7" - resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-4.1.7.tgz#459de6b5f2c80cb589e612b2fa8170a33393dee9" - integrity sha512-kbkI5LMWakyuTIvs6fUJ5qdIVb1XVKsYJAT4OJ938cHMROYMSfmoQdZy0aaAnjbbc8F61vkoTqz/Az+/HiIu5Q== +"@vitest/spy@4.1.8": + version "4.1.8" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-4.1.8.tgz#3abfe9301d25c39f808dcaa9f10fec0dd370e564" + integrity sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA== -"@vitest/utils@4.1.7": - version "4.1.7" - resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-4.1.7.tgz#8d2350588f7054246f24d0dbadffbef5d3a5caff" - integrity sha512-T532WBu791cBxJlCl6SO+J14l81DQx6uQHm1bQbmCDY7nqlEIgkza/UFnSBNaUtSf41unldDFjdOBYEQC4b5Hw== +"@vitest/utils@4.1.8": + version "4.1.8" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-4.1.8.tgz#099ea5255cec08735410cf707edaba2c158c5ad9" + integrity sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg== dependencies: - "@vitest/pretty-format" "4.1.7" + "@vitest/pretty-format" "4.1.8" convert-source-map "^2.0.0" tinyrainbow "^3.1.0" @@ -2381,29 +2381,29 @@ retry@^0.12.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== -rolldown@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/rolldown/-/rolldown-1.0.2.tgz#ea2c786c5f063d08fd22b49e51997f15ec532bbd" - integrity sha512-oZx5zVDtVB44AW3eaifgDml1gWRDZGvjcfdxonE4swNPG98PrrXjaO/KrnUjzlMnztCCRVlUueA1kCXhARGk6g== +rolldown@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/rolldown/-/rolldown-1.0.3.tgz#db88a3008fb0e28230a00423727ce75ba32121ac" + integrity sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g== dependencies: - "@oxc-project/types" "=0.132.0" + "@oxc-project/types" "=0.133.0" "@rolldown/pluginutils" "^1.0.0" optionalDependencies: - "@rolldown/binding-android-arm64" "1.0.2" - "@rolldown/binding-darwin-arm64" "1.0.2" - "@rolldown/binding-darwin-x64" "1.0.2" - "@rolldown/binding-freebsd-x64" "1.0.2" - "@rolldown/binding-linux-arm-gnueabihf" "1.0.2" - "@rolldown/binding-linux-arm64-gnu" "1.0.2" - "@rolldown/binding-linux-arm64-musl" "1.0.2" - "@rolldown/binding-linux-ppc64-gnu" "1.0.2" - "@rolldown/binding-linux-s390x-gnu" "1.0.2" - "@rolldown/binding-linux-x64-gnu" "1.0.2" - "@rolldown/binding-linux-x64-musl" "1.0.2" - "@rolldown/binding-openharmony-arm64" "1.0.2" - "@rolldown/binding-wasm32-wasi" "1.0.2" - "@rolldown/binding-win32-arm64-msvc" "1.0.2" - "@rolldown/binding-win32-x64-msvc" "1.0.2" + "@rolldown/binding-android-arm64" "1.0.3" + "@rolldown/binding-darwin-arm64" "1.0.3" + "@rolldown/binding-darwin-x64" "1.0.3" + "@rolldown/binding-freebsd-x64" "1.0.3" + "@rolldown/binding-linux-arm-gnueabihf" "1.0.3" + "@rolldown/binding-linux-arm64-gnu" "1.0.3" + "@rolldown/binding-linux-arm64-musl" "1.0.3" + "@rolldown/binding-linux-ppc64-gnu" "1.0.3" + "@rolldown/binding-linux-s390x-gnu" "1.0.3" + "@rolldown/binding-linux-x64-gnu" "1.0.3" + "@rolldown/binding-linux-x64-musl" "1.0.3" + "@rolldown/binding-openharmony-arm64" "1.0.3" + "@rolldown/binding-wasm32-wasi" "1.0.3" + "@rolldown/binding-win32-arm64-msvc" "1.0.3" + "@rolldown/binding-win32-x64-msvc" "1.0.3" rooks@^9.8.0: version "9.8.0" @@ -2542,10 +2542,10 @@ tinyexec@^1.0.2: resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-1.0.2.tgz#bdd2737fe2ba40bd6f918ae26642f264b99ca251" integrity sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg== -tinyglobby@^0.2.15, tinyglobby@^0.2.16: - version "0.2.16" - resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.16.tgz#1c3b7eb953fce42b226bc5a1ee06428281aff3d6" - integrity sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg== +tinyglobby@^0.2.15, tinyglobby@^0.2.17: + version "0.2.17" + resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.17.tgz#562a9a6c9eb2b3b123d39719f9af5bb44fcd7631" + integrity sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g== dependencies: fdir "^6.5.0" picomatch "^4.0.4" @@ -2555,10 +2555,10 @@ tinyrainbow@^3.1.0: resolved "https://registry.yarnpkg.com/tinyrainbow/-/tinyrainbow-3.1.0.tgz#1d8a623893f95cf0a2ddb9e5d11150e191409421" integrity sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw== -tmp@^0.2.6: - version "0.2.6" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.6.tgz#0dfac10fd09a9319288eb0e8f0ed524604e183b4" - integrity sha512-5sJPdPjfI5Kx+qbrDesxkglRBxW//g7hCsqspEjwkewGvBMGIKMOTKzLt1hFVJzyadba3lDUN20O9qhvbQUSTA== +tmp@^0.2.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.7.tgz#26f4db11d1601ce8012dcb8a798ece1c06a99059" + integrity sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw== trim-lines@^3.0.0: version "3.0.1" @@ -2712,31 +2712,31 @@ vite-plugin-checker@^0.14.1: proper-lockfile "^4.1.2" tiny-invariant "^1.3.3" -"vite@^6.0.0 || ^7.0.0 || ^8.0.0", vite@^8.0.14: - version "8.0.14" - resolved "https://registry.yarnpkg.com/vite/-/vite-8.0.14.tgz#da5d8d1f63dbd106385cbe9c211acbc7a7a5b192" - integrity sha512-s4BJJ+5y1pYL6Otw51FHhVJQhPnuRinKig64g/1+EUNaJsd3gCKdD31IPFvswUgW9/60QT9oFHbZHbQK5imcxw== +"vite@^6.0.0 || ^7.0.0 || ^8.0.0", vite@^8.0.16: + version "8.0.16" + resolved "https://registry.yarnpkg.com/vite/-/vite-8.0.16.tgz#ae073866c06563d6634a90169a496e11bd84f1a6" + integrity sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw== dependencies: lightningcss "^1.32.0" picomatch "^4.0.4" postcss "^8.5.15" - rolldown "1.0.2" - tinyglobby "^0.2.16" + rolldown "1.0.3" + tinyglobby "^0.2.17" optionalDependencies: fsevents "~2.3.3" -vitest@^4.1.7: - version "4.1.7" - resolved "https://registry.yarnpkg.com/vitest/-/vitest-4.1.7.tgz#5ae483c0a901081bbf1428e07dafe80c36e62e6c" - integrity sha512-flYyaFd2CgoCoU+0UKt3pxksgC+S02iTDN0n3LtqaMeXsI9SBcdNujc2k0DeFLzUn/0k538yNjOSdwgCqcrwJA== - dependencies: - "@vitest/expect" "4.1.7" - "@vitest/mocker" "4.1.7" - "@vitest/pretty-format" "4.1.7" - "@vitest/runner" "4.1.7" - "@vitest/snapshot" "4.1.7" - "@vitest/spy" "4.1.7" - "@vitest/utils" "4.1.7" +vitest@^4.1.8: + version "4.1.8" + resolved "https://registry.yarnpkg.com/vitest/-/vitest-4.1.8.tgz#9fed17277bf7350497e54338898a7afd46dfd509" + integrity sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig== + dependencies: + "@vitest/expect" "4.1.8" + "@vitest/mocker" "4.1.8" + "@vitest/pretty-format" "4.1.8" + "@vitest/runner" "4.1.8" + "@vitest/snapshot" "4.1.8" + "@vitest/spy" "4.1.8" + "@vitest/utils" "4.1.8" es-module-lexer "^2.0.0" expect-type "^1.3.0" magic-string "^0.30.21" From a08f821c548e9b905751e72cc82b2af8f456b4b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jun 2026 13:59:29 +0000 Subject: [PATCH 06/77] Bump node-rsa from 1.1.1 to 2.0.0 in /backend Bumps [node-rsa](https://github.com/rzcoder/node-rsa) from 1.1.1 to 2.0.0. - [Release notes](https://github.com/rzcoder/node-rsa/releases) - [Changelog](https://github.com/rzcoder/node-rsa/blob/master/CHANGELOG.md) - [Commits](https://github.com/rzcoder/node-rsa/compare/1.1.1...v2.0.0) --- updated-dependencies: - dependency-name: node-rsa dependency-version: 2.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- backend/package.json | 2 +- backend/yarn.lock | 27 ++++++++++----------------- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/backend/package.json b/backend/package.json index 80ae74b45e..2c91ca4412 100644 --- a/backend/package.json +++ b/backend/package.json @@ -31,7 +31,7 @@ "lodash": "^4.18.1", "moment": "^2.30.1", "mysql2": "^3.22.3", - "node-rsa": "^1.1.1", + "node-rsa": "^2.0.0", "objection": "3.1.5", "otplib": "^13.4.0", "path": "^0.12.7", diff --git a/backend/yarn.lock b/backend/yarn.lock index 427e834fa1..49c54d1c5a 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -100,10 +100,10 @@ dependencies: minipass "^7.0.4" -"@noble/hashes@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-2.0.1.tgz#fc1a928061d1232b0a52bb754393c37a5216c89e" - integrity sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw== +"@noble/hashes@^2.0.1", "@noble/hashes@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-2.2.0.tgz#22da1d16a469954fce877055d559900a6c73b63b" + integrity sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg== "@otplib/core@13.4.0": version "13.4.0" @@ -264,13 +264,6 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -asn1@^0.2.4: - version "0.2.6" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" - integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== - dependencies: - safer-buffer "~2.1.0" - ast-types@^0.13.4: version "0.13.4" resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.4.tgz#ee0d77b343263965ecc3fb62da16e7222b2b6782" @@ -1526,12 +1519,12 @@ node-gyp@12.x: undici "^6.25.0" which "^6.0.0" -node-rsa@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/node-rsa/-/node-rsa-1.1.1.tgz#efd9ad382097782f506153398496f79e4464434d" - integrity sha512-Jd4cvbJMryN21r5HgxQOpMEqv+ooke/korixNNK3mGqfGJmy0M77WDDzo/05969+OkMy3XW1UuZsSmW9KQm7Fw== +node-rsa@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/node-rsa/-/node-rsa-2.0.0.tgz#f55c99fb3ffef08b24bab414b7d2f24b30d12081" + integrity sha512-7yfzccmBd5rm7pALJf709tPwLL987WvdT7LC/QK5Oxa5S2aabdBPjxRDxhWKkbfCc9/FiC82lwSc+ulGZHH44g== dependencies: - asn1 "^0.2.4" + "@noble/hashes" "^2.2.0" nodemon@^3.1.14: version "3.1.14" @@ -2032,7 +2025,7 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -"safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== From 6311329772ca4a357ef7249903ee72cb4b14ef97 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jun 2026 14:00:10 +0000 Subject: [PATCH 07/77] Bump the prod-patch-updates group in /frontend with 3 updates Bumps the prod-patch-updates group in /frontend with 3 updates: [react](https://github.com/facebook/react/tree/HEAD/packages/react), [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) and [react-intl](https://github.com/formatjs/formatjs). Updates `react` from 19.2.6 to 19.2.7 - [Release notes](https://github.com/facebook/react/releases) - [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md) - [Commits](https://github.com/facebook/react/commits/v19.2.7/packages/react) Updates `react-dom` from 19.2.6 to 19.2.7 - [Release notes](https://github.com/facebook/react/releases) - [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md) - [Commits](https://github.com/facebook/react/commits/v19.2.7/packages/react-dom) Updates `react-intl` from 10.1.9 to 10.1.11 - [Release notes](https://github.com/formatjs/formatjs/releases) - [Commits](https://github.com/formatjs/formatjs/compare/react-intl@10.1.9...react-intl@10.1.11) --- updated-dependencies: - dependency-name: react dependency-version: 19.2.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod-patch-updates - dependency-name: react-dom dependency-version: 19.2.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod-patch-updates - dependency-name: react-intl dependency-version: 10.1.11 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: prod-patch-updates ... Signed-off-by: dependabot[bot] --- frontend/package.json | 8 ++++---- frontend/yarn.lock | 32 ++++++++++++++++---------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 769a2a7702..0ddaf220b8 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -29,10 +29,10 @@ "generate-password-browser": "^1.1.0", "humps": "^2.0.1", "query-string": "^9.3.1", - "react": "^19.2.6", + "react": "^19.2.7", "react-bootstrap": "^2.10.10", - "react-dom": "^19.2.6", - "react-intl": "^10.1.9", + "react-dom": "^19.2.7", + "react-intl": "^10.1.11", "react-markdown": "^10.1.0", "react-router-dom": "^7.15.1", "react-select": "^5.10.2", @@ -49,7 +49,7 @@ "@types/country-flag-icons": "^1.2.2", "@types/humps": "^2.0.6", "@types/node": "^25.9.1", - "@types/react": "^19.2.15", + "@types/react": "^19.2.16", "@types/react-dom": "^19.2.3", "@types/react-table": "^7.7.20", "@vitejs/plugin-react": "^6.0.2", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index d5f803762f..f55a563af6 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -818,10 +818,10 @@ resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.12.tgz#b5d76568485b02a307238270bfe96cb51ee2a044" integrity sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w== -"@types/react@*", "@types/react@>=16.9.11", "@types/react@^19.2.15": - version "19.2.15" - resolved "https://registry.yarnpkg.com/@types/react/-/react-19.2.15.tgz#9e2c6a4251a290f5c525c3143caa872fa6e01e0d" - integrity sha512-eRwcGNHve+E8qtEQSSRl6urh+rFop4v8gm6O8rGv25CodbvFdLjA1vVQ1KkiFE0w0UPOnb8tDiFKL5lp0rtY5Q== +"@types/react@*", "@types/react@>=16.9.11", "@types/react@^19.2.16": + version "19.2.16" + resolved "https://registry.yarnpkg.com/@types/react/-/react-19.2.16.tgz#9868b153fd9e34e0117afcd5d7e372b8179337e1" + integrity sha512-esJiCAnl0kfpNdE69f3So4WJUXy95dLZydX0KwK46riIHDzHM7O9Vtf9xCHW0PXIqvgqNrswl522kA/5yx+F4w== dependencies: csstype "^3.2.2" @@ -2173,10 +2173,10 @@ react-bootstrap@^2.10.10: uncontrollable "^7.2.1" warning "^4.0.3" -react-dom@^19.2.6: - version "19.2.6" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.2.6.tgz#44a81b0bcca22da814c00847d09d01c8615529b7" - integrity sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g== +react-dom@^19.2.7: + version "19.2.7" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.2.7.tgz#0450dc9ae9ddbff76ef196401cd8b8c7fb466ccc" + integrity sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ== dependencies: scheduler "^0.27.0" @@ -2185,10 +2185,10 @@ react-fast-compare@^2.0.1: resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9" integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw== -react-intl@^10.1.9: - version "10.1.9" - resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-10.1.9.tgz#e256f0c28a049d391d421bf658e49fe137fb2cdf" - integrity sha512-FOWpTmwnZnAfz8JegRzyGnjUiuzLW3xJFjp/o8VR4HZAQ+Eg++YaeMhoUULLY+LMx7gZm3czaZEqcU4hntwerw== +react-intl@^10.1.11: + version "10.1.11" + resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-10.1.11.tgz#1b08edb40082eeb4f8b783cecda33c84ab0da80f" + integrity sha512-9VCaWKumbrP91QvS50IYRlbZsD4KdSLwcfEeF9CQLmnqK9qCvFCfyof694I9lqHJL2/TUxBwLCA+whjF129oAg== dependencies: "@formatjs/icu-messageformat-parser" "3.5.10" "@formatjs/intl" "4.1.12" @@ -2273,10 +2273,10 @@ react-transition-group@^4.3.0, react-transition-group@^4.4.5: loose-envify "^1.4.0" prop-types "^15.6.2" -react@^19.2.6: - version "19.2.6" - resolved "https://registry.yarnpkg.com/react/-/react-19.2.6.tgz#3dadb8e12b2a7934c1d5317973e5dce1301f9a4d" - integrity sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q== +react@^19.2.7: + version "19.2.7" + resolved "https://registry.yarnpkg.com/react/-/react-19.2.7.tgz#1f47a1bfc06f8ec885752c6f4af14369a9f8260b" + integrity sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ== readdirp@^5.0.0: version "5.0.0" From 94176d2f9cca98670e12bda81a184bc5c9675220 Mon Sep 17 00:00:00 2001 From: Tony Chau <90050474+fo5for@users.noreply.github.com> Date: Wed, 3 Jun 2026 20:03:29 +0800 Subject: [PATCH 08/77] Update s6 overlay to 3.2.3.0 --- docker/scripts/install-s6 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/scripts/install-s6 b/docker/scripts/install-s6 index 5fcb4e09bd..55513fe1e7 100755 --- a/docker/scripts/install-s6 +++ b/docker/scripts/install-s6 @@ -8,7 +8,7 @@ BLUE='\E[1;34m' GREEN='\E[1;32m' RESET='\E[0m' -S6_OVERLAY_VERSION=3.2.1.0 +S6_OVERLAY_VERSION=3.2.3.0 TARGETPLATFORM=${1:-linux/amd64} # Determine the correct binary file for the architecture given From 06f060dc0fa138f280e3bd92e438085d9659df7d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Jun 2026 21:21:13 +0000 Subject: [PATCH 09/77] Bump tmp from 0.2.5 to 0.2.7 in /test Bumps [tmp](https://github.com/raszi/node-tmp) from 0.2.5 to 0.2.7. - [Changelog](https://github.com/raszi/node-tmp/blob/master/CHANGELOG.md) - [Commits](https://github.com/raszi/node-tmp/compare/v0.2.5...v0.2.7) --- updated-dependencies: - dependency-name: tmp dependency-version: 0.2.6 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- test/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/yarn.lock b/test/yarn.lock index ca6b6539ea..f4bd7ca231 100644 --- a/test/yarn.lock +++ b/test/yarn.lock @@ -2284,9 +2284,9 @@ tldts@^6.1.32: tldts-core "^6.1.86" tmp@~0.2.4: - version "0.2.5" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.5.tgz#b06bcd23f0f3c8357b426891726d16015abfd8f8" - integrity sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow== + version "0.2.7" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.7.tgz#26f4db11d1601ce8012dcb8a798ece1c06a99059" + integrity sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw== to-regex-range@^5.0.1: version "5.0.1" From 300d0653e07c931c000450ac77ecc38a3db6dfdc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Jun 2026 21:22:00 +0000 Subject: [PATCH 10/77] Bump the prod-minor-updates group across 1 directory with 4 updates Bumps the prod-minor-updates group with 4 updates in the /frontend directory: [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query), [date-fns](https://github.com/date-fns/date-fns), [query-string](https://github.com/sindresorhus/query-string) and [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom). Updates `@tanstack/react-query` from 5.100.14 to 5.101.0 - [Release notes](https://github.com/TanStack/query/releases) - [Changelog](https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md) - [Commits](https://github.com/TanStack/query/commits/@tanstack/react-query@5.101.0/packages/react-query) Updates `date-fns` from 4.3.0 to 4.4.0 - [Release notes](https://github.com/date-fns/date-fns/releases) - [Commits](https://github.com/date-fns/date-fns/compare/v4.3.0...v4.4.0) Updates `query-string` from 9.3.1 to 9.4.0 - [Release notes](https://github.com/sindresorhus/query-string/releases) - [Commits](https://github.com/sindresorhus/query-string/compare/v9.3.1...v9.4.0) Updates `react-router-dom` from 7.15.1 to 7.16.0 - [Release notes](https://github.com/remix-run/react-router/releases) - [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md) - [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@7.16.0/packages/react-router-dom) --- updated-dependencies: - dependency-name: "@tanstack/react-query" dependency-version: 5.101.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates - dependency-name: date-fns dependency-version: 4.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates - dependency-name: query-string dependency-version: 9.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates - dependency-name: react-router-dom dependency-version: 7.16.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates ... Signed-off-by: dependabot[bot] --- frontend/package.json | 8 +++---- frontend/yarn.lock | 52 +++++++++++++++++++++---------------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 002c9fe179..a592fda5c8 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -18,23 +18,23 @@ "dependencies": { "@tabler/core": "^1.4.0", "@tabler/icons-react": "^3.44.0", - "@tanstack/react-query": "^5.100.14", + "@tanstack/react-query": "^5.101.0", "@tanstack/react-table": "^8.21.3", "@uiw/react-textarea-code-editor": "^3.1.1", "classnames": "^2.5.1", "country-flag-icons": "^1.6.17", - "date-fns": "^4.3.0", + "date-fns": "^4.4.0", "ez-modal-react": "^1.0.5", "formik": "^2.4.9", "generate-password-browser": "^1.1.0", "humps": "^2.0.1", - "query-string": "^9.3.1", + "query-string": "^9.4.0", "react": "^19.2.7", "react-bootstrap": "^2.10.10", "react-dom": "^19.2.7", "react-intl": "^10.1.11", "react-markdown": "^10.1.0", - "react-router-dom": "^7.15.1", + "react-router-dom": "^7.16.0", "react-select": "^5.10.2", "react-toastify": "^11.1.0", "rooks": "^9.8.0" diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 6f5875595d..5fe787ee2b 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -623,10 +623,10 @@ resolved "https://registry.yarnpkg.com/@tabler/icons/-/icons-3.44.0.tgz#286b203aac98591e27360de03974762568bbb272" integrity sha512-Wn0AOZG9sg0L+bjfMqq4eNhC6pQjIrk94LvvWYNYkY8KH8wC3YILRzQlrnVJc4FUeMxH/AK97QsYCX35H3LndA== -"@tanstack/query-core@5.100.14": - version "5.100.14" - resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.100.14.tgz#6bf11c9a6a33dbbbba21f05d880b93930d80000c" - integrity sha512-5X41dGpxgeaHISCRW2oYwcSycZeULZzAunaudXT9ov1KOTj9xwt0CH6hbwqP1/z74ZWF7rYFnDpyYH07XFcZew== +"@tanstack/query-core@5.101.0": + version "5.101.0" + resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.101.0.tgz#45391ce143c270b7e7a55bd1a6696918f20782d1" + integrity sha512-cQetA74EB+seWySv1TTKr828TnP0u39m6LykwDXIo84SNortpDkp30TMEjkqtYCNP9c40uT/iwl6MLiufEt0Ow== "@tanstack/query-devtools@5.100.14": version "5.100.14" @@ -640,12 +640,12 @@ dependencies: "@tanstack/query-devtools" "5.100.14" -"@tanstack/react-query@^5.100.14": - version "5.100.14" - resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.100.14.tgz#799fe305421fd84bf2f6df40930c859c945b42ab" - integrity sha512-oOr6aRdSFEwWhzxEkD/9ZcItM3+LjBSkeVmadWKwUssAHTsqd/7bOjWrX4AbvEkoEhgAxzN0Xk6H/aYzXiYBAw== +"@tanstack/react-query@^5.101.0": + version "5.101.0" + resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.101.0.tgz#2dd56c5b96ec816d6b6ec9cee5c80ed298974733" + integrity sha512-rLlJXSpkqfizLWgkR5+eLeIk0MvTx/meEIR7LRjxic+qxiQP8zVjq7BqQkiCMNLQBlLfuOLqqr6KO5GtrDlmSg== dependencies: - "@tanstack/query-core" "5.100.14" + "@tanstack/query-core" "5.101.0" "@tanstack/react-table@^8.21.3": version "8.21.3" @@ -1090,10 +1090,10 @@ csstype@^3.0.2, csstype@^3.2.2: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.2.3.tgz#ec48c0f3e993e50648c86da559e2610995cf989a" integrity sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ== -date-fns@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-4.3.0.tgz#95663b78f2be5ce664eb6606d94582acc39c77ba" - integrity sha512-OYcL+3N/jyWbYdFGqoMAhytDgxP9pbYPUUiRCOgn4Fewaadk9l/Wam4Avciiyp2BgkpfQyBV9B+ehnVJych+eQ== +date-fns@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-4.4.0.tgz#806539edf45c616b2b76b5f78b88c56ed3c7e036" + integrity sha512-+1UMbeh68lH1SegH83CGWwpb6OHHbpSgr3+s5Eww5M4CAgswBpoWS0AjTOfEJ33HiYKz1hdj/KTFprzXHmq/6w== debug@^4.0.0, debug@^4.3.1: version "4.4.3" @@ -2131,10 +2131,10 @@ property-information@^7.0.0: resolved "https://registry.yarnpkg.com/property-information/-/property-information-7.1.0.tgz#b622e8646e02b580205415586b40804d3e8bfd5d" integrity sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ== -query-string@^9.3.1: - version "9.3.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-9.3.1.tgz#d0c93e6c7fb7c17bdf04aa09e382114580ede270" - integrity sha512-5fBfMOcDi5SA9qj5jZhWAcTtDfKF5WFdd2uD9nVNlbxVv1baq65aALy6qofpNEGELHvisjjasxQp7BlM9gvMzw== +query-string@^9.4.0: + version "9.4.0" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-9.4.0.tgz#4f2cd518680e087dd781dd605f75dcb18c7f7a53" + integrity sha512-ivvWyHqU9K1Log4hJFhqVIIMoEi0nzmlRhvk2pPcTuQH/Y0K5iTTMxEx7R0PRHD2Z1hMVbWnjfsEWbIKIK+3IA== dependencies: decode-uri-component "^0.4.1" filter-obj "^5.1.0" @@ -2226,17 +2226,17 @@ react-markdown@^10.1.0: unist-util-visit "^5.0.0" vfile "^6.0.0" -react-router-dom@^7.15.1: - version "7.15.1" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-7.15.1.tgz#cf5aee65a44e407a17a2e9718d5350482b1e281f" - integrity sha512-AzF62gjY6U9rkMq4RfP/r2EVtQ7DMfNMjyOp/flLTCrtRylLiK4wT4pSq6O8rOXZ2eXdZYJPEYe+ifomiv+Igg== +react-router-dom@^7.16.0: + version "7.16.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-7.16.0.tgz#284a7cd021052aa7d0a9240dca4a02eec24eceb5" + integrity sha512-kMUAbimWB5FVbF4Bce4bJsiKJWLIUHq/mEG8+CFDnCSgltptBiG5nguducmsJeGKytlCvQud9Qhzpn49iduTlA== dependencies: - react-router "7.15.1" + react-router "7.16.0" -react-router@7.15.1: - version "7.15.1" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-7.15.1.tgz#0a12fece05887a47c54970480745385c793bcaac" - integrity sha512-R8rl9HhgikFYoPJymnUtPXWbnDb3oget6lQnfIoupbt61aT9aOhRkDsY2XRhZRyX1Z/8a5sL74fXmFNm3NRK5A== +react-router@7.16.0: + version "7.16.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-7.16.0.tgz#fb41536aef2ccc2c7be12ea6be819a1e56eb6343" + integrity sha512-wArC8lVyJb3+jM9OpDyW6hLCizACWkvQR/sSGqSs+o5uEXEtGlqdZ4v8hENR3Jad6i+LRkK93q/+bQAcvl6V1A== dependencies: cookie "^1.0.1" set-cookie-parser "^2.6.0" From 45a3659ffdff2e7eabac0e1fb20ec224a65a13ce Mon Sep 17 00:00:00 2001 From: Yassine Damiri <54901715+Yasha-ops@users.noreply.github.com> Date: Thu, 4 Jun 2026 15:08:31 +0200 Subject: [PATCH 11/77] Change fs import to use fs/promises --- backend/setup.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/setup.js b/backend/setup.js index c46e5743e1..c0418e170b 100644 --- a/backend/setup.js +++ b/backend/setup.js @@ -6,7 +6,7 @@ import certificateModel from "./models/certificate.js"; import settingModel from "./models/setting.js"; import userModel from "./models/user.js"; import userPermissionModel from "./models/user_permission.js"; -import fs from "fs"; +import fs from "fs/promises"; export const isSetup = async () => { const row = await userModel.query().select("id").where("is_deleted", 0).first(); @@ -123,7 +123,8 @@ const setupCertbotPlugins = async () => { const credentials_loc = `/etc/letsencrypt/credentials/credentials-${certificate.id}`; if (typeof certificate.meta.dns_provider_credentials === "string") { promises.push(fs.mkdir("/etc/letsencrypt/credentials", { recursive: true }) - .then(() => fs.writeFile(credentials_loc, certificate.meta.dns_provider_credentials, { mode: 0o600, flag: "wx" }))); + .then(() => fs.writeFile(credentials_loc, certificate.meta.dns_provider_credentials, { mode: 0o600, flag: "wx" })) + .catch((err) => { if (err.code !== "EEXIST") throw err; })); } } return true; From a62c2a6dc3ab51e6fedc34d3ea3506bc9373953f Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Tue, 9 Jun 2026 10:25:10 +1000 Subject: [PATCH 12/77] Adds support for custom admin port via env var #3808 and documentation --- docker/dev/Dockerfile | 2 +- docker/dev/squid.conf | 1 + docker/docker-compose.ci.postgres.yml | 4 +++ docker/docker-compose.ci.yml | 1 + ...oduction.conf => production.conf.template} | 4 +-- .../etc/s6-overlay/s6-rc.d/prepare/00-all.sh | 1 + .../s6-rc.d/prepare/45-admin-port.sh | 30 +++++++++++++++++++ .../etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh | 4 --- docker/rootfs/usr/bin/check-health | 2 +- docker/rootfs/usr/bin/common.sh | 4 +++ docs/src/advanced-config/index.md | 18 +++++++++++ scripts/wait-healthy | 2 +- test/cypress/config/ci.mjs | 4 ++- 13 files changed, 67 insertions(+), 10 deletions(-) rename docker/rootfs/etc/nginx/conf.d/{production.conf => production.conf.template} (89%) create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/45-admin-port.sh diff --git a/docker/dev/Dockerfile b/docker/dev/Dockerfile index 8593fd5ef6..56875fd849 100644 --- a/docker/dev/Dockerfile +++ b/docker/dev/Dockerfile @@ -25,7 +25,7 @@ RUN curl -sL 'https://taskfile.dev/install.sh' | sh COPY rootfs / COPY scripts/install-s6 /tmp/install-s6 -RUN rm -f /etc/nginx/conf.d/production.conf \ +RUN rm -f /etc/nginx/conf.d/production.conf.template \ && chmod 644 /etc/logrotate.d/nginx-proxy-manager \ && /tmp/install-s6 "${TARGETPLATFORM}" \ && rm -f /tmp/install-s6 \ diff --git a/docker/dev/squid.conf b/docker/dev/squid.conf index cdd749f582..b335f01af1 100644 --- a/docker/dev/squid.conf +++ b/docker/dev/squid.conf @@ -28,6 +28,7 @@ acl SSL_ports port 443 acl Safe_ports port 80 # http acl Safe_ports port 81 acl Safe_ports port 443 # https +acl Safe_ports port 8000 # for CI testing with custom admin port # # Recommended minimum Access Permission configuration: diff --git a/docker/docker-compose.ci.postgres.yml b/docker/docker-compose.ci.postgres.yml index b8c4244668..90245ed399 100644 --- a/docker/docker-compose.ci.postgres.yml +++ b/docker/docker-compose.ci.postgres.yml @@ -3,6 +3,7 @@ services: cypress: environment: CYPRESS_stack: "postgres" + NPM_ADMIN_PORT: 8000 fullstack: environment: @@ -11,11 +12,14 @@ services: DB_POSTGRES_USER: "npm" DB_POSTGRES_PASSWORD: "npmpass" DB_POSTGRES_NAME: "npm" + NPM_ADMIN_PORT: 8000 depends_on: - db-postgres - authentik - authentik-worker - authentik-ldap + expose: + - "8000/tcp" db-postgres: image: postgres:17 diff --git a/docker/docker-compose.ci.yml b/docker/docker-compose.ci.yml index 6130f82e3c..1bb3c7450b 100644 --- a/docker/docker-compose.ci.yml +++ b/docker/docker-compose.ci.yml @@ -105,6 +105,7 @@ services: environment: HTTP_PROXY: "squid:3128" HTTPS_PROXY: "squid:3128" + NPM_ADMIN_PORT: 81 volumes: - "cypress_logs:/test/results" - "./dev/resolv.conf:/etc/resolv.conf:ro" diff --git a/docker/rootfs/etc/nginx/conf.d/production.conf b/docker/rootfs/etc/nginx/conf.d/production.conf.template similarity index 89% rename from docker/rootfs/etc/nginx/conf.d/production.conf rename to docker/rootfs/etc/nginx/conf.d/production.conf.template index 877e51dda2..452609bcbc 100644 --- a/docker/rootfs/etc/nginx/conf.d/production.conf +++ b/docker/rootfs/etc/nginx/conf.d/production.conf.template @@ -1,7 +1,7 @@ # Admin Interface server { - listen 81 default; - listen [::]:81 default; + listen {{NPM_ADMIN_PORT}} default; + listen [::]:{{NPM_ADMIN_PORT}} default; server_name nginxproxymanager; root /app/frontend; diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/00-all.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/00-all.sh index d2e62f3bbc..172290eae6 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/00-all.sh +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/00-all.sh @@ -17,6 +17,7 @@ fi . /etc/s6-overlay/s6-rc.d/prepare/20-paths.sh . /etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh . /etc/s6-overlay/s6-rc.d/prepare/40-dynamic.sh +. /etc/s6-overlay/s6-rc.d/prepare/45-admin-port.sh . /etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh . /etc/s6-overlay/s6-rc.d/prepare/60-secrets.sh . /etc/s6-overlay/s6-rc.d/prepare/90-banner.sh diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/45-admin-port.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/45-admin-port.sh new file mode 100644 index 0000000000..3807c7d76c --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/45-admin-port.sh @@ -0,0 +1,30 @@ +#!/command/with-contenv bash +# shellcheck shell=bash + +# This command reads the `NPM_ADMIN_PORT` env var and will fall +# back to 81 if this is not set or is not a number. + +set -e + +log_info 'Admin Port ...' + +NPM_ADMIN_PORT="${NPM_ADMIN_PORT:-81}" +# ensure admin port is a number +if ! [[ "$NPM_ADMIN_PORT" =~ ^[0-9]+$ ]]; then + echo "WARNING: NPM_ADMIN_PORT must be a number. Defaulting to 81" >&2 + NPM_ADMIN_PORT=81 +fi + +PRODFILE="/etc/nginx/conf.d/production.conf" +SED_REGEX="s/\{\{NPM_ADMIN_PORT\}\}/${NPM_ADMIN_PORT}/g" + +if is_mounted "$PRODFILE"; then + echo "WARNING: skipping ${PRODFILE} — mounted file" >&2 +elif [ -f "$PRODFILE.template" ]; then + if sed -E "$SED_REGEX" "$PRODFILE.template" > "$PRODFILE" && [ -s "$PRODFILE" ]; then + # success + log_info "Generated ${PRODFILE} from template" + else + log_fatal "Failed to generate ${PRODFILE} from template" + fi +fi diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh index 36387a98dc..e37d11cfa0 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh @@ -8,10 +8,6 @@ set -e log_info 'IPv6 ...' -is_mounted() { - awk -v p="$1" '$5 == p { found=1 } END { exit !found }' /proc/self/mountinfo -} - process_folder () { FILES=$(find "$1" -type f -name "*.conf") SED_REGEX= diff --git a/docker/rootfs/usr/bin/check-health b/docker/rootfs/usr/bin/check-health index bcf5552b39..de23c903b6 100755 --- a/docker/rootfs/usr/bin/check-health +++ b/docker/rootfs/usr/bin/check-health @@ -1,6 +1,6 @@ #!/bin/bash -OK=$(curl --silent http://127.0.0.1:81/api/ | jq --raw-output '.status') +OK=$(curl --silent "http://127.0.0.1:${NPM_ADMIN_PORT:-81}/api/" | jq --raw-output '.status') if [ "$OK" == "OK" ]; then echo "OK" diff --git a/docker/rootfs/usr/bin/common.sh b/docker/rootfs/usr/bin/common.sh index 92bf19d9c6..32d4570444 100644 --- a/docker/rootfs/usr/bin/common.sh +++ b/docker/rootfs/usr/bin/common.sh @@ -70,3 +70,7 @@ is_true () { echo '0' fi } + +is_mounted() { + awk -v p="$1" '$5 == p { found=1 } END { exit !found }' /proc/self/mountinfo +} diff --git a/docs/src/advanced-config/index.md b/docs/src/advanced-config/index.md index 3ab04ce25b..a93a1a4d09 100644 --- a/docs/src/advanced-config/index.md +++ b/docs/src/advanced-config/index.md @@ -248,3 +248,21 @@ On startup, we generate a resolvers directive for Nginx unless this is defined: In this configuration, all DNS queries performed by Nginx will fall to the `/etc/hosts` file and then the `/etc/resolv.conf`. + + +## Changing the Admin UI port from 81 to something else + +First, add an env var to your docker compose file: +```yml + environment: + NPM_ADMIN_PORT: '8000' +``` + +And you'll probably want to expose that port as well + +```yml + ports: + - '8000:8000' +``` + +Then you'll be able to access admin UI at `http://localhost:8000` diff --git a/scripts/wait-healthy b/scripts/wait-healthy index 503d6a908e..7ca017686d 100755 --- a/scripts/wait-healthy +++ b/scripts/wait-healthy @@ -19,7 +19,7 @@ echo -e "${BLUE}❯ ${CYAN}Waiting for healthy: ${YELLOW}${SERVICE}${RESET}" until [ "${HEALTHY}" = "healthy" ]; do echo -n "." sleep 1 - HEALTHY="$(docker inspect -f '{{.State.Health.Status}}' $SERVICE)" + HEALTHY="$(docker inspect -f '{{.State.Health.Status}}' "$SERVICE")" ((LOOPCOUNT++)) if [ "$LOOPCOUNT" == "$LIMIT" ]; then diff --git a/test/cypress/config/ci.mjs b/test/cypress/config/ci.mjs index ea203a89ee..86c0a80dfb 100644 --- a/test/cypress/config/ci.mjs +++ b/test/cypress/config/ci.mjs @@ -1,6 +1,8 @@ import { defineConfig } from 'cypress'; import pluginSetup from '../plugins/index.mjs'; +const adminPort = process.env.NPM_ADMIN_PORT ?? 81; + export default defineConfig({ allowCypressEnv: false, requestTimeout: 30000, @@ -19,6 +21,6 @@ export default defineConfig({ env: { swaggerBase: `{{baseUrl}}/api/schema?ts=${Date.now()}`, }, - baseUrl: "http://fullstack:81", + baseUrl: `http://fullstack:${adminPort}`, } }); From cbf2782571dd13634e157fc9faa5b231a33b6aec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Jul 2026 00:15:51 +0000 Subject: [PATCH 13/77] Bump systeminformation from 5.31.6 to 5.31.17 in /test Bumps [systeminformation](https://github.com/sebhildebrandt/systeminformation) from 5.31.6 to 5.31.17. - [Release notes](https://github.com/sebhildebrandt/systeminformation/releases) - [Changelog](https://github.com/sebhildebrandt/systeminformation/blob/master/CHANGELOG.md) - [Commits](https://github.com/sebhildebrandt/systeminformation/compare/v5.31.6...v5.31.17) --- updated-dependencies: - dependency-name: systeminformation dependency-version: 5.31.17 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- test/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/yarn.lock b/test/yarn.lock index f4bd7ca231..a2ccda8e1c 100644 --- a/test/yarn.lock +++ b/test/yarn.lock @@ -2243,9 +2243,9 @@ supports-color@^8.1.1: has-flag "^4.0.0" systeminformation@^5.31.1: - version "5.31.6" - resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-5.31.6.tgz#2da4979a7262974fd068a3a306ded30aed6127c0" - integrity sha512-Uv2b2uGGM6ns+26czgW2cYRabYdnswM0ddSOOlryHOaelzsmDSet1iM/NT7VOYxW8x/BW+HkY+b1Ve2pLTSGSA== + version "5.31.17" + resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-5.31.17.tgz#60bd1cdaeb34212b5ad2410608ee47d41d2d8560" + integrity sha512-TvFA9iwDWlMjqZVlKIJ0Cy+Zgm9ttlMx0SMRwJDMNKyhlEKWBMb3+WRwDi/3dvHdWbexpos4Osp4U49p5WjB5g== tar@^7.5.13: version "7.5.15" From 553f879c06ab9232910949b0f857a3af606a74b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Jul 2026 08:31:47 +0000 Subject: [PATCH 14/77] Bump immutable from 5.1.5 to 5.1.9 in /frontend Bumps [immutable](https://github.com/immutable-js/immutable-js) from 5.1.5 to 5.1.9. - [Release notes](https://github.com/immutable-js/immutable-js/releases) - [Changelog](https://github.com/immutable-js/immutable-js/blob/main/CHANGELOG.md) - [Commits](https://github.com/immutable-js/immutable-js/compare/v5.1.5...v5.1.9) --- updated-dependencies: - dependency-name: immutable dependency-version: 5.1.9 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- frontend/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 5fe787ee2b..e4ccf077ac 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -1426,9 +1426,9 @@ ieee754@^1.2.1: integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== immutable@^5.1.5: - version "5.1.5" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-5.1.5.tgz#93ee4db5c2a9ab42a4a783069f3c5d8847d40165" - integrity sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A== + version "5.1.9" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-5.1.9.tgz#ac23c3a01992ab665e14ac9ffff298f28cd74a0c" + integrity sha512-m8nVez3rwrgmWxtLMt1ZYXB2Lv7OKYn/disyxAlSDYAlKSlFoPPfIAmAM/M5xqL4m4C/wAPw7S2/CNaUii1Hxg== import-fresh@^3.2.1: version "3.3.1" From 9aa7fd5722320cde499a0dfe3da7a642c06285cb Mon Sep 17 00:00:00 2001 From: addielarue Date: Sat, 25 Jul 2026 22:55:58 +1000 Subject: [PATCH 15/77] fix(stream): bracket IPv6 forward host for valid nginx upstream A Stream Host with an IPv6 address as the Forward Host was accepted and saved but never activated. The generated stream config rendered `proxy_pass {{ forwarding_host }}:{{ forwarding_port }}` as e.g. `fe80::528:3c87:e7bb:ab08:25`, which nginx rejects with "invalid port in upstream" because an IPv6 literal must be wrapped in square brackets before the port is appended (`[fe80::...]:25`). Normalize the stream forward host in generateConfig (alongside the existing per-host-type data massaging) using net.isIPv6(), so IPv6 hosts render as `[address]:port` while IPv4 addresses and hostnames are emitted unchanged. The mutation is applied to the deep-copied render object, so persisted and audit data are unaffected. Fixes #5740 --- backend/internal/nginx.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/backend/internal/nginx.js b/backend/internal/nginx.js index fe84607f96..bd405d802a 100644 --- a/backend/internal/nginx.js +++ b/backend/internal/nginx.js @@ -1,4 +1,5 @@ import fs from "node:fs"; +import net from "node:net"; import { dirname } from "node:path"; import { fileURLToPath } from "node:url"; import _ from "lodash"; @@ -221,6 +222,14 @@ const internalNginx = { host.forward_scheme = "$scheme"; } + // A stream forwarding to an IPv6 literal must have the address wrapped in + // square brackets before nginx appends ":". Without the brackets nginx + // reads the trailing ":" as part of the address and rejects the upstream + // ("invalid port in upstream"), so the stream saves but never activates (#5740). + if (nice_host_type === "stream" && net.isIPv6(host.forwarding_host)) { + host.forwarding_host = `[${host.forwarding_host}]`; + } + if (host.locations) { //logger.info ('host.locations = ' + JSON.stringify(host.locations, null, 2)); origLocations = [].concat(host.locations); From 20b8068aaae91cb923db127a5ee40fbbd699dfc2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 26 Jul 2026 16:21:19 +0000 Subject: [PATCH 16/77] Bump tar from 7.5.15 to 7.5.22 in /test Bumps [tar](https://github.com/isaacs/node-tar) from 7.5.15 to 7.5.22. - [Release notes](https://github.com/isaacs/node-tar/releases) - [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md) - [Commits](https://github.com/isaacs/node-tar/compare/v7.5.15...v7.5.22) --- updated-dependencies: - dependency-name: tar dependency-version: 7.5.22 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- test/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/yarn.lock b/test/yarn.lock index f4bd7ca231..46214bbc59 100644 --- a/test/yarn.lock +++ b/test/yarn.lock @@ -2248,9 +2248,9 @@ systeminformation@^5.31.1: integrity sha512-Uv2b2uGGM6ns+26czgW2cYRabYdnswM0ddSOOlryHOaelzsmDSet1iM/NT7VOYxW8x/BW+HkY+b1Ve2pLTSGSA== tar@^7.5.13: - version "7.5.15" - resolved "https://registry.yarnpkg.com/tar/-/tar-7.5.15.tgz#afe6d1316cddf614a566e3813e42fe01aed46fee" - integrity sha512-dzGK0boVlC4W5QFuQN1EFSl3bIDYsk7Tj40U6eIBnK2k/8ml7TZ5agbI5j5+qnoVcAA+rNtBml8SEiLxZpNqRQ== + version "7.5.22" + resolved "https://registry.yarnpkg.com/tar/-/tar-7.5.22.tgz#a696f998136e71487dc3f869a85bba2c67971ba9" + integrity sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA== dependencies: "@isaacs/fs-minipass" "^4.0.0" chownr "^3.0.0" From 2cd346d054edca856ed7c7ea10ebd83716cec141 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 2 Aug 2026 06:13:35 +0000 Subject: [PATCH 17/77] Bump postcss from 8.5.14 to 8.5.25 in /docs Bumps [postcss](https://github.com/postcss/postcss) from 8.5.14 to 8.5.25. - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/postcss/compare/8.5.14...8.5.25) --- updated-dependencies: - dependency-name: postcss dependency-version: 8.5.25 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- docs/yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/yarn.lock b/docs/yarn.lock index c756948271..f8c7568b23 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -952,10 +952,10 @@ mitt@^3.0.1: resolved "https://registry.yarnpkg.com/mitt/-/mitt-3.0.1.tgz#ea36cf0cc30403601ae074c8f77b7092cdab36d1" integrity sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw== -nanoid@^3.3.11: - version "3.3.11" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" - integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== +nanoid@^3.3.16: + version "3.3.16" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.16.tgz#a04d8ec4b1f10009d2d533947aefe4293737816c" + integrity sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q== oniguruma-to-es@^3.1.0: version "3.1.1" @@ -977,11 +977,11 @@ picocolors@^1.1.1: integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== postcss@^8.4.43, postcss@^8.5.6: - version "8.5.14" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.14.tgz#a66c2d7808fadf69ebb5b84a03f8bafd76c4919c" - integrity sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg== + version "8.5.25" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.25.tgz#5012a598eaaa897f21bbe8553be3cb7bd2bd78cb" + integrity sha512-DTPx3RWSSnWyzLxQnlH0rJP+EW5ekl16ZU4/psbIhA0e53kJfdgaN5vKM+xP7yJtXVu+nfdVFmlgFDEKAe4Pyw== dependencies: - nanoid "^3.3.11" + nanoid "^3.3.16" picocolors "^1.1.1" source-map-js "^1.2.1" From a42614094f95ef919e104b0445d20e75b5eef787 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Aug 2026 13:06:48 +0000 Subject: [PATCH 18/77] Bump actions/stale from 10 to 11 Bumps [actions/stale](https://github.com/actions/stale) from 10 to 11. - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/v10...v11) --- updated-dependencies: - dependency-name: actions/stale dependency-version: '11' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 3a2ae9e8f9..d44ec466d4 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -8,7 +8,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v10 + - uses: actions/stale@v11 with: stale-issue-label: 'stale' stale-pr-label: 'stale' From ab96d78f4d8f47a6a7cfb5bca7d41962246fa751 Mon Sep 17 00:00:00 2001 From: Fatih Emre Date: Tue, 4 Aug 2026 16:11:46 +0300 Subject: [PATCH 19/77] Collapse custom locations into a filterable list The Custom Locations tab rendered every location fully expanded, which becomes unusable once a host has more than a handful of them. Each row is now a collapsible card showing its path and forward target, collapsed by default, with the Add Location button moved to the top so it stays reachable without scrolling to the end of the list. A filter appears once there are five or more locations and matches on the path as well as the forward scheme, host and port. New locations are still appended to the end of the list, so the generated nginx config is unchanged. Also fixes two existing issues in this component: the per-location inputs shared the same DOM ids across rows, and the advanced-config toggle state was keyed by array index, so removing a location moved it onto the wrong row. --- .../Form/LocationsFields.module.css | 50 ++- .../src/components/Form/LocationsFields.tsx | 401 ++++++++++++------ frontend/src/locale/src/en.json | 9 + frontend/src/locale/src/tr.json | 9 + 4 files changed, 340 insertions(+), 129 deletions(-) diff --git a/frontend/src/components/Form/LocationsFields.module.css b/frontend/src/components/Form/LocationsFields.module.css index 4b48ef3cb9..9551e0d4ef 100644 --- a/frontend/src/components/Form/LocationsFields.module.css +++ b/frontend/src/components/Form/LocationsFields.module.css @@ -1,3 +1,51 @@ +/* card-active points --tblr-card-border-color at --tblr-primary, which both the + card outline and the card header's bottom border are drawn from. Tabler's + stylesheet is loaded after this one, so the override needs !important. */ .locationCard { - border-color: light-dark(var(--tblr-gray-200), var(--tblr-gray-700)) !important; + --tblr-card-border-color: light-dark(var(--tblr-gray-200), var(--tblr-gray-700)) !important; +} + +.filter { + max-width: 20rem; +} + +/* The header is a plain toggle rather than a button-styled control, so that a + list of collapsed locations reads as rows instead of a stack of buttons. */ +.toggle { + display: flex; + flex: 1 1 auto; + align-self: stretch; + align-items: center; + min-width: 0; + padding: 0; + color: inherit; + text-align: left; + background: transparent; + border: 0; +} + +.toggle:focus-visible { + outline: 2px solid var(--tblr-primary); + outline-offset: -2px; +} + +/* Keeps the marker on one line next to the delete button, and lets it drop out + of the way before the path does when the row runs out of room. */ +.marker { + display: flex; + flex: 0 1 auto; + align-items: center; + overflow: hidden; + white-space: nowrap; +} + +.path { + font-weight: 500; + white-space: nowrap; +} + +.summary { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } diff --git a/frontend/src/components/Form/LocationsFields.tsx b/frontend/src/components/Form/LocationsFields.tsx index 4240b1f986..23198c10c0 100644 --- a/frontend/src/components/Form/LocationsFields.tsx +++ b/frontend/src/components/Form/LocationsFields.tsx @@ -1,20 +1,43 @@ -import { IconSettings } from "@tabler/icons-react"; +import { + IconChevronDown, + IconChevronRight, + IconPlus, + IconSearch, + IconSettings, + IconTrash, + IconX, +} from "@tabler/icons-react"; import CodeEditor from "@uiw/react-textarea-code-editor"; import cn from "classnames"; import { useFormikContext } from "formik"; -import { useState } from "react"; +import { useRef, useState } from "react"; import type { ProxyLocation } from "src/api/backend"; import { intl, T } from "src/locale"; import styles from "./LocationsFields.module.css"; +// Below this many locations the list is short enough to scan by eye, and the +// filter would only take up space. +const FILTER_THRESHOLD = 5; + +// Locations are identified by a client-side id rather than their array index, +// so that expanded/advanced state stays with the right row when one is removed. +interface Row { + id: number; + value: ProxyLocation; +} + interface Props { initialValues: ProxyLocation[]; name?: string; } export function LocationsFields({ initialValues, name = "locations" }: Props) { - const [values, setValues] = useState(initialValues || []); + const [rows, setRows] = useState(() => (initialValues || []).map((value, id) => ({ id, value }))); const { setFieldValue } = useFormikContext(); + const [expanded, setExpanded] = useState([]); const [advVisible, setAdvVisible] = useState([]); + const [filter, setFilter] = useState(""); + const nextId = useRef(rows.length); + const scrollToId = useRef(null); const blankItem: ProxyLocation = { path: "", @@ -24,32 +47,62 @@ export function LocationsFields({ initialValues, name = "locations" }: Props) { forwardPort: 80, }; - const toggleAdvVisible = (idx: number) => { - setAdvVisible(advVisible.includes(idx) ? advVisible.filter((i) => i !== idx) : [...advVisible, idx]); + const toggleExpanded = (id: number) => { + setExpanded(expanded.includes(id) ? expanded.filter((i) => i !== id) : [...expanded, id]); + }; + + const toggleAdvVisible = (id: number) => { + setAdvVisible(advVisible.includes(id) ? advVisible.filter((i) => i !== id) : [...advVisible, id]); }; const handleAdd = () => { - setValues([...values, blankItem]); + const id = nextId.current++; + setRows([...rows, { id, value: blankItem }]); + // A new location starts empty, so open it and make sure an active filter + // doesn't hide the row that was just added. + setExpanded([...expanded, id]); + setFilter(""); + scrollToId.current = id; }; - const handleRemove = (idx: number) => { - const newValues = values.filter((_: ProxyLocation, i: number) => i !== idx); - setValues(newValues); - setFormField(newValues); + const handleRemove = (id: number) => { + const newRows = rows.filter((r: Row) => r.id !== id); + setRows(newRows); + setExpanded(expanded.filter((i) => i !== id)); + setAdvVisible(advVisible.filter((i) => i !== id)); + setFormField(newRows); }; - const handleChange = (idx: number, field: string, fieldValue: string) => { - const newValues = values.map((v: ProxyLocation, i: number) => (i === idx ? { ...v, [field]: fieldValue } : v)); - setValues(newValues); - setFormField(newValues); + const handleChange = (id: number, field: string, fieldValue: string) => { + const newRows = rows.map((r: Row) => (r.id === id ? { ...r, value: { ...r.value, [field]: fieldValue } } : r)); + setRows(newRows); + setFormField(newRows); }; - const setFormField = (newValues: ProxyLocation[]) => { - const filtered = newValues.filter((v: ProxyLocation) => v?.path?.trim() !== ""); + const setFormField = (newRows: Row[]) => { + const filtered = newRows.map((r: Row) => r.value).filter((v: ProxyLocation) => v?.path?.trim() !== ""); setFieldValue(name, filtered); }; - if (values.length === 0) { + const forwardSummary = (item: ProxyLocation) => { + if (!item.forwardHost) { + return ""; + } + return `${item.forwardScheme}://${item.forwardHost}${item.forwardPort ? `:${item.forwardPort}` : ""}`; + }; + + // Matches the path as well as the destination, so a location can be found by + // the host or port it forwards to and not just by its path. + const matchesFilter = (item: ProxyLocation, query: string) => + [item.path, item.forwardScheme, item.forwardHost, item.forwardPort, forwardSummary(item)] + .join(" ") + .toLowerCase() + .includes(query); + + const query = filter.trim().toLowerCase(); + const visibleRows = query ? rows.filter((r: Row) => matchesFilter(r.value, query)) : rows; + + if (rows.length === 0) { return (
+ ) : null} +
+ )} + + + {visibleRows.length === 0 ? ( +
+ +
+ ) : ( + visibleRows.map((row: Row) => { + const item = row.value; + const isOpen = expanded.includes(row.id); + const bodyId = `location-body-${row.id}`; + return ( +
{ + if (node && scrollToId.current === row.id) { + scrollToId.current = null; + node.scrollIntoView({ block: "nearest" }); + } + }} + className={cn("card", "card-active", "mb-2", styles.locationCard)} + > +
-
-
-
-
-
- - -
-
-
-
- - handleChange(idx, "forwardHost", e.target.value)} - /> -
+ + + ) : null} +
-
-
- - handleChange(idx, "forwardPort", e.target.value)} - /> + {isOpen && ( +
+
+
+
+ Location + handleChange(row.id, "path", e.target.value)} + /> +
+
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + handleChange(row.id, "forwardHost", e.target.value) + } + /> +
+
+
+
+ + + handleChange(row.id, "forwardPort", e.target.value) + } + /> +
+
+
+ {advVisible.includes(row.id) && ( +
+ handleChange(row.id, "advancedConfig", e.target.value)} + style={{ + fontFamily: + "ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace", + borderRadius: "0.3rem", + minHeight: "170px", + }} + /> +
+ )}
-
+ )}
- {advVisible.includes(idx) && ( -
- handleChange(idx, "advancedConfig", e.target.value)} - style={{ - fontFamily: - "ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace", - borderRadius: "0.3rem", - minHeight: "170px", - }} - /> -
- )} - -
- - ))} -
- -
+ ); + }) + )} ); } diff --git a/frontend/src/locale/src/en.json b/frontend/src/locale/src/en.json index bb00ac3322..88fdd724ed 100644 --- a/frontend/src/locale/src/en.json +++ b/frontend/src/locale/src/en.json @@ -101,6 +101,9 @@ "action.allow": { "defaultMessage": "Allow" }, + "action.clear": { + "defaultMessage": "Clear" + }, "action.close": { "defaultMessage": "Close" }, @@ -461,6 +464,12 @@ "loading": { "defaultMessage": "Loading…" }, + "location.advanced-config": { + "defaultMessage": "Has custom Nginx configuration" + }, + "location.filter": { + "defaultMessage": "Filter by path or destination" + }, "login.2fa-code": { "defaultMessage": "Verification Code" }, diff --git a/frontend/src/locale/src/tr.json b/frontend/src/locale/src/tr.json index 972fa895ec..cc2d488811 100644 --- a/frontend/src/locale/src/tr.json +++ b/frontend/src/locale/src/tr.json @@ -44,6 +44,9 @@ "action.allow": { "defaultMessage": "İzin Ver" }, + "action.clear": { + "defaultMessage": "Temizle" + }, "action.close": { "defaultMessage": "Kapat" }, @@ -386,6 +389,12 @@ "loading": { "defaultMessage": "Yükleniyor…" }, + "location.advanced-config": { + "defaultMessage": "Özel Nginx yapılandırması var" + }, + "location.filter": { + "defaultMessage": "Yol veya hedefe göre filtrele" + }, "login.title": { "defaultMessage": "Hesabınıza giriş yapın" }, From 4a0f21228941aa06baacda3777a24bb4477608ba Mon Sep 17 00:00:00 2001 From: "Dimas R. Wisnu" Date: Fri, 7 Aug 2026 16:40:32 +0700 Subject: [PATCH 20/77] feat: per-path access lists, host logs modal, PostgreSQL support - Per-path access lists: assign different access lists to individual locations on the same proxy host - Host logs modal: view access/error logs from proxy host dropdown - PostgreSQL JSON containment query (@>) for location regeneration - Locale keys: action.logs, column.error --- backend/internal/access-list.js | 101 +++++++++++ backend/internal/proxy-host.js | 163 +++++++++++------- backend/routes/nginx/proxy_hosts.js | 67 +++++++ .../schema/components/proxy-host-object.json | 6 +- frontend/src/api/backend/getProxyHostLogs.ts | 8 + frontend/src/api/backend/index.ts | 1 + frontend/src/api/backend/models.ts | 2 + frontend/src/components/Form/AccessField.tsx | 6 +- .../src/components/Form/LocationsFields.tsx | 14 ++ frontend/src/hooks/index.ts | 1 + frontend/src/hooks/useProxyHostLogs.ts | 12 ++ frontend/src/locale/src/en.json | 6 + frontend/src/modals/HostLogsModal.tsx | 93 ++++++++++ frontend/src/modals/index.ts | 1 + frontend/src/pages/Nginx/ProxyHosts/Table.tsx | 28 ++- .../pages/Nginx/ProxyHosts/TableWrapper.tsx | 3 +- 16 files changed, 434 insertions(+), 78 deletions(-) create mode 100644 frontend/src/api/backend/getProxyHostLogs.ts create mode 100644 frontend/src/hooks/useProxyHostLogs.ts create mode 100644 frontend/src/modals/HostLogsModal.tsx diff --git a/backend/internal/access-list.js b/backend/internal/access-list.js index 88bf9df523..413ac067af 100644 --- a/backend/internal/access-list.js +++ b/backend/internal/access-list.js @@ -2,7 +2,9 @@ import fs from "node:fs"; import batchflow from "batchflow"; import _ from "lodash"; import errs from "../lib/error.js"; +import { isMysql, isPostgres } from "../lib/config.js"; import utils from "../lib/utils.js"; +import db from "../db.js"; import { access as logger } from "../logger.js"; import accessListModel from "../models/access_list.js"; import accessListAuthModel from "../models/access_list_auth.js"; @@ -15,6 +17,36 @@ const omissions = () => { return ["is_deleted"]; }; +/** + * Find proxy hosts that reference an access list in their locations JSON. + * + * @param {Integer} accessListId + * @returns {Promise} + */ +const getProxyHostsUsingAccessListInLocations = async (accessListId) => { + let result; + if (isMysql()) { + const searchObj = JSON.stringify([{ access_list_id: accessListId }]); + result = await db().raw( + `SELECT id FROM proxy_host WHERE is_deleted = 0 AND JSON_CONTAINS(locations, ?, ?)`, + [searchObj, "$"], + ); + } else if (isPostgres()) { + result = await db().raw( + `SELECT id FROM proxy_host WHERE is_deleted = 0 AND locations::jsonb @> ?::jsonb`, + [JSON.stringify([{ access_list_id: accessListId }])], + ); + } else { + result = await db().raw( + `SELECT id FROM proxy_host WHERE is_deleted = 0 AND locations LIKE ?`, + [`%"access_list_id":${accessListId}%`], + ); + } + // knex raw() returns [rows, metadata] for MySQL + const rows = Array.isArray(result) && Array.isArray(result[0]) ? result[0] : result; + return rows || []; +}; + const internalAccessList = { /** * @param {Access} access @@ -187,6 +219,44 @@ const internalAccessList = { if (Number.parseInt(freshRow.proxy_host_count, 10)) { await internalNginx.bulkGenerateConfigs("proxy_host", freshRow.proxy_hosts); } + + // Also regenerate configs for proxy hosts that reference this access list in their locations + const locationHostRows = await getProxyHostsUsingAccessListInLocations(data.id); + if (locationHostRows && locationHostRows.length) { + const locationHostIds = locationHostRows.map((r) => r.id).filter((id) => { + // Exclude hosts already regenerated above + return !freshRow.proxy_hosts || !freshRow.proxy_hosts.find((h) => h.id === id); + }); + if (locationHostIds.length) { + const locationHosts = await proxyHostModel.query() + .where("is_deleted", 0) + .whereIn("id", locationHostIds) + .allowGraph(proxyHostModel.defaultAllowGraph) + .withGraphFetched("[owner, certificate, access_list.[clients,items]]"); + for (const host of locationHosts) { + // Fetch access lists for locations + if (host.locations && host.locations.length) { + for (let i = 0; i < host.locations.length; i++) { + const loc = host.locations[i]; + if (loc.access_list_id && loc.access_list_id > 0) { + const locAccessList = await accessListModel + .query() + .allowGraph("[clients,items]") + .where("is_deleted", 0) + .andWhere("id", loc.access_list_id) + .withGraphFetched("[clients,items]") + .first(); + if (locAccessList) { + host.locations[i].access_list = locAccessList; + } + } + } + } + } + await internalNginx.bulkGenerateConfigs("proxy_host", locationHosts); + } + } + await internalNginx.reload(); return internalAccessList.maskItems(freshRow); }, @@ -291,6 +361,37 @@ const internalAccessList = { await internalNginx.bulkGenerateConfigs("proxy_host", row.proxy_hosts); } + // Also handle proxy hosts that reference this access list in their locations JSON + const locationHostRows = await getProxyHostsUsingAccessListInLocations(row.id); + if (locationHostRows && locationHostRows.length) { + const locationHostIds = locationHostRows.map((r) => r.id).filter((id) => { + return !row.proxy_hosts || !row.proxy_hosts.find((h) => h.id === id); + }); + if (locationHostIds.length) { + // Clear the access_list_id in locations JSON for these hosts + for (const hostId of locationHostIds) { + const host = await proxyHostModel.query().where("id", hostId).first(); + if (host && host.locations) { + const updatedLocations = host.locations.map((loc) => { + if (loc.access_list_id === row.id) { + return { ...loc, access_list_id: 0 }; + } + return loc; + }); + await proxyHostModel.query().where("id", hostId).patch({ locations: updatedLocations }); + } + } + + // Re-fetch and regenerate configs + const locationHosts = await proxyHostModel.query() + .where("is_deleted", 0) + .whereIn("id", locationHostIds) + .allowGraph(proxyHostModel.defaultExpand) + .withGraphFetched("[owner, certificate, access_list.[clients,items]]"); + await internalNginx.bulkGenerateConfigs("proxy_host", locationHosts); + } + } + await internalNginx.reload(); // delete the htpasswd file diff --git a/backend/internal/proxy-host.js b/backend/internal/proxy-host.js index 2c159d48ad..96cfab480e 100644 --- a/backend/internal/proxy-host.js +++ b/backend/internal/proxy-host.js @@ -2,6 +2,7 @@ import _ from "lodash"; import errs from "../lib/error.js"; import { castJsonIfNeed } from "../lib/helpers.js"; import utils from "../lib/utils.js"; +import accessListModel from "../models/access_list.js"; import proxyHostModel from "../models/proxy_host.js"; import internalAuditLog from "./audit-log.js"; import internalCertificate from "./certificate.js"; @@ -12,6 +13,33 @@ const omissions = () => { return ["is_deleted", "owner.is_deleted"]; }; +/** + * Fetches access lists for each location that has its own access_list_id. + * Attaches the expanded access_list object (with clients and items) to each location. + * + * @param {Object} host + * @returns {Promise} + */ +const fetchLocationAccessLists = async (host) => { + if (!host.locations || !host.locations.length) { + return; + } + for (let i = 0; i < host.locations.length; i++) { + const loc = host.locations[i]; + if (loc.access_list_id && loc.access_list_id > 0) { + const accessList = await accessListModel + .query() + .where("is_deleted", 0) + .andWhere("id", loc.access_list_id) + .withGraphFetched("[clients,items]") + .first(); + if (accessList) { + host.locations[i].access_list = accessList; + } + } + } +}; + const internalProxyHost = { /** * @param {Access} access @@ -83,28 +111,29 @@ const internalProxyHost = { expand: ["certificate", "owner", "access_list.[clients,items]"], }); }) - .then((row) => { - // Configure nginx - return internalNginx.configure(proxyHostModel, "proxy_host", row).then(() => { + .then(async (row) => { + await fetchLocationAccessLists(row); + // Configure nginx + return internalNginx.configure(proxyHostModel, "proxy_host", row).then(() => { + return row; + }); + }) + .then((row) => { + // Audit log + thisData.meta = _.assign({}, thisData.meta || {}, row.meta); + + // Add to audit log + return internalAuditLog + .add(access, { + action: "created", + object_type: "proxy-host", + object_id: row.id, + meta: thisData, + }) + .then(() => { return row; }); - }) - .then((row) => { - // Audit log - thisData.meta = _.assign({}, thisData.meta || {}, row.meta); - - // Add to audit log - return internalAuditLog - .add(access, { - action: "created", - object_type: "proxy-host", - object_id: row.id, - meta: thisData, - }) - .then(() => { - return row; - }); - }); + }); }, /** @@ -202,24 +231,25 @@ const internalProxyHost = { }); }); }) - .then(() => { - return internalProxyHost - .get(access, { - id: thisData.id, - expand: ["owner", "certificate", "access_list.[clients,items]"], - }) - .then((row) => { - if (!row.enabled) { - // No need to add nginx config if host is disabled - return row; - } - // Configure nginx - return internalNginx.configure(proxyHostModel, "proxy_host", row).then((new_meta) => { - row.meta = new_meta; - return _.omit(internalHost.cleanRowCertificateMeta(row), omissions()); - }); + .then(() => { + return internalProxyHost + .get(access, { + id: thisData.id, + expand: ["owner", "certificate", "access_list.[clients,items]"], + }) + .then(async (row) => { + if (!row.enabled) { + // No need to add nginx config if host is disabled + return row; + } + await fetchLocationAccessLists(row); + // Configure nginx + return internalNginx.configure(proxyHostModel, "proxy_host", row).then((new_meta) => { + row.meta = new_meta; + return _.omit(internalHost.cleanRowCertificateMeta(row), omissions()); }); - }); + }); + }); }, /** @@ -326,39 +356,38 @@ const internalProxyHost = { expand: ["certificate", "owner", "access_list"], }); }) - .then((row) => { - if (!row?.id) { - throw new errs.ItemNotFoundError(data.id); - } - if (row.enabled) { - throw new errs.ValidationError("Host is already enabled"); - } + .then(async (row) => { + if (!row?.id) { + throw new errs.ItemNotFoundError(data.id); + } + if (row.enabled) { + throw new errs.ValidationError("Host is already enabled"); + } + + row.enabled = 1; + + await proxyHostModel + .query() + .where("id", row.id) + .patch({ + enabled: 1, + }); - row.enabled = 1; + await fetchLocationAccessLists(row); - return proxyHostModel - .query() - .where("id", row.id) - .patch({ - enabled: 1, - }) - .then(() => { - // Configure nginx - return internalNginx.configure(proxyHostModel, "proxy_host", row); - }) - .then(() => { - // Add to audit log - return internalAuditLog.add(access, { - action: "enabled", - object_type: "proxy-host", - object_id: row.id, - meta: _.omit(row, omissions()), - }); - }); - }) - .then(() => { - return true; + // Configure nginx + await internalNginx.configure(proxyHostModel, "proxy_host", row); + + // Add to audit log + await internalAuditLog.add(access, { + action: "enabled", + object_type: "proxy-host", + object_id: row.id, + meta: _.omit(row, omissions()), }); + + return true; + }); }, /** diff --git a/backend/routes/nginx/proxy_hosts.js b/backend/routes/nginx/proxy_hosts.js index 7045a195cc..ef62cf835a 100644 --- a/backend/routes/nginx/proxy_hosts.js +++ b/backend/routes/nginx/proxy_hosts.js @@ -1,4 +1,5 @@ import express from "express"; +import fs from "node:fs"; import internalProxyHost from "../../internal/proxy-host.js"; import jwtdecode from "../../lib/express/jwt-decode.js"; import apiValidator from "../../lib/validator/api.js"; @@ -206,4 +207,70 @@ router } }); +/** + * Proxy-host logs + * + * /api/nginx/proxy-hosts/123/logs + */ +router + .route("/:host_id/logs") + .options((_, res) => { + res.sendStatus(204); + }) + .all(jwtdecode()) + + /** + * GET /api/nginx/proxy-hosts/123/logs + * + * Retrieve logs for a specific proxy-host + */ + .get(async (req, res, next) => { + try { + const data = await validator( + { + required: ["host_id"], + additionalProperties: false, + properties: { + host_id: { + $ref: "common#/properties/id", + }, + type: { + type: "string", + enum: ["access", "error"], + }, + }, + }, + { + host_id: req.params.host_id, + type: req.query.type || "access", + }, + ); + + const hostId = Number.parseInt(data.host_id, 10); + const logType = data.type === "error" ? "error" : "access"; + const logFile = `/data/logs/proxy-host-${hostId}_${logType}.log`; + + // Check access permission + await res.locals.access.can("proxy_hosts:get", hostId); + + let logs = ""; + if (fs.existsSync(logFile)) { + const content = fs.readFileSync(logFile, { encoding: "utf8" }); + const lines = content.split("\n"); + // Return last 1000 lines to avoid huge payloads + const maxLines = 1000; + if (lines.length > maxLines) { + logs = lines.slice(-maxLines).join("\n"); + } else { + logs = content; + } + } + + res.status(200).send({ logs }); + } catch (err) { + debug(logger, `${req.method.toUpperCase()} ${req.path}: ${err}`); + next(err); + } + }); + export default router; diff --git a/backend/schema/components/proxy-host-object.json b/backend/schema/components/proxy-host-object.json index 3ac6462136..90e6e23bb2 100644 --- a/backend/schema/components/proxy-host-object.json +++ b/backend/schema/components/proxy-host-object.json @@ -124,6 +124,9 @@ }, "advanced_config": { "type": "string" + }, + "access_list_id": { + "$ref": "../common.json#/properties/access_list_id" } } }, @@ -132,7 +135,8 @@ "path": "/app", "forward_scheme": "http", "forward_host": "example.com", - "forward_port": 80 + "forward_port": 80, + "access_list_id": 0 } ] }, diff --git a/frontend/src/api/backend/getProxyHostLogs.ts b/frontend/src/api/backend/getProxyHostLogs.ts new file mode 100644 index 0000000000..91944c9d72 --- /dev/null +++ b/frontend/src/api/backend/getProxyHostLogs.ts @@ -0,0 +1,8 @@ +import * as api from "./base"; + +export async function getProxyHostLogs(id: number, type: "access" | "error" = "access"): Promise<{ logs: string }> { + return await api.get({ + url: `/nginx/proxy-hosts/${id}/logs`, + params: { type }, + }); +} diff --git a/frontend/src/api/backend/index.ts b/frontend/src/api/backend/index.ts index 40cb4142fc..6be435b6a8 100644 --- a/frontend/src/api/backend/index.ts +++ b/frontend/src/api/backend/index.ts @@ -27,6 +27,7 @@ export * from "./getDeadHosts"; export * from "./getHealth"; export * from "./getHostsReport"; export * from "./getProxyHost"; +export * from "./getProxyHostLogs"; export * from "./getProxyHosts"; export * from "./getRedirectionHost"; export * from "./getRedirectionHosts"; diff --git a/frontend/src/api/backend/models.ts b/frontend/src/api/backend/models.ts index 2ae0b08348..4818f77699 100644 --- a/frontend/src/api/backend/models.ts +++ b/frontend/src/api/backend/models.ts @@ -103,6 +103,8 @@ export interface ProxyLocation { forwardScheme: string; forwardHost: string; forwardPort: number; + accessListId?: number; + accessList?: AccessList; } export interface ProxyHost { diff --git a/frontend/src/components/Form/AccessField.tsx b/frontend/src/components/Form/AccessField.tsx index afcbd0cf7d..1c1004e711 100644 --- a/frontend/src/components/Form/AccessField.tsx +++ b/frontend/src/components/Form/AccessField.tsx @@ -31,14 +31,18 @@ interface Props { id?: string; name?: string; label?: string; + onFormChange?: (value: number) => void; } -export function AccessField({ name = "accessListId", label = "access-list", id = "accessListId" }: Props) { +export function AccessField({ name = "accessListId", label = "access-list", id = "accessListId", onFormChange }: Props) { const { locale } = useLocaleState(); const { isLoading, isError, error, data } = useAccessLists(["owner", "items", "clients"]); const { setFieldValue } = useFormikContext(); const handleChange = (newValue: any, _actionMeta: ActionMeta) => { setFieldValue(name, newValue?.value); + if (onFormChange) { + onFormChange(newValue?.value ?? 0); + } }; const options: AccessOption[] = diff --git a/frontend/src/components/Form/LocationsFields.tsx b/frontend/src/components/Form/LocationsFields.tsx index 4240b1f986..9422bd8933 100644 --- a/frontend/src/components/Form/LocationsFields.tsx +++ b/frontend/src/components/Form/LocationsFields.tsx @@ -5,6 +5,7 @@ import { useFormikContext } from "formik"; import { useState } from "react"; import type { ProxyLocation } from "src/api/backend"; import { intl, T } from "src/locale"; +import { AccessField } from "./AccessField"; import styles from "./LocationsFields.module.css"; interface Props { @@ -22,6 +23,7 @@ export function LocationsFields({ initialValues, name = "locations" }: Props) { forwardScheme: "http", forwardHost: "", forwardPort: 80, + accessListId: 0, }; const toggleAdvVisible = (idx: number) => { @@ -44,6 +46,12 @@ export function LocationsFields({ initialValues, name = "locations" }: Props) { setFormField(newValues); }; + const handleAccessListChange = (idx: number, accessListId: number) => { + const newValues = values.map((v: ProxyLocation, i: number) => (i === idx ? { ...v, accessListId } : v)); + setValues(newValues); + setFormField(newValues); + }; + const setFormField = (newValues: ProxyLocation[]) => { const filtered = newValues.filter((v: ProxyLocation) => v?.path?.trim() !== ""); setFieldValue(name, filtered); @@ -141,6 +149,12 @@ export function LocationsFields({ initialValues, name = "locations" }: Props) { + handleAccessListChange(idx, value)} + /> {advVisible.includes(idx) && (
{ + return useQuery<{ logs: string }, Error>({ + queryKey: ["proxy-host-logs", id, type], + queryFn: () => getProxyHostLogs(id, type), + staleTime: 10_000, + }); +}; + +export { useProxyHostLogs }; diff --git a/frontend/src/locale/src/en.json b/frontend/src/locale/src/en.json index bb00ac3322..b5043fc83a 100644 --- a/frontend/src/locale/src/en.json +++ b/frontend/src/locale/src/en.json @@ -122,6 +122,9 @@ "action.enable": { "defaultMessage": "Enable" }, + "action.logs": { + "defaultMessage": "Logs" + }, "action.permissions": { "defaultMessage": "Permissions" }, @@ -248,6 +251,9 @@ "column.access": { "defaultMessage": "Access" }, + "column.error": { + "defaultMessage": "Error" + }, "column.authorization": { "defaultMessage": "Authorization" }, diff --git a/frontend/src/modals/HostLogsModal.tsx b/frontend/src/modals/HostLogsModal.tsx new file mode 100644 index 0000000000..a0df04ee71 --- /dev/null +++ b/frontend/src/modals/HostLogsModal.tsx @@ -0,0 +1,93 @@ +import CodeEditor from "@uiw/react-textarea-code-editor"; +import EasyModal, { type InnerModalProps } from "ez-modal-react"; +import { useState } from "react"; +import { Alert } from "react-bootstrap"; +import Modal from "react-bootstrap/Modal"; +import { Button, Loading } from "src/components"; +import { useProxyHostLogs } from "src/hooks"; +import { T } from "src/locale"; + +const showHostLogsModal = (id: number) => { + EasyModal.show(HostLogsModal, { id }); +}; + +interface Props extends InnerModalProps { + id: number; +} +const HostLogsModal = EasyModal.create(({ id, visible, remove }: Props) => { + const [logType, setLogType] = useState<"access" | "error">("access"); + const { data, isLoading, error } = useProxyHostLogs(id, logType); + + return ( + + {!isLoading && error && ( + + {error?.message || "Unknown error"} + + )} + + + + + + + + {isLoading ? ( + + ) : ( +
+ +
+ )} +
+ + + +
+ ); +}); + +export { showHostLogsModal }; diff --git a/frontend/src/modals/index.ts b/frontend/src/modals/index.ts index a06a0c0d71..902d0d73d0 100644 --- a/frontend/src/modals/index.ts +++ b/frontend/src/modals/index.ts @@ -6,6 +6,7 @@ export * from "./DeleteConfirmModal"; export * from "./DNSCertificateModal"; export * from "./EventDetailsModal"; export * from "./HelpModal"; +export * from "./HostLogsModal"; export * from "./HTTPCertificateModal"; export * from "./PermissionsModal"; export * from "./ProxyHostModal"; diff --git a/frontend/src/pages/Nginx/ProxyHosts/Table.tsx b/frontend/src/pages/Nginx/ProxyHosts/Table.tsx index 5af58081ad..ad6714b79d 100644 --- a/frontend/src/pages/Nginx/ProxyHosts/Table.tsx +++ b/frontend/src/pages/Nginx/ProxyHosts/Table.tsx @@ -1,4 +1,4 @@ -import { IconDotsVertical, IconEdit, IconPower, IconTrash } from "@tabler/icons-react"; +import { IconDotsVertical, IconEdit, IconFileText, IconPower, IconTrash } from "@tabler/icons-react"; import { createColumnHelper, getCoreRowModel, @@ -28,9 +28,10 @@ interface Props { onEdit?: (id: number) => void; onDelete?: (id: number) => void; onDisableToggle?: (id: number, enabled: boolean) => void; + onLogs?: (id: number) => void; onNew?: () => void; } -export default function Table({ data, isFetching, onEdit, onDelete, onDisableToggle, onNew, isFiltered }: Props) { +export default function Table({ data, isFetching, onEdit, onDelete, onDisableToggle, onLogs, onNew, isFiltered }: Props) { const columnHelper = createColumnHelper(); const columns = useMemo( () => [ @@ -115,19 +116,30 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog data={{ id: info.row.original.id }} /> + { + e.preventDefault(); + onEdit?.(info.row.original.id); + }} + > + + + + { e.preventDefault(); - onEdit?.(info.row.original.id); + onLogs?.(info.row.original.id); }} > - - + + - - { @@ -160,7 +172,7 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog }, }), ], - [columnHelper, onEdit, onDisableToggle, onDelete], + [columnHelper, onEdit, onDisableToggle, onDelete, onLogs], ); const [sorting, setSorting] = useState([]); diff --git a/frontend/src/pages/Nginx/ProxyHosts/TableWrapper.tsx b/frontend/src/pages/Nginx/ProxyHosts/TableWrapper.tsx index 5d6602e2db..7845fb029b 100644 --- a/frontend/src/pages/Nginx/ProxyHosts/TableWrapper.tsx +++ b/frontend/src/pages/Nginx/ProxyHosts/TableWrapper.tsx @@ -6,7 +6,7 @@ import { deleteProxyHost, toggleProxyHost } from "src/api/backend"; import { Button, HasPermission, LoadingPage } from "src/components"; import { useProxyHosts } from "src/hooks"; import { T } from "src/locale"; -import { showDeleteConfirmModal, showHelpModal, showProxyHostModal } from "src/modals"; +import { showDeleteConfirmModal, showHelpModal, showHostLogsModal, showProxyHostModal } from "src/modals"; import { MANAGE, PROXY_HOSTS } from "src/modules/Permissions"; import { showObjectSuccess } from "src/notifications"; import Table from "./Table"; @@ -99,6 +99,7 @@ export default function TableWrapper() { isFiltered={!!search} isFetching={isFetching} onEdit={(id: number) => showProxyHostModal(id)} + onLogs={(id: number) => showHostLogsModal(id)} onDelete={(id: number) => { const host = data?.find((h) => h.id === id); showDeleteConfirmModal({ From 35ad8227d765541ac72a3099fb265acd830b4d6e Mon Sep 17 00:00:00 2001 From: "Dimas R. Wisnu" Date: Fri, 7 Aug 2026 17:01:20 +0700 Subject: [PATCH 21/77] fix: resolve biome lint errors - Use optional chaining for nullable checks - Replace template literals with string literals for plain SQL - Add node: protocol to fs/promises import in setup.js --- backend/internal/access-list.js | 18 +++++++++--------- backend/internal/proxy-host.js | 2 +- backend/setup.js | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/backend/internal/access-list.js b/backend/internal/access-list.js index 413ac067af..f8c4547944 100644 --- a/backend/internal/access-list.js +++ b/backend/internal/access-list.js @@ -28,17 +28,17 @@ const getProxyHostsUsingAccessListInLocations = async (accessListId) => { if (isMysql()) { const searchObj = JSON.stringify([{ access_list_id: accessListId }]); result = await db().raw( - `SELECT id FROM proxy_host WHERE is_deleted = 0 AND JSON_CONTAINS(locations, ?, ?)`, + "SELECT id FROM proxy_host WHERE is_deleted = 0 AND JSON_CONTAINS(locations, ?, ?)", [searchObj, "$"], ); } else if (isPostgres()) { result = await db().raw( - `SELECT id FROM proxy_host WHERE is_deleted = 0 AND locations::jsonb @> ?::jsonb`, + "SELECT id FROM proxy_host WHERE is_deleted = 0 AND locations::jsonb @> ?::jsonb", [JSON.stringify([{ access_list_id: accessListId }])], ); } else { result = await db().raw( - `SELECT id FROM proxy_host WHERE is_deleted = 0 AND locations LIKE ?`, + "SELECT id FROM proxy_host WHERE is_deleted = 0 AND locations LIKE ?", [`%"access_list_id":${accessListId}%`], ); } @@ -222,10 +222,10 @@ const internalAccessList = { // Also regenerate configs for proxy hosts that reference this access list in their locations const locationHostRows = await getProxyHostsUsingAccessListInLocations(data.id); - if (locationHostRows && locationHostRows.length) { + if (locationHostRows?.length) { const locationHostIds = locationHostRows.map((r) => r.id).filter((id) => { // Exclude hosts already regenerated above - return !freshRow.proxy_hosts || !freshRow.proxy_hosts.find((h) => h.id === id); + return !freshRow.proxy_hosts?.find((h) => h.id === id); }); if (locationHostIds.length) { const locationHosts = await proxyHostModel.query() @@ -235,7 +235,7 @@ const internalAccessList = { .withGraphFetched("[owner, certificate, access_list.[clients,items]]"); for (const host of locationHosts) { // Fetch access lists for locations - if (host.locations && host.locations.length) { + if (host.locations?.length) { for (let i = 0; i < host.locations.length; i++) { const loc = host.locations[i]; if (loc.access_list_id && loc.access_list_id > 0) { @@ -363,15 +363,15 @@ const internalAccessList = { // Also handle proxy hosts that reference this access list in their locations JSON const locationHostRows = await getProxyHostsUsingAccessListInLocations(row.id); - if (locationHostRows && locationHostRows.length) { + if (locationHostRows?.length) { const locationHostIds = locationHostRows.map((r) => r.id).filter((id) => { - return !row.proxy_hosts || !row.proxy_hosts.find((h) => h.id === id); + return !row.proxy_hosts?.find((h) => h.id === id); }); if (locationHostIds.length) { // Clear the access_list_id in locations JSON for these hosts for (const hostId of locationHostIds) { const host = await proxyHostModel.query().where("id", hostId).first(); - if (host && host.locations) { + if (host?.locations) { const updatedLocations = host.locations.map((loc) => { if (loc.access_list_id === row.id) { return { ...loc, access_list_id: 0 }; diff --git a/backend/internal/proxy-host.js b/backend/internal/proxy-host.js index 96cfab480e..6bd0be1a66 100644 --- a/backend/internal/proxy-host.js +++ b/backend/internal/proxy-host.js @@ -21,7 +21,7 @@ const omissions = () => { * @returns {Promise} */ const fetchLocationAccessLists = async (host) => { - if (!host.locations || !host.locations.length) { + if (!host.locations?.length) { return; } for (let i = 0; i < host.locations.length; i++) { diff --git a/backend/setup.js b/backend/setup.js index c0418e170b..362cbdfe43 100644 --- a/backend/setup.js +++ b/backend/setup.js @@ -6,7 +6,7 @@ import certificateModel from "./models/certificate.js"; import settingModel from "./models/setting.js"; import userModel from "./models/user.js"; import userPermissionModel from "./models/user_permission.js"; -import fs from "fs/promises"; +import fs from "node:fs/promises"; export const isSetup = async () => { const row = await userModel.query().select("id").where("is_deleted", 0).first(); From f43ef16fb543a99a27af1d873484fae862a6fcc7 Mon Sep 17 00:00:00 2001 From: zergflag Date: Sun, 9 Aug 2026 14:59:39 +0200 Subject: [PATCH 22/77] Update dns-plugins.json --- backend/certbot/dns-plugins.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/backend/certbot/dns-plugins.json b/backend/certbot/dns-plugins.json index 220819404e..b0f4469ff8 100644 --- a/backend/certbot/dns-plugins.json +++ b/backend/certbot/dns-plugins.json @@ -686,5 +686,13 @@ "name": "RcodeZero", "package_name": "certbot-dns-rcode0", "version": "~=0.0.0.2" + }, + "lws": { + "credentials": "dns_lws_login = 123456\ndns_lws_api_key = YOUR_API_KEY", + "dependencies": "", + "full_plugin_name": "dns-lws", + "name": "LWS", + "package_name": "certbot-dns-lws", + "version": "~=1.0.0" } } From 70f00d60bec4e03e869eb6c9d2bc8b0f024e8953 Mon Sep 17 00:00:00 2001 From: Leon Schmidt Date: Tue, 18 Aug 2026 10:19:06 +0200 Subject: [PATCH 23/77] Add German translations for two-factor authentication and various UI elements --- frontend/src/locale/src/de.json | 124 +++++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 2 deletions(-) diff --git a/frontend/src/locale/src/de.json b/frontend/src/locale/src/de.json index f654e10858..6cdb64cf39 100644 --- a/frontend/src/locale/src/de.json +++ b/frontend/src/locale/src/de.json @@ -1,4 +1,61 @@ { + "2fa.backup-codes-remaining": { + "defaultMessage": "Verbleibende Backup-Codes: {count}" + }, + "2fa.backup-warning": { + "defaultMessage": "Bewahre diese Backup-Codes an einem sicheren Ort auf. Jeder Code kann nur einmal verwendet werden." + }, + "2fa.disable": { + "defaultMessage": "Zwei-Faktor-Authentifizierung deaktivieren" + }, + "2fa.disable-confirm": { + "defaultMessage": "2FA deaktivieren" + }, + "2fa.disable-warning": { + "defaultMessage": "Das Deaktivieren der Zwei-Faktor-Authentifizierung macht dein Konto weniger sicher." + }, + "2fa.disabled": { + "defaultMessage": "Deaktiviert" + }, + "2fa.done": { + "defaultMessage": "Ich habe meine Backup-Codes gespeichert" + }, + "2fa.enable": { + "defaultMessage": "Zwei-Faktor-Authentifizierung aktivieren" + }, + "2fa.enabled": { + "defaultMessage": "Aktiviert" + }, + "2fa.enter-code": { + "defaultMessage": "Verifizierungscode eingeben" + }, + "2fa.enter-code-disable": { + "defaultMessage": "Verifizierungscode zum Deaktivieren eingeben" + }, + "2fa.regenerate": { + "defaultMessage": "Neu generieren" + }, + "2fa.regenerate-backup": { + "defaultMessage": "Backup-Codes neu generieren" + }, + "2fa.regenerate-instructions": { + "defaultMessage": "Gib einen Verifizierungscode ein, um neue Backup-Codes zu generieren. Deine alten Codes werden dadurch ungültig." + }, + "2fa.secret-key": { + "defaultMessage": "Geheimer Schlüssel" + }, + "2fa.setup-instructions": { + "defaultMessage": "Scanne diesen QR-Code mit deiner Authenticator-App oder gib den geheimen Schlüssel manuell ein." + }, + "2fa.status": { + "defaultMessage": "Status" + }, + "2fa.title": { + "defaultMessage": "Zwei-Faktor-Authentifizierung" + }, + "2fa.verify-enable": { + "defaultMessage": "Verifizieren und aktivieren" + }, "access-list": { "defaultMessage": "Zugriffsliste" }, @@ -23,6 +80,9 @@ "access-list.public.subtitle": { "defaultMessage": "Keine Authentifizierung erforderlich" }, + "access-list.rule-source.placeholder": { + "defaultMessage": "192.168.1.100 oder 192.168.1.0/24 oder 2001:0db8::/32" + }, "access-list.satisfy-any": { "defaultMessage": "Satisfy Any" }, @@ -38,12 +98,18 @@ "action.add-location": { "defaultMessage": "Pfad hinzufügen" }, + "action.allow": { + "defaultMessage": "Erlauben" + }, "action.close": { "defaultMessage": "Schließen" }, "action.delete": { "defaultMessage": "Löschen" }, + "action.deny": { + "defaultMessage": "Verweigern" + }, "action.disable": { "defaultMessage": "Deaktivieren" }, @@ -68,6 +134,9 @@ "auditlogs": { "defaultMessage": "Protokolle" }, + "auto": { + "defaultMessage": "Automatisch" + }, "cancel": { "defaultMessage": "Abbrechen" }, @@ -128,6 +197,9 @@ "certificates.dns.provider": { "defaultMessage": "DNS Provider" }, + "certificates.dns.provider.placeholder": { + "defaultMessage": "Anbieter auswählen..." + }, "certificates.dns.warning": { "defaultMessage": "Dieser Abschnitt erfordert einige Kenntnisse über Certbot und seine DNS-Plugins. Bitte konsultieren Sie die jeweilige Plugin-Dokumentation." }, @@ -275,6 +347,9 @@ "domain-names.wildcards-not-supported": { "defaultMessage": "Wildcards werden für diese Zertifizierungsstelle nicht unterstützt." }, + "domains.advanced": { + "defaultMessage": "Erweitert" + }, "domains.force-ssl": { "defaultMessage": "Erzwinge SSL" }, @@ -287,6 +362,9 @@ "domains.http2-support": { "defaultMessage": "HTTP/2 Support" }, + "domains.trust-forwarded-proto": { + "defaultMessage": "Upstream Forwarded-Proto-Header vertrauen" + }, "domains.use-dns": { "defaultMessage": "Nutze DNS Challenge" }, @@ -354,7 +432,7 @@ "defaultMessage": "Pfad beibehalten" }, "host.flags.protocols": { - "defaultMessage": "Protokole" + "defaultMessage": "Protokolle" }, "host.flags.websockets-upgrade": { "defaultMessage": "Websockets Support" @@ -383,6 +461,21 @@ "loading": { "defaultMessage": "Laden…" }, + "login.2fa-code": { + "defaultMessage": "Verifizierungscode" + }, + "login.2fa-code-placeholder": { + "defaultMessage": "Code eingeben" + }, + "login.2fa-description": { + "defaultMessage": "Gib den Code aus deiner Authenticator-App ein" + }, + "login.2fa-title": { + "defaultMessage": "Zwei-Faktor-Authentifizierung" + }, + "login.2fa-verify": { + "defaultMessage": "Verifizieren" + }, "login.title": { "defaultMessage": "Anmelden" }, @@ -530,6 +623,24 @@ "redirection-hosts.count": { "defaultMessage": "{count} {count, plural, one {Redirection Host} other {Redirection Hosts}}" }, + "redirection-hosts.http-code.300": { + "defaultMessage": "300 Mehrere Auswahlmöglichkeiten" + }, + "redirection-hosts.http-code.301": { + "defaultMessage": "301 Dauerhaft verschoben" + }, + "redirection-hosts.http-code.302": { + "defaultMessage": "302 Vorübergehend verschoben" + }, + "redirection-hosts.http-code.303": { + "defaultMessage": "303 Siehe andere" + }, + "redirection-hosts.http-code.307": { + "defaultMessage": "307 Temporäre Umleitung" + }, + "redirection-hosts.http-code.308": { + "defaultMessage": "308 Permanente Umleitung" + }, "role.admin": { "defaultMessage": "Administrator" }, @@ -587,6 +698,9 @@ "stream.forward-host": { "defaultMessage": "Forward Host" }, + "stream.forward-host.placeholder": { + "defaultMessage": "example.com oder 10.0.0.1 oder 2001:db8:3333:4444:5555:6666:7777:8888" + }, "stream.incoming-port": { "defaultMessage": "Incoming Port" }, @@ -605,6 +719,9 @@ "test": { "defaultMessage": "Test" }, + "update-available": { + "defaultMessage": "Update verfügbar: {latestVersion}" + }, "user": { "defaultMessage": "User" }, @@ -647,10 +764,13 @@ "user.switch-light": { "defaultMessage": "Zum Light Mode wechseln" }, + "user.two-factor": { + "defaultMessage": "Zwei-Faktor-Auth" + }, "username": { "defaultMessage": "Benutzername" }, "users": { "defaultMessage": "Benutzer" } -} +} \ No newline at end of file From d64d9a8ab2e94f56268e02fdf4e6bf0abc6e372a Mon Sep 17 00:00:00 2001 From: Daniel Slavkovsky Date: Tue, 18 Aug 2026 11:13:20 +0200 Subject: [PATCH 24/77] fix(certbot): update Websupport DNS plugin to 5.0.0 --- backend/certbot/dns-plugins.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/certbot/dns-plugins.json b/backend/certbot/dns-plugins.json index 220819404e..346288636a 100644 --- a/backend/certbot/dns-plugins.json +++ b/backend/certbot/dns-plugins.json @@ -661,7 +661,7 @@ "full_plugin_name": "dns-websupport", "name": "Websupport.sk", "package_name": "certbot-dns-websupport", - "version": "~=2.0.1" + "version": "~=5.0.0" }, "wedos": { "credentials": "dns_wedos_user = \ndns_wedos_auth = ", From fc8b1eb1fb7076a3a98927ad3b020ac9849cd464 Mon Sep 17 00:00:00 2001 From: Daniel Jacob Butcher Date: Thu, 20 Aug 2026 00:04:47 +0300 Subject: [PATCH 25/77] Fixed Estonian flag bug The Estonian flag was appearing as an Ethiopian flag, due to a mixup of ISO 639 language codes and ISO 3166 country codes --- frontend/src/locale/IntlProvider.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/locale/IntlProvider.tsx b/frontend/src/locale/IntlProvider.tsx index a5fb956c0d..0c8580d84d 100755 --- a/frontend/src/locale/IntlProvider.tsx +++ b/frontend/src/locale/IntlProvider.tsx @@ -73,6 +73,7 @@ const getFlagCodeForLocale = (locale?: string) => { ko: "kr", // Korea cs: "cz", // Czechia ga: "ie", // Ireland (Irish) + et: "ee", // Estonia }; if (specialCases[thisLocale]) { From 4cbeecaad29e3265c996107d0bb718f6d8d37937 Mon Sep 17 00:00:00 2001 From: Silas Date: Sat, 22 Aug 2026 16:19:50 +0800 Subject: [PATCH 26/77] fix: bump certbot-dns-tencentcloud to 2.1.1 --- backend/certbot/dns-plugins.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/certbot/dns-plugins.json b/backend/certbot/dns-plugins.json index 220819404e..03545f7bc1 100644 --- a/backend/certbot/dns-plugins.json +++ b/backend/certbot/dns-plugins.json @@ -629,7 +629,7 @@ "full_plugin_name": "dns-tencentcloud", "name": "Tencent Cloud", "package_name": "certbot-dns-tencentcloud", - "version": "~=2.0.2" + "version": "~=2.1.1" }, "timeweb": { "credentials": "dns_timeweb_api_key = XXXXXXXXXXXXXXXXXXX", From ce4e35a3d469548921978a55c26a180e5685b1b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9=20Stoifl?= Date: Sat, 22 Aug 2026 13:07:09 +0200 Subject: [PATCH 27/77] Fix missing `new` on PermissionError in access.can() The catch block in `access.can()` constructed `errs.PermissionError` without `new`. The error constructors in `backend/lib/error.js` are plain constructor functions that assign to `this` and return nothing, so calling one without `new` evaluates to `undefined`. The statement therefore did `throw undefined`, the express error handler in `backend/app.js` received undefined (and could not read `.status` or `.public` off it), and the request fell through to the catch-all 404 handler in `backend/routes/main.js`. Net effect: every authorization failure raised by `access.can(...)` was reported to clients as `404 Not Found` instead of `403 Forbidden`. Line 45 of the same file already used `new` correctly, which shows this was an oversight rather than deliberate resource-existence hiding. A grep over `backend/` confirms this was the only error constructor invoked without `new`. --- backend/lib/access.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/lib/access.js b/backend/lib/access.js index a4dec5c4dd..1ecaf250c2 100644 --- a/backend/lib/access.js +++ b/backend/lib/access.js @@ -271,7 +271,7 @@ export default function (tokenString) { err.permission = permission; err.permission_data = data; logger.error(permission, data, err.message); - throw errs.PermissionError("Permission Denied", err); + throw new errs.PermissionError("Permission Denied", err); } }, }; From 4e2b052b502520e14a1ebb4086df38165257269d Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Sat, 22 Aug 2026 23:10:26 +1000 Subject: [PATCH 28/77] Updated backend packages --- backend/biome.json | 161 ++-- backend/db.js | 8 +- backend/internal/2fa.js | 18 +- backend/internal/access-list.js | 55 +- backend/internal/audit-log.js | 7 +- backend/internal/dead-host.js | 54 +- backend/internal/nginx.js | 5 +- backend/internal/token.js | 18 +- backend/internal/user.js | 8 +- backend/knexfile.js | 22 +- backend/lib/access.js | 5 +- backend/lib/config.js | 52 +- backend/lib/express/pagination.js | 2 +- backend/lib/express/user-id-from-me.js | 4 +- backend/lib/validator/api.js | 6 +- backend/lib/validator/index.js | 2 +- backend/migrations/20190227065017_settings.js | 15 +- .../20251111090000_redirect_auto_scheme.js | 8 +- .../20260131163528_trust_forwarded_proto.js | 34 +- backend/models/setting.js | 16 +- backend/models/user_permission.js | 14 +- backend/package.json | 20 +- backend/routes/audit-log.js | 5 +- backend/routes/nginx/certificates.js | 36 +- backend/routes/users.js | 51 +- backend/setup.js | 67 +- backend/yarn.lock | 741 ++++++++++-------- 27 files changed, 684 insertions(+), 750 deletions(-) diff --git a/backend/biome.json b/backend/biome.json index a0164fd99c..5d1794b5a9 100644 --- a/backend/biome.json +++ b/backend/biome.json @@ -1,91 +1,74 @@ { - "$schema": "https://biomejs.dev/schemas/2.4.15/schema.json", - "vcs": { - "enabled": true, - "clientKind": "git", - "useIgnoreFile": true - }, - "files": { - "ignoreUnknown": false, - "includes": [ - "**/*.ts", - "**/*.tsx", - "**/*.js", - "**/*.jsx", - "!**/dist/**/*" - ] - }, - "formatter": { - "enabled": true, - "indentStyle": "tab", - "indentWidth": 4, - "lineWidth": 120, - "formatWithErrors": true - }, - "assist": { - "actions": { - "source": { - "organizeImports": { - "level": "on", - "options": { - "groups": [ - ":BUN:", - ":NODE:", - [ - "npm:*", - "npm:*/**" - ], - ":PACKAGE_WITH_PROTOCOL:", - ":URL:", - ":PACKAGE:", - [ - "/src/*", - "/src/**" - ], - [ - "/**" - ], - [ - "#*", - "#*/**" - ], - ":PATH:" - ] - } - } - } - } - }, - "linter": { - "enabled": true, - "rules": { - "recommended": true, - "correctness": { - "useUniqueElementIds": "off" - }, - "suspicious": { - "noExplicitAny": "off" - }, - "performance": { - "noDelete": "off" - }, - "nursery": "off", - "a11y": { - "useSemanticElements": "off", - "useValidAnchor": "off" - }, - "style": { - "noParameterAssign": "error", - "useAsConstAssertion": "error", - "useDefaultParameterLast": "error", - "useEnumInitializers": "error", - "useSelfClosingElements": "error", - "useSingleVarDeclarator": "error", - "noUnusedTemplateLiteral": "error", - "useNumberNamespace": "error", - "noInferrableTypes": "error", - "noUselessElse": "error" - } - } - } + "$schema": "https://biomejs.dev/schemas/2.5.10/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "ignoreUnknown": false, + "includes": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "!**/dist/**/*"] + }, + "formatter": { + "enabled": true, + "indentStyle": "tab", + "indentWidth": 4, + "lineWidth": 120, + "formatWithErrors": true + }, + "assist": { + "actions": { + "source": { + "organizeImports": { + "level": "on", + "options": { + "groups": [ + ":BUN:", + ":NODE:", + ["npm:*", "npm:*/**"], + ":PACKAGE_WITH_PROTOCOL:", + ":URL:", + ":PACKAGE:", + ["/src/*", "/src/**"], + ["/**"], + ["#*", "#*/**"], + ":PATH:" + ] + } + } + } + } + }, + "linter": { + "enabled": true, + "rules": { + "preset": "recommended", + "correctness": { + "useUniqueElementIds": "off" + }, + "suspicious": { + "noExplicitAny": "off" + }, + "performance": { + "noDelete": "off" + }, + "nursery": "off", + "a11y": { + "useSemanticElements": "off", + "useValidAnchor": "off" + }, + "style": { + "noParameterAssign": "error", + "useAsConstAssertion": "error", + "useDefaultParameterLast": "error", + "useEnumInitializers": "error", + "useSelfClosingElements": "error", + "useSingleVarDeclarator": "error", + "noUnusedTemplateLiteral": "error", + "useNumberNamespace": "error", + "noInferrableTypes": "error", + "noUselessElse": "error" + } + } + } } diff --git a/backend/db.js b/backend/db.js index bf540f8a22..5b18d3a9a4 100644 --- a/backend/db.js +++ b/backend/db.js @@ -1,5 +1,5 @@ import knex from "knex"; -import {configGet, configHas} from "./lib/config.js"; +import { configGet, configHas } from "./lib/config.js"; let instance = null; @@ -23,8 +23,8 @@ const generateDbConfig = () => { user: cfg.user, password: cfg.password, database: cfg.name, - port: cfg.port, - ...(cfg.ssl ? { ssl: cfg.ssl } : {}) + port: cfg.port, + ...(cfg.ssl ? { ssl: cfg.ssl } : {}), }, migrations: { tableName: "migrations", @@ -37,6 +37,6 @@ const getInstance = () => { instance = knex(generateDbConfig()); } return instance; -} +}; export default getInstance; diff --git a/backend/internal/2fa.js b/backend/internal/2fa.js index 43307e02c3..db1c3385ea 100644 --- a/backend/internal/2fa.js +++ b/backend/internal/2fa.js @@ -161,12 +161,12 @@ const internal2fa = { } const result = await verify({ - token: code, - secret: auth.meta.totp_secret, - guardrails: createGuardrails({ - MIN_SECRET_BYTES: 10, - }), - }); + token: code, + secret: auth.meta.totp_secret, + guardrails: createGuardrails({ + MIN_SECRET_BYTES: 10, + }), + }); if (!result.valid) { throw new errs.AuthError("Invalid verification code"); @@ -288,11 +288,7 @@ const internal2fa = { }, getUserPasswordAuth: async (userId) => { - const auth = await authModel - .query() - .where("user_id", userId) - .andWhere("type", "password") - .first(); + const auth = await authModel.query().where("user_id", userId).andWhere("type", "password").first(); if (!auth) { throw new errs.ItemNotFoundError("Auth not found"); diff --git a/backend/internal/access-list.js b/backend/internal/access-list.js index 88bf9df523..fc9e8dbab1 100644 --- a/backend/internal/access-list.js +++ b/backend/internal/access-list.js @@ -66,7 +66,7 @@ const internalAccessList = { id: data.id, expand: ["owner", "items", "clients", "proxy_hosts.access_list.[clients,items]"], }, - true // skip masking + true, // skip masking ); // Audit log @@ -180,10 +180,10 @@ const internalAccessList = { id: data.id, expand: ["owner", "items", "clients", "proxy_hosts.[certificate,access_list.[clients,items]]"], }, - true // skip masking + true, // skip masking ); - await internalAccessList.build(freshRow) + await internalAccessList.build(freshRow); if (Number.parseInt(freshRow.proxy_host_count, 10)) { await internalNginx.bulkGenerateConfigs("proxy_host", freshRow.proxy_hosts); } @@ -202,17 +202,13 @@ const internalAccessList = { */ get: async (access, data, skipMasking) => { const thisData = data || {}; - const accessData = await access.can("access_lists:get", thisData.id) + const accessData = await access.can("access_lists:get", thisData.id); const query = accessListModel .query() .select("access_list.*", accessListModel.raw("COUNT(proxy_host.id) as proxy_host_count")) .leftJoin("proxy_host", function () { - this.on("proxy_host.access_list_id", "=", "access_list.id").andOn( - "proxy_host.is_deleted", - "=", - 0, - ); + this.on("proxy_host.access_list_id", "=", "access_list.id").andOn("proxy_host.is_deleted", "=", 0); }) .where("access_list.is_deleted", 0) .andWhere("access_list.id", thisData.id) @@ -267,19 +263,13 @@ const internalAccessList = { // 4. audit log // 1. update row to be deleted - await accessListModel - .query() - .where("id", row.id) - .patch({ - is_deleted: 1, - }); + await accessListModel.query().where("id", row.id).patch({ + is_deleted: 1, + }); // 2. update any proxy hosts that were using it (ignoring permissions) if (row.proxy_hosts) { - await proxyHostModel - .query() - .where("access_list_id", "=", row.id) - .patch({ access_list_id: 0 }); + await proxyHostModel.query().where("access_list_id", "=", row.id).patch({ access_list_id: 0 }); // 3. reconfigure those hosts, then reload nginx // set the access_list_id to zero for these items @@ -325,11 +315,7 @@ const internalAccessList = { .query() .select("access_list.*", accessListModel.raw("COUNT(proxy_host.id) as proxy_host_count")) .leftJoin("proxy_host", function () { - this.on("proxy_host.access_list_id", "=", "access_list.id").andOn( - "proxy_host.is_deleted", - "=", - 0, - ); + this.on("proxy_host.access_list_id", "=", "access_list.id").andOn("proxy_host.is_deleted", "=", 0); }) .where("access_list.is_deleted", 0) .groupBy("access_list.id") @@ -371,10 +357,7 @@ const internalAccessList = { * @returns {Promise} */ getCount: async (userId, visibility) => { - const query = accessListModel - .query() - .count("id as count") - .where("is_deleted", 0); + const query = accessListModel.query().count("id as count").where("is_deleted", 0); if (visibility !== "all") { query.andWhere("owner_user_id", userId); @@ -436,20 +419,24 @@ const internalAccessList = { } // 2. create empty access file - fs.writeFileSync(htpasswdFile, '', {encoding: 'utf8'}); + fs.writeFileSync(htpasswdFile, "", { encoding: "utf8" }); // 3. generate password for each user if (list.items.length) { await new Promise((resolve, reject) => { - batchflow(list.items).sequential() + batchflow(list.items) + .sequential() .each((_i, item, next) => { if (item.password?.length) { logger.info(`Adding: ${item.username}`); - utils.execFile('openssl', ['passwd', '-apr1', item.password]) + utils + .execFile("openssl", ["passwd", "-apr1", item.password]) .then((res) => { try { - fs.appendFileSync(htpasswdFile, `${item.username}:${res}\n`, {encoding: 'utf8'}); + fs.appendFileSync(htpasswdFile, `${item.username}:${res}\n`, { + encoding: "utf8", + }); } catch (err) { reject(err); } @@ -471,7 +458,7 @@ const internalAccessList = { }); }); } - } -} + }, +}; export default internalAccessList; diff --git a/backend/internal/audit-log.js b/backend/internal/audit-log.js index 02700dc5da..5155028c87 100644 --- a/backend/internal/audit-log.js +++ b/backend/internal/audit-log.js @@ -3,7 +3,6 @@ import { castJsonIfNeed } from "../lib/helpers.js"; import auditLogModel from "../models/audit-log.js"; const internalAuditLog = { - /** * All logs * @@ -46,11 +45,7 @@ const internalAuditLog = { get: async (access, data) => { await access.can("auditlog:list"); - const query = auditLogModel - .query() - .andWhere("id", data.id) - .allowGraph("[user]") - .first(); + const query = auditLogModel.query().andWhere("id", data.id).allowGraph("[user]").first(); if (typeof data.expand !== "undefined" && data.expand !== null) { query.withGraphFetched(`[${data.expand.join(", ")}]`); diff --git a/backend/internal/dead-host.js b/backend/internal/dead-host.js index ee27e53cc5..1afb6c6714 100644 --- a/backend/internal/dead-host.js +++ b/backend/internal/dead-host.js @@ -54,9 +54,7 @@ const internalDeadHost = { thisData.advanced_config = ""; } - const row = await deadHostModel.query() - .insertAndFetch(thisData) - .then(utils.omitRow(omissions())); + const row = await deadHostModel.query().insertAndFetch(thisData).then(utils.omitRow(omissions())); // Add to audit log await internalAuditLog.add(access, { @@ -153,12 +151,8 @@ const internalDeadHost = { thisData = internalHost.cleanSslHstsData(thisData, row); - // do the row update - await deadHostModel - .query() - .where({id: data.id}) - .patch(data); + await deadHostModel.query().where({ id: data.id }).patch(data); // Add to audit log await internalAuditLog.add(access, { @@ -168,11 +162,10 @@ const internalDeadHost = { meta: thisData, }); - const thisRow = await internalDeadHost - .get(access, { - id: thisData.id, - expand: ["owner", "certificate"], - }); + const thisRow = await internalDeadHost.get(access, { + id: thisData.id, + expand: ["owner", "certificate"], + }); // Configure nginx const newMeta = await internalNginx.configure(deadHostModel, "dead_host", row); @@ -224,18 +217,15 @@ const internalDeadHost = { * @returns {Promise} */ delete: async (access, data) => { - await access.can("dead_hosts:delete", data.id) + await access.can("dead_hosts:delete", data.id); const row = await internalDeadHost.get(access, { id: data.id }); if (!row?.id) { throw new errs.ItemNotFoundError(data.id); } - await deadHostModel - .query() - .where("id", row.id) - .patch({ - is_deleted: 1, - }); + await deadHostModel.query().where("id", row.id).patch({ + is_deleted: 1, + }); // Delete Nginx Config await internalNginx.deleteConfig("dead_host", row); @@ -259,7 +249,7 @@ const internalDeadHost = { * @returns {Promise} */ enable: async (access, data) => { - await access.can("dead_hosts:update", data.id) + await access.can("dead_hosts:update", data.id); const row = await internalDeadHost.get(access, { id: data.id, expand: ["certificate", "owner"], @@ -273,12 +263,9 @@ const internalDeadHost = { row.enabled = 1; - await deadHostModel - .query() - .where("id", row.id) - .patch({ - enabled: 1, - }); + await deadHostModel.query().where("id", row.id).patch({ + enabled: 1, + }); // Configure nginx await internalNginx.configure(deadHostModel, "dead_host", row); @@ -301,7 +288,7 @@ const internalDeadHost = { * @returns {Promise} */ disable: async (access, data) => { - await access.can("dead_hosts:update", data.id) + await access.can("dead_hosts:update", data.id); const row = await internalDeadHost.get(access, { id: data.id }); if (!row?.id) { throw new errs.ItemNotFoundError(data.id); @@ -312,12 +299,9 @@ const internalDeadHost = { row.enabled = 0; - await deadHostModel - .query() - .where("id", row.id) - .patch({ - enabled: 0, - }); + await deadHostModel.query().where("id", row.id).patch({ + enabled: 0, + }); // Delete Nginx Config await internalNginx.deleteConfig("dead_host", row); @@ -342,7 +326,7 @@ const internalDeadHost = { * @returns {Promise} */ getAll: async (access, expand, searchQuery) => { - const accessData = await access.can("dead_hosts:list") + const accessData = await access.can("dead_hosts:list"); const query = deadHostModel .query() .where("is_deleted", 0) diff --git a/backend/internal/nginx.js b/backend/internal/nginx.js index fe84607f96..80cb0c2904 100644 --- a/backend/internal/nginx.js +++ b/backend/internal/nginx.js @@ -217,7 +217,10 @@ const internalNginx = { } // For redirection hosts, if the scheme is not http or https, set it to $scheme - if (nice_host_type === "redirection_host" && ['http', 'https'].indexOf(host.forward_scheme.toLowerCase()) === -1) { + if ( + nice_host_type === "redirection_host" && + ["http", "https"].indexOf(host.forward_scheme.toLowerCase()) === -1 + ) { host.forward_scheme = "$scheme"; } diff --git a/backend/internal/token.js b/backend/internal/token.js index 126283e2dd..67255b2134 100644 --- a/backend/internal/token.js +++ b/backend/internal/token.js @@ -38,11 +38,7 @@ export default { throw new errs.AuthError(ERROR_MESSAGE_INVALID_AUTH); } - const auth = await authModel - .query() - .where("user_id", "=", user.id) - .where("type", "=", "password") - .first(); + const auth = await authModel.query().where("user_id", "=", user.id).where("type", "=", "password").first(); if (!auth) { throw new errs.AuthError(ERROR_MESSAGE_INVALID_AUTH); @@ -50,10 +46,7 @@ export default { const valid = await auth.verifyPassword(data.secret); if (!valid) { - throw new errs.AuthError( - ERROR_MESSAGE_INVALID_AUTH, - ERROR_MESSAGE_INVALID_AUTH_I18N, - ); + throw new errs.AuthError(ERROR_MESSAGE_INVALID_AUTH, ERROR_MESSAGE_INVALID_AUTH_I18N); } if (data.scope !== "user" && _.indexOf(user.roles, data.scope) === -1) { @@ -171,7 +164,7 @@ export default { } // Check scope - if (!tokenData.scope || tokenData.scope[0] !== "2fa-challenge") { + if (tokenData.scope?.[0] !== "2fa-challenge") { throw new errs.AuthError("Invalid challenge token"); } @@ -183,10 +176,7 @@ export default { // Verify 2FA code const valid = await twoFactor.verifyForLogin(userId, code); if (!valid) { - throw new errs.AuthError( - ERROR_MESSAGE_INVALID_2FA, - ERROR_MESSAGE_INVALID_2FA_I18N, - ); + throw new errs.AuthError(ERROR_MESSAGE_INVALID_2FA, ERROR_MESSAGE_INVALID_2FA_I18N); } // Create full token diff --git a/backend/internal/user.js b/backend/internal/user.js index 56a5ea8598..d4080dd78f 100644 --- a/backend/internal/user.js +++ b/backend/internal/user.js @@ -257,11 +257,9 @@ const internalUser = { }, deleteAll: async () => { - await userModel - .query() - .patch({ - is_deleted: 1, - }); + await userModel.query().patch({ + is_deleted: 1, + }); }, /** diff --git a/backend/knexfile.js b/backend/knexfile.js index 607552f6fc..0e7e5e5afb 100644 --- a/backend/knexfile.js +++ b/backend/knexfile.js @@ -1,19 +1,19 @@ module.exports = { development: { - client: 'mysql2', + client: "mysql2", migrations: { - tableName: 'migrations', - stub: 'lib/migrate_template.js', - directory: 'migrations' - } + tableName: "migrations", + stub: "lib/migrate_template.js", + directory: "migrations", + }, }, production: { - client: 'mysql2', + client: "mysql2", migrations: { - tableName: 'migrations', - stub: 'lib/migrate_template.js', - directory: 'migrations' - } - } + tableName: "migrations", + stub: "lib/migrate_template.js", + directory: "migrations", + }, + }, }; diff --git a/backend/lib/access.js b/backend/lib/access.js index a4dec5c4dd..ffe12b7147 100644 --- a/backend/lib/access.js +++ b/backend/lib/access.js @@ -119,10 +119,7 @@ export default function (tokenString) { // Proxy Hosts case "proxy_hosts": { - const query = proxyHostModel - .query() - .select("id") - .andWhere("is_deleted", 0); + const query = proxyHostModel.query().select("id").andWhere("is_deleted", 0); if (permissions.visibility === "user") { query.andWhere("owner_user_id", tokenUserId); diff --git a/backend/lib/config.js b/backend/lib/config.js index a491c190e8..71205013a1 100644 --- a/backend/lib/config.js +++ b/backend/lib/config.js @@ -2,13 +2,13 @@ import fs from "node:fs"; import NodeRSA from "node-rsa"; import { global as logger } from "../logger.js"; -const keysFile = '/data/keys.json'; -const mysqlEngine = 'mysql2'; -const postgresEngine = 'pg'; -const sqliteClientName = 'better-sqlite3'; +const keysFile = "/data/keys.json"; +const mysqlEngine = "mysql2"; +const postgresEngine = "pg"; +const sqliteClientName = "better-sqlite3"; // Not used for new setups anymore but may exist in legacy setups -const legacySqliteClientName = 'sqlite3'; +const legacySqliteClientName = "sqlite3"; let instance = null; @@ -40,14 +40,20 @@ const configure = () => { } } - const toBool = (v) => /^(1|true|yes|on)$/i.test((v || '').trim()); + const toBool = (v) => /^(1|true|yes|on)$/i.test((v || "").trim()); - const envMysqlHost = process.env.DB_MYSQL_HOST || null; - const envMysqlUser = process.env.DB_MYSQL_USER || null; - const envMysqlName = process.env.DB_MYSQL_NAME || null; - const envMysqlSSL = toBool(process.env.DB_MYSQL_SSL); - const envMysqlSSLRejectUnauthorized = process.env.DB_MYSQL_SSL_REJECT_UNAUTHORIZED === undefined ? true : toBool(process.env.DB_MYSQL_SSL_REJECT_UNAUTHORIZED); - const envMysqlSSLVerifyIdentity = process.env.DB_MYSQL_SSL_VERIFY_IDENTITY === undefined ? true : toBool(process.env.DB_MYSQL_SSL_VERIFY_IDENTITY); + const envMysqlHost = process.env.DB_MYSQL_HOST || null; + const envMysqlUser = process.env.DB_MYSQL_USER || null; + const envMysqlName = process.env.DB_MYSQL_NAME || null; + const envMysqlSSL = toBool(process.env.DB_MYSQL_SSL); + const envMysqlSSLRejectUnauthorized = + process.env.DB_MYSQL_SSL_REJECT_UNAUTHORIZED === undefined + ? true + : toBool(process.env.DB_MYSQL_SSL_REJECT_UNAUTHORIZED); + const envMysqlSSLVerifyIdentity = + process.env.DB_MYSQL_SSL_VERIFY_IDENTITY === undefined + ? true + : toBool(process.env.DB_MYSQL_SSL_VERIFY_IDENTITY); if (envMysqlHost && envMysqlUser && envMysqlName) { // we have enough mysql creds to go with mysql logger.info("Using MySQL configuration"); @@ -58,8 +64,10 @@ const configure = () => { port: process.env.DB_MYSQL_PORT || 3306, user: envMysqlUser, password: process.env.DB_MYSQL_PASSWORD, - name: envMysqlName, - ssl: envMysqlSSL ? { rejectUnauthorized: envMysqlSSLRejectUnauthorized, verifyIdentity: envMysqlSSLVerifyIdentity } : false, + name: envMysqlName, + ssl: envMysqlSSL + ? { rejectUnauthorized: envMysqlSSLRejectUnauthorized, verifyIdentity: envMysqlSSLVerifyIdentity } + : false, }, keys: getKeys(), }; @@ -222,7 +230,7 @@ const isDebugMode = () => !!process.env.DEBUG; * * @returns {boolean} */ -const isCI = () => process.env.CI === 'true' && process.env.DEBUG === 'true'; +const isCI = () => process.env.CI === "true" && process.env.DEBUG === "true"; /** * Returns a public key @@ -259,4 +267,16 @@ const useLetsencryptServer = () => { return null; }; -export { isCI, configHas, configGet, isSqlite, isMysql, isPostgres, isDebugMode, getPrivateKey, getPublicKey, useLetsencryptStaging, useLetsencryptServer }; +export { + isCI, + configHas, + configGet, + isSqlite, + isMysql, + isPostgres, + isDebugMode, + getPrivateKey, + getPublicKey, + useLetsencryptStaging, + useLetsencryptServer, +}; diff --git a/backend/lib/express/pagination.js b/backend/lib/express/pagination.js index 188df2779d..457c954d2d 100644 --- a/backend/lib/express/pagination.js +++ b/backend/lib/express/pagination.js @@ -1,4 +1,4 @@ -import _ from "lodash"; +import _ from "lodash"; export default (default_sort, default_offset, default_limit, max_limit) => { /** diff --git a/backend/lib/express/user-id-from-me.js b/backend/lib/express/user-id-from-me.js index 9c29ba2721..5035d8fdd9 100644 --- a/backend/lib/express/user-id-from-me.js +++ b/backend/lib/express/user-id-from-me.js @@ -1,6 +1,6 @@ export default (req, res, next) => { - if (req.params.user_id === 'me' && res.locals.access) { - req.params.user_id = res.locals.access.token.get('attrs').id; + if (req.params.user_id === "me" && res.locals.access) { + req.params.user_id = res.locals.access.token.get("attrs").id; } else { req.params.user_id = Number.parseInt(req.params.user_id, 10); } diff --git a/backend/lib/validator/api.js b/backend/lib/validator/api.js index 6c738d5097..f4981a80c9 100644 --- a/backend/lib/validator/api.js +++ b/backend/lib/validator/api.js @@ -24,21 +24,17 @@ const apiValidator = async (schema, payload /*, description*/) => { throw new errs.ValidationError("Payload is undefined"); } - const validate = ajv.compile(schema); const valid = validate(payload); - if (valid && !validate.errors) { return payload; } - - const message = ajv.errorsText(validate.errors); const err = new errs.ValidationError(message); - err.debug = {validationErrors: validate.errors, payload}; + err.debug = { validationErrors: validate.errors, payload }; throw err; }; diff --git a/backend/lib/validator/index.js b/backend/lib/validator/index.js index 5f2586fd67..5d9f8f38a8 100644 --- a/backend/lib/validator/index.js +++ b/backend/lib/validator/index.js @@ -1,4 +1,4 @@ -import Ajv from 'ajv/dist/2020.js'; +import Ajv from "ajv/dist/2020.js"; import _ from "lodash"; import commonDefinitions from "../../schema/common.json" with { type: "json" }; import errs from "../error.js"; diff --git a/backend/migrations/20190227065017_settings.js b/backend/migrations/20190227065017_settings.js index a6cbe2c99a..471d0b8577 100644 --- a/backend/migrations/20190227065017_settings.js +++ b/backend/migrations/20190227065017_settings.js @@ -13,13 +13,14 @@ const migrateName = "settings"; const up = (knex) => { logger.info(`[${migrateName}] Migrating Up...`); - return knex.schema.createTable('setting', (table) => { - table.string('id').notNull().primary(); - table.string('name', 100).notNull(); - table.string('description', 255).notNull(); - table.string('value', 255).notNull(); - table.json('meta').notNull(); - }) + return knex.schema + .createTable("setting", (table) => { + table.string("id").notNull().primary(); + table.string("name", 100).notNull(); + table.string("description", 255).notNull(); + table.string("value", 255).notNull(); + table.json("meta").notNull(); + }) .then(() => { logger.info(`[${migrateName}] setting Table created`); }); diff --git a/backend/migrations/20251111090000_redirect_auto_scheme.js b/backend/migrations/20251111090000_redirect_auto_scheme.js index 9f5f9d0642..a15f3e3f3c 100644 --- a/backend/migrations/20251111090000_redirect_auto_scheme.js +++ b/backend/migrations/20251111090000_redirect_auto_scheme.js @@ -17,9 +17,7 @@ const up = (knex) => { .table("redirection_host", async (table) => { // change the column default from $scheme to auto await table.string("forward_scheme").notNull().defaultTo("auto").alter(); - await knex('redirection_host') - .where('forward_scheme', '$scheme') - .update({ forward_scheme: 'auto' }); + await knex("redirection_host").where("forward_scheme", "$scheme").update({ forward_scheme: "auto" }); }) .then(() => { logger.info(`[${migrateName}] redirection_host Table altered`); @@ -38,9 +36,7 @@ const down = (knex) => { return knex.schema .table("redirection_host", async (table) => { await table.string("forward_scheme").notNull().defaultTo("$scheme").alter(); - await knex('redirection_host') - .where('forward_scheme', 'auto') - .update({ forward_scheme: '$scheme' }); + await knex("redirection_host").where("forward_scheme", "auto").update({ forward_scheme: "$scheme" }); }) .then(() => { logger.info(`[${migrateName}] redirection_host Table altered`); diff --git a/backend/migrations/20260131163528_trust_forwarded_proto.js b/backend/migrations/20260131163528_trust_forwarded_proto.js index c32c6fb697..24c50e8d4a 100644 --- a/backend/migrations/20260131163528_trust_forwarded_proto.js +++ b/backend/migrations/20260131163528_trust_forwarded_proto.js @@ -11,15 +11,15 @@ const migrateName = "trust_forwarded_proto"; * @returns {Promise} */ const up = (knex) => { - logger.info(`[${migrateName}] Migrating Up...`); + logger.info(`[${migrateName}] Migrating Up...`); - return knex.schema - .alterTable('proxy_host', (table) => { - table.tinyint('trust_forwarded_proto').notNullable().defaultTo(0); - }) - .then(() => { - logger.info(`[${migrateName}] proxy_host Table altered`); - }); + return knex.schema + .alterTable("proxy_host", (table) => { + table.tinyint("trust_forwarded_proto").notNullable().defaultTo(0); + }) + .then(() => { + logger.info(`[${migrateName}] proxy_host Table altered`); + }); }; /** @@ -29,15 +29,15 @@ const up = (knex) => { * @returns {Promise} */ const down = (knex) => { - logger.info(`[${migrateName}] Migrating Down...`); + logger.info(`[${migrateName}] Migrating Down...`); - return knex.schema - .alterTable('proxy_host', (table) => { - table.dropColumn('trust_forwarded_proto'); - }) - .then(() => { - logger.info(`[${migrateName}] proxy_host Table altered`); - }); + return knex.schema + .alterTable("proxy_host", (table) => { + table.dropColumn("trust_forwarded_proto"); + }) + .then(() => { + logger.info(`[${migrateName}] proxy_host Table altered`); + }); }; -export { up, down }; \ No newline at end of file +export { up, down }; diff --git a/backend/models/setting.js b/backend/models/setting.js index 56f7dc5aac..1fbef374cc 100644 --- a/backend/models/setting.js +++ b/backend/models/setting.js @@ -7,23 +7,23 @@ import db from "../db.js"; Model.knex(db()); class Setting extends Model { - $beforeInsert () { + $beforeInsert() { // Default for meta - if (typeof this.meta === 'undefined') { + if (typeof this.meta === "undefined") { this.meta = {}; } } - static get name () { - return 'Setting'; + static get name() { + return "Setting"; } - static get tableName () { - return 'setting'; + static get tableName() { + return "setting"; } - static get jsonAttributes () { - return ['meta']; + static get jsonAttributes() { + return ["meta"]; } } diff --git a/backend/models/user_permission.js b/backend/models/user_permission.js index d878471780..cc6eac2cc7 100644 --- a/backend/models/user_permission.js +++ b/backend/models/user_permission.js @@ -8,21 +8,21 @@ import now from "./now_helper.js"; Model.knex(db()); class UserPermission extends Model { - $beforeInsert () { - this.created_on = now(); + $beforeInsert() { + this.created_on = now(); this.modified_on = now(); } - $beforeUpdate () { + $beforeUpdate() { this.modified_on = now(); } - static get name () { - return 'UserPermission'; + static get name() { + return "UserPermission"; } - static get tableName () { - return 'user_permission'; + static get tableName() { + return "user_permission"; } } diff --git a/backend/package.json b/backend/package.json index 2c91ca4412..8eda0451c5 100644 --- a/backend/package.json +++ b/backend/package.json @@ -13,37 +13,37 @@ "regenerate-config": "node scripts/regenerate-config" }, "dependencies": { - "@apidevtools/json-schema-ref-parser": "^15.3.5", + "@apidevtools/json-schema-ref-parser": "^16.0.0", "ajv": "^8.20.0", "archiver": "^8.0.0", "batchflow": "^0.4.0", "bcrypt": "^6.0.0", - "better-sqlite3": "^12.10.0", - "body-parser": "^2.2.2", + "better-sqlite3": "^13.0.3", + "body-parser": "^2.3.0", "chalk": "5.6.2", "compression": "^1.8.1", "express": "^5.2.1", "express-fileupload": "^1.5.2", "gravatar": "^1.8.2", "jsonwebtoken": "^9.0.3", - "knex": "3.2.10", - "liquidjs": "10.27.0", + "knex": "3.3.0", + "liquidjs": "10.29.0", "lodash": "^4.18.1", "moment": "^2.30.1", - "mysql2": "^3.22.3", + "mysql2": "^3.23.4", "node-rsa": "^2.0.0", "objection": "3.1.5", - "otplib": "^13.4.0", + "otplib": "^13.5.0", "path": "^0.12.7", - "pg": "^8.21.0", - "proxy-agent": "^8.0.1", + "pg": "^8.23.0", + "proxy-agent": "^8.0.2", "signale": "1.4.0", "sqlite3": "^6.0.1", "temp-write": "^6.0.1" }, "devDependencies": { "@apidevtools/swagger-parser": "^12.1.0", - "@biomejs/biome": "^2.4.15", + "@biomejs/biome": "^2.5.10", "nodemon": "^3.1.14" }, "signale": { diff --git a/backend/routes/audit-log.js b/backend/routes/audit-log.js index c40b1628d8..54edef6e31 100644 --- a/backend/routes/audit-log.js +++ b/backend/routes/audit-log.js @@ -86,10 +86,7 @@ router }, { event_id: req.params.event_id, - expand: - typeof req.query.expand === "string" - ? req.query.expand.split(",") - : null, + expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, }, ); diff --git a/backend/routes/nginx/certificates.js b/backend/routes/nginx/certificates.js index 99f429b446..dea8094230 100644 --- a/backend/routes/nginx/certificates.js +++ b/backend/routes/nginx/certificates.js @@ -44,18 +44,11 @@ router }, }, { - expand: - typeof req.query.expand === "string" - ? req.query.expand.split(",") - : null, + expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, query: typeof req.query.query === "string" ? req.query.query : null, }, ); - const rows = await internalCertificate.getAll( - res.locals.access, - data.expand, - data.query, - ); + const rows = await internalCertificate.getAll(res.locals.access, data.expand, data.query); res.status(200).send(rows); } catch (err) { debug(logger, `${req.method.toUpperCase()} ${req.path}: ${err}`); @@ -70,15 +63,9 @@ router */ .post(async (req, res, next) => { try { - const payload = await apiValidator( - getValidationSchema("/nginx/certificates", "post"), - req.body, - ); + const payload = await apiValidator(getValidationSchema("/nginx/certificates", "post"), req.body); req.setTimeout(900000); // 15 minutes timeout - const result = await internalCertificate.create( - res.locals.access, - payload, - ); + const result = await internalCertificate.create(res.locals.access, payload); res.status(201).send(result); } catch (err) { debug(logger, `${req.method.toUpperCase()} ${req.path}: ${err}`); @@ -139,16 +126,10 @@ router */ .post(async (req, res, next) => { try { - const payload = await apiValidator( - getValidationSchema("/nginx/certificates/test-http", "post"), - req.body, - ); + const payload = await apiValidator(getValidationSchema("/nginx/certificates/test-http", "post"), req.body); req.setTimeout(60000); // 1 minute timeout - const result = await internalCertificate.testHttpsChallenge( - res.locals.access, - payload, - ); + const result = await internalCertificate.testHttpsChallenge(res.locals.access, payload); res.status(200).send(result); } catch (err) { debug(logger, `${req.method.toUpperCase()} ${req.path}: ${err}`); @@ -224,10 +205,7 @@ router }, { certificate_id: req.params.certificate_id, - expand: - typeof req.query.expand === "string" - ? req.query.expand.split(",") - : null, + expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, }, ); const row = await internalCertificate.get(res.locals.access, { diff --git a/backend/routes/users.js b/backend/routes/users.js index 7c3da8c1d1..3f972223be 100644 --- a/backend/routes/users.js +++ b/backend/routes/users.js @@ -48,18 +48,11 @@ router }, }, { - expand: - typeof req.query.expand === "string" - ? req.query.expand.split(",") - : null, + expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, query: typeof req.query.query === "string" ? req.query.query : null, }, ); - const users = await internalUser.getAll( - res.locals.access, - data.expand, - data.query, - ); + const users = await internalUser.getAll(res.locals.access, data.expand, data.query); res.status(200).send(users); } catch (err) { debug(logger, `${req.method.toUpperCase()} ${req.path}: ${err}`); @@ -95,10 +88,7 @@ router } } - const payload = await apiValidator( - getValidationSchema("/users", "post"), - body, - ); + const payload = await apiValidator(getValidationSchema("/users", "post"), body); const user = await internalUser.create(res.locals.access, payload); res.status(201).send(user); } catch (err) { @@ -169,20 +159,14 @@ router }, { user_id: req.params.user_id, - expand: - typeof req.query.expand === "string" - ? req.query.expand.split(",") - : null, + expand: typeof req.query.expand === "string" ? req.query.expand.split(",") : null, }, ); const user = await internalUser.get(res.locals.access, { id: data.user_id, expand: data.expand, - omit: internalUser.getUserOmisionsByAccess( - res.locals.access, - data.user_id, - ), + omit: internalUser.getUserOmisionsByAccess(res.locals.access, data.user_id), }); res.status(200).send(user); } catch (err) { @@ -198,10 +182,7 @@ router */ .put(async (req, res, next) => { try { - const payload = await apiValidator( - getValidationSchema("/users/{userID}", "put"), - req.body, - ); + const payload = await apiValidator(getValidationSchema("/users/{userID}", "put"), req.body); payload.id = req.params.user_id; const result = await internalUser.update(res.locals.access, payload); res.status(200).send(result); @@ -248,10 +229,7 @@ router */ .put(async (req, res, next) => { try { - const payload = await apiValidator( - getValidationSchema("/users/{userID}/auth", "put"), - req.body, - ); + const payload = await apiValidator(getValidationSchema("/users/{userID}/auth", "put"), req.body); payload.id = req.params.user_id; const result = await internalUser.setPassword(res.locals.access, payload); res.status(200).send(result); @@ -281,15 +259,9 @@ router */ .put(async (req, res, next) => { try { - const payload = await apiValidator( - getValidationSchema("/users/{userID}/permissions", "put"), - req.body, - ); + const payload = await apiValidator(getValidationSchema("/users/{userID}/permissions", "put"), req.body); payload.id = req.params.user_id; - const result = await internalUser.setPermissions( - res.locals.access, - payload, - ); + const result = await internalUser.setPermissions(res.locals.access, payload); res.status(200).send(result); } catch (err) { debug(logger, `${req.method.toUpperCase()} ${req.path}: ${err}`); @@ -408,10 +380,7 @@ router */ .post(async (req, res, next) => { try { - const { code } = await apiValidator( - getValidationSchema("/users/{userID}/2fa/enable", "post"), - req.body, - ); + const { code } = await apiValidator(getValidationSchema("/users/{userID}/2fa/enable", "post"), req.body); const result = await internal2FA.enable(res.locals.access, req.params.user_id, code); res.status(200).send(result); } catch (err) { diff --git a/backend/setup.js b/backend/setup.js index c0418e170b..f6b1454434 100644 --- a/backend/setup.js +++ b/backend/setup.js @@ -1,3 +1,4 @@ +import fs from "node:fs/promises"; import { installPlugins } from "./lib/certbot.js"; import utils from "./lib/utils.js"; import { setup as logger } from "./logger.js"; @@ -6,12 +7,11 @@ import certificateModel from "./models/certificate.js"; import settingModel from "./models/setting.js"; import userModel from "./models/user.js"; import userPermissionModel from "./models/user_permission.js"; -import fs from "fs/promises"; export const isSetup = async () => { const row = await userModel.query().select("id").where("is_deleted", 0).first(); return row?.id > 0; -} +}; /** * Creates a default admin users if one doesn't already exist in the database @@ -45,18 +45,14 @@ const setupDefaultUser = async () => { roles: ["admin"], }; - const user = await userModel - .query() - .insertAndFetch(data); + const user = await userModel.query().insertAndFetch(data); - await authModel - .query() - .insert({ - user_id: user.id, - type: "password", - secret: initialAdminPassword, - meta: {}, - }); + await authModel.query().insert({ + user_id: user.id, + type: "password", + secret: initialAdminPassword, + meta: {}, + }); await userPermissionModel.query().insert({ user_id: user.id, @@ -78,22 +74,16 @@ const setupDefaultUser = async () => { * @returns {Promise} */ const setupDefaultSettings = async () => { - const row = await settingModel - .query() - .select("id") - .where({ id: "default-site" }) - .first(); + const row = await settingModel.query().select("id").where({ id: "default-site" }).first(); if (!row?.id) { - await settingModel - .query() - .insert({ - id: "default-site", - name: "Default Site", - description: "What to show when Nginx is hit with an unknown Host", - value: "congratulations", - meta: {}, - }); + await settingModel.query().insert({ + id: "default-site", + name: "Default Site", + description: "What to show when Nginx is hit with an unknown Host", + value: "congratulations", + meta: {}, + }); logger.info("Default settings added"); } }; @@ -104,10 +94,7 @@ const setupDefaultSettings = async () => { * @returns {Promise} */ const setupCertbotPlugins = async () => { - const certificates = await certificateModel - .query() - .where("is_deleted", 0) - .andWhere("provider", "letsencrypt"); + const certificates = await certificateModel.query().where("is_deleted", 0).andWhere("provider", "letsencrypt"); if (certificates?.length) { const plugins = []; @@ -122,14 +109,24 @@ const setupCertbotPlugins = async () => { // Make sure credentials file exists const credentials_loc = `/etc/letsencrypt/credentials/credentials-${certificate.id}`; if (typeof certificate.meta.dns_provider_credentials === "string") { - promises.push(fs.mkdir("/etc/letsencrypt/credentials", { recursive: true }) - .then(() => fs.writeFile(credentials_loc, certificate.meta.dns_provider_credentials, { mode: 0o600, flag: "wx" })) - .catch((err) => { if (err.code !== "EEXIST") throw err; })); + promises.push( + fs + .mkdir("/etc/letsencrypt/credentials", { recursive: true }) + .then(() => + fs.writeFile(credentials_loc, certificate.meta.dns_provider_credentials, { + mode: 0o600, + flag: "wx", + }), + ) + .catch((err) => { + if (err.code !== "EEXIST") throw err; + }), + ); } } return true; }); - + await installPlugins(plugins); if (promises.length) { diff --git a/backend/yarn.lock b/backend/yarn.lock index 49c54d1c5a..5050c58482 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -10,12 +10,13 @@ "@types/json-schema" "^7.0.15" js-yaml "^4.1.0" -"@apidevtools/json-schema-ref-parser@^15.3.5": - version "15.3.5" - resolved "https://registry.yarnpkg.com/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-15.3.5.tgz#503726178d8d792eea7b195566272aaee6837e2f" - integrity sha512-orNOYXw3hYXxxisXMldjzjBzqqTLBPbwOtHg7ovBPvfBHDue1qM9YJENZ3W2BQuS+7z4ThogMbEzEsov57Itkg== +"@apidevtools/json-schema-ref-parser@^16.0.0": + version "16.0.0" + resolved "https://registry.yarnpkg.com/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-16.0.0.tgz#3fddc23ab7ad61fd3d547f97e9bf197d2d1c164e" + integrity sha512-Am2KotB8TVU8McHvOOnmUiuVHwCs3dw3o16aOApAxEuY1XOlqQeT5mvGb35rhYa6/UtTTNHJwRe9aQFnLASi6Q== dependencies: - js-yaml "^4.1.1" + js-yaml "^5.2.3" + undici "^8.10.0" "@apidevtools/openapi-schemas@^2.1.0": version "2.1.0" @@ -39,59 +40,59 @@ ajv-draft-04 "^1.0.0" call-me-maybe "^1.0.2" -"@biomejs/biome@^2.4.15": - version "2.4.15" - resolved "https://registry.yarnpkg.com/@biomejs/biome/-/biome-2.4.15.tgz#cb84ad6eb4235e7230b3c105a825e9bc03399944" - integrity sha512-j5VH3a/h/HXTKBM50MDMxRCzkeLv9S2XJcW2WgnZT1+xyisi+0bISrXR82gCX+8S9lvK0skEvHJRN+3Ktr2hlw== +"@biomejs/biome@^2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@biomejs/biome/-/biome-2.5.10.tgz#c2a42fc6f9c7d9e12c1f77f63dfb6b5489c497b7" + integrity sha512-WRKXARA3kTuiV5sxqTpobJ/I0MVd4vk3pOL6wnp5az4LntFIhWTj1RWZq3DI9PCEN3lXcqy7p5aqUHzvq8AXyQ== optionalDependencies: - "@biomejs/cli-darwin-arm64" "2.4.15" - "@biomejs/cli-darwin-x64" "2.4.15" - "@biomejs/cli-linux-arm64" "2.4.15" - "@biomejs/cli-linux-arm64-musl" "2.4.15" - "@biomejs/cli-linux-x64" "2.4.15" - "@biomejs/cli-linux-x64-musl" "2.4.15" - "@biomejs/cli-win32-arm64" "2.4.15" - "@biomejs/cli-win32-x64" "2.4.15" - -"@biomejs/cli-darwin-arm64@2.4.15": - version "2.4.15" - resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.15.tgz#3469daa56ac3ff4f16588a120df706381a96f65c" - integrity sha512-rF3PPqLq1yoST79zaQbDjVJwsuIeci/O+9bgNmC5QpgOqz6aqYuzA4abyAGx+mgyiDXn4A049xAN8gijbuR1Qg== - -"@biomejs/cli-darwin-x64@2.4.15": - version "2.4.15" - resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.15.tgz#0697b81089409635da16682ac1e539165c262006" - integrity sha512-/5KHXYMfSJs1fNXiX30xFtI8JcCFV6zaVVLxOa0M2sfqBKHkpQhRTv94yxQWxeTY2lzo2OuTlNvPC+hDQt2wcQ== - -"@biomejs/cli-linux-arm64-musl@2.4.15": - version "2.4.15" - resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.15.tgz#c6af054e3732c361e9ad8c44070f909666b5616f" - integrity sha512-ZPcxznxm0pogHBLZhYntyR3sR+MrZjqJIKEr7ZqVen0Rl+P/4upVmfYXjftizi9RoqZntg33fv/1fbdhbYXpEQ== - -"@biomejs/cli-linux-arm64@2.4.15": - version "2.4.15" - resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.15.tgz#527cef60339649a442d51a9cd129ae9dfe9da926" - integrity sha512-owaAMZD/T4LrD0ELNCk0Km3qrRHuM0X6EAyVE1FSqGY0rbLoiDLrO4Us2tllm6cAeB2Ioa9C2C08NZPdr8+0Ug== - -"@biomejs/cli-linux-x64-musl@2.4.15": - version "2.4.15" - resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.15.tgz#b39292ad106c3d5a612bf3c61ba3119f66833013" - integrity sha512-CNq/9W38SYSH023lfcQ4KKU8K0YX8T//FZUhcgtMMRABDojx5XsMV7jlweAvGSl389wJQB29Qo6Zb/a+jdvt+w== - -"@biomejs/cli-linux-x64@2.4.15": - version "2.4.15" - resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.15.tgz#7360b7f81ff03ec6d9350bedc76b89f783b0945d" - integrity sha512-0jj7THz12GbUOLmMibktK6DZjqz2zV64KFxyBtcFTKPiiOIY0a7vns1elpO1dERvxpsZ5ik0oFfz0oGwFde1+g== - -"@biomejs/cli-win32-arm64@2.4.15": - version "2.4.15" - resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.15.tgz#9542aac679174892a9379267e0c0048f8eee4d9f" - integrity sha512-ouhkYdlhp/1GghEJPdWwD/Vi3gQ1nFxuSpMolWsbq3Lsq3QUR4jl6UdhhscdCugKU5vOEuMiJhvKj66O0OCq+w== - -"@biomejs/cli-win32-x64@2.4.15": - version "2.4.15" - resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.15.tgz#80288e4eea8f916fc5c876e9a486baadb8de537d" - integrity sha512-zBrGq5mx5wwpnow4+2BxUvleDM+GNd4sLbPaMapsSLQLD0NGRCquqPBTgN+7XkUteHvj7M+BstuI8tmnV7+HgQ== + "@biomejs/cli-darwin-arm64" "2.5.10" + "@biomejs/cli-darwin-x64" "2.5.10" + "@biomejs/cli-linux-arm64" "2.5.10" + "@biomejs/cli-linux-arm64-musl" "2.5.10" + "@biomejs/cli-linux-x64" "2.5.10" + "@biomejs/cli-linux-x64-musl" "2.5.10" + "@biomejs/cli-win32-arm64" "2.5.10" + "@biomejs/cli-win32-x64" "2.5.10" + +"@biomejs/cli-darwin-arm64@2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.5.10.tgz#f1453a7f2e63f228a34645df1c33962f22a6c2a8" + integrity sha512-ItCrxKK6SXVT6flYs0qIuBd4AA3TTTl4d66Re6YI2FuGZnN85NmuYNzkiTJUyYw8qBLv69L5zTUB6uyWd++h3Q== + +"@biomejs/cli-darwin-x64@2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.5.10.tgz#e21041e7bfab01cd453f609b940bf613713d0e24" + integrity sha512-yLsPU9pAmtChXDu8vhKAzErqe+LeeYuwuUB2FZMkRitsmdodxsYRa9KHrFispsUHzzOu+9HB3nP/TQxyia+Sjw== + +"@biomejs/cli-linux-arm64-musl@2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.5.10.tgz#57fc8aee25c08ca6c14526ccc44e282e7ba96eb6" + integrity sha512-t1QAKZwQJRB4dvgJSgFiQ4BNfNPChg69BNonz854qLVxnjT3UvDzQg9mbkTJRu35ZqU0Rw10A73J8Urgbg2RPw== + +"@biomejs/cli-linux-arm64@2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.5.10.tgz#aef789a71e5aa86f5a0e1aff6cb4c1b757ec5be1" + integrity sha512-VG8uQW/86a1roLaIFvtIbEigxIdzdJ190oGyg1tV7VYeQtOS+x10sflk7WbuXgw91EtZX5DlIIIej1YqkNLlcg== + +"@biomejs/cli-linux-x64-musl@2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.5.10.tgz#1aebe9f928dc72dc3c112e60f1211a4d646990c4" + integrity sha512-pgDDqp9JybHm2I0KRgzN6i4+lt8xu4iqxUwLzglUMmOmyRTU1AYBGKzh9sNMOtIjah7xoWvKHlLVetvyifzoiQ== + +"@biomejs/cli-linux-x64@2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64/-/cli-linux-x64-2.5.10.tgz#a82b414abf5d9668fb035ee50a710bf78a7c5fbf" + integrity sha512-4O6T0eq2heoHZN0a9UX+rWQoxXEBaKf+lRi2hbsGlHneUz9BWXM76nEWMK7Eeq8gzMxR1khQB6BFpAASpeXqGg== + +"@biomejs/cli-win32-arm64@2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.5.10.tgz#db671cf67d7040a374e8cdda5aebe73c3f4ffba0" + integrity sha512-pxAbxduPO4xq/Cvgaa2lOrs9BB0hEXmmDqfMNP4ZOffGOkUrD1/QGw9UAMpFQpX2P8MqTIIRuQKcmetum4Oa6A== + +"@biomejs/cli-win32-x64@2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-x64/-/cli-win32-x64-2.5.10.tgz#3bdeaf5856f21aec6b6c50a7bca5464b9cda5623" + integrity sha512-M+2dgBsl3lXRiTfgPVc2p3anS4Tocojke4rzFLScZ2Y/wmF+36dRb1iHCLiyGqOzQGyTplZH1HnEYviiAqi3nA== "@isaacs/fs-minipass@^4.0.0": version "4.0.1" @@ -100,60 +101,60 @@ dependencies: minipass "^7.0.4" -"@noble/hashes@^2.0.1", "@noble/hashes@^2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-2.2.0.tgz#22da1d16a469954fce877055d559900a6c73b63b" - integrity sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg== +"@noble/hashes@^2.2.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-2.3.0.tgz#505fd39c3134a37e67c8c4e6c6049a496154879c" + integrity sha512-oN+QwyX7VSHotibwubG3kpzbwKrfnyR6OOO+3Nk/53ADL7FmgHHz4TgrbaYKvvOw09u6QTx0oiH1cNCIOuN0CQ== -"@otplib/core@13.4.0": - version "13.4.0" - resolved "https://registry.yarnpkg.com/@otplib/core/-/core-13.4.0.tgz#14db803de5bd09f7c412eba86c7d193a09d57187" - integrity sha512-JqOGcvZQi2wIkEQo8f3/iAjstavpXy6gouIDMHygjNuH6Q0FjbHOiXMdcE94RwfgDNMABhzwUmvaPsxvgm9NYw== +"@otplib/core@13.5.0": + version "13.5.0" + resolved "https://registry.yarnpkg.com/@otplib/core/-/core-13.5.0.tgz#629a7fef5b6394f34ff55213b936223b368796a4" + integrity sha512-2rURdkYkb3BDhMs3j/oCCPTve1ybJ6ruLfLfSe1ZSPV+y6RFTbLfAuT0m0ZCnps88ogkIq9t/+Li/kg5RofQwQ== -"@otplib/hotp@13.4.0": - version "13.4.0" - resolved "https://registry.yarnpkg.com/@otplib/hotp/-/hotp-13.4.0.tgz#e12a69cc54c000213e4bf2d92dc9741a6897d3a2" - integrity sha512-MJjE0x06mn2ptymz5qZmQveb+vWFuaIftqE0b5/TZZqUOK7l97cV8lRTmid5BpAQMwJDNLW6RnYxGeCRiNdekw== +"@otplib/hotp@13.5.0": + version "13.5.0" + resolved "https://registry.yarnpkg.com/@otplib/hotp/-/hotp-13.5.0.tgz#2832cc6e52f3d037428f094177b4779babe19aa5" + integrity sha512-1EwwAti05CeWJn4xXOVMBK9N6dIJlJw/cQkQyiL9OVlkeS452wAve3ffodi+5IUZdWoF1wxVug38RisdxDqDWw== dependencies: - "@otplib/core" "13.4.0" - "@otplib/uri" "13.4.0" + "@otplib/core" "13.5.0" + "@otplib/uri" "13.5.0" -"@otplib/plugin-base32-scure@13.4.0": - version "13.4.0" - resolved "https://registry.yarnpkg.com/@otplib/plugin-base32-scure/-/plugin-base32-scure-13.4.0.tgz#04c3b31075bc733ed3fb54d3335a65813faed0fe" - integrity sha512-/t9YWJmMbB8bF5z8mXrBZc2FXBe8B/3hG5FhWr9K8cFwFhyxScbPysmZe8s1UTzSA6N+s8Uv8aIfCtVXPNjJWw== +"@otplib/plugin-base32-scure@13.5.0": + version "13.5.0" + resolved "https://registry.yarnpkg.com/@otplib/plugin-base32-scure/-/plugin-base32-scure-13.5.0.tgz#ba2f329aeea3ed4df3c4e21ce2e9c2e8c9aaed4f" + integrity sha512-3JEIHindUMiIeNL0jXepSAkZ/7IkWq4sPdG9eXK0lrMXZG9RdKu5oz/4tuuTodtsFUPYhKlRMqv5xUvQIkMIaA== dependencies: - "@otplib/core" "13.4.0" - "@scure/base" "^2.0.0" + "@otplib/core" "13.5.0" + "@scure/base" "^2.2.0" -"@otplib/plugin-crypto-noble@13.4.0": - version "13.4.0" - resolved "https://registry.yarnpkg.com/@otplib/plugin-crypto-noble/-/plugin-crypto-noble-13.4.0.tgz#048c6ad84fd718a2b66f108048aa2f7fd118e5d8" - integrity sha512-KrvE4m7Zv+TT1944HzgqFJWJpKb6AyoxDbvhPStmBqdMlv5Gekb80d66cuFRL08kkPgJ5gXUSb5SFpYeB+bACg== +"@otplib/plugin-crypto-noble@13.5.0": + version "13.5.0" + resolved "https://registry.yarnpkg.com/@otplib/plugin-crypto-noble/-/plugin-crypto-noble-13.5.0.tgz#820227beb159090a7448ce7245a4e615b5579f0e" + integrity sha512-fihOAGFvc4b8XTKyIK3jifFP2nLrUNc2bOaJ3UkUKJjy1XI2FbHKG0WmOH+jFsPfa6VsOnouCnEmSznDxIe0pA== dependencies: - "@noble/hashes" "^2.0.1" - "@otplib/core" "13.4.0" + "@noble/hashes" "^2.2.0" + "@otplib/core" "13.5.0" -"@otplib/totp@13.4.0": - version "13.4.0" - resolved "https://registry.yarnpkg.com/@otplib/totp/-/totp-13.4.0.tgz#f43543435f9ea4c7798913ef8f975462f80fce63" - integrity sha512-dK+vl0f0ekzf6mCENRI9AKS2NJUC7OjI3+X8e7QSnhQ2WM7I+i4PGpb3QxKi5hxjTtwVuoZwXR2CFtXdcRtNdQ== +"@otplib/totp@13.5.0": + version "13.5.0" + resolved "https://registry.yarnpkg.com/@otplib/totp/-/totp-13.5.0.tgz#48a60807457726ea34f1d1185f994120652e4468" + integrity sha512-GD9LzQnbHDwXCp79s8AaiA5cJR6luX5fEr9AN32AWx4ooRvllPbMkG80gHSA0jbGCnAIX/ChyOtTZ8tgJHMkSg== dependencies: - "@otplib/core" "13.4.0" - "@otplib/hotp" "13.4.0" - "@otplib/uri" "13.4.0" + "@otplib/core" "13.5.0" + "@otplib/hotp" "13.5.0" + "@otplib/uri" "13.5.0" -"@otplib/uri@13.4.0": - version "13.4.0" - resolved "https://registry.yarnpkg.com/@otplib/uri/-/uri-13.4.0.tgz#23fa0b727bec026bb871afd42e1c3e5ff57bed1d" - integrity sha512-x1ozBa5bPbdZCrrTL/HK21qchiK7jYElTu+0ft22abeEhiLYgH1+SIULvOcVk3CK8YwF4kdcidvkq4ciejucJA== +"@otplib/uri@13.5.0": + version "13.5.0" + resolved "https://registry.yarnpkg.com/@otplib/uri/-/uri-13.5.0.tgz#d2da470be24f872bb1c24717bcdd2e5c122e3ce3" + integrity sha512-LsL1hqTEgJHY40U2eb/Qp6OR1tKkNGwHQTrqqjIuJj0cawGWkLEmeUFK1MHzWBQ4bgy5IdeB5Et7gIDSAH/CRw== dependencies: - "@otplib/core" "13.4.0" + "@otplib/core" "13.5.0" -"@scure/base@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-2.0.0.tgz#ba6371fddf92c2727e88ad6ab485db6e624f9a98" - integrity sha512-3E1kpuZginKkek01ovG8krQ0Z44E3DHPjc5S2rjJw9lZn3KSQOs8S7wqikF/AH7iRanHypj85uGyxk0XAyC37w== +"@scure/base@^2.2.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-2.3.0.tgz#fc7acb5b7084c53e4e2537d83fa72cddac7143fd" + integrity sha512-NsG6Y03tY6R5BUis4FdVtHVkur0U6FOzskgs9ZXNl78CUc9fkZ78HmENUle1nSOkCasDmbubmWD9qwB7mm4PZA== "@types/json-schema@^7.0.15": version "7.0.15" @@ -197,17 +198,7 @@ ajv-formats@^2.1.1: dependencies: ajv "^8.0.0" -ajv@^8.0.0, ajv@^8.17.1: - version "8.18.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.18.0.tgz#8864186b6738d003eb3a933172bb3833e10cefbc" - integrity sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A== - dependencies: - fast-deep-equal "^3.1.3" - fast-uri "^3.0.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - -ajv@^8.20.0: +ajv@^8.0.0, ajv@^8.17.1, ajv@^8.20.0: version "8.20.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.20.0.tgz#304b3636add88ba7d936760dd50ece006dea95f9" integrity sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA== @@ -281,27 +272,59 @@ aws-ssl-profiles@^1.1.2: resolved "https://registry.yarnpkg.com/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz#157dd77e9f19b1d123678e93f120e6f193022641" integrity sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g== -b4a@^1.6.4: - version "1.8.0" - resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.8.0.tgz#1ca3ba0edc9469aaabef5647e769a83d50180b1a" - integrity sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg== +b4a@^1.6.4, b4a@^1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.8.1.tgz#7f16334ca80127aeb26064a28841acbf174840a4" + integrity sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw== balanced-match@^4.0.2: - version "4.0.3" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-4.0.3.tgz#6337a2f23e0604a30481423432f99eac603599f9" - integrity sha512-1pHv8LX9CpKut1Zp4EXey7Z8OfH11ONNH6Dhi2WDUt31VVZFXZzKwXcysBgqSumFCmR+0dqjMK5v5JiFHzi0+g== + version "4.0.4" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-4.0.4.tgz#bfb10662feed8196a2c62e7c68e17720c274179a" + integrity sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA== + +bare-events@^2.5.4, bare-events@^2.7.0: + version "2.9.1" + resolved "https://registry.yarnpkg.com/bare-events/-/bare-events-2.9.1.tgz#5c86616966343bcb03a1b3155feab253eadbf349" + integrity sha512-Z0oHEHAFDZkffN8Qc39zNZjQlMDkPJRyyyZieU1VH7u8c5S+qHZ2S8ixdKIAxEjfHO7FJxXmJWgteOghVanIsg== + +bare-fs@^4.5.5: + version "4.8.0" + resolved "https://registry.yarnpkg.com/bare-fs/-/bare-fs-4.8.0.tgz#8c0f916833ae11e6d9d347f9e0a7f46f7375bb8f" + integrity sha512-fM+MhCvdQhZ7NV6S95a07gPSqjIYKn6mFaXfx266wN3ajZGl/+1AzH+ubkXQ0fFZvOe2nk9VHkzdYkQE5zMV3Q== + dependencies: + bare-events "^2.5.4" + bare-path "^3.0.0" + bare-stream "^2.6.4" + bare-url "^2.2.2" + fast-fifo "^1.3.2" -bare-events@^2.7.0: - version "2.8.2" - resolved "https://registry.yarnpkg.com/bare-events/-/bare-events-2.8.2.tgz#7b3e10bd8e1fc80daf38bb516921678f566ab89f" - integrity sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ== +bare-path@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/bare-path/-/bare-path-3.1.1.tgz#d4a207c088609b4663a7556a46a97342398bf7e2" + integrity sha512-JprUlveX3QjApC1cTpsUOiscADftCGVWkzitbHsRqv84hzYwYHw2mbluddsq5TvI8mH/8Ov1f4BiMAdcB0oYnQ== + +bare-stream@^2.6.4: + version "2.13.3" + resolved "https://registry.yarnpkg.com/bare-stream/-/bare-stream-2.13.3.tgz#f6186c7cbb4bbf53a4560f35e48b16373ba51ce6" + integrity sha512-Kc+brLqvEqGkjyfiwJmImAOqLZL7OsoLKuavx+hJjgVV3nLTOjloJyPMFxjUPerGGHrNH0fLU06jjykMLWrERQ== + dependencies: + b4a "^1.8.1" + streamx "^2.25.0" + teex "^1.0.1" + +bare-url@^2.2.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/bare-url/-/bare-url-2.5.2.tgz#e8dafaefbdb56891a0fbc2b0e1c051296d241cd6" + integrity sha512-L13PCJzKG8RGvx8V1/DdMi12ERhC3tprr7/8a94BxpmnRsFqxh5XZNdhtMxu5HPkRshYOOWRGY8lDP7ZhpG9Cg== + dependencies: + bare-path "^3.0.0" base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -basic-ftp@^5.2.0: +basic-ftp@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/basic-ftp/-/basic-ftp-5.3.1.tgz#3148ee9af43c0522514a4f973fecb1d3cbb6d71e" integrity sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw== @@ -319,13 +342,12 @@ bcrypt@^6.0.0: node-addon-api "^8.3.0" node-gyp-build "^4.8.4" -better-sqlite3@^12.10.0: - version "12.10.0" - resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-12.10.0.tgz#bde622d14a18008583a53bc53501ae98f1a12221" - integrity sha512-CyzaZRQKyHkB2ZInfTTl2nvT33EbDpjkLEbE8/Zck3Ll6O0qqvuGdrJ45HgtH+HykRg88ITY3AdreBGN70aBSQ== +better-sqlite3@^13.0.3: + version "13.0.3" + resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-13.0.3.tgz#b6ea0dc7fff7e28d04d9093e81051d38f7beabe2" + integrity sha512-RbOBxmLBG8uvFUc15X9+9SFemKcQ0WBuISBVkpuiaUB2qblC8UWlHEjdWVoZ8AdhSwmoEgsiXKfopX0CQxaACQ== dependencies: - bindings "^1.5.0" - prebuild-install "^7.1.1" + node-addon-api "^8.0.0" binary-extensions@^2.0.0: version "2.3.0" @@ -353,25 +375,25 @@ blueimp-md5@^2.16.0: resolved "https://registry.yarnpkg.com/blueimp-md5/-/blueimp-md5-2.19.0.tgz#b53feea5498dcb53dc6ec4b823adb84b729c4af0" integrity sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w== -body-parser@^2.2.1, body-parser@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-2.2.2.tgz#1a32cdb966beaf68de50a9dfbe5b58f83cb8890c" - integrity sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA== +body-parser@^2.2.1, body-parser@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-2.3.0.tgz#6d8662f4d8c336028b8ac9aa24251b0ca64ba437" + integrity sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw== dependencies: bytes "^3.1.2" - content-type "^1.0.5" + content-type "^2.0.0" debug "^4.4.3" - http-errors "^2.0.0" - iconv-lite "^0.7.0" + http-errors "^2.0.1" + iconv-lite "^0.7.2" on-finished "^2.4.1" - qs "^6.14.1" - raw-body "^3.0.1" - type-is "^2.0.1" + qs "^6.15.2" + raw-body "^3.0.2" + type-is "^2.1.0" -brace-expansion@^5.0.5: - version "5.0.6" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-5.0.6.tgz#ec68fe0a641a29d8711579caf641d05bae1f2285" - integrity sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g== +brace-expansion@^5.0.8: + version "5.0.9" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-5.0.9.tgz#7c72438809b5fa5babf54199a1f1c281a6984fcf" + integrity sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg== dependencies: balanced-match "^4.0.2" @@ -560,15 +582,20 @@ compression@^1.8.1: vary "~1.1.2" content-disposition@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-1.0.1.tgz#a8b7bbeb2904befdfb6787e5c0c086959f605f9b" - integrity sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q== + version "1.1.0" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-1.1.0.tgz#f3db789c752d45564cc7e9e1e0b31790d4a38e17" + integrity sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g== content-type@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== +content-type@^2.0.0, content-type@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-2.1.0.tgz#d9389c43c0a8cf6a355db464d21e07092a40493a" + integrity sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag== + cookie-signature@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.2.2.tgz#57c7fc3cc293acab9fec54d73e15690ebe4a1793" @@ -654,11 +681,6 @@ degenerator@7.0.1: escodegen "^2.1.0" esprima "^4.0.1" -denque@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1" - integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== - depd@^2.0.0, depd@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" @@ -735,9 +757,9 @@ es-errors@^1.3.0: integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1" - integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== + version "1.1.2" + resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.2.tgz#a2d0b373205724dfa525d23b0c3e1b1ca582c99b" + integrity sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw== dependencies: es-errors "^1.3.0" @@ -871,9 +893,9 @@ fast-fifo@^1.2.0, fast-fifo@^1.3.2: integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== fast-uri@^3.0.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.2.tgz#8af3d4fc9d3e71b11572cc2673b514a7d1a8c8ec" - integrity sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ== + version "3.1.5" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.5.tgz#610f37419a030270430cecd68d74e3d4d96725d0" + integrity sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw== fdir@^6.5.0: version "6.5.0" @@ -992,12 +1014,12 @@ get-proto@^1.0.1: dunder-proto "^1.0.1" es-object-atoms "^1.0.0" -get-uri@8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-8.0.0.tgz#3ac2e278c4bd8a717be70c8f8f8841e7d6aead93" - integrity sha512-CqtZlMKvfJeY0Zxv8wazDwXmSKmnMnsmNy8j8+wudi8EyG/pMUB1NqHc+Tv1QaNtpYsK9nOYjb7r7Ufu32RPSw== +get-uri@8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-8.0.1.tgz#772b1418bf034c2c43ddd6a41af24a4262e135ee" + integrity sha512-/5N/P4Lrh0p/mDwlDRi7Y1+P2o/OyzZI3l6Iz1Ov6XXwwm1y3RlZLuo3gVgML99djrEDtV980bBxSuOeHLk8ww== dependencies: - basic-ftp "^5.2.0" + basic-ftp "^5.3.1" data-uri-to-buffer "8.0.0" debug "^4.3.4" @@ -1048,10 +1070,10 @@ has-symbols@^1.1.0: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== -hasown@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" - integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== +hasown@^2.0.2, hasown@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.4.tgz#8c62d8cb90beb2aad5d0a5b67581ad9854c3f003" + integrity sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A== dependencies: function-bind "^1.1.2" @@ -1066,26 +1088,28 @@ http-errors@^2.0.0, http-errors@^2.0.1, http-errors@~2.0.1: statuses "~2.0.2" toidentifier "~1.0.1" -http-proxy-agent@9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-9.0.0.tgz#473fe9c2b8ffea87611f8c68dfb9872b835c91d1" - integrity sha512-FcF8VhXYLQcxWCnt/cCpT2apKsRDUGeVEeMqGu4HSTu29U8Yw0TLOjdYIlDsYk3IkUh+taX4IDWpPcCqKDhCjA== +http-proxy-agent@9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-9.1.0.tgz#fd8b39dcb58ac8046139e5f4ea80de78e8beaf7b" + integrity sha512-2NxoveTT58mjYT4n3RPTEfCZGLMbidoO8XEieXfpSYxu+PQJ1qpx4ypwH6N+uF9twBPIvRRgvkvW5HUTYWENig== dependencies: agent-base "9.0.0" debug "^4.3.4" + proxy-agent-negotiate "1.1.0" -https-proxy-agent@9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-9.0.0.tgz#89256adf9dc20926fe43ea1d3ca0feb9e23cc4bd" - integrity sha512-/MVmHp58WkOypgFhCLk4fzpPcFQvTJ/e6LBI7irpIO2HfxUbpmYoHF+KzipzJpxxzJu7aJNWQ0xojJ/dzV2G5g== +https-proxy-agent@9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-9.1.0.tgz#a9f60f79bc1578c37b166dd7f58b6bcb5c57e44b" + integrity sha512-ag87y7cJJ9/3+GxFr8Oy4O5faDsGRGnBGsJj/YjOSsSx/5eadKLYTMPlzuR6obgoCDDm0abAAZitXXQkMOPSpA== dependencies: agent-base "9.0.0" debug "^4.3.4" + proxy-agent-negotiate "1.1.0" -iconv-lite@^0.7.0, iconv-lite@^0.7.2, iconv-lite@~0.7.0: - version "0.7.2" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.7.2.tgz#d0bdeac3f12b4835b7359c2ad89c422a4d1cc72e" - integrity sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw== +iconv-lite@^0.7.2, iconv-lite@^0.7.3, iconv-lite@~0.7.0: + version "0.7.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.7.3.tgz#84ee12f963e7de50bc01a13e160a078b3b0f415f" + integrity sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ== dependencies: safer-buffer ">= 2.1.2 < 3.0.0" @@ -1119,10 +1143,10 @@ interpret@^2.2.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== -ip-address@^10.0.1: - version "10.2.0" - resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-10.2.0.tgz#805fc178b20c518bd4c8548b24fe30892d7f3206" - integrity sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA== +ip-address@^10.1.1: + version "10.5.0" + resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-10.5.0.tgz#fcd6d7dfe9e68416b7cb71afe9bc960b3e38c13b" + integrity sha512-R5SnVLJmgYYvf2F2ZgwSBnelz5G4q5AxIC277GDfUaNbrZKNANcBC7RHqYYePlszf4kBolVkJauG0ZjHHFh55g== ipaddr.js@1.9.1: version "1.9.1" @@ -1142,11 +1166,11 @@ is-binary-path@~2.1.0: binary-extensions "^2.0.0" is-core-module@^2.16.1: - version "2.16.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" - integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== + version "2.16.2" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.2.tgz#3e07450a8080ebce3fbf0cac494f4d2ab324e082" + integrity sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA== dependencies: - hasown "^2.0.2" + hasown "^2.0.3" is-extglob@^2.1.1: version "2.1.1" @@ -1195,10 +1219,17 @@ isexe@^4.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-4.0.0.tgz#48f6576af8e87a18feb796b7ed5e2e5903b43dca" integrity sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw== -js-yaml@^4.1.0, js-yaml@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b" - integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== +js-yaml@^4.1.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.3.1.tgz#01216c001d67f48e2cd560d708c7af21090a3848" + integrity sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ== + dependencies: + argparse "^2.0.1" + +js-yaml@^5.2.3: + version "5.3.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-5.3.0.tgz#526430a6da31065127528ae695ce168cfc5f91f0" + integrity sha512-muutsYr+e2+d3rTgUGslq5rxbBlUy3cJ61IsHag2QNDQV+7zXWjkUpmALIajhrlLlrgRUiymj6U3zUr/TMK84Q== dependencies: argparse "^2.0.1" @@ -1245,10 +1276,10 @@ jws@^4.0.1: jwa "^2.0.1" safe-buffer "^5.0.1" -knex@3.2.10: - version "3.2.10" - resolved "https://registry.yarnpkg.com/knex/-/knex-3.2.10.tgz#ca8f77a10851b1e18b26463a6dc995e563c3b165" - integrity sha512-oypTHfrc9i72iyxaUQBKHOxhcr0xM65MPf6FpN02nimsftXwzXprIkLjfXdubvhbu4PMWLp023q8o8CYvHSuZw== +knex@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/knex/-/knex-3.3.0.tgz#451d24d5670939fc4ce54f2269163dbf2627d682" + integrity sha512-LgWl031hNuLv9Lhxdd9093zULa2aNcoP04Bk29e5NidgRcEr/T0rAr2WYi4BhjTiCDoQiRU56meUE5rppLKZzQ== dependencies: colorette "2.0.19" commander "^10.0.0" @@ -1262,7 +1293,7 @@ knex@3.2.10: pg-connection-string "2.6.2" rechoir "^0.8.0" resolve-from "^5.0.0" - tarn "^3.0.2" + tarn "^3.1.0" tildify "2.0.0" lazystream@^1.0.0: @@ -1272,10 +1303,10 @@ lazystream@^1.0.0: dependencies: readable-stream "^2.0.5" -liquidjs@10.27.0: - version "10.27.0" - resolved "https://registry.yarnpkg.com/liquidjs/-/liquidjs-10.27.0.tgz#e31dc4c539e1a26aee46c847b4e60a6ede32564a" - integrity sha512-tw/OA59K7aIBlMKIrKlumr37fiZUheShVHXY8cVctWisgY1p9mc5hreOvlreoS0wTiwlWk14Ya7305c2a/Cg5w== +liquidjs@10.29.0: + version "10.29.0" + resolved "https://registry.yarnpkg.com/liquidjs/-/liquidjs-10.29.0.tgz#ee061890ccf0da26be377aad4f02bd32da0140d8" + integrity sha512-pCVOhs6FLAR8su3ItJ07diN26t6W5dHQRnmTMy8HPyTFuv1+oSCVJIGp5pGjfQyOZfh50KswvKtMTp6p4JEIdw== dependencies: commander "^10.0.0" @@ -1365,9 +1396,9 @@ math-intrinsics@^1.1.0: integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== media-typer@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-1.1.0.tgz#6ab74b8f2d3320f2064b2a87a38e7931ff3a5561" - integrity sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw== + version "1.1.1" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-1.1.1.tgz#6f035400dfe3ab9d5607bc77546ce30cc2f9c6b8" + integrity sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ== merge-descriptors@^2.0.0: version "2.0.0" @@ -1392,11 +1423,11 @@ mimic-response@^3.1.0: integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== minimatch@^10.2.1, minimatch@^10.2.2: - version "10.2.5" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.2.5.tgz#bd48687a0be38ed2961399105600f832095861d1" - integrity sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg== + version "10.2.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.2.6.tgz#fd956bbe0b77241e9f15ac5dccb1c638060968ef" + integrity sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A== dependencies: - brace-expansion "^5.0.5" + brace-expansion "^5.0.8" minimist@^1.2.0, minimist@^1.2.3: version "1.2.8" @@ -1440,19 +1471,18 @@ ms@^2.1.1, ms@^2.1.3: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -mysql2@^3.22.3: - version "3.22.3" - resolved "https://registry.yarnpkg.com/mysql2/-/mysql2-3.22.3.tgz#884a36a1171501ef752ba90057dbcde528f322e3" - integrity sha512-uWWxvZSRvRhtBdh2CdcuK83YcOfPdmEeEYB069bAmPnV93QApDGVPuvCQOLjlh7tYHEWdgQPrn6kosDxHBVLkA== +mysql2@^3.23.4: + version "3.23.4" + resolved "https://registry.yarnpkg.com/mysql2/-/mysql2-3.23.4.tgz#33550efbf42f05f8b1ecea98b214010680766112" + integrity sha512-J1Rgl8Oy5iw3mOBjKeTMQ3cJNjMYtJYavQVXShsMtSj9rKV8Q1+QaGKNJqDVQFcNINqYYp6Vxd90r69cCoBxBA== dependencies: aws-ssl-profiles "^1.1.2" - denque "^2.1.0" generate-function "^2.3.1" - iconv-lite "^0.7.2" + iconv-lite "^0.7.3" long "^5.3.2" lru.min "^1.1.4" named-placeholders "^1.1.6" - sql-escaper "^1.3.3" + sql-escaper "^1.5.1" named-placeholders@^1.1.6: version "1.1.6" @@ -1467,9 +1497,11 @@ napi-build-utils@^2.0.0: integrity sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA== negotiator@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-1.0.0.tgz#b6c91bb47172d69f93cfd7c357bbb529019b5f6a" - integrity sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg== + version "1.1.0" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-1.1.0.tgz#16e003d0db4ac24fd9df168edf871625deeae3df" + integrity sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg== + dependencies: + content-type "^2.1.0" negotiator@~0.6.4: version "0.6.4" @@ -1477,26 +1509,21 @@ negotiator@~0.6.4: integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== netmask@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7" - integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg== + version "2.1.1" + resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.1.1.tgz#80043d265b53aa521b3bd01e8fcdf353f9e1e81e" + integrity sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA== node-abi@^3.3.0: - version "3.87.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.87.0.tgz#423e28fea5c2f195fddd98acded9938c001ae6dd" - integrity sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ== + version "3.94.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.94.0.tgz#007181ed0d1b56ae9670ea6c084d2bf83538405f" + integrity sha512-W5ZNO5KRPB5TkYmGVD9F6YqhsglXJzE6etpbmT+f6EQElhiX/UTG551cnsRGvLG3fyZEg9HwaDmNmj5nwJ4z9g== dependencies: semver "^7.3.5" -node-addon-api@^8.0.0: - version "8.7.0" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-8.7.0.tgz#f64f8413456ecbe900221305a3f883c37666473f" - integrity sha512-9MdFxmkKaOYVTV+XVRG8ArDwwQ77XIgIPyKASB1k3JPq3M8fGQQQE3YpMOrKm6g//Ktx8ivZr8xo1Qmtqub+GA== - -node-addon-api@^8.3.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-8.5.0.tgz#c91b2d7682fa457d2e1c388150f0dff9aafb8f3f" - integrity sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A== +node-addon-api@^8.0.0, node-addon-api@^8.3.0: + version "8.9.2" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-8.9.2.tgz#db7ac94a13ffd9b55e6cb04584bd5ef8e1d74b18" + integrity sha512-VijLXbi3UACN69I0JVXJsX4tjACjNoQDgv2gTF6sx2wWEi8tkSg2eX8p5gSIFi8z2+DL3oHmY6OyKce38SDolg== node-gyp-build@^4.8.4: version "4.8.4" @@ -1504,9 +1531,9 @@ node-gyp-build@^4.8.4: integrity sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ== node-gyp@12.x: - version "12.3.0" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-12.3.0.tgz#a0e0d9364779451eaf4148b6f9a7366f98000b3f" - integrity sha512-QNcUWM+HgJplcPzBvFBZ9VXacyGZ4+VTOb80PwWR+TlVzoHbRKULNEzpRsnaoxG3Wzr7Qh7BYxGDU3CbKib2Yg== + version "12.4.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-12.4.0.tgz#2d017b6ea1ca9294dbbee75be533728f49257024" + integrity sha512-OMcPNvqTCFUnNaBlmdgq+lfNqY7gTiSmNRDjY3uAXRyudeKZEZxu3CLtjMQrx4zZxCX2b/mpNqTtwuCJgXhHkw== dependencies: env-paths "^2.2.0" exponential-backoff "^3.1.1" @@ -1554,7 +1581,7 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -object-inspect@^1.13.3: +object-inspect@^1.13.3, object-inspect@^1.13.4: version "1.13.4" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213" integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== @@ -1587,17 +1614,17 @@ once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" -otplib@^13.4.0: - version "13.4.0" - resolved "https://registry.yarnpkg.com/otplib/-/otplib-13.4.0.tgz#5743391a7fe1900cb1ac364af0bbb407a72af76b" - integrity sha512-RUcYcRMCgRWhUE/XabRppXpUwCwaWBNHe5iPXhdvP8wwDGpGpsIf/kxX/ec3zFsOaM1Oq8lEhUqDwk6W7DHkwg== +otplib@^13.5.0: + version "13.5.0" + resolved "https://registry.yarnpkg.com/otplib/-/otplib-13.5.0.tgz#78b5d0d9edf83078d7fe37243bbcdd96d7a65d37" + integrity sha512-RpcC6aq4rANX6MverMuU3pqHVLgMPO7vl6qR8ga7YzoEHlPJknJ58cSVAaf3jBYnasiQVQHXXl2mj/4pYlsVEQ== dependencies: - "@otplib/core" "13.4.0" - "@otplib/hotp" "13.4.0" - "@otplib/plugin-base32-scure" "13.4.0" - "@otplib/plugin-crypto-noble" "13.4.0" - "@otplib/totp" "13.4.0" - "@otplib/uri" "13.4.0" + "@otplib/core" "13.5.0" + "@otplib/hotp" "13.5.0" + "@otplib/plugin-base32-scure" "13.5.0" + "@otplib/plugin-crypto-noble" "13.5.0" + "@otplib/totp" "13.5.0" + "@otplib/uri" "13.5.0" p-limit@^1.1.0: version "1.3.0" @@ -1637,19 +1664,19 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== -pac-proxy-agent@9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-9.0.1.tgz#9cee1f8b41b00c53418f10824a8a41b3e07587dd" - integrity sha512-3ZOSpLboOlpW4yp8Cuv21KlTULRqyJ5Uuad3wXpSKFrxdNgcHEyoa22GRaZ2UlgCVuR6z+5BiavtYVvbajL/Yw== +pac-proxy-agent@9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-9.1.0.tgz#cafd7bb54905de0b6804283cd273eb22028c6abd" + integrity sha512-1aU+1mpj3DrQPfo3gh+3Gap3G5x+axnMx1P/y0ZF2ch7kb2meyOCAH8K2k9d27ROsTE7TnAerzxqF9aon2jqnA== dependencies: agent-base "9.0.0" debug "^4.3.4" - get-uri "8.0.0" - http-proxy-agent "9.0.0" - https-proxy-agent "9.0.0" + get-uri "8.0.1" + http-proxy-agent "9.1.0" + https-proxy-agent "9.1.0" pac-resolver "9.0.1" quickjs-wasi "^2.2.0" - socks-proxy-agent "10.0.0" + socks-proxy-agent "10.1.0" pac-resolver@9.0.1: version "9.0.1" @@ -1710,10 +1737,10 @@ pg-connection-string@2.6.2: resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.6.2.tgz#713d82053de4e2bd166fab70cd4f26ad36aab475" integrity sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA== -pg-connection-string@^2.13.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.13.0.tgz#8678113465a5af3cc977dcb51eadc847b27aa2de" - integrity sha512-EMnU9E2fSULdsbErBbMaXJvFeD9B4+nPcM3f+4lsiCR0BHLPrLVjv3DbyM2hgQQviKJaTWIRRTjKjWlHg3p2ig== +pg-connection-string@^2.14.0: + version "2.14.0" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.14.0.tgz#abc26ee4f37c56c0f3ae0fcf0b0653cc4e1c0fd9" + integrity sha512-XwWDGcLRGCXAR8F/AM5bG7Q+A3Wm2s6QeEjlOKZLlH3UYcguiqCWKyWXVag5TLTIjR7oOJUY8kcADaZgWPyLeg== pg-int8@1.0.1: version "1.0.1" @@ -1725,10 +1752,10 @@ pg-pool@^3.14.0: resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.14.0.tgz#f35ae4eb846780cad71af24099b3edfa9781ad90" integrity sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw== -pg-protocol@^1.14.0: - version "1.14.0" - resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.14.0.tgz#c1f045b74274b007078c687147141f785f59b8de" - integrity sha512-n5taZ1kO3s9ngDTVxsEznOqCyToTgz0FLuPq0B33COy5pPpuWJpY3/2oRBVETuOgzdqRXfWpM9HIhp2LBBT1BA== +pg-protocol@^1.16.0: + version "1.16.0" + resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.16.0.tgz#cffb008826561ee9770a8a15dc21f269d731b305" + integrity sha512-sILXutLVjCLjcDuOmvhX5e2Z4cS5qG/6Bu3VkpFwdf/633ElGLpEh9bgmuI5I4sqKqkifQiGyiCcx1HdtrK7tg== pg-types@2.2.0: version "2.2.0" @@ -1741,14 +1768,14 @@ pg-types@2.2.0: postgres-date "~1.0.4" postgres-interval "^1.1.0" -pg@^8.21.0: - version "8.21.0" - resolved "https://registry.yarnpkg.com/pg/-/pg-8.21.0.tgz#d7fa2118d960cec5cc7d2b24525f9850dd5932b0" - integrity sha512-AUP1EYJuHraQGsVoCQVIcM7TEJVGtDzxWtGFZd8rds9d+CCXlU5Js1rYgfLNvxy9iJrpHjGrRjoi/3BT9fRyiA== +pg@^8.23.0: + version "8.23.0" + resolved "https://registry.yarnpkg.com/pg/-/pg-8.23.0.tgz#5c2026d32bd0cb4fbd9196bac1ecf5ae66607180" + integrity sha512-Ip2EQCngowJLGOfCwkFhPXU7/ljlhn6Rxlmy4XYfL2Y+vyRM59+8uR2xqRWKdYmbXmxCFOAmKxBuSUCdF34qLg== dependencies: - pg-connection-string "^2.13.0" + pg-connection-string "^2.14.0" pg-pool "^3.14.0" - pg-protocol "^1.14.0" + pg-protocol "^1.16.0" pg-types "2.2.0" pgpass "1.0.5" optionalDependencies: @@ -1767,9 +1794,9 @@ picomatch@^2.0.4, picomatch@^2.2.1: integrity sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA== picomatch@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.4.tgz#fd6f5e00a143086e074dffe4c924b8fb293b0589" - integrity sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A== + version "4.0.5" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.5.tgz#51ea57a17d86f605f81039595fbc40ed06a55fab" + integrity sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A== pify@^3.0.0: version "3.0.0" @@ -1806,7 +1833,7 @@ postgres-interval@^1.1.0: dependencies: xtend "^4.0.0" -prebuild-install@^7.1.1, prebuild-install@^7.1.3: +prebuild-install@^7.1.3: version "7.1.3" resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.3.tgz#d630abad2b147443f20a212917beae68b8092eec" integrity sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug== @@ -1847,19 +1874,24 @@ proxy-addr@^2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" -proxy-agent@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-8.0.1.tgz#4819c7b14637c6940424aeed840e9883a378a15d" - integrity sha512-kccqGBqHZXR8onQhY/ganJjoO8QIKKRiFBhPOzbTZK16attzSZ/0XSmp9H7jrRxPKHjhGyx1q32lMPrJ3uLFgA== +proxy-agent-negotiate@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-agent-negotiate/-/proxy-agent-negotiate-1.1.0.tgz#de7d37aede9d71e74346125d6f484fac8092b615" + integrity sha512-N8IBcM3UgCVzz2L2Lqv8DVntDnnC8/hiV4nEDUPkqq72TPUgYWjQc+bdZlBPZK9LzPAvOY//gAt0S0DApoOXWQ== + +proxy-agent@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-8.0.2.tgz#70737a3b9cdc8bd7a282c9e6ff54a64f5252413c" + integrity sha512-idLLRewuemWd7GH/BDJzGiB0dWGfT2SQs3jy6NtZtGWU9uPTTSdeC1/cdbqLwgzhfv027daGFuXX426e2Eg20A== dependencies: agent-base "9.0.0" debug "^4.3.4" - http-proxy-agent "9.0.0" - https-proxy-agent "9.0.0" + http-proxy-agent "9.1.0" + https-proxy-agent "9.1.0" lru-cache "^7.14.1" - pac-proxy-agent "9.0.1" + pac-proxy-agent "9.1.0" proxy-from-env "^2.0.0" - socks-proxy-agent "10.0.0" + socks-proxy-agent "10.1.0" proxy-from-env@^2.0.0: version "2.1.0" @@ -1872,19 +1904,20 @@ pstree.remy@^1.1.8: integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== pump@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.3.tgz#151d979f1a29668dc0025ec589a455b53282268d" - integrity sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA== + version "3.0.4" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.4.tgz#1f313430527fa8b905622ebd22fe1444e757ab3c" + integrity sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA== dependencies: end-of-stream "^1.1.0" once "^1.3.1" -qs@^6.14.0, qs@^6.14.1: - version "6.15.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.15.2.tgz#fd55426d710403ddccc45e0f9eab16db7727ece9" - integrity sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw== +qs@^6.14.0, qs@^6.15.2: + version "6.15.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.15.3.tgz#76852132a58ed5c7c0ef67e4441b9bb5d6061b3b" + integrity sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A== dependencies: - side-channel "^1.1.0" + es-define-property "^1.0.1" + side-channel "^1.1.1" querystring@0.2.0: version "0.2.0" @@ -1897,11 +1930,11 @@ quickjs-wasi@^2.2.0: integrity sha512-zQxXmQMrEoD3S+jQdYsloq4qAuaxKFHZj6hHqOYGwB2iQZH+q9e/lf5zQPXCKOk0WJuAjzRFbO4KwHIp2D05Iw== range-parser@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + version "1.3.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.3.0.tgz#d7f19be812bb62721472b45d3be219ef09572b47" + integrity sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw== -raw-body@^3.0.1: +raw-body@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-3.0.2.tgz#3e3ada5ae5568f9095d84376fd3a49b8fb000a51" integrity sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA== @@ -1996,10 +2029,11 @@ resolve-from@^5.0.0: integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== resolve@^1.20.0: - version "1.22.11" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.11.tgz#aad857ce1ffb8bfa9b0b1ac29f1156383f68c262" - integrity sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ== + version "1.22.12" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.12.tgz#f5b2a680897c69c238a13cd16b15671f8b73549f" + integrity sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA== dependencies: + es-errors "^1.3.0" is-core-module "^2.16.1" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -2031,9 +2065,9 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== semver@^7.3.5, semver@^7.5.3, semver@^7.5.4: - version "7.7.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.4.tgz#28464e36060e991fa7a11d0279d2d3f3b57a7e8a" - integrity sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA== + version "7.8.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.8.5.tgz#39b646037dd50c14fb451e7e4cac58ed8b863f69" + integrity sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA== send@^1.1.0, send@^1.2.0: version "1.2.1" @@ -2072,13 +2106,13 @@ setprototypeof@~1.2.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== -side-channel-list@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad" - integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== +side-channel-list@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.1.tgz#c2e0b5a14a540aebee3bbc6c3f8666cc9b509127" + integrity sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w== dependencies: es-errors "^1.3.0" - object-inspect "^1.13.3" + object-inspect "^1.13.4" side-channel-map@^1.0.1: version "1.0.1" @@ -2101,14 +2135,14 @@ side-channel-weakmap@^1.0.2: object-inspect "^1.13.3" side-channel-map "^1.0.1" -side-channel@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9" - integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== +side-channel@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.1.tgz#ea02c62e05dc4bea67d4442f0fb71ee192f8e0ab" + integrity sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ== dependencies: es-errors "^1.3.0" - object-inspect "^1.13.3" - side-channel-list "^1.0.0" + object-inspect "^1.13.4" + side-channel-list "^1.0.1" side-channel-map "^1.0.1" side-channel-weakmap "^1.0.2" @@ -2147,21 +2181,21 @@ smart-buffer@^4.2.0: resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== -socks-proxy-agent@10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-10.0.0.tgz#e94a497f890d790a67274c19837c5bbe3f182220" - integrity sha512-pyp2YR3mNxAMu0mGLtzs4g7O3uT4/9sQOLAKcViAkaS9fJWkud7nmaf6ZREFqQEi24IPkBcjfHjXhPTUWjo3uA== +socks-proxy-agent@10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-10.1.0.tgz#8eaf7d64ad8752ca43ab04a1a9567be9b7fc40b1" + integrity sha512-WlMj/67cEJ6MDI1OcsnjuYKDNDoyPCCYZ249kuuXPiMDw9F8PXkVaQ7YWu3siTydfQ/4BEZcvGzu+aYvz7dDCQ== dependencies: agent-base "9.0.0" debug "^4.3.4" socks "^2.8.3" socks@^2.8.3: - version "2.8.7" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.7.tgz#e2fb1d9a603add75050a2067db8c381a0b5669ea" - integrity sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A== + version "2.8.9" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.9.tgz#aa5f130ca0f88a43fa44faf4869c50d22aa27752" + integrity sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw== dependencies: - ip-address "^10.0.1" + ip-address "^10.1.1" smart-buffer "^4.2.0" source-map@~0.6.1: @@ -2174,10 +2208,10 @@ split2@^4.1.0: resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== -sql-escaper@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/sql-escaper/-/sql-escaper-1.3.3.tgz#65faf89f048d26bb9a75566b82b5990ddf8a5b7f" - integrity sha512-BsTCV265VpTp8tm1wyIm1xqQCS+Q9NHx2Sr+WcnUrgLrQ6yiDIvHYJV5gHxsj1lMBy2zm5twLaZao8Jd+S8JJw== +sql-escaper@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/sql-escaper/-/sql-escaper-1.5.1.tgz#fbaee511294d1f7da92fb68ca1faee2255839c7b" + integrity sha512-4toX5E1fQbBrpfXidaHnF0669nkAdETeIPTs2SUjxxD7RRIs9ICG4gtpmfc68JCEKehsdwLFqBu9VlQqZ1P1gg== sqlite3@^6.0.1: version "6.0.1" @@ -2201,10 +2235,10 @@ streamsearch@^1.1.0: resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== -streamx@^2.15.0: - version "2.23.0" - resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.23.0.tgz#7d0f3d00d4a6c5de5728aecd6422b4008d66fd0b" - integrity sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg== +streamx@^2.12.5, streamx@^2.15.0, streamx@^2.25.0: + version "2.28.0" + resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.28.0.tgz#035ab56057b7ed2211b51d532e6973f0f99fbf11" + integrity sha512-1Yowhzjf0ivGMrTIkY9hav5TxobO9qIVqUE41fiCGMGgc3CLlf4MY+9AHmZqBWgDTue0fY9zWjYFVyf6Diuobw== dependencies: events-universal "^1.0.0" fast-fifo "^1.3.2" @@ -2263,9 +2297,9 @@ supports-preserve-symlinks-flag@^1.0.0: integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== tar-fs@^2.0.0: - version "2.1.4" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.4.tgz#800824dbf4ef06ded9afea4acafe71c67c76b930" - integrity sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ== + version "2.1.5" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.5.tgz#33e9c29413dce0c58ada7ff77db4e5a30afffe70" + integrity sha512-OboTd8mmMhZDNPV+UjQcK9yKAatXu2aJ+r1w4im1Otd4M4fl2hwvdoXUxIYHFTHWK/3y3FarBP70v3vwmGlOxw== dependencies: chownr "^1.1.1" mkdirp-classic "^0.5.2" @@ -2284,18 +2318,19 @@ tar-stream@^2.1.4: readable-stream "^3.1.1" tar-stream@^3.0.0: - version "3.1.7" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-3.1.7.tgz#24b3fb5eabada19fe7338ed6d26e5f7c482e792b" - integrity sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ== + version "3.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-3.2.0.tgz#0d0064d9b67ea3c9f5abde155e35faab0df37591" + integrity sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg== dependencies: b4a "^1.6.4" + bare-fs "^4.5.5" fast-fifo "^1.2.0" streamx "^2.15.0" tar@^7.5.10, tar@^7.5.4: - version "7.5.15" - resolved "https://registry.yarnpkg.com/tar/-/tar-7.5.15.tgz#afe6d1316cddf614a566e3813e42fe01aed46fee" - integrity sha512-dzGK0boVlC4W5QFuQN1EFSl3bIDYsk7Tj40U6eIBnK2k/8ml7TZ5agbI5j5+qnoVcAA+rNtBml8SEiLxZpNqRQ== + version "7.5.22" + resolved "https://registry.yarnpkg.com/tar/-/tar-7.5.22.tgz#a696f998136e71487dc3f869a85bba2c67971ba9" + integrity sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA== dependencies: "@isaacs/fs-minipass" "^4.0.0" chownr "^3.0.0" @@ -2303,10 +2338,17 @@ tar@^7.5.10, tar@^7.5.4: minizlib "^3.1.0" yallist "^5.0.0" -tarn@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/tarn/-/tarn-3.0.2.tgz#73b6140fbb881b71559c4f8bfde3d9a4b3d27693" - integrity sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ== +tarn@^3.1.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/tarn/-/tarn-3.1.2.tgz#d2922d34a232c8b027605f3873a9c55318ce4f34" + integrity sha512-3RTvqKZcK/17jnJ8rMKFXbyNogywTs1z0gVPPwFsJGX46rkmUHOdIaSQ/aVO1rS7nH+soiXiWk7rvUXxndm8Dg== + +teex@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/teex/-/teex-1.0.1.tgz#b8fa7245ef8e8effa8078281946c85ab780a0b12" + integrity sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg== + dependencies: + streamx "^2.12.5" temp-dir@^3.0.0: version "3.0.0" @@ -2335,9 +2377,9 @@ tildify@2.0.0: integrity sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw== tinyglobby@^0.2.12: - version "0.2.16" - resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.16.tgz#1c3b7eb953fce42b226bc5a1ee06428281aff3d6" - integrity sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg== + version "0.2.17" + resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.17.tgz#562a9a6c9eb2b3b123d39719f9af5bb44fcd7631" + integrity sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g== dependencies: fdir "^6.5.0" picomatch "^4.0.4" @@ -2371,12 +2413,12 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" -type-is@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-2.0.1.tgz#64f6cf03f92fce4015c2b224793f6bdd4b068c97" - integrity sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw== +type-is@^2.0.1, type-is@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-2.1.0.tgz#71d1a7053293582e16ac9f3ebaf1ab9aa49e5570" + integrity sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA== dependencies: - content-type "^1.0.5" + content-type "^2.0.0" media-typer "^1.1.0" mime-types "^3.0.0" @@ -2386,9 +2428,14 @@ undefsafe@^2.0.5: integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== undici@^6.25.0: - version "6.25.0" - resolved "https://registry.yarnpkg.com/undici/-/undici-6.25.0.tgz#8c4efb8c998dc187fc1cfb5dde1ef19a211849fb" - integrity sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg== + version "6.28.0" + resolved "https://registry.yarnpkg.com/undici/-/undici-6.28.0.tgz#9f0e385744fef5021d6596c5bccd783f61193c1c" + integrity sha512-LIY910g9TI13YS95lrMFrs8Rm/u/irgHeTWoKCoteeJ04CUJ92eEfj0rVn+7VKMPBpUPiUoBKfhNyLI23EE/KA== + +undici@^8.10.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/undici/-/undici-8.10.0.tgz#67ed7c4087f0f40fba7bef3a46f2be80572f2473" + integrity sha512-HvltHd7avK13QIw/oLe4qoOLyoVSoafqJ2jYOrtMRBkbYT31eiBQ8O0ehRKZiEZCMEyLFQNIADpgCWC5fALvYQ== unpipe@~1.0.0: version "1.0.0" From 4ecb047299b23a8735abbe9c0de0b10e5885c4b5 Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Sat, 22 Aug 2026 23:23:20 +1000 Subject: [PATCH 29/77] Update frontend packages - Major update for react-table - Fix Hosts menu staying around after selecting a menu item --- frontend/biome.json | 163 +- frontend/package.json | 50 +- frontend/src/components/EmptyData.tsx | 11 +- .../components/Form/AccessClientFields.tsx | 23 +- .../src/components/Form/BasicAuthFields.tsx | 11 +- .../src/components/Form/SSLOptionsFields.tsx | 14 +- frontend/src/components/SiteHeader.tsx | 5 +- frontend/src/components/SiteMenu.tsx | 16 +- frontend/src/components/Table/EmptyRow.tsx | 9 +- frontend/src/components/Table/TableBody.tsx | 4 +- frontend/src/components/Table/TableHeader.tsx | 4 +- frontend/src/components/Table/TableHelpers.ts | 2 +- frontend/src/components/Table/TableLayout.tsx | 9 +- frontend/src/components/Table/features.ts | 35 + frontend/src/components/Table/index.ts | 1 + frontend/src/locale/IntlProvider.tsx | 164 +- frontend/src/locale/Utils.ts | 7 +- frontend/src/locale/src/HelpDoc/et/index.ts | 2 +- frontend/src/locale/src/HelpDoc/index.ts | 17 +- frontend/src/locale/src/HelpDoc/ko/index.ts | 1 - frontend/src/locale/src/HelpDoc/tr/index.ts | 1 - frontend/src/modals/DNSCertificateModal.tsx | 6 +- frontend/src/modals/HTTPCertificateModal.tsx | 6 +- frontend/src/modals/RedirectionHostModal.tsx | 28 +- frontend/src/modals/StreamModal.tsx | 4 +- frontend/src/modals/TwoFactorModal.tsx | 15 +- frontend/src/pages/Access/Table.tsx | 10 +- frontend/src/pages/AuditLog/Table.tsx | 14 +- frontend/src/pages/Certificates/Table.tsx | 10 +- frontend/src/pages/Login/index.tsx | 4 +- frontend/src/pages/Nginx/DeadHosts/Table.tsx | 19 +- frontend/src/pages/Nginx/ProxyHosts/Table.tsx | 21 +- .../pages/Nginx/RedirectionHosts/Table.tsx | 19 +- frontend/src/pages/Nginx/Streams/Table.tsx | 21 +- frontend/src/pages/Users/Table.tsx | 10 +- frontend/yarn.lock | 1658 +++++++++-------- 36 files changed, 1282 insertions(+), 1112 deletions(-) create mode 100644 frontend/src/components/Table/features.ts diff --git a/frontend/biome.json b/frontend/biome.json index 13f21e36ba..e84969d2b0 100644 --- a/frontend/biome.json +++ b/frontend/biome.json @@ -1,92 +1,75 @@ { - "$schema": "https://biomejs.dev/schemas/2.4.15/schema.json", - "vcs": { - "enabled": true, - "clientKind": "git", - "useIgnoreFile": true - }, - "files": { - "ignoreUnknown": false, - "includes": [ - "**/*.ts", - "**/*.tsx", - "**/*.js", - "**/*.jsx", - "!**/dist/**/*" - ] - }, - "formatter": { - "enabled": true, - "indentStyle": "tab", - "indentWidth": 4, - "lineWidth": 120, - "formatWithErrors": true - }, - "assist": { - "actions": { - "source": { - "organizeImports": { - "level": "on", - "options": { - "groups": [ - ":BUN:", - ":NODE:", - [ - "npm:*", - "npm:*/**" - ], - ":PACKAGE_WITH_PROTOCOL:", - ":URL:", - ":PACKAGE:", - [ - "/src/*", - "/src/**" - ], - [ - "/**" - ], - [ - "#*", - "#*/**" - ], - ":PATH:" - ] - } - } - } - } - }, - "linter": { - "enabled": true, - "rules": { - "recommended": true, - "correctness": { - "useUniqueElementIds": "off" - }, - "suspicious": { - "noExplicitAny": "off", - "noArrayIndexKey": "off" - }, - "performance": { - "noDelete": "off" - }, - "nursery": "off", - "a11y": { - "useSemanticElements": "off", - "useValidAnchor": "off" - }, - "style": { - "noParameterAssign": "error", - "useAsConstAssertion": "error", - "useDefaultParameterLast": "error", - "useEnumInitializers": "error", - "useSelfClosingElements": "error", - "useSingleVarDeclarator": "error", - "noUnusedTemplateLiteral": "error", - "useNumberNamespace": "error", - "noInferrableTypes": "error", - "noUselessElse": "error" - } - } - } + "$schema": "https://biomejs.dev/schemas/2.5.10/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "ignoreUnknown": false, + "includes": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "!**/dist/**/*"] + }, + "formatter": { + "enabled": true, + "indentStyle": "tab", + "indentWidth": 4, + "lineWidth": 120, + "formatWithErrors": true + }, + "assist": { + "actions": { + "source": { + "organizeImports": { + "level": "on", + "options": { + "groups": [ + ":BUN:", + ":NODE:", + ["npm:*", "npm:*/**"], + ":PACKAGE_WITH_PROTOCOL:", + ":URL:", + ":PACKAGE:", + ["/src/*", "/src/**"], + ["/**"], + ["#*", "#*/**"], + ":PATH:" + ] + } + } + } + } + }, + "linter": { + "enabled": true, + "rules": { + "preset": "recommended", + "correctness": { + "useUniqueElementIds": "off" + }, + "suspicious": { + "noExplicitAny": "off", + "noArrayIndexKey": "off" + }, + "performance": { + "noDelete": "off" + }, + "nursery": "off", + "a11y": { + "useSemanticElements": "off", + "useValidAnchor": "off" + }, + "style": { + "noParameterAssign": "error", + "useAsConstAssertion": "error", + "useDefaultParameterLast": "error", + "useEnumInitializers": "error", + "useSelfClosingElements": "error", + "useSingleVarDeclarator": "error", + "noUnusedTemplateLiteral": "error", + "useNumberNamespace": "error", + "noInferrableTypes": "error", + "noUselessElse": "error" + } + } + } } diff --git a/frontend/package.json b/frontend/package.json index a592fda5c8..ceacd3e702 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,50 +17,50 @@ }, "dependencies": { "@tabler/core": "^1.4.0", - "@tabler/icons-react": "^3.44.0", - "@tanstack/react-query": "^5.101.0", - "@tanstack/react-table": "^8.21.3", + "@tabler/icons-react": "^3.46.0", + "@tanstack/react-query": "^5.101.4", + "@tanstack/react-table": "^9.1.2", "@uiw/react-textarea-code-editor": "^3.1.1", "classnames": "^2.5.1", - "country-flag-icons": "^1.6.17", + "country-flag-icons": "^1.6.20", "date-fns": "^4.4.0", "ez-modal-react": "^1.0.5", "formik": "^2.4.9", "generate-password-browser": "^1.1.0", "humps": "^2.0.1", - "query-string": "^9.4.0", - "react": "^19.2.7", + "query-string": "^9.5.0", + "react": "^19.2.8", "react-bootstrap": "^2.10.10", - "react-dom": "^19.2.7", - "react-intl": "^10.1.11", + "react-dom": "^19.2.8", + "react-intl": "^10.1.22", "react-markdown": "^10.1.0", - "react-router-dom": "^7.16.0", + "react-router-dom": "^7.18.2", "react-select": "^5.10.2", "react-toastify": "^11.1.0", - "rooks": "^9.8.0" + "rooks": "^9.9.0" }, "devDependencies": { - "@biomejs/biome": "^2.4.15", - "@formatjs/cli": "^6.16.6", - "@tanstack/react-query-devtools": "^5.100.14", + "@biomejs/biome": "^2.5.10", + "@formatjs/cli": "^6.16.19", + "@tanstack/react-query-devtools": "^5.101.4", "@testing-library/dom": "^10.4.1", - "@testing-library/jest-dom": "^6.9.1", + "@testing-library/jest-dom": "^7.0.1", "@testing-library/react": "^16.3.2", "@types/country-flag-icons": "^1.2.2", "@types/humps": "^2.0.6", - "@types/node": "^25.9.1", - "@types/react": "^19.2.16", - "@types/react-dom": "^19.2.3", + "@types/node": "^26.2.0", + "@types/react": "^19.2.18", + "@types/react-dom": "^19.2.4", "@types/react-table": "^7.7.20", - "@vitejs/plugin-react": "^6.0.2", - "happy-dom": "^20.9.0", - "postcss": "^8.5.15", + "@vitejs/plugin-react": "^6.1.0", + "happy-dom": "^20.11.6", + "postcss": "^8.5.26", "postcss-simple-vars": "^7.0.1", - "sass": "^1.100.0", + "sass": "^1.103.1", "tmp": "^0.2.7", - "typescript": "6.0.3", - "vite": "^8.0.16", - "vite-plugin-checker": "^0.14.1", - "vitest": "^4.1.8" + "typescript": "7.0.2", + "vite": "^8.2.2", + "vite-plugin-checker": "^0.14.5", + "vitest": "^4.1.11" } } diff --git a/frontend/src/components/EmptyData.tsx b/frontend/src/components/EmptyData.tsx index 46a9664c2f..104c8a3611 100644 --- a/frontend/src/components/EmptyData.tsx +++ b/frontend/src/components/EmptyData.tsx @@ -1,12 +1,13 @@ -import type { Table as ReactTable } from "@tanstack/react-table"; +import type { Table as ReactTable, RowData } from "@tanstack/react-table"; import cn from "classnames"; import type { ReactNode } from "react"; import { Button, HasPermission } from "src/components"; +import type { Features } from "src/components/Table/features"; import { T } from "src/locale"; import { type ADMIN, MANAGE, type Permission, type Section } from "src/modules/Permissions"; -interface Props { - tableInstance: ReactTable; +interface Props { + tableInstance: ReactTable; onNew?: () => void; isFiltered?: boolean; object: string; @@ -16,7 +17,7 @@ interface Props { permissionSection?: Section | typeof ADMIN; permission?: Permission; } -function EmptyData({ +function EmptyData({ tableInstance, onNew, isFiltered, @@ -26,7 +27,7 @@ function EmptyData({ customAddBtn, permissionSection, permission, -}: Props) { +}: Props) { return ( diff --git a/frontend/src/components/Form/AccessClientFields.tsx b/frontend/src/components/Form/AccessClientFields.tsx index 9dda8c3de0..bac4458409 100644 --- a/frontend/src/components/Form/AccessClientFields.tsx +++ b/frontend/src/components/Form/AccessClientFields.tsx @@ -65,8 +65,12 @@ export function AccessClientFields({ initialValues, name = "clients" }: Props) { value={client.directive} onChange={(e) => handleChange(idx, "directive", e.target.value)} > - - + +
))} @@ -112,7 +113,9 @@ export function AccessClientFields({ initialValues, name = "clients" }: Props) { value="deny" disabled > - + ))} diff --git a/frontend/src/components/Form/SSLOptionsFields.tsx b/frontend/src/components/Form/SSLOptionsFields.tsx index ecf23d26f1..ebfe38a65d 100644 --- a/frontend/src/components/Form/SSLOptionsFields.tsx +++ b/frontend/src/components/Form/SSLOptionsFields.tsx @@ -10,7 +10,13 @@ interface Props { requireDomainNames?: boolean; // used for streams color?: string; } -export function SSLOptionsFields({ forHttp = true, forProxyHost = false, forceDNSForNew, requireDomainNames, color = "bg-cyan" }: Props) { +export function SSLOptionsFields({ + forHttp = true, + forProxyHost = false, + forceDNSForNew, + requireDomainNames, + color = "bg-cyan", +}: Props) { const { values, setFieldValue } = useFormikContext(); const v: any = values || {}; @@ -116,10 +122,12 @@ export function SSLOptionsFields({ forHttp = true, forProxyHost = false, forceDN ); - const getHttpAdvancedOptions = () =>( + const getHttpAdvancedOptions = () => (
- + + +
diff --git a/frontend/src/components/SiteHeader.tsx b/frontend/src/components/SiteHeader.tsx index f00d38d6ed..bf28640a0a 100644 --- a/frontend/src/components/SiteHeader.tsx +++ b/frontend/src/components/SiteHeader.tsx @@ -72,7 +72,10 @@ export function SiteHeader() {
{/* biome-ignore lint/a11y/noStaticElementInteractions lint/a11y/useKeyWithClickEvents: This div is not interactive. */} -
e.stopPropagation()}> +
e.stopPropagation()} + >
{currentUser?.nickname}
diff --git a/frontend/src/components/SiteMenu.tsx b/frontend/src/components/SiteMenu.tsx index 265150bb54..565fa01bf9 100644 --- a/frontend/src/components/SiteMenu.tsx +++ b/frontend/src/components/SiteMenu.tsx @@ -143,7 +143,6 @@ const getMenuDropown = (item: MenuItem, onClick?: () => void) => { className="nav-link dropdown-toggle" href={item.to} data-bs-toggle="dropdown" - data-bs-auto-close="outside" aria-expanded="false" role="button" > @@ -176,13 +175,14 @@ const getMenuDropown = (item: MenuItem, onClick?: () => void) => { }; export function SiteMenu() { - const closeMenu = () => setTimeout(() => { - const navbarToggler = document.querySelector(".navbar-toggler"); - const navbarMenu = document.querySelector("#navbar-menu"); - if (navbarToggler && navbarMenu?.classList.contains("show")) { - navbarToggler.click(); - } - }, 300); + const closeMenu = () => + setTimeout(() => { + const navbarToggler = document.querySelector(".navbar-toggler"); + const navbarMenu = document.querySelector("#navbar-menu"); + if (navbarToggler && navbarMenu?.classList.contains("show")) { + navbarToggler.click(); + } + }, 300); return (
diff --git a/frontend/src/components/Table/EmptyRow.tsx b/frontend/src/components/Table/EmptyRow.tsx index 2daee952ac..ada39e3e16 100644 --- a/frontend/src/components/Table/EmptyRow.tsx +++ b/frontend/src/components/Table/EmptyRow.tsx @@ -1,9 +1,10 @@ -import type { Table as ReactTable } from "@tanstack/react-table"; +import type { Table as ReactTable, RowData } from "@tanstack/react-table"; +import type { Features } from "./features"; -interface Props { - tableInstance: ReactTable; +interface Props { + tableInstance: ReactTable; } -function EmptyRow({ tableInstance }: Props) { +function EmptyRow({ tableInstance }: Props) { return ( diff --git a/frontend/src/components/Table/TableBody.tsx b/frontend/src/components/Table/TableBody.tsx index d8fe9bf3a4..a3114196b8 100644 --- a/frontend/src/components/Table/TableBody.tsx +++ b/frontend/src/components/Table/TableBody.tsx @@ -1,8 +1,8 @@ -import { flexRender } from "@tanstack/react-table"; +import { flexRender, type RowData } from "@tanstack/react-table"; import type { TableLayoutProps } from "src/components"; import { EmptyRow } from "./EmptyRow"; -function TableBody(props: TableLayoutProps) { +function TableBody(props: TableLayoutProps) { const { tableInstance, extraStyles, emptyState } = props; const rows = tableInstance.getRowModel().rows; diff --git a/frontend/src/components/Table/TableHeader.tsx b/frontend/src/components/Table/TableHeader.tsx index dd409d59d8..f656c4656e 100644 --- a/frontend/src/components/Table/TableHeader.tsx +++ b/frontend/src/components/Table/TableHeader.tsx @@ -1,8 +1,8 @@ import { IconArrowsSort, IconChevronDown, IconChevronUp } from "@tabler/icons-react"; -import { flexRender } from "@tanstack/react-table"; +import { flexRender, type RowData } from "@tanstack/react-table"; import type { TableLayoutProps } from "src/components"; -function TableHeader(props: TableLayoutProps) { +function TableHeader(props: TableLayoutProps) { const { tableInstance } = props; const headerGroups = tableInstance.getHeaderGroups(); diff --git a/frontend/src/components/Table/TableHelpers.ts b/frontend/src/components/Table/TableHelpers.ts index 0df329c804..a6302e09bf 100644 --- a/frontend/src/components/Table/TableHelpers.ts +++ b/frontend/src/components/Table/TableHelpers.ts @@ -61,4 +61,4 @@ const tableEventReducer = (state: any, { type, payload }: any) => { } }; -export { tableEvents, tableEventReducer }; +export { tableEventReducer, tableEvents }; diff --git a/frontend/src/components/Table/TableLayout.tsx b/frontend/src/components/Table/TableLayout.tsx index 630340919d..5db64bafc0 100644 --- a/frontend/src/components/Table/TableLayout.tsx +++ b/frontend/src/components/Table/TableLayout.tsx @@ -1,15 +1,16 @@ -import type { Table as ReactTable } from "@tanstack/react-table"; +import type { Table as ReactTable, RowData } from "@tanstack/react-table"; +import type { Features } from "./features"; import { TableBody } from "./TableBody"; import { TableHeader } from "./TableHeader"; -interface TableLayoutProps { - tableInstance: ReactTable; +interface TableLayoutProps { + tableInstance: ReactTable; emptyState?: React.ReactNode; extraStyles?: { row: (rowData: TFields) => any | undefined; }; } -function TableLayout(props: TableLayoutProps) { +function TableLayout(props: TableLayoutProps) { const hasRows = props.tableInstance.getRowModel().rows.length > 0; return (
diff --git a/frontend/src/components/Table/features.ts b/frontend/src/components/Table/features.ts new file mode 100644 index 0000000000..9b79e1d596 --- /dev/null +++ b/frontend/src/components/Table/features.ts @@ -0,0 +1,35 @@ +import { + columnVisibilityFeature, + createSortedRowModel, + metaHelper, + rowSortingFeature, + tableFeatures, +} from "@tanstack/react-table"; + +interface ColumnMeta { + className?: string; +} + +interface TableMeta { + isFetching?: boolean; +} + +/** + * Shared TanStack Table v9 feature registration for every table in the app. + * Sorting and column visibility are used (or their APIs are called + * unconditionally, e.g. `getVisibleFlatColumns`/`getVisibleCells`) by the + * shared TableLayout/TableHeader/TableBody/EmptyData components, so every + * table instance must register them even when a particular table doesn't + * wire up controlled sorting state itself. + */ +const features = tableFeatures({ + rowSortingFeature, + sortedRowModel: createSortedRowModel(), + columnVisibilityFeature, + columnMeta: metaHelper(), + tableMeta: metaHelper(), +}); + +type Features = typeof features; + +export { type ColumnMeta, type Features, features, type TableMeta }; diff --git a/frontend/src/components/Table/index.ts b/frontend/src/components/Table/index.ts index d471d45d5c..84b64610a5 100644 --- a/frontend/src/components/Table/index.ts +++ b/frontend/src/components/Table/index.ts @@ -1,4 +1,5 @@ export * from "./Formatter"; +export * from "./features"; export * from "./TableHeader"; export * from "./TableHelpers"; export * from "./TableLayout"; diff --git a/frontend/src/locale/IntlProvider.tsx b/frontend/src/locale/IntlProvider.tsx index a5fb956c0d..a001a231b3 100755 --- a/frontend/src/locale/IntlProvider.tsx +++ b/frontend/src/locale/IntlProvider.tsx @@ -27,73 +27,73 @@ import langList from "./lang/lang-list.json"; // not the country code // Remember when adding to this list, also update check-locales.js script const localeOptions = [ - ["en", "en-US", langEn], - ["de", "de-DE", langDe], - ["es", "es-ES", langEs], - ["et", "et-EE", langEt], - ["pt", "pt-PT", langPt], - ["fr", "fr-FR", langFr], - ["ga", "ga-IE", langGa], - ["ja", "ja-JP", langJa], - ["it", "it-IT", langIt], - ["nl", "nl-NL", langNl], - ["pl", "pl-PL", langPl], - ["ru", "ru-RU", langRu], - ["sk", "sk-SK", langSk], - ["cs", "cs-CZ", langCs], - ["vi", "vi-VN", langVi], - ["zh", "zh-CN", langZh], - ["ko", "ko-KR", langKo], - ["bg", "bg-BG", langBg], - ["id", "id-ID", langId], - ["tr", "tr-TR", langTr], - ["hu", "hu-HU", langHu], - ["no", "no-NO", langNo], + ["en", "en-US", langEn], + ["de", "de-DE", langDe], + ["es", "es-ES", langEs], + ["et", "et-EE", langEt], + ["pt", "pt-PT", langPt], + ["fr", "fr-FR", langFr], + ["ga", "ga-IE", langGa], + ["ja", "ja-JP", langJa], + ["it", "it-IT", langIt], + ["nl", "nl-NL", langNl], + ["pl", "pl-PL", langPl], + ["ru", "ru-RU", langRu], + ["sk", "sk-SK", langSk], + ["cs", "cs-CZ", langCs], + ["vi", "vi-VN", langVi], + ["zh", "zh-CN", langZh], + ["ko", "ko-KR", langKo], + ["bg", "bg-BG", langBg], + ["id", "id-ID", langId], + ["tr", "tr-TR", langTr], + ["hu", "hu-HU", langHu], + ["no", "no-NO", langNo], ]; const loadMessages = (locale?: string): typeof langList & typeof langEn => { - const thisLocale = (locale || "en").slice(0, 2); + const thisLocale = (locale || "en").slice(0, 2); - // ensure this lang exists in localeOptions above, otherwise fallback to en - if (thisLocale === "en" || !localeOptions.some(([code]) => code === thisLocale)) { - return Object.assign({}, langList, langEn); - } + // ensure this lang exists in localeOptions above, otherwise fallback to en + if (thisLocale === "en" || !localeOptions.some(([code]) => code === thisLocale)) { + return Object.assign({}, langList, langEn); + } - return Object.assign({}, langList, langEn, localeOptions.find(([code]) => code === thisLocale)?.[2]); + return Object.assign({}, langList, langEn, localeOptions.find(([code]) => code === thisLocale)?.[2]); }; const getFlagCodeForLocale = (locale?: string) => { - const thisLocale = (locale || "en").slice(0, 2); + const thisLocale = (locale || "en").slice(0, 2); - // only add to this if your flag is different from the locale code - const specialCases: Record = { - ja: "jp", // Japan - zh: "cn", // China - vi: "vn", // Vietnam - ko: "kr", // Korea - cs: "cz", // Czechia - ga: "ie", // Ireland (Irish) - }; + // only add to this if your flag is different from the locale code + const specialCases: Record = { + ja: "jp", // Japan + zh: "cn", // China + vi: "vn", // Vietnam + ko: "kr", // Korea + cs: "cz", // Czechia + ga: "ie", // Ireland (Irish) + }; - if (specialCases[thisLocale]) { - return specialCases[thisLocale].toUpperCase(); - } - return thisLocale.toUpperCase(); + if (specialCases[thisLocale]) { + return specialCases[thisLocale].toUpperCase(); + } + return thisLocale.toUpperCase(); }; const getLocale = (short = false) => { - let loc = window.localStorage.getItem("locale"); - if (!loc) { - loc = document.documentElement.lang; - } - if (short) { - return loc.slice(0, 2); - } - // finally, fallback - if (!loc) { - loc = "en"; - } - return loc; + let loc = window.localStorage.getItem("locale"); + if (!loc) { + loc = document.documentElement.lang; + } + if (short) { + return loc.slice(0, 2); + } + // finally, fallback + if (!loc) { + loc = "en"; + } + return loc; }; const cache = createIntlCache(); @@ -102,41 +102,41 @@ const initialMessages = loadMessages(getLocale()); let intl = createIntl({ locale: getLocale(), messages: initialMessages }, cache); const changeLocale = (locale: string): void => { - const messages = loadMessages(locale); - intl = createIntl({ locale, messages }, cache); - window.localStorage.setItem("locale", locale); - document.documentElement.lang = locale; + const messages = loadMessages(locale); + intl = createIntl({ locale, messages }, cache); + window.localStorage.setItem("locale", locale); + document.documentElement.lang = locale; }; // This is a translation component that wraps the translation in a span with a data // attribute so devs can inspect the element to see the translation ID const T = ({ - id, - data, - tData, + id, + data, + tData, }: { - id: string; - data?: Record; - tData?: Record; + id: string; + data?: Record; + tData?: Record; }) => { - const translatedData: Record = {}; - if (tData) { - // iterate over tData and translate each value - Object.entries(tData).forEach(([key, value]) => { - translatedData[key] = intl.formatMessage({ id: value }); - }); - } - return ( - - {intl.formatMessage( - { id }, - { - ...data, - ...translatedData, - }, - )} - - ); + const translatedData: Record = {}; + if (tData) { + // iterate over tData and translate each value + Object.entries(tData).forEach(([key, value]) => { + translatedData[key] = intl.formatMessage({ id: value }); + }); + } + return ( + + {intl.formatMessage( + { id }, + { + ...data, + ...translatedData, + }, + )} + + ); }; //console.log("L:", localeOptions); diff --git a/frontend/src/locale/Utils.ts b/frontend/src/locale/Utils.ts index d422427737..ff5cb3b637 100644 --- a/frontend/src/locale/Utils.ts +++ b/frontend/src/locale/Utils.ts @@ -1,9 +1,4 @@ -import { - fromUnixTime, - type IntlFormatFormatOptions, - intlFormat, - parseISO, -} from "date-fns"; +import { fromUnixTime, type IntlFormatFormatOptions, intlFormat, parseISO } from "date-fns"; const isUnixTimestamp = (value: unknown): boolean => { if (typeof value !== "number" && typeof value !== "string") return false; diff --git a/frontend/src/locale/src/HelpDoc/et/index.ts b/frontend/src/locale/src/HelpDoc/et/index.ts index d0178a5d30..a9bb46ba7c 100644 --- a/frontend/src/locale/src/HelpDoc/et/index.ts +++ b/frontend/src/locale/src/HelpDoc/et/index.ts @@ -3,4 +3,4 @@ export * as Certificates from "./Certificates.md"; export * as DeadHosts from "./DeadHosts.md"; export * as ProxyHosts from "./ProxyHosts.md"; export * as RedirectionHosts from "./RedirectionHosts.md"; -export * as Streams from "./Streams.md"; \ No newline at end of file +export * as Streams from "./Streams.md"; diff --git a/frontend/src/locale/src/HelpDoc/index.ts b/frontend/src/locale/src/HelpDoc/index.ts index 7d4af5f5dd..2fb04aea12 100644 --- a/frontend/src/locale/src/HelpDoc/index.ts +++ b/frontend/src/locale/src/HelpDoc/index.ts @@ -22,18 +22,17 @@ import * as hu from "./hu/index"; const items: any = { en, de, pt, es, et, ja, sk, cs, zh, pl, ru, it, vi, nl, bg, ko, ga, id, fr, tr, hu }; - const fallbackLang = "en"; export const getHelpFile = (lang: string, section: string): string => { - if (typeof items[lang] !== "undefined" && typeof items[lang][section] !== "undefined") { - return items[lang][section].default; - } - // Fallback to English - if (typeof items[fallbackLang] !== "undefined" && typeof items[fallbackLang][section] !== "undefined") { - return items[fallbackLang][section].default; - } - throw new Error(`Cannot load help doc for ${lang}-${section}`); + if (typeof items[lang] !== "undefined" && typeof items[lang][section] !== "undefined") { + return items[lang][section].default; + } + // Fallback to English + if (typeof items[fallbackLang] !== "undefined" && typeof items[fallbackLang][section] !== "undefined") { + return items[fallbackLang][section].default; + } + throw new Error(`Cannot load help doc for ${lang}-${section}`); }; export default items; diff --git a/frontend/src/locale/src/HelpDoc/ko/index.ts b/frontend/src/locale/src/HelpDoc/ko/index.ts index 33e015cc81..a9bb46ba7c 100644 --- a/frontend/src/locale/src/HelpDoc/ko/index.ts +++ b/frontend/src/locale/src/HelpDoc/ko/index.ts @@ -4,4 +4,3 @@ export * as DeadHosts from "./DeadHosts.md"; export * as ProxyHosts from "./ProxyHosts.md"; export * as RedirectionHosts from "./RedirectionHosts.md"; export * as Streams from "./Streams.md"; - diff --git a/frontend/src/locale/src/HelpDoc/tr/index.ts b/frontend/src/locale/src/HelpDoc/tr/index.ts index 33e015cc81..a9bb46ba7c 100644 --- a/frontend/src/locale/src/HelpDoc/tr/index.ts +++ b/frontend/src/locale/src/HelpDoc/tr/index.ts @@ -4,4 +4,3 @@ export * as DeadHosts from "./DeadHosts.md"; export * as ProxyHosts from "./ProxyHosts.md"; export * as RedirectionHosts from "./RedirectionHosts.md"; export * as Streams from "./Streams.md"; - diff --git a/frontend/src/modals/DNSCertificateModal.tsx b/frontend/src/modals/DNSCertificateModal.tsx index f062e24dea..bca8df8d3d 100644 --- a/frontend/src/modals/DNSCertificateModal.tsx +++ b/frontend/src/modals/DNSCertificateModal.tsx @@ -70,11 +70,7 @@ const DNSCertificateModal = EasyModal.create(({ visible, remove }: InnerModalPro - diff --git a/frontend/src/modals/HTTPCertificateModal.tsx b/frontend/src/modals/HTTPCertificateModal.tsx index a06df2c62d..d7ec75190c 100644 --- a/frontend/src/modals/HTTPCertificateModal.tsx +++ b/frontend/src/modals/HTTPCertificateModal.tsx @@ -151,11 +151,7 @@ const HTTPCertificateModal = EasyModal.create(({ visible, remove }: InnerModalPr - diff --git a/frontend/src/modals/RedirectionHostModal.tsx b/frontend/src/modals/RedirectionHostModal.tsx index 1bd7877f4f..9a0d95ce89 100644 --- a/frontend/src/modals/RedirectionHostModal.tsx +++ b/frontend/src/modals/RedirectionHostModal.tsx @@ -162,7 +162,9 @@ const RedirectionHostModal = EasyModal.create(({ id, visible, remove }: Props) = required {...field} > - + @@ -224,12 +226,24 @@ const RedirectionHostModal = EasyModal.create(({ id, visible, remove }: Props) = required {...field} > - - - - - - + + + + + + {form.errors.forwardHttpCode ? (
diff --git a/frontend/src/modals/StreamModal.tsx b/frontend/src/modals/StreamModal.tsx index 6d55348896..b87a259c47 100644 --- a/frontend/src/modals/StreamModal.tsx +++ b/frontend/src/modals/StreamModal.tsx @@ -154,7 +154,9 @@ const StreamModal = EasyModal.create(({ id, visible, remove }: Props) => { type="text" className={`form-control ${form.errors.forwardingHost && form.touched.forwardingHost ? "is-invalid" : ""}`} required - placeholder={intl.formatMessage({ id: "stream.forward-host.placeholder" })} + placeholder={intl.formatMessage({ + id: "stream.forward-host.placeholder", + })} {...field} /> {form.errors.forwardingHost ? ( diff --git a/frontend/src/modals/TwoFactorModal.tsx b/frontend/src/modals/TwoFactorModal.tsx index b5dd480c30..fa46c89cc7 100644 --- a/frontend/src/modals/TwoFactorModal.tsx +++ b/frontend/src/modals/TwoFactorModal.tsx @@ -3,13 +3,7 @@ import { Field, Form, Formik } from "formik"; import { type ReactNode, useCallback, useEffect, useState } from "react"; import { Alert } from "react-bootstrap"; import Modal from "react-bootstrap/Modal"; -import { - disable2FA, - enable2FA, - get2FAStatus, - regenerateBackupCodes, - start2FASetup, -} from "src/api/backend"; +import { disable2FA, enable2FA, get2FAStatus, regenerateBackupCodes, start2FASetup } from "src/api/backend"; import { Button } from "src/components"; import { T } from "src/locale"; import { validateString } from "src/modules/Validations"; @@ -137,12 +131,7 @@ const TwoFactorModal = EasyModal.create(({ id, visible, remove }: Props) => { )}
{!isEnabled ? ( - ) : ( diff --git a/frontend/src/pages/Access/Table.tsx b/frontend/src/pages/Access/Table.tsx index 433c077b34..1783a2cffe 100644 --- a/frontend/src/pages/Access/Table.tsx +++ b/frontend/src/pages/Access/Table.tsx @@ -1,8 +1,9 @@ import { IconDotsVertical, IconEdit, IconTrash } from "@tabler/icons-react"; -import { createColumnHelper, getCoreRowModel, useReactTable } from "@tanstack/react-table"; +import { createColumnHelper, useTable } from "@tanstack/react-table"; import { useMemo } from "react"; import type { AccessList } from "src/api/backend"; import { EmptyData, GravatarFormatter, HasPermission, ValueWithDateFormatter } from "src/components"; +import { type Features, features } from "src/components/Table/features"; import { TableLayout } from "src/components/Table/TableLayout"; import { intl, T } from "src/locale"; import { ACCESS_LISTS, MANAGE } from "src/modules/Permissions"; @@ -16,7 +17,7 @@ interface Props { onNew?: () => void; } export default function Table({ data, isFetching, isFiltered, onEdit, onDelete, onNew }: Props) { - const columnHelper = createColumnHelper(); + const columnHelper = createColumnHelper(); const columns = useMemo( () => [ columnHelper.accessor((row: any) => row.owner, { @@ -114,11 +115,10 @@ export default function Table({ data, isFetching, isFiltered, onEdit, onDelete, [columnHelper, onEdit, onDelete], ); - const tableInstance = useReactTable({ + const tableInstance = useTable({ + features, columns, data, - getCoreRowModel: getCoreRowModel(), - rowCount: data.length, meta: { isFetching, }, diff --git a/frontend/src/pages/AuditLog/Table.tsx b/frontend/src/pages/AuditLog/Table.tsx index f61809a56f..2be8e72bf3 100644 --- a/frontend/src/pages/AuditLog/Table.tsx +++ b/frontend/src/pages/AuditLog/Table.tsx @@ -1,7 +1,8 @@ -import { createColumnHelper, getCoreRowModel, useReactTable } from "@tanstack/react-table"; +import { createColumnHelper, useTable } from "@tanstack/react-table"; import { useMemo } from "react"; import type { AuditLog } from "src/api/backend"; import { EventFormatter, GravatarFormatter } from "src/components"; +import { type Features, features } from "src/components/Table/features"; import { TableLayout } from "src/components/Table/TableLayout"; import { intl, T } from "src/locale"; @@ -11,10 +12,10 @@ interface Props { onSelectItem?: (id: number) => void; } export default function Table({ data, isFetching, onSelectItem }: Props) { - const columnHelper = createColumnHelper(); + const columnHelper = createColumnHelper(); const columns = useMemo( () => [ - columnHelper.accessor((row: AuditLog) => row.user, { + columnHelper.accessor((row: any) => row.user, { id: "user.avatar", cell: (info: any) => { const value = info.getValue(); @@ -24,7 +25,7 @@ export default function Table({ data, isFetching, onSelectItem }: Props) { className: "w-1", }, }), - columnHelper.accessor((row: AuditLog) => row, { + columnHelper.accessor((row: any) => row, { id: "objectType", header: intl.formatMessage({ id: "column.event" }), cell: (info: any) => { @@ -55,11 +56,10 @@ export default function Table({ data, isFetching, onSelectItem }: Props) { [columnHelper, onSelectItem], ); - const tableInstance = useReactTable({ + const tableInstance = useTable({ + features, columns, data, - getCoreRowModel: getCoreRowModel(), - rowCount: data.length, meta: { isFetching, }, diff --git a/frontend/src/pages/Certificates/Table.tsx b/frontend/src/pages/Certificates/Table.tsx index 7eaeb77701..2312a9bdf5 100644 --- a/frontend/src/pages/Certificates/Table.tsx +++ b/frontend/src/pages/Certificates/Table.tsx @@ -1,5 +1,5 @@ import { IconDotsVertical, IconDownload, IconRefresh, IconTrash } from "@tabler/icons-react"; -import { createColumnHelper, getCoreRowModel, useReactTable } from "@tanstack/react-table"; +import { createColumnHelper, useTable } from "@tanstack/react-table"; import { useMemo } from "react"; import type { Certificate } from "src/api/backend"; import { @@ -10,6 +10,7 @@ import { GravatarFormatter, HasPermission, } from "src/components"; +import { type Features, features } from "src/components/Table/features"; import { TableLayout } from "src/components/Table/TableLayout"; import { intl, T } from "src/locale"; import { showCustomCertificateModal, showDNSCertificateModal, showHTTPCertificateModal } from "src/modals"; @@ -24,7 +25,7 @@ interface Props { onDownload?: (id: number) => void; } export default function Table({ data, isFetching, onDelete, onRenew, onDownload, isFiltered }: Props) { - const columnHelper = createColumnHelper(); + const columnHelper = createColumnHelper(); const columns = useMemo( () => [ columnHelper.accessor((row: any) => row.owner, { @@ -164,11 +165,10 @@ export default function Table({ data, isFetching, onDelete, onRenew, onDownload, [columnHelper, onDelete, onRenew, onDownload], ); - const tableInstance = useReactTable({ + const tableInstance = useTable({ + features, columns, data, - getCoreRowModel: getCoreRowModel(), - rowCount: data.length, meta: { isFetching, }, diff --git a/frontend/src/pages/Login/index.tsx b/frontend/src/pages/Login/index.tsx index ebf7eeb376..d65b2dc84d 100644 --- a/frontend/src/pages/Login/index.tsx +++ b/frontend/src/pages/Login/index.tsx @@ -193,9 +193,7 @@ export default function Login() {
-
- {twoFactorChallenge ? : } -
+
{twoFactorChallenge ? : }
{getVersion()}
diff --git a/frontend/src/pages/Nginx/DeadHosts/Table.tsx b/frontend/src/pages/Nginx/DeadHosts/Table.tsx index 17143e7504..e5c1b184f0 100644 --- a/frontend/src/pages/Nginx/DeadHosts/Table.tsx +++ b/frontend/src/pages/Nginx/DeadHosts/Table.tsx @@ -1,11 +1,5 @@ import { IconDotsVertical, IconEdit, IconPower, IconTrash } from "@tabler/icons-react"; -import { - createColumnHelper, - getCoreRowModel, - getSortedRowModel, - type SortingState, - useReactTable, -} from "@tanstack/react-table"; +import { createColumnHelper, type SortingState, useTable } from "@tanstack/react-table"; import { useMemo, useState } from "react"; import type { DeadHost } from "src/api/backend"; import { @@ -16,6 +10,7 @@ import { HasPermission, TrueFalseFormatter, } from "src/components"; +import { type Features, features } from "src/components/Table/features"; import { TableLayout } from "src/components/Table/TableLayout"; import { intl, T } from "src/locale"; import { DEAD_HOSTS, MANAGE } from "src/modules/Permissions"; @@ -30,7 +25,7 @@ interface Props { onNew?: () => void; } export default function Table({ data, isFetching, onEdit, onDelete, onDisableToggle, onNew, isFiltered }: Props) { - const columnHelper = createColumnHelper(); + const columnHelper = createColumnHelper(); const columns = useMemo( () => [ columnHelper.accessor((row: any) => row.owner, { @@ -47,7 +42,7 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog columnHelper.accessor((row: any) => row, { id: "domainNames", header: intl.formatMessage({ id: "column.source" }), - sortingFn: (a, b) => { + sortFn: (a, b) => { const aVal = a.original.domainNames?.[0] ?? ""; const bVal = b.original.domainNames?.[0] ?? ""; return aVal.localeCompare(bVal); @@ -143,14 +138,12 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog const [sorting, setSorting] = useState([]); - const tableInstance = useReactTable({ + const tableInstance = useTable({ + features, columns, data, state: { sorting }, onSortingChange: setSorting, - getCoreRowModel: getCoreRowModel(), - getSortedRowModel: getSortedRowModel(), - rowCount: data.length, meta: { isFetching, }, diff --git a/frontend/src/pages/Nginx/ProxyHosts/Table.tsx b/frontend/src/pages/Nginx/ProxyHosts/Table.tsx index 5af58081ad..bddac27007 100644 --- a/frontend/src/pages/Nginx/ProxyHosts/Table.tsx +++ b/frontend/src/pages/Nginx/ProxyHosts/Table.tsx @@ -1,11 +1,5 @@ import { IconDotsVertical, IconEdit, IconPower, IconTrash } from "@tabler/icons-react"; -import { - createColumnHelper, - getCoreRowModel, - getSortedRowModel, - type SortingState, - useReactTable, -} from "@tanstack/react-table"; +import { createColumnHelper, type SortingState, useTable } from "@tanstack/react-table"; import { useMemo, useState } from "react"; import type { ProxyHost } from "src/api/backend"; import { @@ -17,6 +11,7 @@ import { HasPermission, TrueFalseFormatter, } from "src/components"; +import { type Features, features } from "src/components/Table/features"; import { TableLayout } from "src/components/Table/TableLayout"; import { intl, T } from "src/locale"; import { MANAGE, PROXY_HOSTS } from "src/modules/Permissions"; @@ -31,7 +26,7 @@ interface Props { onNew?: () => void; } export default function Table({ data, isFetching, onEdit, onDelete, onDisableToggle, onNew, isFiltered }: Props) { - const columnHelper = createColumnHelper(); + const columnHelper = createColumnHelper(); const columns = useMemo( () => [ columnHelper.accessor((row: any) => row.owner, { @@ -48,7 +43,7 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog columnHelper.accessor((row: any) => row, { id: "domainNames", header: intl.formatMessage({ id: "column.source" }), - sortingFn: (a, b) => { + sortFn: (a, b) => { const aVal = a.original.domainNames?.[0] ?? ""; const bVal = b.original.domainNames?.[0] ?? ""; return aVal.localeCompare(bVal); @@ -61,7 +56,7 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog columnHelper.accessor((row: any) => row, { id: "forwardHost", header: intl.formatMessage({ id: "column.destination" }), - sortingFn: (a, b) => { + sortFn: (a, b) => { const aVal = `${a.original.forwardHost}:${a.original.forwardPort}`; const bVal = `${b.original.forwardHost}:${b.original.forwardPort}`; return aVal.localeCompare(bVal); @@ -165,14 +160,12 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog const [sorting, setSorting] = useState([]); - const tableInstance = useReactTable({ + const tableInstance = useTable({ + features, columns, data, state: { sorting }, onSortingChange: setSorting, - getCoreRowModel: getCoreRowModel(), - getSortedRowModel: getSortedRowModel(), - rowCount: data.length, meta: { isFetching, }, diff --git a/frontend/src/pages/Nginx/RedirectionHosts/Table.tsx b/frontend/src/pages/Nginx/RedirectionHosts/Table.tsx index 8e2d90f555..2457a47380 100644 --- a/frontend/src/pages/Nginx/RedirectionHosts/Table.tsx +++ b/frontend/src/pages/Nginx/RedirectionHosts/Table.tsx @@ -1,11 +1,5 @@ import { IconDotsVertical, IconEdit, IconPower, IconTrash } from "@tabler/icons-react"; -import { - createColumnHelper, - getCoreRowModel, - getSortedRowModel, - type SortingState, - useReactTable, -} from "@tanstack/react-table"; +import { createColumnHelper, type SortingState, useTable } from "@tanstack/react-table"; import { useMemo, useState } from "react"; import type { RedirectionHost } from "src/api/backend"; import { @@ -16,6 +10,7 @@ import { HasPermission, TrueFalseFormatter, } from "src/components"; +import { type Features, features } from "src/components/Table/features"; import { TableLayout } from "src/components/Table/TableLayout"; import { intl, T } from "src/locale"; import { MANAGE, REDIRECTION_HOSTS } from "src/modules/Permissions"; @@ -30,7 +25,7 @@ interface Props { onNew?: () => void; } export default function Table({ data, isFetching, onEdit, onDelete, onDisableToggle, onNew, isFiltered }: Props) { - const columnHelper = createColumnHelper(); + const columnHelper = createColumnHelper(); const columns = useMemo( () => [ columnHelper.accessor((row: any) => row.owner, { @@ -47,7 +42,7 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog columnHelper.accessor((row: any) => row, { id: "domainNames", header: intl.formatMessage({ id: "column.source" }), - sortingFn: (a, b) => { + sortFn: (a, b) => { const aVal = a.original.domainNames?.[0] ?? ""; const bVal = b.original.domainNames?.[0] ?? ""; return aVal.localeCompare(bVal); @@ -164,14 +159,12 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog const [sorting, setSorting] = useState([]); - const tableInstance = useReactTable({ + const tableInstance = useTable({ + features, columns, data, state: { sorting }, onSortingChange: setSorting, - getCoreRowModel: getCoreRowModel(), - getSortedRowModel: getSortedRowModel(), - rowCount: data.length, meta: { isFetching, }, diff --git a/frontend/src/pages/Nginx/Streams/Table.tsx b/frontend/src/pages/Nginx/Streams/Table.tsx index 341317bf45..ec181b2095 100644 --- a/frontend/src/pages/Nginx/Streams/Table.tsx +++ b/frontend/src/pages/Nginx/Streams/Table.tsx @@ -1,11 +1,5 @@ import { IconDotsVertical, IconEdit, IconPower, IconTrash } from "@tabler/icons-react"; -import { - createColumnHelper, - getCoreRowModel, - getSortedRowModel, - type SortingState, - useReactTable, -} from "@tanstack/react-table"; +import { createColumnHelper, type SortingState, useTable } from "@tanstack/react-table"; import { useMemo, useState } from "react"; import type { Stream } from "src/api/backend"; import { @@ -16,6 +10,7 @@ import { TrueFalseFormatter, ValueWithDateFormatter, } from "src/components"; +import { type Features, features } from "src/components/Table/features"; import { TableLayout } from "src/components/Table/TableLayout"; import { intl, T } from "src/locale"; import { MANAGE, STREAMS } from "src/modules/Permissions"; @@ -30,7 +25,7 @@ interface Props { onNew?: () => void; } export default function Table({ data, isFetching, isFiltered, onEdit, onDelete, onDisableToggle, onNew }: Props) { - const columnHelper = createColumnHelper(); + const columnHelper = createColumnHelper(); const columns = useMemo( () => [ columnHelper.accessor((row: any) => row.owner, { @@ -47,7 +42,7 @@ export default function Table({ data, isFetching, isFiltered, onEdit, onDelete, columnHelper.accessor((row: any) => row, { id: "incomingPort", header: intl.formatMessage({ id: "column.incoming-port" }), - sortingFn: (a, b) => (a.original.incomingPort ?? 0) - (b.original.incomingPort ?? 0), + sortFn: (a, b) => (a.original.incomingPort ?? 0) - (b.original.incomingPort ?? 0), cell: (info: any) => { const value = info.getValue(); return ; @@ -56,7 +51,7 @@ export default function Table({ data, isFetching, isFiltered, onEdit, onDelete, columnHelper.accessor((row: any) => row, { id: "forwardHttpCode", header: intl.formatMessage({ id: "column.destination" }), - sortingFn: (a, b) => { + sortFn: (a, b) => { const aVal = `${a.original.forwardingHost}:${a.original.forwardingPort}`; const bVal = `${b.original.forwardingHost}:${b.original.forwardingPort}`; return aVal.localeCompare(bVal); @@ -174,14 +169,12 @@ export default function Table({ data, isFetching, isFiltered, onEdit, onDelete, const [sorting, setSorting] = useState([]); - const tableInstance = useReactTable({ + const tableInstance = useTable({ + features, columns, data, state: { sorting }, onSortingChange: setSorting, - getCoreRowModel: getCoreRowModel(), - getSortedRowModel: getSortedRowModel(), - rowCount: data.length, meta: { isFetching, }, diff --git a/frontend/src/pages/Users/Table.tsx b/frontend/src/pages/Users/Table.tsx index d07fc9bcff..a5a61057bd 100644 --- a/frontend/src/pages/Users/Table.tsx +++ b/frontend/src/pages/Users/Table.tsx @@ -7,7 +7,7 @@ import { IconShield, IconTrash, } from "@tabler/icons-react"; -import { createColumnHelper, getCoreRowModel, useReactTable } from "@tanstack/react-table"; +import { createColumnHelper, useTable } from "@tanstack/react-table"; import { useMemo } from "react"; import type { User } from "src/api/backend"; import { @@ -18,6 +18,7 @@ import { TrueFalseFormatter, ValueWithDateFormatter, } from "src/components"; +import { type Features, features } from "src/components/Table/features"; import { TableLayout } from "src/components/Table/TableLayout"; import { intl, T } from "src/locale"; @@ -47,7 +48,7 @@ export default function Table({ onNewUser, onLoginAs, }: Props) { - const columnHelper = createColumnHelper(); + const columnHelper = createColumnHelper(); const columns = useMemo( () => [ columnHelper.accessor((row: any) => row, { @@ -216,11 +217,10 @@ export default function Table({ ], ); - const tableInstance = useReactTable({ + const tableInstance = useTable({ + features, columns, data, - getCoreRowModel: getCoreRowModel(), - rowCount: data.length, meta: { isFetching, }, diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 5fe787ee2b..493088c867 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -3,170 +3,148 @@ "@adobe/css-tools@^4.4.0": - version "4.4.4" - resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.4.4.tgz#2856c55443d3d461693f32d2b96fb6ea92e1ffa9" - integrity sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg== + version "4.5.0" + resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.5.0.tgz#b5b71a25a4d16afa2482592ddfa62fccc60bc7d1" + integrity sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q== -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.28.6", "@babel/code-frame@^7.29.0": - version "7.29.0" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.0.tgz#7cd7a59f15b3cc0dcd803038f7792712a7d0b15c" - integrity sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.29.0", "@babel/code-frame@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.7.tgz#f2fbbfea87c44a21590ec515b778b2c26d8866e7" + integrity sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw== dependencies: - "@babel/helper-validator-identifier" "^7.28.5" + "@babel/helper-validator-identifier" "^7.29.7" js-tokens "^4.0.0" picocolors "^1.1.1" -"@babel/generator@^7.29.0": - version "7.29.1" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.1.tgz#d09876290111abbb00ef962a7b83a5307fba0d50" - integrity sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw== +"@babel/generator@^7.29.8": + version "7.29.8" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.8.tgz#4b0b887885422643339e09022148a4c4ebaa4979" + integrity sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg== dependencies: - "@babel/parser" "^7.29.0" - "@babel/types" "^7.29.0" + "@babel/parser" "^7.29.8" + "@babel/types" "^7.29.8" "@jridgewell/gen-mapping" "^0.3.12" "@jridgewell/trace-mapping" "^0.3.28" jsesc "^3.0.2" -"@babel/helper-globals@^7.28.0": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz#b9430df2aa4e17bc28665eadeae8aa1d985e6674" - integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw== +"@babel/helper-globals@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.29.7.tgz#f04a96fbd8473241b1079243f5b3f03a3010ab7b" + integrity sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA== "@babel/helper-module-imports@^7.16.7": - version "7.28.6" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz#60632cbd6ffb70b22823187201116762a03e2d5c" - integrity sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw== + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz#ef25048a518e828d7393fac5882ddd73921d7396" + integrity sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g== dependencies: - "@babel/traverse" "^7.28.6" - "@babel/types" "^7.28.6" + "@babel/traverse" "^7.29.7" + "@babel/types" "^7.29.7" -"@babel/helper-string-parser@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" - integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== +"@babel/helper-string-parser@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz#7f0871d99824d23137d60f86fcf6130fd5a1b51f" + integrity sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw== -"@babel/helper-validator-identifier@^7.28.5": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz#010b6938fab7cb7df74aa2bbc06aa503b8fe5fb4" - integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q== +"@babel/helper-validator-identifier@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz#bd87084ced0c796ec46bda492de6e83d29e89fc2" + integrity sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg== -"@babel/parser@^7.28.6", "@babel/parser@^7.29.0": - version "7.29.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.0.tgz#669ef345add7d057e92b7ed15f0bac07611831b6" - integrity sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww== +"@babel/parser@^7.29.7", "@babel/parser@^7.29.8": + version "7.29.8" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.8.tgz#9653716a2f10c677b98fbc63d4bfb000c302cf17" + integrity sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA== dependencies: - "@babel/types" "^7.29.0" + "@babel/types" "^7.29.8" "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.6", "@babel/runtime@^7.24.7", "@babel/runtime@^7.26.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.7": - version "7.28.6" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.6.tgz#d267a43cb1836dc4d182cce93ae75ba954ef6d2b" - integrity sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA== - -"@babel/template@^7.28.6": - version "7.28.6" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.28.6.tgz#0e7e56ecedb78aeef66ce7972b082fce76a23e57" - integrity sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ== - dependencies: - "@babel/code-frame" "^7.28.6" - "@babel/parser" "^7.28.6" - "@babel/types" "^7.28.6" - -"@babel/traverse@^7.28.6": - version "7.29.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.0.tgz#f323d05001440253eead3c9c858adbe00b90310a" - integrity sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA== - dependencies: - "@babel/code-frame" "^7.29.0" - "@babel/generator" "^7.29.0" - "@babel/helper-globals" "^7.28.0" - "@babel/parser" "^7.29.0" - "@babel/template" "^7.28.6" - "@babel/types" "^7.29.0" + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.29.7.tgz#12022450c45a4da6d8d8287b18a4ff2ddb23f768" + integrity sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw== + +"@babel/template@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.29.7.tgz#4d9d4004f645cdd304de958c725162784ecac700" + integrity sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg== + dependencies: + "@babel/code-frame" "^7.29.7" + "@babel/parser" "^7.29.7" + "@babel/types" "^7.29.7" + +"@babel/traverse@^7.29.7": + version "7.29.8" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.8.tgz#4111014cdc71a0f95d9471907590baa0b8a6b28a" + integrity sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg== + dependencies: + "@babel/code-frame" "^7.29.7" + "@babel/generator" "^7.29.8" + "@babel/helper-globals" "^7.29.7" + "@babel/parser" "^7.29.8" + "@babel/template" "^7.29.7" + "@babel/types" "^7.29.8" debug "^4.3.1" -"@babel/types@^7.28.6", "@babel/types@^7.29.0": - version "7.29.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.0.tgz#9f5b1e838c446e72cf3cd4b918152b8c605e37c7" - integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A== +"@babel/types@^7.29.7", "@babel/types@^7.29.8": + version "7.29.8" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.8.tgz#1229eef31d85156d70fa3f4cd859376d0eaf6863" + integrity sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg== dependencies: - "@babel/helper-string-parser" "^7.27.1" - "@babel/helper-validator-identifier" "^7.28.5" + "@babel/helper-string-parser" "^7.29.7" + "@babel/helper-validator-identifier" "^7.29.7" -"@biomejs/biome@^2.4.15": - version "2.4.15" - resolved "https://registry.yarnpkg.com/@biomejs/biome/-/biome-2.4.15.tgz#cb84ad6eb4235e7230b3c105a825e9bc03399944" - integrity sha512-j5VH3a/h/HXTKBM50MDMxRCzkeLv9S2XJcW2WgnZT1+xyisi+0bISrXR82gCX+8S9lvK0skEvHJRN+3Ktr2hlw== +"@biomejs/biome@^2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@biomejs/biome/-/biome-2.5.10.tgz#c2a42fc6f9c7d9e12c1f77f63dfb6b5489c497b7" + integrity sha512-WRKXARA3kTuiV5sxqTpobJ/I0MVd4vk3pOL6wnp5az4LntFIhWTj1RWZq3DI9PCEN3lXcqy7p5aqUHzvq8AXyQ== optionalDependencies: - "@biomejs/cli-darwin-arm64" "2.4.15" - "@biomejs/cli-darwin-x64" "2.4.15" - "@biomejs/cli-linux-arm64" "2.4.15" - "@biomejs/cli-linux-arm64-musl" "2.4.15" - "@biomejs/cli-linux-x64" "2.4.15" - "@biomejs/cli-linux-x64-musl" "2.4.15" - "@biomejs/cli-win32-arm64" "2.4.15" - "@biomejs/cli-win32-x64" "2.4.15" - -"@biomejs/cli-darwin-arm64@2.4.15": - version "2.4.15" - resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.15.tgz#3469daa56ac3ff4f16588a120df706381a96f65c" - integrity sha512-rF3PPqLq1yoST79zaQbDjVJwsuIeci/O+9bgNmC5QpgOqz6aqYuzA4abyAGx+mgyiDXn4A049xAN8gijbuR1Qg== - -"@biomejs/cli-darwin-x64@2.4.15": - version "2.4.15" - resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.15.tgz#0697b81089409635da16682ac1e539165c262006" - integrity sha512-/5KHXYMfSJs1fNXiX30xFtI8JcCFV6zaVVLxOa0M2sfqBKHkpQhRTv94yxQWxeTY2lzo2OuTlNvPC+hDQt2wcQ== - -"@biomejs/cli-linux-arm64-musl@2.4.15": - version "2.4.15" - resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.15.tgz#c6af054e3732c361e9ad8c44070f909666b5616f" - integrity sha512-ZPcxznxm0pogHBLZhYntyR3sR+MrZjqJIKEr7ZqVen0Rl+P/4upVmfYXjftizi9RoqZntg33fv/1fbdhbYXpEQ== - -"@biomejs/cli-linux-arm64@2.4.15": - version "2.4.15" - resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.15.tgz#527cef60339649a442d51a9cd129ae9dfe9da926" - integrity sha512-owaAMZD/T4LrD0ELNCk0Km3qrRHuM0X6EAyVE1FSqGY0rbLoiDLrO4Us2tllm6cAeB2Ioa9C2C08NZPdr8+0Ug== - -"@biomejs/cli-linux-x64-musl@2.4.15": - version "2.4.15" - resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.15.tgz#b39292ad106c3d5a612bf3c61ba3119f66833013" - integrity sha512-CNq/9W38SYSH023lfcQ4KKU8K0YX8T//FZUhcgtMMRABDojx5XsMV7jlweAvGSl389wJQB29Qo6Zb/a+jdvt+w== - -"@biomejs/cli-linux-x64@2.4.15": - version "2.4.15" - resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.15.tgz#7360b7f81ff03ec6d9350bedc76b89f783b0945d" - integrity sha512-0jj7THz12GbUOLmMibktK6DZjqz2zV64KFxyBtcFTKPiiOIY0a7vns1elpO1dERvxpsZ5ik0oFfz0oGwFde1+g== - -"@biomejs/cli-win32-arm64@2.4.15": - version "2.4.15" - resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.15.tgz#9542aac679174892a9379267e0c0048f8eee4d9f" - integrity sha512-ouhkYdlhp/1GghEJPdWwD/Vi3gQ1nFxuSpMolWsbq3Lsq3QUR4jl6UdhhscdCugKU5vOEuMiJhvKj66O0OCq+w== - -"@biomejs/cli-win32-x64@2.4.15": - version "2.4.15" - resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.15.tgz#80288e4eea8f916fc5c876e9a486baadb8de537d" - integrity sha512-zBrGq5mx5wwpnow4+2BxUvleDM+GNd4sLbPaMapsSLQLD0NGRCquqPBTgN+7XkUteHvj7M+BstuI8tmnV7+HgQ== - -"@emnapi/core@1.10.0": - version "1.10.0" - resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.10.0.tgz#380ccc8f2412ea22d1d972df7f8ee23a3b9c7467" - integrity sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw== - dependencies: - "@emnapi/wasi-threads" "1.2.1" - tslib "^2.4.0" - -"@emnapi/runtime@1.10.0": - version "1.10.0" - resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.10.0.tgz#4b260c0d3534204e98c6110b8db1a987d26ec87c" - integrity sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA== - dependencies: - tslib "^2.4.0" - -"@emnapi/wasi-threads@1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz#28fed21a1ba1ce797c44a070abc94d42f3ae8548" - integrity sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w== - dependencies: - tslib "^2.4.0" + "@biomejs/cli-darwin-arm64" "2.5.10" + "@biomejs/cli-darwin-x64" "2.5.10" + "@biomejs/cli-linux-arm64" "2.5.10" + "@biomejs/cli-linux-arm64-musl" "2.5.10" + "@biomejs/cli-linux-x64" "2.5.10" + "@biomejs/cli-linux-x64-musl" "2.5.10" + "@biomejs/cli-win32-arm64" "2.5.10" + "@biomejs/cli-win32-x64" "2.5.10" + +"@biomejs/cli-darwin-arm64@2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.5.10.tgz#f1453a7f2e63f228a34645df1c33962f22a6c2a8" + integrity sha512-ItCrxKK6SXVT6flYs0qIuBd4AA3TTTl4d66Re6YI2FuGZnN85NmuYNzkiTJUyYw8qBLv69L5zTUB6uyWd++h3Q== + +"@biomejs/cli-darwin-x64@2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.5.10.tgz#e21041e7bfab01cd453f609b940bf613713d0e24" + integrity sha512-yLsPU9pAmtChXDu8vhKAzErqe+LeeYuwuUB2FZMkRitsmdodxsYRa9KHrFispsUHzzOu+9HB3nP/TQxyia+Sjw== + +"@biomejs/cli-linux-arm64-musl@2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.5.10.tgz#57fc8aee25c08ca6c14526ccc44e282e7ba96eb6" + integrity sha512-t1QAKZwQJRB4dvgJSgFiQ4BNfNPChg69BNonz854qLVxnjT3UvDzQg9mbkTJRu35ZqU0Rw10A73J8Urgbg2RPw== + +"@biomejs/cli-linux-arm64@2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.5.10.tgz#aef789a71e5aa86f5a0e1aff6cb4c1b757ec5be1" + integrity sha512-VG8uQW/86a1roLaIFvtIbEigxIdzdJ190oGyg1tV7VYeQtOS+x10sflk7WbuXgw91EtZX5DlIIIej1YqkNLlcg== + +"@biomejs/cli-linux-x64-musl@2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.5.10.tgz#1aebe9f928dc72dc3c112e60f1211a4d646990c4" + integrity sha512-pgDDqp9JybHm2I0KRgzN6i4+lt8xu4iqxUwLzglUMmOmyRTU1AYBGKzh9sNMOtIjah7xoWvKHlLVetvyifzoiQ== + +"@biomejs/cli-linux-x64@2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64/-/cli-linux-x64-2.5.10.tgz#a82b414abf5d9668fb035ee50a710bf78a7c5fbf" + integrity sha512-4O6T0eq2heoHZN0a9UX+rWQoxXEBaKf+lRi2hbsGlHneUz9BWXM76nEWMK7Eeq8gzMxR1khQB6BFpAASpeXqGg== + +"@biomejs/cli-win32-arm64@2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.5.10.tgz#db671cf67d7040a374e8cdda5aebe73c3f4ffba0" + integrity sha512-pxAbxduPO4xq/Cvgaa2lOrs9BB0hEXmmDqfMNP4ZOffGOkUrD1/QGw9UAMpFQpX2P8MqTIIRuQKcmetum4Oa6A== + +"@biomejs/cli-win32-x64@2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-x64/-/cli-win32-x64-2.5.10.tgz#3bdeaf5856f21aec6b6c50a7bca5464b9cda5623" + integrity sha512-M+2dgBsl3lXRiTfgPVc2p3anS4Tocojke4rzFLScZ2Y/wmF+36dRb1iHCLiyGqOzQGyTplZH1HnEYviiAqi3nA== "@emotion/babel-plugin@^11.13.5": version "11.13.5" @@ -256,81 +234,114 @@ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz#5e13fac887f08c44f76b0ccaf3370eb00fec9bb6" integrity sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg== -"@floating-ui/core@^1.7.4": - version "1.7.4" - resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.7.4.tgz#4a006a6e01565c0f87ba222c317b056a2cffd2f4" - integrity sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg== +"@floating-ui/core@^1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.8.0.tgz#d01c0bbea02e4a57f6fd7d5de6fc2c5c7dca40e1" + integrity sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ== dependencies: - "@floating-ui/utils" "^0.2.10" + "@floating-ui/utils" "^0.2.12" "@floating-ui/dom@^1.0.1": - version "1.7.5" - resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.7.5.tgz#60bfc83a4d1275b2a90db76bf42ca2a5f2c231c2" - integrity sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg== - dependencies: - "@floating-ui/core" "^1.7.4" - "@floating-ui/utils" "^0.2.10" - -"@floating-ui/utils@^0.2.10": - version "0.2.10" - resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.10.tgz#a2a1e3812d14525f725d011a73eceb41fef5bc1c" - integrity sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ== - -"@formatjs/cli-native-darwin-arm64@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@formatjs/cli-native-darwin-arm64/-/cli-native-darwin-arm64-1.1.1.tgz#abf5d12040511bbb9225ae6835fb6107f3e7f866" - integrity sha512-G2IfmxwDN1kUMIbM9ec5HfJTNR89X11+U3bt4lewfrRqoHOc9bQAkkVHLsY8gNVLjyQIXch58Ewd+AAHkg6cag== - -"@formatjs/cli-native-linux-arm64@1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@formatjs/cli-native-linux-arm64/-/cli-native-linux-arm64-1.2.1.tgz#b55884c1bbe4c68a6545dd4e87e60e043c394c0e" - integrity sha512-dbafLt5p1wQi16QnTFuz6s5j5c8HcyRSw+gUp5xEtaQ9Ua2YKRu+YqlgsERg+ArTWN+ZTHIGu+0YymTvfTropA== - -"@formatjs/cli-native-linux-x64@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@formatjs/cli-native-linux-x64/-/cli-native-linux-x64-1.1.1.tgz#e3439d454b6006537abc22130989f285d036426b" - integrity sha512-zi6eOPAc03fszPyiGCkmzBxjIxynDFflie9zgbyZIQgKV7MhXEmUmpGYeaTTDX903OFCJJ3ZvpajSTdZ7C7yeQ== - -"@formatjs/cli-native-win32-x64@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@formatjs/cli-native-win32-x64/-/cli-native-win32-x64-1.1.2.tgz#6cc2db043243d5215065d3548e7198233e342c0d" - integrity sha512-2TKatQRlDbVc+eJE4b9n0/+bsDg+DpS0kmHw7OYI1zGXhus4YqRPtlJnraazRmPlXtRNgvY/UYCPgBvX7DbYhw== - -"@formatjs/cli@^6.16.6": - version "6.16.6" - resolved "https://registry.yarnpkg.com/@formatjs/cli/-/cli-6.16.6.tgz#dcc47f28756eec01f59e3911f58407293ff9c65f" - integrity sha512-82l9wmeqvClrtI/8VQOcFVZQwZWYEiMI505hywngF+xr7ti94OQXg0gi3piYaQarfiIac2GSMibLQ2aQM5mJaA== + version "1.8.0" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.8.0.tgz#8a20e6facbe2456afdbeb6c8b968a72df689cf63" + integrity sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg== + dependencies: + "@floating-ui/core" "^1.8.0" + "@floating-ui/utils" "^0.2.12" + +"@floating-ui/utils@^0.2.12": + version "0.2.12" + resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.12.tgz#afefe785949f16ac4cdd1e695935a321572dd56a" + integrity sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww== + +"@formatjs/cli-native-darwin-arm64@1.1.13": + version "1.1.13" + resolved "https://registry.yarnpkg.com/@formatjs/cli-native-darwin-arm64/-/cli-native-darwin-arm64-1.1.13.tgz#b9bb994d3b0043061deacf18b6431e452338f67f" + integrity sha512-YFmGCKyIgAo/yQ6r156Ty1BTRVHxR85kPFXQ5AhpQoHO9z6DE+iVo5sOcu/RaomwNTzPELP5nY7iqiPXqxnPoQ== + +"@formatjs/cli-native-linux-arm64-musl@1.0.11": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@formatjs/cli-native-linux-arm64-musl/-/cli-native-linux-arm64-musl-1.0.11.tgz#346b1a0396de28ed06d2d37c83e661bd4e200e4f" + integrity sha512-/0QMXaWCdqi1ZWwWuHn2Po593oCWBuZAohf9OVjnUvuSfZyQs3aD5DZVvJuai7bCeBDArN40fv8RrD8bI4F89Q== + +"@formatjs/cli-native-linux-arm64@1.2.13": + version "1.2.13" + resolved "https://registry.yarnpkg.com/@formatjs/cli-native-linux-arm64/-/cli-native-linux-arm64-1.2.13.tgz#09e6cd544d41daf12134789d4441ddb2470dad4e" + integrity sha512-5T79kvS6fUXyTrt1EWhFtWJJucPX39TbSHPAMSXl2SdRgTWlRZcMAplnpg18JMjXUcsRySeLQiCgfX+0al+0Gw== + +"@formatjs/cli-native-linux-x64-musl@1.0.11": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@formatjs/cli-native-linux-x64-musl/-/cli-native-linux-x64-musl-1.0.11.tgz#72efee12b3fee10637b28043cc67e3dfe086fa03" + integrity sha512-+hQH5fsuo7Mrdm2Omzmp6foTDP8MmrLU07LbyThZ4EtGV4Q1t9in3tgnD9/+lkfmqVfugYSHJQeMK6zpm84Ovw== + +"@formatjs/cli-native-linux-x64@1.1.13": + version "1.1.13" + resolved "https://registry.yarnpkg.com/@formatjs/cli-native-linux-x64/-/cli-native-linux-x64-1.1.13.tgz#d4a69a0fd36dbac165f7e2d2a659f0c09f23659c" + integrity sha512-tG+8iLAC0b6PKAIqijYktzkFIDjZShmPuQUlKxD7G3WrNAHSNOVXJ8+Cf49GTYeYP5zBw/NzeElhgud+LBx46A== + +"@formatjs/cli-native-win32-x64@1.1.14": + version "1.1.14" + resolved "https://registry.yarnpkg.com/@formatjs/cli-native-win32-x64/-/cli-native-win32-x64-1.1.14.tgz#5c2f5731a6c99cb647ff0932bc3caf3345a321ba" + integrity sha512-lNHPcA5rRacs/6nWOC+CCQ45Q/QY1zc0kLXjtss4h4cue5ShR2aPHEHBONRDjDWuuqbkolhIC5lTFD6Dg12eGQ== + +"@formatjs/cli@^6.16.19": + version "6.16.19" + resolved "https://registry.yarnpkg.com/@formatjs/cli/-/cli-6.16.19.tgz#b92ab015bbb7370ef967a6c4ca7aafb46545fa9a" + integrity sha512-/0F4n6To1wvroswFT+/3CE+eA8SRi/6y/22OrWmanNVwyeqpkUTHreQy2QzZDgFROH/C/b1tG7qxmQdPCoi1Vw== optionalDependencies: - "@formatjs/cli-native-darwin-arm64" "1.1.1" - "@formatjs/cli-native-linux-arm64" "1.2.1" - "@formatjs/cli-native-linux-x64" "1.1.1" - "@formatjs/cli-native-win32-x64" "1.1.2" - -"@formatjs/fast-memoize@3.1.5": - version "3.1.5" - resolved "https://registry.yarnpkg.com/@formatjs/fast-memoize/-/fast-memoize-3.1.5.tgz#bdfe0b884cdecc25100534086f36a0b30bd15b3b" - integrity sha512-KLi3fan6WnCHmigd9pmEEN8Hid0v4wiFBW576M/d07KMWYecf1CvyMI3n34vCmHT4AoVqG2n702kiHbXjzZX2A== - -"@formatjs/icu-messageformat-parser@3.5.10": - version "3.5.10" - resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-3.5.10.tgz#0ced2d6e8009eed57c6f0e7b4cc51dfea63b9bff" - integrity sha512-XeJihYLy1lCe19xfK1KWKG/betBOK2rB0luL8lSkjfvJj0zP+LTJvkC+RKd0jsFI8mWxN71LrarHSrEXE8xxOQ== + "@formatjs/cli-native-darwin-arm64" "1.1.13" + "@formatjs/cli-native-linux-arm64" "1.2.13" + "@formatjs/cli-native-linux-arm64-musl" "1.0.11" + "@formatjs/cli-native-linux-x64" "1.1.13" + "@formatjs/cli-native-linux-x64-musl" "1.0.11" + "@formatjs/cli-native-win32-x64" "1.1.14" + +"@formatjs/fast-memoize@3.1.7": + version "3.1.7" + resolved "https://registry.yarnpkg.com/@formatjs/fast-memoize/-/fast-memoize-3.1.7.tgz#5f79b3756e4bcb5faee47b3a2f01216e1212c9e4" + integrity sha512-zXfhLpvA6T7+efdt9JLbBwZ00tT7NsBMDVnDu8rpHeNNv8KfRZAMo2gkG0k9lK/Nzc//3kJ9pImsfuJxk3KhUA== + +"@formatjs/icu-messageformat-parser@3.5.17": + version "3.5.17" + resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-3.5.17.tgz#7ac90ff6dde99468cd0b4a3f55344ccf8ae2ed87" + integrity sha512-cN9jhVqT7u0K9tix43fhjoUwL0nazyW6zsNIXs2QdPADr+nurPfYyssUiMqcSCGlPcCiqnYVxgSn7zBSuI+5Bg== + dependencies: + "@formatjs/icu-skeleton-parser" "2.1.11" + +"@formatjs/icu-skeleton-parser@2.1.11": + version "2.1.11" + resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-2.1.11.tgz#09226edf55a18e3fea80304d2cc95aaeb0095436" + integrity sha512-j8cUmOJzVgkHuS0QiQ6ga76UIoLOFSAMWhs7aZJztH3aAdCOAE6vpC8KVvFB4cU10ON0y2/5oOVmPJ43s2lTwA== + +"@formatjs/intl@4.1.19": + version "4.1.19" + resolved "https://registry.yarnpkg.com/@formatjs/intl/-/intl-4.1.19.tgz#29463bc50ebc159f8c4309d6bd739fc5c95e9aa4" + integrity sha512-bZMROATl+rzfL8wsDZ53i8XWHx5e6rVr8QlGT5GDvHImEUro4WE9pxUd2dobzmI3CtD+zkt/wkEdqcb+3CK8Fg== + dependencies: + "@formatjs/fast-memoize" "3.1.7" + "@formatjs/icu-messageformat-parser" "3.5.17" + intl-messageformat "11.2.14" + +"@internationalized/date@^3.12.3": + version "3.12.3" + resolved "https://registry.yarnpkg.com/@internationalized/date/-/date-3.12.3.tgz#e11d14dbf12bf45057dd5996bac77f7c2f89ff9c" + integrity sha512-fuLX+3ZKLsxI73y8b01EG/WjHb6gE6weCqlfawPO27kBWGMh9G1yH6Csv1uU7/cac9H2GHmOMt6CjmuQ1aia4Q== dependencies: - "@formatjs/icu-skeleton-parser" "2.1.9" + "@swc/helpers" "^0.5.0" -"@formatjs/icu-skeleton-parser@2.1.9": - version "2.1.9" - resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-2.1.9.tgz#746edae664b2ef148df1301845d1bb40000bbebb" - integrity sha512-rsxswgHMfU1zUgB2byc08fesf83wLGjFnzLCEtuf00mx2doiqc6pYrf67raI37XqdRcGUviQepk2UKGqpng74Q== +"@internationalized/number@^3.6.7": + version "3.6.7" + resolved "https://registry.yarnpkg.com/@internationalized/number/-/number-3.6.7.tgz#5a0a8fa413b5f8679a59dcf37e2a74dc508b8371" + integrity sha512-3ji1fcrT+FPAK86UqEhB/psHixYo6niWPJtt7+qRaYFynt/BaJG8GhAPimtWUpEiVSTq8ZM8L5psMxGquiB/Vg== + dependencies: + "@swc/helpers" "^0.5.0" -"@formatjs/intl@4.1.12": - version "4.1.12" - resolved "https://registry.yarnpkg.com/@formatjs/intl/-/intl-4.1.12.tgz#a29521f9bba79df1690c430f3d2cee8817778674" - integrity sha512-r288ut+p+CUQZSg+0gAT+D0i6xgrnoxE0B4HTbPY2zei/AtYmFhlu87BKjgCf1CweH4pZIbr152JFjxO8jVb1A== +"@internationalized/string@^3.2.10": + version "3.2.10" + resolved "https://registry.yarnpkg.com/@internationalized/string/-/string-3.2.10.tgz#c38bd59a69509a41bf7422f1b2fc3af7468e4322" + integrity sha512-PDx6//vHSpRnHfxqMqto11zQvhsaU74O3mKv2F/0eicGZcl9NLjQmGlbHz/LsJh5tLKp4A4L7ZVTzN1/MmMTvA== dependencies: - "@formatjs/fast-memoize" "3.1.5" - "@formatjs/icu-messageformat-parser" "3.5.10" - intl-messageformat "11.2.7" + "@swc/helpers" "^0.5.0" "@jridgewell/gen-mapping@^0.3.12": version "0.3.13" @@ -365,106 +376,93 @@ dependencies: jsbi "^4.3.0" -"@napi-rs/wasm-runtime@^1.1.4": - version "1.1.4" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz#a46bbfedc29751b7170c5d23bc1d8ee8c7e3c1e1" - integrity sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow== - dependencies: - "@tybys/wasm-util" "^0.10.1" - -"@oxc-project/types@=0.133.0": - version "0.133.0" - resolved "https://registry.yarnpkg.com/@oxc-project/types/-/types-0.133.0.tgz#2e282ef9e1d26e06b68ccd14b73f310a3b2cf7f8" - integrity sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA== - -"@parcel/watcher-android-arm64@2.5.6": - version "2.5.6" - resolved "https://registry.yarnpkg.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz#5f32e0dba356f4ac9a11068d2a5c134ca3ba6564" - integrity sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A== - -"@parcel/watcher-darwin-arm64@2.5.6": - version "2.5.6" - resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz#88d3e720b59b1eceffce98dac46d7c40e8be5e8e" - integrity sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA== - -"@parcel/watcher-darwin-x64@2.5.6": - version "2.5.6" - resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz#bf05d76a78bc15974f15ec3671848698b0838063" - integrity sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg== - -"@parcel/watcher-freebsd-x64@2.5.6": - version "2.5.6" - resolved "https://registry.yarnpkg.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz#8bc26e9848e7303ac82922a5ae1b1ef1bdb48a53" - integrity sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng== - -"@parcel/watcher-linux-arm-glibc@2.5.6": - version "2.5.6" - resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz#1328fee1deb0c2d7865079ef53a2ba4cc2f8b40a" - integrity sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ== - -"@parcel/watcher-linux-arm-musl@2.5.6": - version "2.5.6" - resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz#bad0f45cb3e2157746db8b9d22db6a125711f152" - integrity sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg== - -"@parcel/watcher-linux-arm64-glibc@2.5.6": - version "2.5.6" - resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz#b75913fbd501d9523c5f35d420957bf7d0204809" - integrity sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA== - -"@parcel/watcher-linux-arm64-musl@2.5.6": - version "2.5.6" - resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz#da5621a6a576070c8c0de60dea8b46dc9c3827d4" - integrity sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA== - -"@parcel/watcher-linux-x64-glibc@2.5.6": - version "2.5.6" - resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz#ce437accdc4b30f93a090b4a221fd95cd9b89639" - integrity sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ== - -"@parcel/watcher-linux-x64-musl@2.5.6": - version "2.5.6" - resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz#02400c54b4a67efcc7e2327b249711920ac969e2" - integrity sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg== - -"@parcel/watcher-win32-arm64@2.5.6": - version "2.5.6" - resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz#caae3d3c7583ca0a7171e6bd142c34d20ea1691e" - integrity sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q== - -"@parcel/watcher-win32-ia32@2.5.6": - version "2.5.6" - resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz#9ac922550896dfe47bfc5ae3be4f1bcaf8155d6d" - integrity sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g== - -"@parcel/watcher-win32-x64@2.5.6": - version "2.5.6" - resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz#73fdafba2e21c448f0e456bbe13178d8fe11739d" - integrity sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw== +"@oxc-project/types@=0.146.0": + version "0.146.0" + resolved "https://registry.yarnpkg.com/@oxc-project/types/-/types-0.146.0.tgz#d57a2591abbf1f6e50981b07ee24ab269530d87a" + integrity sha512-XC0QsnnhVe7sLIWmYmdPw7x5P0h4W8vUU3Nv1ySgWXtvCz8NizoAEpGXA0sOYoJQV2Rl13LgURAHQ5cI5ILCSA== + +"@parcel/watcher-android-arm64@2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.6.0.tgz#99aaa3223d43807c9340af439cad7e9b6d26ada6" + integrity sha512-trgpLSCKRC/huFjXX/Smh+0sWe4+YtKfktIToiMl59ghz7z+qkH6kMvNnUbLyRs9N11t8l4svSCs1+5B3rOAhA== + +"@parcel/watcher-darwin-arm64@2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.6.0.tgz#024496e586b4744f09ce532bbe89fe38ef02a64e" + integrity sha512-Y3QV0gl7Q1zbfueunkWIERICbEojQFCgpyG7YqOGNFLsckXyI1xu9mAIUpKY9QBYzBtSkN8dBPwd3yiAO9ovMw== + +"@parcel/watcher-darwin-x64@2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.6.0.tgz#a4621df1359a93d39a332d9bab5ff09016a0608f" + integrity sha512-Ohv6OpzhUfKYD7Beb8kDvG0jbIxORCYY1JRdZnaBtnjjkJxgD7ZVL0nw2sCYd0yTMKTvz3nnTnOF3cDifK+kvw== + +"@parcel/watcher-freebsd-x64@2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.6.0.tgz#7f565ed1a5b3a5e604e6a4799121518265d62a3d" + integrity sha512-5HmXvDgs8VK+74jF9y9/2FE3/OnlcKmc56tjmSrEuZjpSZOGL+fvAu+HKJBdPs9uwoP2hE6TlSUpXZ/C5jUFmQ== + +"@parcel/watcher-linux-arm-glibc@2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.6.0.tgz#ad7d3825e67b81999165da42593022045abc0889" + integrity sha512-Ps/hui3A+vMbjdqlqAowK2ZL8+BO8dBjxeWXj6npTBs3jx4wWmbPpaLuqwrQrSqIVMCnpWo238bJ1U37GhQOYg== + +"@parcel/watcher-linux-arm-musl@2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.6.0.tgz#fe7d1cccb2c483215c090e938cf5cf404d2f9a8c" + integrity sha512-9c6AUHgHoG+IY88MRIHupztQiQnrbqHYQjkM2btA+Bf/wQnQMuiD0Wfk1EVv3TlNT3x41uU71rn6E4xh/+zvkw== + +"@parcel/watcher-linux-arm64-glibc@2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.6.0.tgz#7e239dcb4646c4c79f006a7131a48238249530da" + integrity sha512-yHRqS2owEXe6Hic9z6Mh1ECsCd+ODVOGvZDyciqRd21+v+o+DnXMOrw50DSpIG2sb8GPEaPPmfeCAWKPJdq46g== + +"@parcel/watcher-linux-arm64-musl@2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.6.0.tgz#c58b8d9c6d8d81594be00dd83aab741c1aaf7e0e" + integrity sha512-WhB2e/V7rqdHHWZusBSPuy5Ei8S6lSz6FE5TKKQz5h3a0O+C+mhY7vxU9b/stqvMb8beLnPY82ZrFTLKs+SrKA== + +"@parcel/watcher-linux-x64-glibc@2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.6.0.tgz#5184fa9a770478d86e56875f4ee163a0abdc8791" + integrity sha512-ulGE6x6Oz6iAwg75T8YQSoguBWasniIbX+QWpaYPcCnDOpdWX3k+4xbEYPZVLxOuoJI+svJJPD3sEj8G7lrQ3A== + +"@parcel/watcher-linux-x64-musl@2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.6.0.tgz#2d1c55aa7246cbc7670e2612058a8a542c9cf246" + integrity sha512-tkBYKt7YQrjIJWYDnto2YgO8MRkjlMTSNoRHzsXinBqbLdeOM3L32wPZJvIZxqaLMfSlS/4sUjH/6STVP/XDLw== + +"@parcel/watcher-win32-arm64@2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.6.0.tgz#15e09432040fee9e2213aa9c10ed589012526def" + integrity sha512-gIZAP23jaHjGWasY/TY6yL7NHFClf0Ga7FN+iINvk+KN94rhm94lYZhFsbYFNcA04/onvGD9kKmiJLJB2HbNwQ== + +"@parcel/watcher-win32-x64@2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.6.0.tgz#9bee199a2a4accd557b451ac2c1c793f305ae012" + integrity sha512-cA+/pXV2YkfxlIcXOQ5fSWqAzzPyD78/x5qbK/I0vUkrlYHA8TIz+MXjAbGouguKVSI4bOmkTSJ1/poVSsgt+A== "@parcel/watcher@^2.4.1": - version "2.5.6" - resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.5.6.tgz#3f932828c894f06d0ad9cfefade1756ecc6ef1f1" - integrity sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ== + version "2.6.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.6.0.tgz#99661f6220070b76a766aba6b7e313a087a1be4f" + integrity sha512-7FNeNl8NCE7aINx7WXiKQrPYZWC/hvrTsmk6zmxbI7LTXE7hVek/n8AfVgpe2y82zl3w0HvCHN0bVKMBoJcC0w== dependencies: detect-libc "^2.0.3" is-glob "^4.0.3" node-addon-api "^7.0.0" - picomatch "^4.0.3" + picomatch "^4.0.4" optionalDependencies: - "@parcel/watcher-android-arm64" "2.5.6" - "@parcel/watcher-darwin-arm64" "2.5.6" - "@parcel/watcher-darwin-x64" "2.5.6" - "@parcel/watcher-freebsd-x64" "2.5.6" - "@parcel/watcher-linux-arm-glibc" "2.5.6" - "@parcel/watcher-linux-arm-musl" "2.5.6" - "@parcel/watcher-linux-arm64-glibc" "2.5.6" - "@parcel/watcher-linux-arm64-musl" "2.5.6" - "@parcel/watcher-linux-x64-glibc" "2.5.6" - "@parcel/watcher-linux-x64-musl" "2.5.6" - "@parcel/watcher-win32-arm64" "2.5.6" - "@parcel/watcher-win32-ia32" "2.5.6" - "@parcel/watcher-win32-x64" "2.5.6" + "@parcel/watcher-android-arm64" "2.6.0" + "@parcel/watcher-darwin-arm64" "2.6.0" + "@parcel/watcher-darwin-x64" "2.6.0" + "@parcel/watcher-freebsd-x64" "2.6.0" + "@parcel/watcher-linux-arm-glibc" "2.6.0" + "@parcel/watcher-linux-arm-musl" "2.6.0" + "@parcel/watcher-linux-arm64-glibc" "2.6.0" + "@parcel/watcher-linux-arm64-musl" "2.6.0" + "@parcel/watcher-linux-x64-glibc" "2.6.0" + "@parcel/watcher-linux-x64-musl" "2.6.0" + "@parcel/watcher-win32-arm64" "2.6.0" + "@parcel/watcher-win32-x64" "2.6.0" "@popperjs/core@^2.11.8": version "2.11.8" @@ -472,11 +470,17 @@ integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== "@react-aria/ssr@^3.5.0": - version "3.9.10" - resolved "https://registry.yarnpkg.com/@react-aria/ssr/-/ssr-3.9.10.tgz#7fdc09e811944ce0df1d7e713de1449abd7435e6" - integrity sha512-hvTm77Pf+pMBhuBm760Li0BVIO38jv1IBws1xFm1NoL26PU+fe+FMW5+VZWyANR6nYL65joaJKZqOdTQMkO9IQ== + version "3.10.1" + resolved "https://registry.yarnpkg.com/@react-aria/ssr/-/ssr-3.10.1.tgz#d082600c811e35e8ab780c55c47b5d731359aaf7" + integrity sha512-jn038/ZYmu6DpfXJ6r2U9zFFppjbc9wnApPJSCxao2RZVEqep4YyoniHSy8qv6V21/xyS4IV7W9a+X2jOjSuag== dependencies: "@swc/helpers" "^0.5.0" + react-aria "^3.48.0" + +"@react-types/shared@^3.36.1": + version "3.36.1" + resolved "https://registry.yarnpkg.com/@react-types/shared/-/shared-3.36.1.tgz#edb8081e3872ae68a4eb4a65e62233d0754ec186" + integrity sha512-AzsuD9OfxTOZMMvTRhlN3oHBwOmFN7tDh27LzqmHt4+uOgPhJT7ZM7/kVs/8/o0WxayMUIk3hBmCFRHv1FUoag== "@restart/hooks@^0.4.9": version "0.4.16" @@ -507,86 +511,82 @@ uncontrollable "^8.0.4" warning "^4.0.3" -"@rolldown/binding-android-arm64@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz#54ce8f8382213f4a314a0c2f7ba83f81ffeae592" - integrity sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw== - -"@rolldown/binding-darwin-arm64@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz#388fca1566c14c00c4b446fc3928630e7f0d95fc" - integrity sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA== - -"@rolldown/binding-darwin-x64@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz#53f57de1f599ecf1db13823cfc88c18fb80954ad" - integrity sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg== - -"@rolldown/binding-freebsd-x64@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz#6f3fdda1b7aeaac9d268a526804b4fb96e4e35f1" - integrity sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g== - -"@rolldown/binding-linux-arm-gnueabihf@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz#d87a454bf585cc9676849377e91d6e375297326f" - integrity sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw== - -"@rolldown/binding-linux-arm64-gnu@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz#419fd6bf612cf348f10528cbcd94ebab9607d8d1" - integrity sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw== - -"@rolldown/binding-linux-arm64-musl@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz#fcc6918696bb76844877e1e4930a18fd0d374069" - integrity sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q== - -"@rolldown/binding-linux-ppc64-gnu@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz#32aecb7c8dae5d4f2a8cde57a058ec86991542f8" - integrity sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg== - -"@rolldown/binding-linux-s390x-gnu@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz#bed9346ea81e6bb8b93cf11f5d88b77db890b763" - integrity sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg== - -"@rolldown/binding-linux-x64-gnu@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz#64c2d26f75dffd9b5a1f97557a00ae77250c8cb7" - integrity sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg== - -"@rolldown/binding-linux-x64-musl@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz#5a45132e8a47659eeaaf3b540c2954a97c860ff3" - integrity sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow== - -"@rolldown/binding-openharmony-arm64@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz#290513068c55e849dc8457a32afee1d7b0acb309" - integrity sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg== - -"@rolldown/binding-wasm32-wasi@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz#3d9972dbf1a953d3c7afaa4a0f20ef2b2e39f31b" - integrity sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg== - dependencies: - "@emnapi/core" "1.10.0" - "@emnapi/runtime" "1.10.0" - "@napi-rs/wasm-runtime" "^1.1.4" - -"@rolldown/binding-win32-arm64-msvc@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz#a004ab607a16d6f03bcb555728ff888af75773ad" - integrity sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g== - -"@rolldown/binding-win32-x64-msvc@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz#e2a25b34691a1cc8a1209d7de709063026dd0cdb" - integrity sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA== - -"@rolldown/pluginutils@^1.0.0": +"@rolldown/binding-android-arm-eabi@1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.5.tgz#165b80910de7cd33f772d5b7b045b259acb7420c" + integrity sha512-DLe/i+l8ynIBY7XEQ191TeZvCoowIGa18R+dIV30GW7DiOtp74i/xX8hs8GUjW5ARV7VZuie3d6AumSmCwbeRA== + +"@rolldown/binding-android-arm64@1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.5.tgz#5ed74d4b8fa56c68eb1aeb81d0d207a85b6de05c" + integrity sha512-zXcwKlQApYAOELHd8PwKDFkagYF9Wy4e0RJ+0qnzl9Pjnpj75TEG8ufv40p2J7kCEfwZAsNiuzRIyNNMWT38ig== + +"@rolldown/binding-darwin-arm64@1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.5.tgz#6f27c7060e58ca03061fa7d50f9dc409bc377fe1" + integrity sha512-dK4QakI42nzWgJT5sm4y4y/O//D4OxM75/cH28RLV+nzIN9AY+YsbuUVrUTjlLjXR6vpyxFbSsbmNuJ6BP9sww== + +"@rolldown/binding-darwin-x64@1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.5.tgz#74ab897d134ede4072fdc6108f00193e6167ee28" + integrity sha512-fqSALaUu1Wjd1nK2uW2kJDWdLCc8lx1IcY+MTY26Aurfdx19anlzhqXOgCFbBFQnlFDTn4TC1/7Nz4Bl2mLP3A== + +"@rolldown/binding-freebsd-x64@1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.5.tgz#7d337f9ae4b739674e1938747118ab0676c8ef8a" + integrity sha512-/vCnNxlkxs9tKxNDcyWUePpJ/PgTzxIaVhoM5SmG8UV+GR/IcPam4VYxi7GIMo7PSDuNqlJqvprqii9NqqVCMw== + +"@rolldown/binding-linux-arm-gnueabihf@1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.5.tgz#a8195dc1091ade0f912b0613ef6500941e5615f4" + integrity sha512-abk0NLA519LxRCszmbE0jYKuQ9YPocOXTiOXOo6Yr+YAT95VH+PtqYAjOJvGKt3viEd/x4qzabAlwd5bHOOARg== + +"@rolldown/binding-linux-arm64-gnu@1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.5.tgz#40fbbb97072b1acaa3e0e8fe9774fe524e860bba" + integrity sha512-Y7eALiJ8lr0M2HH103Js+g7V34wf6snlpZLAsHI90uLhr3PVlNsbFVAXJC9d/V6BnPyKtpSwI+NcB/RLxsQxuA== + +"@rolldown/binding-linux-arm64-musl@1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.5.tgz#3cfe8b0f7c13de29dace9a9fc6c03081164176ab" + integrity sha512-xMvZgnbZg4YVnR/AX2b3oOPDTFYJvUVaJg5FedA/LuvexAtXibZQej4cnTkw3rjsJ/ggUROB64TdtETiim+FYA== + +"@rolldown/binding-linux-ppc64-gnu@1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.5.tgz#3bd890d96ae29f93718aa142ed0982f2ee2978ad" + integrity sha512-GRjeqTUDHTo5GwntsLaAMcBahG3nlpjftXWZLN73HiYQlhwEowvarFgQnRnQZtIp4keXX7quXFbG38uPZBa2EA== + +"@rolldown/binding-linux-s390x-gnu@1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.5.tgz#0959a0d5af22741d5787918e27aef70dc8602804" + integrity sha512-vLNTR45F2Uwc8AufkNXPmB4VliaXs+FvcheEogIzOXzO4l+LzieXF5A/TWxLy5HtqpsRCHUfd0lPVrrdgXdLHQ== + +"@rolldown/binding-linux-x64-gnu@1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.5.tgz#7baa94e826328ac6f457d9e1abacffa0353e8d22" + integrity sha512-Mgj59/HTuYeK9Gz2MA+mBWKnHsAgkBSec15ZMb1st3oIfFbX7gCjOae7GydHhzcyQi9Z/7M1QuN9bR3oFqF0jQ== + +"@rolldown/binding-linux-x64-musl@1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.5.tgz#5f37597eaf0e22313d1e3d4be7d1be1fd332904e" + integrity sha512-mY8AP0/ichsbhAxGnLa3d3+MwV0EfgrPND2bplI3Ym8T6R2pJ0N87bvrKVwNXmdy3jnr6eQBecdqx/HMknBmpA== + +"@rolldown/binding-openharmony-arm64@1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.5.tgz#d096567af3f738cbe6aa858ab0a01aae9f357ef4" + integrity sha512-8SLssA2oweAxyRgDp789ACfRb/3P+zNRJpzZxSizxF9m8NUDQ4+3xjo8ttjhVGGw6Qxb70oZiEtIjaKikCO7Yw== + +"@rolldown/binding-win32-arm64-msvc@1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.5.tgz#d53b911aa4e6b547b789c07747fabab2ac8c237d" + integrity sha512-vGbruD5zquhoc8D9SViXgN2FBJtNdTyQ4DtG+SWiEGlJiAzoKcZ2xp+xuXCffhubVdt0NJlTZqkeRuERy7g8Cw== + +"@rolldown/binding-win32-x64-msvc@1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.5.tgz#7bbd08cfda6a98de9b756472c772a36ebb7229bc" + integrity sha512-e/SXpgISz+IoqVcSSI0rx/d/he8zqLex+/rCWpnHpmVfmPIUjag9H6P7zotf0gJHwPUhQxZ/mF8tr6acebT9yw== + +"@rolldown/pluginutils@^1.0.0", "@rolldown/pluginutils@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz#e3fcee093fbb5ce765e1ad088ff4de2889f6f9be" integrity sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw== @@ -597,9 +597,9 @@ integrity sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w== "@swc/helpers@^0.5.0": - version "0.5.18" - resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.18.tgz#feeeabea0d10106ee25aaf900165df911ab6d3b1" - integrity sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ== + version "0.5.23" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.23.tgz#19287d0d86d962b111376039a50c792902c9a86a" + integrity sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw== dependencies: tslib "^2.8.0" @@ -611,53 +611,69 @@ "@popperjs/core" "^2.11.8" bootstrap "5.3.7" -"@tabler/icons-react@^3.44.0": - version "3.44.0" - resolved "https://registry.yarnpkg.com/@tabler/icons-react/-/icons-react-3.44.0.tgz#26e84ee0ef756bfae5dcbd8265312ba3cd5a91d9" - integrity sha512-8+rvzBbVm/1Z3sG3x7GUNAaxIKxwgz8xaMhRs23nrCnMTKRFAhEC+82zAIFeAA0seXdrAGX5HFCkaLpGK2rVHg== +"@tabler/icons-react@^3.46.0": + version "3.46.0" + resolved "https://registry.yarnpkg.com/@tabler/icons-react/-/icons-react-3.46.0.tgz#9840606d10aab071ad2c0dbdfcfba0eef6e9825d" + integrity sha512-CCm7xJWhDT2PH4ZIFkP6AgYKtVhq0gpYkjUN+GVh1AzmIQaa77OW0bQPBPQiTE0PsXMR9oSxFqA3qBglzPyrVQ== dependencies: - "@tabler/icons" "3.44.0" + "@tabler/icons" "3.46.0" -"@tabler/icons@3.44.0": - version "3.44.0" - resolved "https://registry.yarnpkg.com/@tabler/icons/-/icons-3.44.0.tgz#286b203aac98591e27360de03974762568bbb272" - integrity sha512-Wn0AOZG9sg0L+bjfMqq4eNhC6pQjIrk94LvvWYNYkY8KH8wC3YILRzQlrnVJc4FUeMxH/AK97QsYCX35H3LndA== +"@tabler/icons@3.46.0": + version "3.46.0" + resolved "https://registry.yarnpkg.com/@tabler/icons/-/icons-3.46.0.tgz#28ba3f4895715863fdd78b49a5617764c9557fe5" + integrity sha512-f2RYFl3fzPwj5WO82x6en0dmkjefxEfOm16D1ByM6cj/McNiwOkL4VaPUoP9VVIrXAD9WnTSVFr70px703b//A== -"@tanstack/query-core@5.101.0": - version "5.101.0" - resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.101.0.tgz#45391ce143c270b7e7a55bd1a6696918f20782d1" - integrity sha512-cQetA74EB+seWySv1TTKr828TnP0u39m6LykwDXIo84SNortpDkp30TMEjkqtYCNP9c40uT/iwl6MLiufEt0Ow== +"@tanstack/query-core@5.101.4": + version "5.101.4" + resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.101.4.tgz#c01b4289b3094144d8ef96235aa506242cf83efa" + integrity sha512-gNwcvOJcRbLWPOLG/2OBm+zM+Yv+MKsXKEOWC57USuZDEsI71hEErQsiEGx5wX9rzWWkfwM0fVSPoiIFSsxfiw== -"@tanstack/query-devtools@5.100.14": - version "5.100.14" - resolved "https://registry.yarnpkg.com/@tanstack/query-devtools/-/query-devtools-5.100.14.tgz#1555c8e1e4ea74db85dd2faaea2b7b50e135faf1" - integrity sha512-g96SmSSQecYTYcyuAMRXr895GplJv01UGt7qttQWPOUyZ5EGz5tbRc589bMc2m5BsPFD6O0PCEAHdbDYNP6UBw== +"@tanstack/query-devtools@5.101.4": + version "5.101.4" + resolved "https://registry.yarnpkg.com/@tanstack/query-devtools/-/query-devtools-5.101.4.tgz#4fa86fd8f8a1e974923faf1987d93cf543b8305a" + integrity sha512-z5IPHnDX3aUWeTWlRKLyooBQekaCAw4xRpZqPQ390RiWTDBcTynjpPT221BArw0u2+pnQMdGvPQI9YNNubBcmA== -"@tanstack/react-query-devtools@^5.100.14": - version "5.100.14" - resolved "https://registry.yarnpkg.com/@tanstack/react-query-devtools/-/react-query-devtools-5.100.14.tgz#0774021fdc0b417a86b67b196d5ffb9820cff10c" - integrity sha512-JkP5VDgKOw3t/QSA1OABRHEqx8BuNs5MfvZRooNqdvN57SzTuGq3fKR1a2IH5rqa5HDLUm+FOXUEnB9ueHiLzg== +"@tanstack/react-query-devtools@^5.101.4": + version "5.101.4" + resolved "https://registry.yarnpkg.com/@tanstack/react-query-devtools/-/react-query-devtools-5.101.4.tgz#adbac799a9b70d67c52e4a483450005d68c9a127" + integrity sha512-VeK2gtmfj7kvRBjtxS7TKxt/6qKhn8VzabY4UiYMr7NV9CddjSRYRgeYyld+NpjAkgMV9dd+2Qdr8ah5I03NeA== dependencies: - "@tanstack/query-devtools" "5.100.14" + "@tanstack/query-devtools" "5.101.4" -"@tanstack/react-query@^5.101.0": - version "5.101.0" - resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.101.0.tgz#2dd56c5b96ec816d6b6ec9cee5c80ed298974733" - integrity sha512-rLlJXSpkqfizLWgkR5+eLeIk0MvTx/meEIR7LRjxic+qxiQP8zVjq7BqQkiCMNLQBlLfuOLqqr6KO5GtrDlmSg== +"@tanstack/react-query@^5.101.4": + version "5.101.4" + resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.101.4.tgz#044137754d79aaa30a82f6e6c42488be79c86ea7" + integrity sha512-yRg2pfOCxIs4ZJW3XYYHU/WgtD04FHSnfHlpRT7h7pR77hwkdRG4wxbKe4aq6P0RvXUTBSQpQeadS1SUYUe+KA== dependencies: - "@tanstack/query-core" "5.101.0" + "@tanstack/query-core" "5.101.4" -"@tanstack/react-table@^8.21.3": - version "8.21.3" - resolved "https://registry.yarnpkg.com/@tanstack/react-table/-/react-table-8.21.3.tgz#2c38c747a5731c1a07174fda764b9c2b1fb5e91b" - integrity sha512-5nNMTSETP4ykGegmVkhjcS8tTLW6Vl4axfEGQN3v0zdHYbK4UfoqfPChclTrJ4EoK9QynqAu9oUf8VEmrpZ5Ww== +"@tanstack/react-store@^0.11.0": + version "0.11.1" + resolved "https://registry.yarnpkg.com/@tanstack/react-store/-/react-store-0.11.1.tgz#e1e58036ffffa58f5b5d8826c2389f97502fac2c" + integrity sha512-HaIGKI3YLmjBYIvy5DFDY23oNaYZIsTZfngey07Uh5iLVJgM3bIGCnZeOFOqzjFld9JHWcaHJnasD/bKoGKwJQ== dependencies: - "@tanstack/table-core" "8.21.3" + "@tanstack/store" "0.11.1" + use-sync-external-store "^1.6.0" -"@tanstack/table-core@8.21.3": - version "8.21.3" - resolved "https://registry.yarnpkg.com/@tanstack/table-core/-/table-core-8.21.3.tgz#2977727d8fc8dfa079112d9f4d4c019110f1732c" - integrity sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg== +"@tanstack/react-table@^9.1.2": + version "9.1.2" + resolved "https://registry.yarnpkg.com/@tanstack/react-table/-/react-table-9.1.2.tgz#6848c879ec5379c80b107bc1c19c68110bfb8a1f" + integrity sha512-YQPZFJ1nIi/bjjwsPZVouABgahDcl7Gdm33CdTStUJBn0DjEVJ2uhSTVmIoWt9MVKdQziXGAsXipSzy949Hygg== + dependencies: + "@tanstack/react-store" "^0.11.0" + "@tanstack/table-core" "9.1.2" + +"@tanstack/store@0.11.1", "@tanstack/store@^0.11.0": + version "0.11.1" + resolved "https://registry.yarnpkg.com/@tanstack/store/-/store-0.11.1.tgz#063f634fe3cc925ad83704581a7be75301bec612" + integrity sha512-mzTOBhypOuDJAy/D8n2MfUZ1HFkXnmSETviRyhqEC8LUE7/IZQExOTxMANj3KjTofYTkFNpBY67qaVrT41YccA== + +"@tanstack/table-core@9.1.2": + version "9.1.2" + resolved "https://registry.yarnpkg.com/@tanstack/table-core/-/table-core-9.1.2.tgz#75fded10e495fc7215380201f30a05300b157355" + integrity sha512-ONpWQeass1sfg80CWF1NSwQ8r3GiqxA2lT/EdqIcrDEPZ0Z+0mM94eQoFYLPN0Kztzj8TQVb2+PrSZSItqA61g== + dependencies: + "@tanstack/store" "^0.11.0" "@testing-library/dom@^10.4.1": version "10.4.1" @@ -673,10 +689,10 @@ picocolors "1.1.1" pretty-format "^27.0.2" -"@testing-library/jest-dom@^6.9.1": - version "6.9.1" - resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz#7613a04e146dd2976d24ddf019730d57a89d56c2" - integrity sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA== +"@testing-library/jest-dom@^7.0.1": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-7.0.1.tgz#649a9a8b2039f28d29f9f7a46eba9a8b727f811e" + integrity sha512-oMDTC3oA+6CXSO2JZnvOI7CA6oVub6kij5ggk9ohwye5slmkwxYDXcPOVxgMw/RQlticjtO0C1RZkR97HgrWMw== dependencies: "@adobe/css-tools" "^4.4.0" aria-query "^5.0.0" @@ -692,13 +708,6 @@ dependencies: "@babel/runtime" "^7.12.5" -"@tybys/wasm-util@^0.10.1": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@tybys/wasm-util/-/wasm-util-0.10.2.tgz#12b3a1b33db1f9cad4ddff1f604ab7dd00bf464e" - integrity sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg== - dependencies: - tslib "^2.4.0" - "@types/aria-query@^5.0.1": version "5.0.4" resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.4.tgz#1a31c3d378850d2778dabb6374d036dcba4ba708" @@ -718,9 +727,9 @@ integrity sha512-CefEn/J336TBDp7NX8JqzlDtCBOsm8M3r1Li0gEOt0HOMHF1XemNyrx9lSHjsafcb1yYWybU0N8ZAXuyCaND0w== "@types/debug@^4.0.0": - version "4.1.12" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917" - integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ== + version "4.1.13" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.13.tgz#22d1cc9d542d3593caea764f974306ab36286ee7" + integrity sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw== dependencies: "@types/ms" "*" @@ -737,9 +746,9 @@ "@types/estree" "*" "@types/estree@*", "@types/estree@^1.0.0": - version "1.0.8" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" - integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== + version "1.0.9" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.9.tgz#cf3f0e876d7bee15a93ab925b82bf570a3904a24" + integrity sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg== "@types/hast@^2.0.0": version "2.3.10" @@ -749,9 +758,9 @@ "@types/unist" "^2" "@types/hast@^3.0.0": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/hast/-/hast-3.0.4.tgz#1d6b39993b82cea6ad783945b0508c25903e15aa" - integrity sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ== + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-3.0.5.tgz#48020de4c0e63492f4ca9db42068c108f68b7f8f" + integrity sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g== dependencies: "@types/unist" "*" @@ -779,12 +788,12 @@ resolved "https://registry.yarnpkg.com/@types/ms/-/ms-2.1.0.tgz#052aa67a48eccc4309d7f0191b7e41434b90bb78" integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA== -"@types/node@*", "@types/node@>=20.0.0", "@types/node@^25.9.1": - version "25.9.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-25.9.1.tgz#3bda556db500ae4319c08e7fc9ab94f19013ba0b" - integrity sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg== +"@types/node@*", "@types/node@>=20.0.0", "@types/node@^26.2.0": + version "26.2.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-26.2.0.tgz#5a4875a862fda8fdc57de8faa579bb81ecba1685" + integrity sha512-5IviulTZeRNp2vAJ514cc/HUlY5nZ9fCbq9DMyC52BrhFZACo3nI0R7qBxhQmo/d27NFe96ur/b7Wwxklda+kg== dependencies: - undici-types ">=7.24.0 <7.24.7" + undici-types "~8.3.0" "@types/parse-json@^4.0.0": version "4.0.2" @@ -801,10 +810,10 @@ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.15.tgz#e6e5a86d602beaca71ce5163fadf5f95d70931c7" integrity sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw== -"@types/react-dom@^19.2.3": - version "19.2.3" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-19.2.3.tgz#c1e305d15a52a3e508d54dca770d202cb63abf2c" - integrity sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ== +"@types/react-dom@^19.2.4": + version "19.2.4" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-19.2.4.tgz#165ab5e97dfb081847b0f6755060cf40a3f6666b" + integrity sha512-Bsc+QHgp+P/F02XDzNCY9jnZNCUuLki36KT7VKrTXXLdHf+vHMNZnW1rVu5DNW/rCK+fya3DATySbLM4yhtKUw== "@types/react-table@^7.7.20": version "7.7.20" @@ -818,10 +827,10 @@ resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.12.tgz#b5d76568485b02a307238270bfe96cb51ee2a044" integrity sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w== -"@types/react@*", "@types/react@>=16.9.11", "@types/react@^19.2.16": - version "19.2.16" - resolved "https://registry.yarnpkg.com/@types/react/-/react-19.2.16.tgz#9868b153fd9e34e0117afcd5d7e372b8179337e1" - integrity sha512-esJiCAnl0kfpNdE69f3So4WJUXy95dLZydX0KwK46riIHDzHM7O9Vtf9xCHW0PXIqvgqNrswl522kA/5yx+F4w== +"@types/react@*", "@types/react@>=16.9.11", "@types/react@^19.2.18": + version "19.2.18" + resolved "https://registry.yarnpkg.com/@types/react/-/react-19.2.18.tgz#eb0b6a1fb635d1a9692d5f84a3495bd8ad153707" + integrity sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w== dependencies: csstype "^3.2.2" @@ -836,9 +845,9 @@ integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA== "@types/warning@^3.0.3": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/warning/-/warning-3.0.3.tgz#d1884c8cc4a426d1ac117ca2611bf333834c6798" - integrity sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/warning/-/warning-3.0.4.tgz#ebc0c83180dc83994d902bbd51ab0af8a445b1f9" + integrity sha512-CqN8MnISMwQbLJXO3doBAV4Yw9hx9/Pyr2rZ78+NfaCnhyRA/nKrpyk6E7mKw17ZOaQdLpK9GiUjrqLzBlN3sg== "@types/whatwg-mimetype@^3.0.2": version "3.0.2" @@ -852,6 +861,106 @@ dependencies: "@types/node" "*" +"@typescript/typescript-aix-ppc64@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@typescript/typescript-aix-ppc64/-/typescript-aix-ppc64-7.0.2.tgz#cdc7ce81d60f1e09034960ddfb1fb880d7a776b6" + integrity sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ== + +"@typescript/typescript-darwin-arm64@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@typescript/typescript-darwin-arm64/-/typescript-darwin-arm64-7.0.2.tgz#a55fdfcfa58df58d27db2237cde6a5c1e35a7235" + integrity sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA== + +"@typescript/typescript-darwin-x64@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@typescript/typescript-darwin-x64/-/typescript-darwin-x64-7.0.2.tgz#38d1c9172800a91d707bec64d2a370a016634db4" + integrity sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA== + +"@typescript/typescript-freebsd-arm64@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@typescript/typescript-freebsd-arm64/-/typescript-freebsd-arm64-7.0.2.tgz#f1ff8810030b35d2b5be0db6a2dc650460ea94fa" + integrity sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ== + +"@typescript/typescript-freebsd-x64@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@typescript/typescript-freebsd-x64/-/typescript-freebsd-x64-7.0.2.tgz#3d86b03f353c5b1ba95162eb6ce35533bfc294bd" + integrity sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw== + +"@typescript/typescript-linux-arm64@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@typescript/typescript-linux-arm64/-/typescript-linux-arm64-7.0.2.tgz#d9334d96d6dac6ff85da9c865588948de939e91f" + integrity sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ== + +"@typescript/typescript-linux-arm@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@typescript/typescript-linux-arm/-/typescript-linux-arm-7.0.2.tgz#ad94b41e1aee2a4dcc6a298c7b67c43345fde32e" + integrity sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ== + +"@typescript/typescript-linux-loong64@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@typescript/typescript-linux-loong64/-/typescript-linux-loong64-7.0.2.tgz#2965aee4fc873360139d893daafe6397a29138ad" + integrity sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ== + +"@typescript/typescript-linux-mips64el@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@typescript/typescript-linux-mips64el/-/typescript-linux-mips64el-7.0.2.tgz#1a887a311bed3a833f80bfd4a9ed37c271936cf0" + integrity sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA== + +"@typescript/typescript-linux-ppc64@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@typescript/typescript-linux-ppc64/-/typescript-linux-ppc64-7.0.2.tgz#8b63c9b2f445b393eb4e43ec21da225dade3577d" + integrity sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA== + +"@typescript/typescript-linux-riscv64@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@typescript/typescript-linux-riscv64/-/typescript-linux-riscv64-7.0.2.tgz#b6e8a35c289b3ea97a92a41d461aaeed0d3b36e1" + integrity sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ== + +"@typescript/typescript-linux-s390x@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@typescript/typescript-linux-s390x/-/typescript-linux-s390x-7.0.2.tgz#2ef96693be4861f6d17965427e5b009cbbed1a3e" + integrity sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw== + +"@typescript/typescript-linux-x64@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@typescript/typescript-linux-x64/-/typescript-linux-x64-7.0.2.tgz#73269cb0baba50aea0ca060445a6b88e583f1ce2" + integrity sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A== + +"@typescript/typescript-netbsd-arm64@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@typescript/typescript-netbsd-arm64/-/typescript-netbsd-arm64-7.0.2.tgz#3a3649f97fafa210b4e6e3798c15e06605c8a901" + integrity sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA== + +"@typescript/typescript-netbsd-x64@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@typescript/typescript-netbsd-x64/-/typescript-netbsd-x64-7.0.2.tgz#47ec59491a40c470d2807dc4d2b825528fd979ab" + integrity sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA== + +"@typescript/typescript-openbsd-arm64@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@typescript/typescript-openbsd-arm64/-/typescript-openbsd-arm64-7.0.2.tgz#796be8da0bd989d8a3fb96f2801e38a8365b4baf" + integrity sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ== + +"@typescript/typescript-openbsd-x64@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@typescript/typescript-openbsd-x64/-/typescript-openbsd-x64-7.0.2.tgz#d37fe2a729eb942c076c454ee7f1815faf7d560f" + integrity sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg== + +"@typescript/typescript-sunos-x64@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@typescript/typescript-sunos-x64/-/typescript-sunos-x64-7.0.2.tgz#aba8d3464c3565a7044789baba96916bd4ab2c88" + integrity sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g== + +"@typescript/typescript-win32-arm64@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@typescript/typescript-win32-arm64/-/typescript-win32-arm64-7.0.2.tgz#b9de50a17196383f62620b5f9d0a2f34ad3b60d7" + integrity sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ== + +"@typescript/typescript-win32-x64@7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@typescript/typescript-win32-x64/-/typescript-win32-x64-7.0.2.tgz#cf3b7b0d6ce5635daca4c8e01c189cdcde47ec3c" + integrity sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g== + "@uiw/react-textarea-code-editor@^3.1.1": version "3.1.1" resolved "https://registry.yarnpkg.com/@uiw/react-textarea-code-editor/-/react-textarea-code-editor-3.1.1.tgz#8ca1b706a3081a51c68bc0df91c9c3cdadd9944e" @@ -862,74 +971,74 @@ rehype-prism-plus "2.0.0" "@ungap/structured-clone@^1.0.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz#d06bbb384ebcf6c505fde1c3d0ed4ddffe0aaff8" - integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== + version "1.3.3" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.3.tgz#094041e1a4cb1987f038335421281ac8be390bcc" + integrity sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg== -"@vitejs/plugin-react@^6.0.2": - version "6.0.2" - resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-6.0.2.tgz#f70cb8ed0ce225dbc3055d78070f820d8aa35eda" - integrity sha512-DlSMqo4WhThw4vB8Mpn0Woe9J+Jfq1geJ61AKW0QEgLzGMNwtIMdxbDUzLxcun8W7NbJO0e2Jg/Nxm3cCSVzzg== +"@vitejs/plugin-react@^6.1.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-6.1.0.tgz#a3d7a3b998c618385d076e390b74398c3d8c65bc" + integrity sha512-qd2BzUBehkov86WFhg0JkEFEYyCLG9uPCe6qWTY/kRlss9OvJrOF2UbIWT7p+8IzZHkEu0DNGHc4HSv+JdDLsw== dependencies: - "@rolldown/pluginutils" "^1.0.0" + "@rolldown/pluginutils" "^1.0.1" -"@vitest/expect@4.1.8": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-4.1.8.tgz#45154f1f8559f55c5281eb0dcb1ac37b581a87d8" - integrity sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ== +"@vitest/expect@4.1.11": + version "4.1.11" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-4.1.11.tgz#5f580d1f9cdbba314dbf23b2d911f8eb23878f5f" + integrity sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw== dependencies: "@standard-schema/spec" "^1.1.0" "@types/chai" "^5.2.2" - "@vitest/spy" "4.1.8" - "@vitest/utils" "4.1.8" + "@vitest/spy" "4.1.11" + "@vitest/utils" "4.1.11" chai "^6.2.2" tinyrainbow "^3.1.0" -"@vitest/mocker@4.1.8": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-4.1.8.tgz#d006bfc5894a1af51e74deddef2535d6bd436b16" - integrity sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw== +"@vitest/mocker@4.1.11": + version "4.1.11" + resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-4.1.11.tgz#8e2906361bc5dfa271757a858ae80643118fcbb4" + integrity sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ== dependencies: - "@vitest/spy" "4.1.8" + "@vitest/spy" "4.1.11" estree-walker "^3.0.3" magic-string "^0.30.21" -"@vitest/pretty-format@4.1.8": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-4.1.8.tgz#d9d2e248b900d7ad9556c4374fcdf1871c615193" - integrity sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA== +"@vitest/pretty-format@4.1.11": + version "4.1.11" + resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-4.1.11.tgz#8b28eb8240771d6ea970e33beaeb41384b51868e" + integrity sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw== dependencies: tinyrainbow "^3.1.0" -"@vitest/runner@4.1.8": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-4.1.8.tgz#4631808f3996359b74ccc3ca262990e14c295d50" - integrity sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg== +"@vitest/runner@4.1.11": + version "4.1.11" + resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-4.1.11.tgz#bfbad98c8d6c3f1fb4df12056ad569821ff77f21" + integrity sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw== dependencies: - "@vitest/utils" "4.1.8" + "@vitest/utils" "4.1.11" pathe "^2.0.3" -"@vitest/snapshot@4.1.8": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-4.1.8.tgz#37470135d64ea11bb2a839b1c6b7f5de7018f6ee" - integrity sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ== +"@vitest/snapshot@4.1.11": + version "4.1.11" + resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-4.1.11.tgz#df461eb165924a3155986dde68e13360f53f3d4c" + integrity sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog== dependencies: - "@vitest/pretty-format" "4.1.8" - "@vitest/utils" "4.1.8" + "@vitest/pretty-format" "4.1.11" + "@vitest/utils" "4.1.11" magic-string "^0.30.21" pathe "^2.0.3" -"@vitest/spy@4.1.8": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-4.1.8.tgz#3abfe9301d25c39f808dcaa9f10fec0dd370e564" - integrity sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA== +"@vitest/spy@4.1.11": + version "4.1.11" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-4.1.11.tgz#0add45cae953afed9c88f98e2f6fc9164558c32a" + integrity sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA== -"@vitest/utils@4.1.8": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-4.1.8.tgz#099ea5255cec08735410cf707edaba2c158c5ad9" - integrity sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg== +"@vitest/utils@4.1.11": + version "4.1.11" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-4.1.11.tgz#9b27a4293b827942b223539bfab1bd9f7eada31b" + integrity sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ== dependencies: - "@vitest/pretty-format" "4.1.8" + "@vitest/pretty-format" "4.1.11" convert-source-map "^2.0.0" tinyrainbow "^3.1.0" @@ -943,6 +1052,13 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== +aria-hidden@^1.2.3: + version "1.2.6" + resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.6.tgz#73051c9b088114c795b1ea414e9c0fff874ffc1a" + integrity sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA== + dependencies: + tslib "^2.0.0" + aria-query@5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" @@ -984,6 +1100,13 @@ bootstrap@5.3.7: resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.7.tgz#8640065036124d961d885d80b5945745e1154d90" integrity sha512-7KgiD8UHjfcPBHEpDNg+zGz8L3LqR3GVwqZiBRFX04a1BCArZOz1r2kjly2HQ0WokqTO0v1nF+QAt8dsW4lKlw== +buffer-image-size@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/buffer-image-size/-/buffer-image-size-0.6.4.tgz#357e8173e951ced3b5a2785c695993aa29dbcac4" + integrity sha512-nEh+kZOPY1w+gcCMobZ6ETUp9WfibndnosbpwB1iJk/8Gt5ZF2bhS6+B6bPYz424KtwsR6Rflc3tCz1/ghX2dQ== + dependencies: + "@types/node" "*" + buffer@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" @@ -1039,7 +1162,7 @@ classnames@^2.3.2, classnames@^2.5.1: resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b" integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow== -clsx@^2.1.1: +clsx@^2.0.0, clsx@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999" integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== @@ -1075,10 +1198,10 @@ cosmiconfig@^7.0.0: path-type "^4.0.0" yaml "^1.10.0" -country-flag-icons@^1.6.17: - version "1.6.17" - resolved "https://registry.yarnpkg.com/country-flag-icons/-/country-flag-icons-1.6.17.tgz#875cf35eb2a0d7fcb0f07166fed9fc65863e03f8" - integrity sha512-Nmik0289ZVZSI3c7mJR/amg6DyY7Z59b0sTFSKayeX72mHfPzCPJygwJs2pYgQULzuAyWeCUgwAJ+Dq8OR+JFw== +country-flag-icons@^1.6.20: + version "1.6.20" + resolved "https://registry.yarnpkg.com/country-flag-icons/-/country-flag-icons-1.6.20.tgz#aa6f36104568993f9cd43e7da283f9b7d0a802cc" + integrity sha512-py8JiEKzjhYw6HPJ0L7SxLgCYim36UPRTZX43/kqGueUCZLSvnrqAiwW8HtQibur7mdkFQUkjOgdK+o/9FBtaw== css.escape@^1.5.1: version "1.5.1" @@ -1109,10 +1232,10 @@ decode-named-character-reference@^1.0.0: dependencies: character-entities "^2.0.0" -decode-uri-component@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.4.1.tgz#2ac4859663c704be22bf7db760a1494a49ab2cc5" - integrity sha512-+8VxcR21HhTy8nOt6jf20w0c9CADrw1O8d+VZ/YzzCt4bJ3uBjw+D1q2osAB8RnpwwaeYBxy0HyKQxD5JBMuuQ== +decode-uri-component@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.5.0.tgz#4592fa1e1d640ec5e2760e2e168ad2ab5f2c9da1" + integrity sha512-1BiQVoK8C9gUbQU6NzAtO/tkz2qOFpEObMWpcFvhx4fYnj4Oc5yzaJN/LD36ihkVUdXyh5ZekzX+yM+ty/SrPg== deepmerge@^2.1.1: version "2.2.1" @@ -1171,10 +1294,15 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + es-module-lexer@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-2.1.0.tgz#1dfcbb5ea3bbfb63f28e1fc3676c3676d1c9624c" - integrity sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ== + version "2.3.2" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-2.3.2.tgz#311fa4f40168c1975c505477c51b23234d41ad55" + integrity sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw== escape-string-regexp@^4.0.0: version "4.0.0" @@ -1194,9 +1322,9 @@ estree-walker@^3.0.3: "@types/estree" "^1.0.0" expect-type@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/expect-type/-/expect-type-1.3.0.tgz#0d58ed361877a31bbc4dd6cf71bbfef7faf6bd68" - integrity sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA== + version "1.4.0" + resolved "https://registry.yarnpkg.com/expect-type/-/expect-type-1.4.0.tgz#24edf7f0cc69a44d008567ba4594ab96f3c3a3d6" + integrity sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA== extend@^3.0.0: version "3.0.2" @@ -1265,22 +1393,23 @@ graceful-fs@^4.2.4: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== -happy-dom@^20.9.0: - version "20.9.0" - resolved "https://registry.yarnpkg.com/happy-dom/-/happy-dom-20.9.0.tgz#22fa4f2b8a34d2fbd0fb43eb48227e4bf8e206e8" - integrity sha512-GZZ9mKe8r646NUAf/zemnGbjYh4Bt8/MqASJY+pSm5ZDtc3YQox+4gsLI7yi1hba6o+eCsGxpHn5+iEVn31/FQ== +happy-dom@^20.11.6: + version "20.11.6" + resolved "https://registry.yarnpkg.com/happy-dom/-/happy-dom-20.11.6.tgz#82e505cc1acf3e8bba99bf0f047761c756477682" + integrity sha512-Hldbg8AdAa5a5oDcZpjqnGitp7JB0hqWmfv/8qr+kft4vzSD8BHsbdRfzYvL/0QcbKcURC/yyoygbeDQarPvYg== dependencies: "@types/node" ">=20.0.0" "@types/whatwg-mimetype" "^3.0.2" "@types/ws" "^8.18.1" + buffer-image-size "^0.6.4" entities "^7.0.1" whatwg-mimetype "^3.0.0" - ws "^8.18.3" + ws "^8.21.0" -hasown@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" - integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== +hasown@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.4.tgz#8c62d8cb90beb2aad5d0a5b67581ad9854c3f003" + integrity sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A== dependencies: function-bind "^1.1.2" @@ -1426,9 +1555,9 @@ ieee754@^1.2.1: integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== immutable@^5.1.5: - version "5.1.5" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-5.1.5.tgz#93ee4db5c2a9ab42a4a783069f3c5d8847d40165" - integrity sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A== + version "5.1.9" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-5.1.9.tgz#ac23c3a01992ab665e14ac9ffff298f28cd74a0c" + integrity sha512-m8nVez3rwrgmWxtLMt1ZYXB2Lv7OKYn/disyxAlSDYAlKSlFoPPfIAmAM/M5xqL4m4C/wAPw7S2/CNaUii1Hxg== import-fresh@^3.2.1: version "3.3.1" @@ -1448,13 +1577,13 @@ inline-style-parser@0.2.7: resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.2.7.tgz#b1fc68bfc0313b8685745e4464e37f9376b9c909" integrity sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA== -intl-messageformat@11.2.7: - version "11.2.7" - resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-11.2.7.tgz#1d922a7df8964ec496c56f62928ef2134674bdae" - integrity sha512-+q6Ktg119nULZEpZ8YTuGOst9MyEzFtjD63FTGBlN1mLz0Z/MOUYDIvnpVKwq17eezIEh+cfJIebfJoCetpiNw== +intl-messageformat@11.2.14: + version "11.2.14" + resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-11.2.14.tgz#610e4a21511d85dc06634424409d60bb1e9e441f" + integrity sha512-9f2VD1HFuxUvMw0RxsaP8WmMns6JRTnsNB/zghTFrp11ZktiXWwVDeZBPQchBKEmo+Gx/ZhxI7Qht7YglFD4PA== dependencies: - "@formatjs/fast-memoize" "3.1.5" - "@formatjs/icu-messageformat-parser" "3.5.10" + "@formatjs/fast-memoize" "3.1.7" + "@formatjs/icu-messageformat-parser" "3.5.17" invariant@^2.2.4: version "2.2.4" @@ -1482,11 +1611,11 @@ is-arrayish@^0.2.1: integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== is-core-module@^2.16.1: - version "2.16.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" - integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== + version "2.16.2" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.2.tgz#3e07450a8080ebce3fbf0cac494f4d2ab324e082" + integrity sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA== dependencies: - hasown "^2.0.2" + hasown "^2.0.3" is-decimal@^2.0.0: version "2.0.1" @@ -1535,79 +1664,79 @@ json-parse-even-better-errors@^2.3.0: resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== -lightningcss-android-arm64@1.32.0: - version "1.32.0" - resolved "https://registry.yarnpkg.com/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz#f033885116dfefd9c6f54787523e3514b61e1968" - integrity sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg== - -lightningcss-darwin-arm64@1.32.0: - version "1.32.0" - resolved "https://registry.yarnpkg.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz#50b71871b01c8199584b649e292547faea7af9b5" - integrity sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ== - -lightningcss-darwin-x64@1.32.0: - version "1.32.0" - resolved "https://registry.yarnpkg.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz#35f3e97332d130b9ca181e11b568ded6aebc6d5e" - integrity sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w== - -lightningcss-freebsd-x64@1.32.0: - version "1.32.0" - resolved "https://registry.yarnpkg.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz#9777a76472b64ed6ff94342ad64c7bafd794a575" - integrity sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig== - -lightningcss-linux-arm-gnueabihf@1.32.0: - version "1.32.0" - resolved "https://registry.yarnpkg.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz#13ae652e1ab73b9135d7b7da172f666c410ad53d" - integrity sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw== - -lightningcss-linux-arm64-gnu@1.32.0: - version "1.32.0" - resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz#417858795a94592f680123a1b1f9da8a0e1ef335" - integrity sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ== - -lightningcss-linux-arm64-musl@1.32.0: - version "1.32.0" - resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz#6be36692e810b718040802fd809623cffe732133" - integrity sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg== - -lightningcss-linux-x64-gnu@1.32.0: - version "1.32.0" - resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz#0b7803af4eb21cfd38dd39fe2abbb53c7dd091f6" - integrity sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA== - -lightningcss-linux-x64-musl@1.32.0: - version "1.32.0" - resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz#88dc8ba865ddddb1ac5ef04b0f161804418c163b" - integrity sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg== - -lightningcss-win32-arm64-msvc@1.32.0: - version "1.32.0" - resolved "https://registry.yarnpkg.com/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz#4f30ba3fa5e925f5b79f945e8cc0d176c3b1ab38" - integrity sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw== - -lightningcss-win32-x64-msvc@1.32.0: - version "1.32.0" - resolved "https://registry.yarnpkg.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz#141aa5605645064928902bb4af045fa7d9f4220a" - integrity sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q== - -lightningcss@^1.32.0: - version "1.32.0" - resolved "https://registry.yarnpkg.com/lightningcss/-/lightningcss-1.32.0.tgz#b85aae96486dcb1bf49a7c8571221273f4f1e4a9" - integrity sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ== +lightningcss-android-arm64@1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz#9a6841f88ae50fc83502903892b41af41bc2b907" + integrity sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg== + +lightningcss-darwin-arm64@1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz#c0f2c31c0bfd19fa4dd3f18e957a1f1a152097d6" + integrity sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg== + +lightningcss-darwin-x64@1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz#cb0705965acb538c6683949ce6925fb3cdf7c361" + integrity sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ== + +lightningcss-freebsd-x64@1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz#763538828b26bab2680dadafcc84ee78b0eb502b" + integrity sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg== + +lightningcss-linux-arm-gnueabihf@1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz#6862e3176a331aedbdec1ed352b4d7d0dd0784de" + integrity sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ== + +lightningcss-linux-arm64-gnu@1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz#c6a3a2ed15141daf6bdc2628930f8e39bdf473aa" + integrity sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg== + +lightningcss-linux-arm64-musl@1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz#7fa1334971fc82845f9827df6ef8a0b20914bac6" + integrity sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ== + +lightningcss-linux-x64-gnu@1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz#8b927862ea8c2bbc6831a46509244b50d9936e55" + integrity sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg== + +lightningcss-linux-x64-musl@1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz#0c525bb077dfd94404c059cfe42dad797e96aeaf" + integrity sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw== + +lightningcss-win32-arm64-msvc@1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz#850ee1103dac989cfab50e3ac22d1a69e394e63d" + integrity sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA== + +lightningcss-win32-x64-msvc@1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz#e343ae152eed3609dc6e11949d1a3bf39a1c946f" + integrity sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA== + +lightningcss@^1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/lightningcss/-/lightningcss-1.33.0.tgz#c08867d71a79385c6e190214fd72fef3e5f95f0b" + integrity sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA== dependencies: detect-libc "^2.0.3" optionalDependencies: - lightningcss-android-arm64 "1.32.0" - lightningcss-darwin-arm64 "1.32.0" - lightningcss-darwin-x64 "1.32.0" - lightningcss-freebsd-x64 "1.32.0" - lightningcss-linux-arm-gnueabihf "1.32.0" - lightningcss-linux-arm64-gnu "1.32.0" - lightningcss-linux-arm64-musl "1.32.0" - lightningcss-linux-x64-gnu "1.32.0" - lightningcss-linux-x64-musl "1.32.0" - lightningcss-win32-arm64-msvc "1.32.0" - lightningcss-win32-x64-msvc "1.32.0" + lightningcss-android-arm64 "1.33.0" + lightningcss-darwin-arm64 "1.33.0" + lightningcss-darwin-x64 "1.33.0" + lightningcss-freebsd-x64 "1.33.0" + lightningcss-linux-arm-gnueabihf "1.33.0" + lightningcss-linux-arm64-gnu "1.33.0" + lightningcss-linux-arm64-musl "1.33.0" + lightningcss-linux-x64-gnu "1.33.0" + lightningcss-linux-x64-musl "1.33.0" + lightningcss-win32-arm64-msvc "1.33.0" + lightningcss-win32-x64-msvc "1.33.0" lines-and-columns@^1.1.6: version "1.2.4" @@ -1654,9 +1783,9 @@ magic-string@^0.30.21: "@jridgewell/sourcemap-codec" "^1.5.5" mdast-util-from-markdown@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz#4850390ca7cf17413a9b9a0fbefcd1bc0eb4160a" - integrity sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA== + version "2.0.3" + resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz#c95822b91aab75f18a4cbe8b2f51b873ed2cf0c7" + integrity sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q== dependencies: "@types/mdast" "^4.0.0" "@types/unist" "^3.0.0" @@ -1967,10 +2096,10 @@ ms@^2.1.3: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -nanoid@^3.3.12: - version "3.3.12" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.12.tgz#ab3d912e217a6d0a514f00a72a16543a28982c05" - integrity sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ== +nanoid@^3.3.17: + version "3.3.18" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.18.tgz#f66a2de1199ffde0fcf21c8a5f13106b1c081913" + integrity sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w== node-addon-api@^7.0.0: version "7.1.1" @@ -1991,9 +2120,9 @@ object-assign@^4.1.1: integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== obug@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/obug/-/obug-2.1.1.tgz#2cba74ff241beb77d63055ddf4cd1e9f90b538be" - integrity sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ== + version "2.1.4" + resolved "https://registry.yarnpkg.com/obug/-/obug-2.1.4.tgz#9090d8a548a522517915d2aa6aae907197ac6cf8" + integrity sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA== parent-module@^1.0.0: version "1.0.1" @@ -2067,22 +2196,22 @@ picocolors@1.1.1, picocolors@^1.1.1: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== -picomatch@^4.0.3, picomatch@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.4.tgz#fd6f5e00a143086e074dffe4c924b8fb293b0589" - integrity sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A== +picomatch@^4.0.3, picomatch@^4.0.4, picomatch@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.5.tgz#51ea57a17d86f605f81039595fbc40ed06a55fab" + integrity sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A== postcss-simple-vars@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/postcss-simple-vars/-/postcss-simple-vars-7.0.1.tgz#836b3097a54dcd13dbd3c36a5dbdd512fad2954c" integrity sha512-5GLLXaS8qmzHMOjVxqkk1TZPf1jMqesiI7qLhnlyERalG0sMbHIbJqrcnrpmZdKCLglHnRHoEBB61RtGTsj++A== -postcss@^8.5.15: - version "8.5.15" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.15.tgz#d1eaf677a324e9ec02196da2d3fecf4a0b9a735c" - integrity sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A== +postcss@^8.5.26: + version "8.5.26" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.26.tgz#6e75135780c7e10df3433bf2266c552d35c8c620" + integrity sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ== dependencies: - nanoid "^3.3.12" + nanoid "^3.3.17" picocolors "^1.1.1" source-map-js "^1.2.1" @@ -2127,16 +2256,16 @@ property-information@^6.0.0: integrity sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig== property-information@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/property-information/-/property-information-7.1.0.tgz#b622e8646e02b580205415586b40804d3e8bfd5d" - integrity sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ== + version "7.2.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-7.2.0.tgz#0809b34264e995c0bfcd3227028a1e35210af80a" + integrity sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg== -query-string@^9.4.0: - version "9.4.0" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-9.4.0.tgz#4f2cd518680e087dd781dd605f75dcb18c7f7a53" - integrity sha512-ivvWyHqU9K1Log4hJFhqVIIMoEi0nzmlRhvk2pPcTuQH/Y0K5iTTMxEx7R0PRHD2Z1hMVbWnjfsEWbIKIK+3IA== +query-string@^9.5.0: + version "9.5.0" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-9.5.0.tgz#e6f4003dcb321580dd043109b6fbe2a3890afff6" + integrity sha512-YlJmwNyi0RGYjlxYcuDncMsxFU7YyutbuI7gTm8ySxIGBlwx5yiBCOD5ig9ZNoHkawk/1Dey0N5mEfcUybMVAA== dependencies: - decode-uri-component "^0.4.1" + decode-uri-component "^0.5.0" filter-obj "^5.1.0" split-on-first "^3.0.0" @@ -2154,6 +2283,21 @@ randombytes@^2.0.5: dependencies: safe-buffer "^5.1.0" +react-aria@^3.48.0: + version "3.51.0" + resolved "https://registry.yarnpkg.com/react-aria/-/react-aria-3.51.0.tgz#b8129df769eda51a0f92d256fddcc105badf6ed7" + integrity sha512-AyWLw0XR38cFPwBu/ErgGaVrc5dupLEKmRlMXTGvFKOtbaGRQ2+yQJkjVhpdHhoRhU4+G+tJDFeHDTS8tK3bfQ== + dependencies: + "@internationalized/date" "^3.12.3" + "@internationalized/number" "^3.6.7" + "@internationalized/string" "^3.2.10" + "@react-types/shared" "^3.36.1" + "@swc/helpers" "^0.5.0" + aria-hidden "^1.2.3" + clsx "^2.0.0" + react-stately "3.49.0" + use-sync-external-store "^1.6.0" + react-bootstrap@^2.10.10: version "2.10.10" resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-2.10.10.tgz#be0b0d951a69987152d75c0e6986c80425efdf21" @@ -2173,10 +2317,10 @@ react-bootstrap@^2.10.10: uncontrollable "^7.2.1" warning "^4.0.3" -react-dom@^19.2.7: - version "19.2.7" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.2.7.tgz#0450dc9ae9ddbff76ef196401cd8b8c7fb466ccc" - integrity sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ== +react-dom@^19.2.8: + version "19.2.8" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.2.8.tgz#3b46b9eeda877cdff2cf13d2770fff4ae36c2ec2" + integrity sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ== dependencies: scheduler "^0.27.0" @@ -2185,14 +2329,14 @@ react-fast-compare@^2.0.1: resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9" integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw== -react-intl@^10.1.11: - version "10.1.11" - resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-10.1.11.tgz#1b08edb40082eeb4f8b783cecda33c84ab0da80f" - integrity sha512-9VCaWKumbrP91QvS50IYRlbZsD4KdSLwcfEeF9CQLmnqK9qCvFCfyof694I9lqHJL2/TUxBwLCA+whjF129oAg== +react-intl@^10.1.22: + version "10.1.22" + resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-10.1.22.tgz#049895605ecee3b3ba2d6428b20f2a6b2d46d5cb" + integrity sha512-6PxlTKapYpv/Kl+yYEH06J3T5T7gUVx6STjrWJedeITOAkGEn6sBvb6r0qtjg2pK7PZsom7gXKUFKwNykLoLSQ== dependencies: - "@formatjs/icu-messageformat-parser" "3.5.10" - "@formatjs/intl" "4.1.12" - intl-messageformat "11.2.7" + "@formatjs/icu-messageformat-parser" "3.5.17" + "@formatjs/intl" "4.1.19" + intl-messageformat "11.2.14" react-is@^16.13.1, react-is@^16.3.2, react-is@^16.7.0: version "16.13.1" @@ -2226,17 +2370,17 @@ react-markdown@^10.1.0: unist-util-visit "^5.0.0" vfile "^6.0.0" -react-router-dom@^7.16.0: - version "7.16.0" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-7.16.0.tgz#284a7cd021052aa7d0a9240dca4a02eec24eceb5" - integrity sha512-kMUAbimWB5FVbF4Bce4bJsiKJWLIUHq/mEG8+CFDnCSgltptBiG5nguducmsJeGKytlCvQud9Qhzpn49iduTlA== +react-router-dom@^7.18.2: + version "7.18.2" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-7.18.2.tgz#00bf1d0ce8bf17a6d831949aacda72a6120e4926" + integrity sha512-AIKJ/jgGlFb3EbfCXk5Gzshiwt+l3mqbCrNjmEWMMjqQxNJ3svBa6bgzFyCC2Sw3RA0VWF1kg3uQf2OFhxb8hw== dependencies: - react-router "7.16.0" + react-router "7.18.2" -react-router@7.16.0: - version "7.16.0" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-7.16.0.tgz#fb41536aef2ccc2c7be12ea6be819a1e56eb6343" - integrity sha512-wArC8lVyJb3+jM9OpDyW6hLCizACWkvQR/sSGqSs+o5uEXEtGlqdZ4v8hENR3Jad6i+LRkK93q/+bQAcvl6V1A== +react-router@7.18.2: + version "7.18.2" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-7.18.2.tgz#a76c46ce9e5edacd4f51289d5a71f71305db9152" + integrity sha512-aUVMjFm3GAPTTZL7oYr5E7ETiqfQCHRLH+B+5afnICvf0r7kkK4eR6SMuwbSTJw/7t+12khT/Kahij49fqOCIg== dependencies: cookie "^1.0.1" set-cookie-parser "^2.6.0" @@ -2256,6 +2400,18 @@ react-select@^5.10.2: react-transition-group "^4.3.0" use-isomorphic-layout-effect "^1.2.0" +react-stately@3.49.0: + version "3.49.0" + resolved "https://registry.yarnpkg.com/react-stately/-/react-stately-3.49.0.tgz#bc7fda7d0245e2a1239a8f0451950b27639d0e17" + integrity sha512-13iNq2KzBrRAzxRc+n53hgROfIistiYY/sPtIhCw1qUB7/kmo+X1xEU2uiS5zcCIrc55AUPwoHqOIIpKWSwB9A== + dependencies: + "@internationalized/date" "^3.12.3" + "@internationalized/number" "^3.6.7" + "@internationalized/string" "^3.2.10" + "@react-types/shared" "^3.36.1" + "@swc/helpers" "^0.5.0" + use-sync-external-store "^1.6.0" + react-toastify@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/react-toastify/-/react-toastify-11.1.0.tgz#3d3c73a44d5cac868ee9a52e0f90dd706532c4a4" @@ -2273,15 +2429,15 @@ react-transition-group@^4.3.0, react-transition-group@^4.4.5: loose-envify "^1.4.0" prop-types "^15.6.2" -react@^19.2.7: - version "19.2.7" - resolved "https://registry.yarnpkg.com/react/-/react-19.2.7.tgz#1f47a1bfc06f8ec885752c6f4af14369a9f8260b" - integrity sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ== +react@^19.2.8: + version "19.2.8" + resolved "https://registry.yarnpkg.com/react/-/react-19.2.8.tgz#a80663dbb58d69c6fe3fd291d3cb324e8a7dff2d" + integrity sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw== readdirp@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-5.0.0.tgz#fbf1f71a727891d685bb1786f9ba74084f6e2f91" - integrity sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ== + version "5.1.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-5.1.1.tgz#520bca06f9d1ae1b96cc0800dbe84b983d19422c" + integrity sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA== redent@^3.0.0: version "3.0.0" @@ -2368,10 +2524,11 @@ resolve-from@^4.0.0: integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== resolve@^1.19.0: - version "1.22.11" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.11.tgz#aad857ce1ffb8bfa9b0b1ac29f1156383f68c262" - integrity sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ== + version "1.22.12" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.12.tgz#f5b2a680897c69c238a13cd16b15671f8b73549f" + integrity sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA== dependencies: + es-errors "^1.3.0" is-core-module "^2.16.1" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -2381,34 +2538,34 @@ retry@^0.12.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== -rolldown@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/rolldown/-/rolldown-1.0.3.tgz#db88a3008fb0e28230a00423727ce75ba32121ac" - integrity sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g== +rolldown@~1.2.4: + version "1.2.5" + resolved "https://registry.yarnpkg.com/rolldown/-/rolldown-1.2.5.tgz#1f504a7d05260a769e617d950410bbb051498c50" + integrity sha512-VD2IE5PUG4Oj8zz2VGykiYd5wbnjdIiSsNQb8Qu5B+noEp+A78mu2iVvpp27g8es14Tk9rofNs5Tku9iQCS4fA== dependencies: - "@oxc-project/types" "=0.133.0" + "@oxc-project/types" "=0.146.0" "@rolldown/pluginutils" "^1.0.0" optionalDependencies: - "@rolldown/binding-android-arm64" "1.0.3" - "@rolldown/binding-darwin-arm64" "1.0.3" - "@rolldown/binding-darwin-x64" "1.0.3" - "@rolldown/binding-freebsd-x64" "1.0.3" - "@rolldown/binding-linux-arm-gnueabihf" "1.0.3" - "@rolldown/binding-linux-arm64-gnu" "1.0.3" - "@rolldown/binding-linux-arm64-musl" "1.0.3" - "@rolldown/binding-linux-ppc64-gnu" "1.0.3" - "@rolldown/binding-linux-s390x-gnu" "1.0.3" - "@rolldown/binding-linux-x64-gnu" "1.0.3" - "@rolldown/binding-linux-x64-musl" "1.0.3" - "@rolldown/binding-openharmony-arm64" "1.0.3" - "@rolldown/binding-wasm32-wasi" "1.0.3" - "@rolldown/binding-win32-arm64-msvc" "1.0.3" - "@rolldown/binding-win32-x64-msvc" "1.0.3" - -rooks@^9.8.0: - version "9.8.0" - resolved "https://registry.yarnpkg.com/rooks/-/rooks-9.8.0.tgz#bf4790f1d379cb9d2f60570202e39d297ed88f8a" - integrity sha512-S6FqnmERx5zgl8ZUEcnyTe1jgjwE5xeFCgOV4bzgQHKp26P7YA7uPnzzOgacojtoX6E7pQTcewSGqN83wVyz+g== + "@rolldown/binding-android-arm-eabi" "1.2.5" + "@rolldown/binding-android-arm64" "1.2.5" + "@rolldown/binding-darwin-arm64" "1.2.5" + "@rolldown/binding-darwin-x64" "1.2.5" + "@rolldown/binding-freebsd-x64" "1.2.5" + "@rolldown/binding-linux-arm-gnueabihf" "1.2.5" + "@rolldown/binding-linux-arm64-gnu" "1.2.5" + "@rolldown/binding-linux-arm64-musl" "1.2.5" + "@rolldown/binding-linux-ppc64-gnu" "1.2.5" + "@rolldown/binding-linux-s390x-gnu" "1.2.5" + "@rolldown/binding-linux-x64-gnu" "1.2.5" + "@rolldown/binding-linux-x64-musl" "1.2.5" + "@rolldown/binding-openharmony-arm64" "1.2.5" + "@rolldown/binding-win32-arm64-msvc" "1.2.5" + "@rolldown/binding-win32-x64-msvc" "1.2.5" + +rooks@^9.9.0: + version "9.9.0" + resolved "https://registry.yarnpkg.com/rooks/-/rooks-9.9.0.tgz#3a1437d55bb56f0787f1e90109471c6f065dec9a" + integrity sha512-ygSdaIlRiBNQmaJUYn/f66irkAIvcAFAsxwMFOV8UA9OLg0yokLgUHN73bOsTgSxrZo8+hjbr1Gdo3IYnIHZuw== dependencies: fast-deep-equal "^3.1.3" lodash.debounce "^4.0.8" @@ -2422,10 +2579,10 @@ safe-buffer@^5.1.0: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -sass@^1.100.0: - version "1.100.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.100.0.tgz#b4cab1bed286fe22ac6c879c514f71cd36aa06c8" - integrity sha512-B5j0rYMlinhhOo9tjQebMVVn0TfyXAF+wB3b2ggZUuJ/is/Y+7+JGjirAMxHZ9Z3hIP98NPfamlAkBHa1lAaXQ== +sass@^1.103.1: + version "1.103.1" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.103.1.tgz#13b70f5ff69288db956dc27d27c8fb79f3a27c61" + integrity sha512-9icZURbP51S6S0QGoyaeqk9uB06GNWxsFYWfH5RgpFgqK5FA8tJcM3AdVxrZEVJ7dz+L87nG95gBKf4VuaMHGw== dependencies: chokidar "^5.0.0" immutable "^5.1.5" @@ -2479,9 +2636,9 @@ stackback@0.0.2: integrity sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw== std-env@^4.0.0-rc.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/std-env/-/std-env-4.1.0.tgz#45899abc590d86d682e87f0acd1033a75084cd3f" - integrity sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ== + version "4.2.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-4.2.0.tgz#8ebe0ec60485668ab47227b312f4254cdf80c9d3" + integrity sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw== stringify-entities@^4.0.0: version "4.0.4" @@ -2538,9 +2695,9 @@ tinybench@^2.9.0: integrity sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg== tinyexec@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-1.0.2.tgz#bdd2737fe2ba40bd6f918ae26642f264b99ca251" - integrity sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg== + version "1.3.0" + resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-1.3.0.tgz#aacc1dbb1d4e93e6ad8dd64944e09f9ad147a474" + integrity sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ== tinyglobby@^0.2.15, tinyglobby@^0.2.17: version "0.2.17" @@ -2551,9 +2708,9 @@ tinyglobby@^0.2.15, tinyglobby@^0.2.17: picomatch "^4.0.4" tinyrainbow@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/tinyrainbow/-/tinyrainbow-3.1.0.tgz#1d8a623893f95cf0a2ddb9e5d11150e191409421" - integrity sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw== + version "3.1.1" + resolved "https://registry.yarnpkg.com/tinyrainbow/-/tinyrainbow-3.1.1.tgz#c0168387d3d8d70b6b3c2c0936de5fee738cea20" + integrity sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw== tmp@^0.2.7: version "0.2.7" @@ -2570,15 +2727,36 @@ trough@^2.0.0: resolved "https://registry.yarnpkg.com/trough/-/trough-2.2.0.tgz#94a60bd6bd375c152c1df911a4b11d5b0256f50f" integrity sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw== -tslib@^2.0.0, tslib@^2.4.0, tslib@^2.8.0: +tslib@^2.0.0, tslib@^2.8.0: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== -typescript@6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-6.0.3.tgz#90251dc007916e972786cb94d74d15b185577d21" - integrity sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw== +typescript@7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-7.0.2.tgz#9ec773d7954a8c182c17cc5bbd575aa28bc51582" + integrity sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA== + optionalDependencies: + "@typescript/typescript-aix-ppc64" "7.0.2" + "@typescript/typescript-darwin-arm64" "7.0.2" + "@typescript/typescript-darwin-x64" "7.0.2" + "@typescript/typescript-freebsd-arm64" "7.0.2" + "@typescript/typescript-freebsd-x64" "7.0.2" + "@typescript/typescript-linux-arm" "7.0.2" + "@typescript/typescript-linux-arm64" "7.0.2" + "@typescript/typescript-linux-loong64" "7.0.2" + "@typescript/typescript-linux-mips64el" "7.0.2" + "@typescript/typescript-linux-ppc64" "7.0.2" + "@typescript/typescript-linux-riscv64" "7.0.2" + "@typescript/typescript-linux-s390x" "7.0.2" + "@typescript/typescript-linux-x64" "7.0.2" + "@typescript/typescript-netbsd-arm64" "7.0.2" + "@typescript/typescript-netbsd-x64" "7.0.2" + "@typescript/typescript-openbsd-arm64" "7.0.2" + "@typescript/typescript-openbsd-x64" "7.0.2" + "@typescript/typescript-sunos-x64" "7.0.2" + "@typescript/typescript-win32-arm64" "7.0.2" + "@typescript/typescript-win32-x64" "7.0.2" uncontrollable@^7.2.1: version "7.2.1" @@ -2595,10 +2773,10 @@ uncontrollable@^8.0.4: resolved "https://registry.yarnpkg.com/uncontrollable/-/uncontrollable-8.0.4.tgz#a0a8307f638795162fafd0550f4a1efa0f8c5eb6" integrity sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ== -"undici-types@>=7.24.0 <7.24.7": - version "7.24.6" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.24.6.tgz#61275b485d7fd4e9d269c7cf04ec2873c9cc0f91" - integrity sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg== +undici-types@~8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-8.3.0.tgz#44e9fc9f3244648cdea35e4f9bb2d681e9410809" + integrity sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ== unicorn-magic@^0.3.0: version "0.3.0" @@ -2699,10 +2877,10 @@ vfile@^6.0.0: "@types/unist" "^3.0.0" vfile-message "^4.0.0" -vite-plugin-checker@^0.14.1: - version "0.14.1" - resolved "https://registry.yarnpkg.com/vite-plugin-checker/-/vite-plugin-checker-0.14.1.tgz#0fe694c6d90905c9da7658772fadab4823d7b881" - integrity sha512-Mv8oQc9XYBYf+XkP/riqqQCt8lBP6Iad75PZPho1lHRrpxQI0BwX2gwE10enn4f6Hgc+PvR1F7N38KARcaJtzw== +vite-plugin-checker@^0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/vite-plugin-checker/-/vite-plugin-checker-0.14.5.tgz#b809a65bbec0195d932bfee4bb3a49cdd2907640" + integrity sha512-c9lQ92eisUO+F7Fd93aelojmiOS+NQpPgQ1XR2LTQHox1/laZf4yAoQj+L3RA9Vgh10e2nFd9b8r2LLyYZsbpA== dependencies: "@babel/code-frame" "^7.29.0" chokidar "^5.0.0" @@ -2712,31 +2890,31 @@ vite-plugin-checker@^0.14.1: proper-lockfile "^4.1.2" tiny-invariant "^1.3.3" -"vite@^6.0.0 || ^7.0.0 || ^8.0.0", vite@^8.0.16: - version "8.0.16" - resolved "https://registry.yarnpkg.com/vite/-/vite-8.0.16.tgz#ae073866c06563d6634a90169a496e11bd84f1a6" - integrity sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw== +"vite@^6.0.0 || ^7.0.0 || ^8.0.0", vite@^8.2.2: + version "8.2.2" + resolved "https://registry.yarnpkg.com/vite/-/vite-8.2.2.tgz#399aefad3656145145be110d137a07ea5bb55014" + integrity sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q== dependencies: - lightningcss "^1.32.0" - picomatch "^4.0.4" - postcss "^8.5.15" - rolldown "1.0.3" + lightningcss "^1.33.0" + picomatch "^4.0.5" + postcss "^8.5.26" + rolldown "~1.2.4" tinyglobby "^0.2.17" optionalDependencies: fsevents "~2.3.3" -vitest@^4.1.8: - version "4.1.8" - resolved "https://registry.yarnpkg.com/vitest/-/vitest-4.1.8.tgz#9fed17277bf7350497e54338898a7afd46dfd509" - integrity sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig== - dependencies: - "@vitest/expect" "4.1.8" - "@vitest/mocker" "4.1.8" - "@vitest/pretty-format" "4.1.8" - "@vitest/runner" "4.1.8" - "@vitest/snapshot" "4.1.8" - "@vitest/spy" "4.1.8" - "@vitest/utils" "4.1.8" +vitest@^4.1.11: + version "4.1.11" + resolved "https://registry.yarnpkg.com/vitest/-/vitest-4.1.11.tgz#1653c1521ae917f960d9b21877797c47dfd8bf21" + integrity sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw== + dependencies: + "@vitest/expect" "4.1.11" + "@vitest/mocker" "4.1.11" + "@vitest/pretty-format" "4.1.11" + "@vitest/runner" "4.1.11" + "@vitest/snapshot" "4.1.11" + "@vitest/spy" "4.1.11" + "@vitest/utils" "4.1.11" es-module-lexer "^2.0.0" expect-type "^1.3.0" magic-string "^0.30.21" @@ -2776,10 +2954,10 @@ why-is-node-running@^2.3.0: siginfo "^2.0.0" stackback "0.0.2" -ws@^8.18.3: - version "8.19.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.19.0.tgz#ddc2bdfa5b9ad860204f5a72a4863a8895fd8c8b" - integrity sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg== +ws@^8.21.0: + version "8.21.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.21.3.tgz#660b4faddb6a3e575c86e078126919961f4de4fc" + integrity sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw== yaml@^1.10.0: version "1.10.3" From 29687987b2c30c912f6fa726cd73d0de4f98fa46 Mon Sep 17 00:00:00 2001 From: vgoer Date: Mon, 24 Aug 2026 09:30:22 +0000 Subject: [PATCH 30/77] fix: Restrict JWT key file permissions to 0600 --- backend/lib/config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/lib/config.js b/backend/lib/config.js index 71205013a1..59cb6598de 100644 --- a/backend/lib/config.js +++ b/backend/lib/config.js @@ -145,7 +145,7 @@ const generateKeys = () => { // Write keys config try { - fs.writeFileSync(keysFile, JSON.stringify(keys, null, 2)); + fs.writeFileSync(keysFile, JSON.stringify(keys, null, 2), { mode: 0o600 }); } catch (err) { logger.error(`Could not write JWT key pair to config file: ${keysFile}: ${err.message}`); process.exit(1); From b7772016bafe751f88298b4ce4ddd05ba9ed9f32 Mon Sep 17 00:00:00 2001 From: vgoer Date: Mon, 24 Aug 2026 09:30:36 +0000 Subject: [PATCH 31/77] fix: Ensure JWT key file ownership matches PUID/PGID at startup --- .../rootfs/etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh index fa94651897..4236c90a2e 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh @@ -46,6 +46,12 @@ for loc in "${locations[@]}"; do chownit "$loc" done +# Ensure the JWT key file is owned by the runtime user, even when the /data +# directory ownership already matches PUID:PGID (chownit skips recursion then) +if [ -f /data/keys.json ]; then + chown "$PUID:$PGID" /data/keys.json +fi + if [ "$(is_true "${SKIP_CERTBOT_OWNERSHIP:-}")" = '1' ]; then log_info 'Skipping ownership change of certbot directories' else From 41539c027fdcaef99bc8c02e5d39eb4167d05ceb Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Tue, 25 Aug 2026 10:15:38 +0200 Subject: [PATCH 32/77] fix(certbot): update Timeweb Cloud DNS plugin to 2.0.0 --- backend/certbot/dns-plugins.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/certbot/dns-plugins.json b/backend/certbot/dns-plugins.json index 220819404e..7bb60ca911 100644 --- a/backend/certbot/dns-plugins.json +++ b/backend/certbot/dns-plugins.json @@ -637,7 +637,7 @@ "full_plugin_name": "dns-timeweb", "name": "Timeweb Cloud", "package_name": "certbot-dns-timeweb", - "version": "~=1.0.1" + "version": "~=2.0.0" }, "transip": { "credentials": "dns_transip_username = my_username\ndns_transip_key_file = /etc/letsencrypt/transip-rsa.key", From a5e49a53c05e6c8d0e851efbe8f8a41bd87e880e Mon Sep 17 00:00:00 2001 From: vgoer Date: Tue, 25 Aug 2026 09:13:41 +0000 Subject: [PATCH 33/77] feat: Add react-qr-code dependency --- frontend/package.json | 1 + frontend/yarn.lock | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/frontend/package.json b/frontend/package.json index ceacd3e702..e7c7363c3e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -34,6 +34,7 @@ "react-dom": "^19.2.8", "react-intl": "^10.1.22", "react-markdown": "^10.1.0", + "react-qr-code": "^2.2.0", "react-router-dom": "^7.18.2", "react-select": "^5.10.2", "react-toastify": "^11.1.0", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 493088c867..6304819a21 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2260,6 +2260,11 @@ property-information@^7.0.0: resolved "https://registry.yarnpkg.com/property-information/-/property-information-7.2.0.tgz#0809b34264e995c0bfcd3227028a1e35210af80a" integrity sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg== +qrcode-generator@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/qrcode-generator/-/qrcode-generator-2.0.4.tgz#e8b3f30922577eba52078aa9c0d5a2a74fe1fd94" + integrity sha512-mZSiP6RnbHl4xL2Ap5HfkjLnmxfKcPWpWe/c+5XxCuetEenqmNFf1FH/ftXPCtFG5/TDobjsjz6sSNL0Sr8Z9g== + query-string@^9.5.0: version "9.5.0" resolved "https://registry.yarnpkg.com/query-string/-/query-string-9.5.0.tgz#e6f4003dcb321580dd043109b6fbe2a3890afff6" @@ -2370,6 +2375,14 @@ react-markdown@^10.1.0: unist-util-visit "^5.0.0" vfile "^6.0.0" +react-qr-code@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/react-qr-code/-/react-qr-code-2.2.0.tgz#301b5dc4d2fed503e1e313f237a7f32c1885152a" + integrity sha512-e5nS0UUN22K3Nf8KBRUzemfdJ6OmnN5w+kbnj1lvJaol9RyVRFeGl05bCkxSN2ZegbLxjjYjX1+mmAoX9+fAhw== + dependencies: + prop-types "^15.8.1" + qrcode-generator "^2.0.4" + react-router-dom@^7.18.2: version "7.18.2" resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-7.18.2.tgz#00bf1d0ce8bf17a6d831949aacda72a6120e4926" From 4d30946d2f039f55a185201b00376c29f595b866 Mon Sep 17 00:00:00 2001 From: vgoer Date: Tue, 25 Aug 2026 09:14:44 +0000 Subject: [PATCH 34/77] fix: local QR code --- frontend/src/modals/TwoFactorModal.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/src/modals/TwoFactorModal.tsx b/frontend/src/modals/TwoFactorModal.tsx index fa46c89cc7..2b8639fa9a 100644 --- a/frontend/src/modals/TwoFactorModal.tsx +++ b/frontend/src/modals/TwoFactorModal.tsx @@ -7,6 +7,7 @@ import { disable2FA, enable2FA, get2FAStatus, regenerateBackupCodes, start2FASet import { Button } from "src/components"; import { T } from "src/locale"; import { validateString } from "src/modules/Validations"; +import QRCode from "react-qr-code"; type Step = "loading" | "status" | "setup" | "verify" | "backup" | "disable"; @@ -155,11 +156,10 @@ const TwoFactorModal = EasyModal.create(({ id, visible, remove }: Props) => {

- QR Code
+ handleAccessListChange(row.id, value)} + /> {advVisible.includes(row.id) && (
)}
- handleAccessListChange(idx, value)} - /> - {advVisible.includes(idx) && ( -
- handleChange(idx, "advancedConfig", e.target.value)} - style={{ - fontFamily: - "ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace", - borderRadius: "0.3rem", - minHeight: "170px", - }} - /> -
- )} - -
-
- ))} -
- -
+ ); + }) + )} ); } diff --git a/frontend/src/locale/src/en.json b/frontend/src/locale/src/en.json index aa0b47f5e0..da8765a5e8 100644 --- a/frontend/src/locale/src/en.json +++ b/frontend/src/locale/src/en.json @@ -254,9 +254,6 @@ "column.access": { "defaultMessage": "Access" }, - "column.error": { - "defaultMessage": "Error" - }, "column.authorization": { "defaultMessage": "Authorization" }, @@ -275,6 +272,9 @@ "column.email": { "defaultMessage": "Email" }, + "column.error": { + "defaultMessage": "Error" + }, "column.event": { "defaultMessage": "Event" }, diff --git a/frontend/src/locale/src/et.json b/frontend/src/locale/src/et.json index 9fd0f74d17..989a153aa1 100644 --- a/frontend/src/locale/src/et.json +++ b/frontend/src/locale/src/et.json @@ -125,6 +125,9 @@ "action.enable": { "defaultMessage": "Lülita sisse" }, + "action.logs": { + "defaultMessage": "Logid" + }, "action.permissions": { "defaultMessage": "Õigused" }, @@ -269,6 +272,9 @@ "column.email": { "defaultMessage": "E-post" }, + "column.error": { + "defaultMessage": "Viga" + }, "column.event": { "defaultMessage": "Sündmus" }, diff --git a/frontend/src/pages/Nginx/ProxyHosts/Table.tsx b/frontend/src/pages/Nginx/ProxyHosts/Table.tsx index cc4fc603e3..7a9b4cd6b2 100644 --- a/frontend/src/pages/Nginx/ProxyHosts/Table.tsx +++ b/frontend/src/pages/Nginx/ProxyHosts/Table.tsx @@ -1,11 +1,5 @@ import { IconDotsVertical, IconEdit, IconFileText, IconPower, IconTrash } from "@tabler/icons-react"; -import { - createColumnHelper, - getCoreRowModel, - getSortedRowModel, - type SortingState, - useReactTable, -} from "@tanstack/react-table"; +import { createColumnHelper, type SortingState, useTable } from "@tanstack/react-table"; import { useMemo, useState } from "react"; import type { ProxyHost } from "src/api/backend"; import { @@ -32,8 +26,17 @@ interface Props { onLogs?: (id: number) => void; onNew?: () => void; } -export default function Table({ data, isFetching, onEdit, onDelete, onDisableToggle, onLogs, onNew, isFiltered }: Props) { - const columnHelper = createColumnHelper(); +export default function Table({ + data, + isFetching, + onEdit, + onDelete, + onDisableToggle, + onLogs, + onNew, + isFiltered, +}: Props) { + const columnHelper = createColumnHelper(); const columns = useMemo( () => [ columnHelper.accessor((row: any) => row.owner, { @@ -117,30 +120,30 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog data={{ id: info.row.original.id }} /> - { - e.preventDefault(); - onEdit?.(info.row.original.id); - }} - > - - - - { e.preventDefault(); - onLogs?.(info.row.original.id); + onEdit?.(info.row.original.id); }} > - - + + - + { + e.preventDefault(); + onLogs?.(info.row.original.id); + }} + > + + + + { From 2cfd3395cf979b901cecb390dd3d78810c46b596 Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Thu, 24 Sep 2026 09:50:13 +1000 Subject: [PATCH 77/77] Adds integration tests for per path access lists, fixes ipv6 jsv, and enforces host-wide access list when location access list is not set --- backend/internal/access-list.js | 88 ++--- backend/internal/nginx.js | 26 +- backend/internal/proxy-host.js | 32 -- backend/lib/validator/api.js | 3 + backend/lib/validator/index.js | 3 + backend/models/access_list.js | 4 + backend/schema/components/stream-object.json | 2 +- docker/docker-compose.ci.yml | 10 + frontend/src/components/Form/AccessField.tsx | 35 +- .../src/components/Form/LocationsFields.tsx | 1 + frontend/src/locale/src/en.json | 6 + frontend/src/locale/src/et.json | 6 + scripts/ci/fulltest-cypress | 3 +- .../cypress/e2e/api/AccessListLocations.cy.js | 301 ++++++++++++++++++ test/docker/Dockerfile.website | 6 + test/docker/nginx/conf.d/website123.conf | 29 ++ test/docker/nginx/nginx.conf | 30 ++ test/docker/www/404.html | 9 + test/docker/www/dashboard.html | 9 + test/docker/www/index.html | 9 + test/docker/www/profile.html | 9 + 21 files changed, 518 insertions(+), 103 deletions(-) create mode 100644 test/cypress/e2e/api/AccessListLocations.cy.js create mode 100644 test/docker/Dockerfile.website create mode 100644 test/docker/nginx/conf.d/website123.conf create mode 100644 test/docker/nginx/nginx.conf create mode 100644 test/docker/www/404.html create mode 100644 test/docker/www/dashboard.html create mode 100644 test/docker/www/index.html create mode 100644 test/docker/www/profile.html diff --git a/backend/internal/access-list.js b/backend/internal/access-list.js index bac0c1a410..1fdd65b6ab 100644 --- a/backend/internal/access-list.js +++ b/backend/internal/access-list.js @@ -42,9 +42,11 @@ const getProxyHostsUsingAccessListInLocations = async (accessListId) => { [`%"access_list_id":${accessListId}%`], ); } - // knex raw() returns [rows, metadata] for MySQL - const rows = Array.isArray(result) && Array.isArray(result[0]) ? result[0] : result; - return rows || []; + // knex raw() returns [rows, metadata] for MySQL, { rows } for Postgres and rows for SQLite + if (!Array.isArray(result)) { + return result?.rows || []; + } + return (Array.isArray(result[0]) ? result[0] : result) || []; }; const internalAccessList = { @@ -233,26 +235,6 @@ const internalAccessList = { .whereIn("id", locationHostIds) .allowGraph(proxyHostModel.defaultAllowGraph) .withGraphFetched("[owner, certificate, access_list.[clients,items]]"); - for (const host of locationHosts) { - // Fetch access lists for locations - if (host.locations?.length) { - for (let i = 0; i < host.locations.length; i++) { - const loc = host.locations[i]; - if (loc.access_list_id && loc.access_list_id > 0) { - const locAccessList = await accessListModel - .query() - .allowGraph("[clients,items]") - .where("is_deleted", 0) - .andWhere("id", loc.access_list_id) - .withGraphFetched("[clients,items]") - .first(); - if (locAccessList) { - host.locations[i].access_list = locAccessList; - } - } - } - } - } await internalNginx.bulkGenerateConfigs("proxy_host", locationHosts); } } @@ -338,50 +320,38 @@ const internalAccessList = { }); // 2. update any proxy hosts that were using it (ignoring permissions) - if (row.proxy_hosts) { + const affectedHostIds = new Set((row.proxy_hosts || []).map((h) => h.id)); + if (affectedHostIds.size) { await proxyHostModel.query().where("access_list_id", "=", row.id).patch({ access_list_id: 0 }); - - // 3. reconfigure those hosts, then reload nginx - // set the access_list_id to zero for these items - row.proxy_hosts.map((_val, idx) => { - row.proxy_hosts[idx].access_list_id = 0; - return true; - }); - - await internalNginx.bulkGenerateConfigs("proxy_host", row.proxy_hosts); } - // Also handle proxy hosts that reference this access list in their locations JSON + // Also clear it from any proxy host locations using it, these will then inherit the host's access list const locationHostRows = await getProxyHostsUsingAccessListInLocations(row.id); - if (locationHostRows?.length) { - const locationHostIds = locationHostRows.map((r) => r.id).filter((id) => { - return !row.proxy_hosts?.find((h) => h.id === id); - }); - if (locationHostIds.length) { - // Clear the access_list_id in locations JSON for these hosts - for (const hostId of locationHostIds) { - const host = await proxyHostModel.query().where("id", hostId).first(); - if (host?.locations) { - const updatedLocations = host.locations.map((loc) => { - if (loc.access_list_id === row.id) { - return { ...loc, access_list_id: 0 }; - } - return loc; - }); - await proxyHostModel.query().where("id", hostId).patch({ locations: updatedLocations }); + for (const { id: hostId } of locationHostRows) { + const host = await proxyHostModel.query().where("id", hostId).first(); + if (host?.locations?.some((loc) => loc.access_list_id === row.id)) { + const updatedLocations = host.locations.map((loc) => { + if (loc.access_list_id === row.id) { + return { ...loc, access_list_id: 0 }; } - } - - // Re-fetch and regenerate configs - const locationHosts = await proxyHostModel.query() - .where("is_deleted", 0) - .whereIn("id", locationHostIds) - .allowGraph(proxyHostModel.defaultExpand) - .withGraphFetched("[owner, certificate, access_list.[clients,items]]"); - await internalNginx.bulkGenerateConfigs("proxy_host", locationHosts); + return loc; + }); + await proxyHostModel.query().where("id", hostId).patch({ locations: updatedLocations }); + affectedHostIds.add(hostId); } } + // 3. reconfigure those hosts from fresh rows, then reload nginx + if (affectedHostIds.size) { + const affectedHosts = await proxyHostModel + .query() + .where("is_deleted", 0) + .whereIn("id", [...affectedHostIds]) + .allowGraph(proxyHostModel.defaultAllowGraph) + .withGraphFetched("[owner, certificate, access_list.[clients,items]]"); + await internalNginx.bulkGenerateConfigs("proxy_host", affectedHosts); + } + await internalNginx.reload(); // delete the htpasswd file diff --git a/backend/internal/nginx.js b/backend/internal/nginx.js index 4b0b2b3c6c..a50e0780dc 100644 --- a/backend/internal/nginx.js +++ b/backend/internal/nginx.js @@ -6,6 +6,7 @@ import _ from "lodash"; import errs from "../lib/error.js"; import utils from "../lib/utils.js"; import { debug, nginx as logger } from "../logger.js"; +import accessListModel from "../models/access_list.js"; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); @@ -168,6 +169,24 @@ const internalNginx = { host.locations[i], ); + // A location with its own access list overrides the host's, + // otherwise it inherits the host's access list + let locationAccessList = null; + if (locationCopy.access_list_id > 0 && locationCopy.access_list_id !== host.access_list?.id) { + locationAccessList = await accessListModel + .query() + .where("is_deleted", 0) + .andWhere("id", locationCopy.access_list_id) + .withGraphFetched("[clients,items]") + .first(); + } + if (locationAccessList) { + locationCopy.access_list = locationAccessList; + } else { + locationCopy.access_list_id = host.access_list_id; + locationCopy.access_list = host.access_list; + } + if (locationCopy.forward_host.indexOf("/") > -1) { const splitted = locationCopy.forward_host.split("/"); @@ -179,7 +198,9 @@ const internalNginx = { } }; - locationRendering().then(() => resolve(renderedLocations)); + locationRendering() + .then(() => resolve(renderedLocations)) + .catch(reject); }); }, @@ -271,6 +292,9 @@ const internalNginx = { debug(logger, `Could not write ${filename}:`, err.message); reject(new errs.ConfigurationError(err.message)); }); + }).catch((err) => { + debug(logger, `Could not render locations for ${filename}:`, err.message); + reject(new errs.ConfigurationError(err.message)); }); }); }, diff --git a/backend/internal/proxy-host.js b/backend/internal/proxy-host.js index 6bd0be1a66..eac0c148aa 100644 --- a/backend/internal/proxy-host.js +++ b/backend/internal/proxy-host.js @@ -2,7 +2,6 @@ import _ from "lodash"; import errs from "../lib/error.js"; import { castJsonIfNeed } from "../lib/helpers.js"; import utils from "../lib/utils.js"; -import accessListModel from "../models/access_list.js"; import proxyHostModel from "../models/proxy_host.js"; import internalAuditLog from "./audit-log.js"; import internalCertificate from "./certificate.js"; @@ -13,33 +12,6 @@ const omissions = () => { return ["is_deleted", "owner.is_deleted"]; }; -/** - * Fetches access lists for each location that has its own access_list_id. - * Attaches the expanded access_list object (with clients and items) to each location. - * - * @param {Object} host - * @returns {Promise} - */ -const fetchLocationAccessLists = async (host) => { - if (!host.locations?.length) { - return; - } - for (let i = 0; i < host.locations.length; i++) { - const loc = host.locations[i]; - if (loc.access_list_id && loc.access_list_id > 0) { - const accessList = await accessListModel - .query() - .where("is_deleted", 0) - .andWhere("id", loc.access_list_id) - .withGraphFetched("[clients,items]") - .first(); - if (accessList) { - host.locations[i].access_list = accessList; - } - } - } -}; - const internalProxyHost = { /** * @param {Access} access @@ -112,7 +84,6 @@ const internalProxyHost = { }); }) .then(async (row) => { - await fetchLocationAccessLists(row); // Configure nginx return internalNginx.configure(proxyHostModel, "proxy_host", row).then(() => { return row; @@ -242,7 +213,6 @@ const internalProxyHost = { // No need to add nginx config if host is disabled return row; } - await fetchLocationAccessLists(row); // Configure nginx return internalNginx.configure(proxyHostModel, "proxy_host", row).then((new_meta) => { row.meta = new_meta; @@ -373,8 +343,6 @@ const internalProxyHost = { enabled: 1, }); - await fetchLocationAccessLists(row); - // Configure nginx await internalNginx.configure(proxyHostModel, "proxy_host", row); diff --git a/backend/lib/validator/api.js b/backend/lib/validator/api.js index f4981a80c9..0597ef635b 100644 --- a/backend/lib/validator/api.js +++ b/backend/lib/validator/api.js @@ -1,3 +1,4 @@ +import net from "node:net"; import Ajv from "ajv/dist/2020.js"; import errs from "../error.js"; @@ -9,6 +10,8 @@ const ajv = new Ajv({ coerceTypes: true, }); +ajv.addFormat("ipv6", { type: "string", validate: (value) => net.isIPv6(value) }); + /** * @param {Object} schema * @param {Object} payload diff --git a/backend/lib/validator/index.js b/backend/lib/validator/index.js index 5d9f8f38a8..767353f61f 100644 --- a/backend/lib/validator/index.js +++ b/backend/lib/validator/index.js @@ -1,3 +1,4 @@ +import net from "node:net"; import Ajv from "ajv/dist/2020.js"; import _ from "lodash"; import commonDefinitions from "../../schema/common.json" with { type: "json" }; @@ -14,6 +15,8 @@ const ajv = new Ajv({ schemas: [commonDefinitions], }); +ajv.addFormat("ipv6", { type: "string", validate: (value) => net.isIPv6(value) }); + /** * * @param {Object} schema diff --git a/backend/models/access_list.js b/backend/models/access_list.js index 427d447d62..192f045b9b 100644 --- a/backend/models/access_list.js +++ b/backend/models/access_list.js @@ -31,6 +31,10 @@ class AccessList extends Model { $parseDatabaseJson(json) { const thisJson = super.$parseDatabaseJson(json); + // Postgres returns COUNT() as a string + if (typeof thisJson.proxy_host_count === "string") { + thisJson.proxy_host_count = Number.parseInt(thisJson.proxy_host_count, 10); + } return convertIntFieldsToBool(thisJson, boolFields); } diff --git a/backend/schema/components/stream-object.json b/backend/schema/components/stream-object.json index 602073ceca..3a1cd52101 100644 --- a/backend/schema/components/stream-object.json +++ b/backend/schema/components/stream-object.json @@ -44,7 +44,7 @@ }, { "type": "string", - "format": "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$" + "pattern": "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$" }, { "type": "string", diff --git a/docker/docker-compose.ci.yml b/docker/docker-compose.ci.yml index 1bb3c7450b..be6f517d3d 100644 --- a/docker/docker-compose.ci.yml +++ b/docker/docker-compose.ci.yml @@ -38,6 +38,16 @@ services: - website2.example.com - website3.example.com + examplesite: + image: "${IMAGE}-examplesite:ci-${BUILD_NUMBER}" + build: + context: ../test/docker + dockerfile: Dockerfile.website + expose: + - "80/tcp" + networks: + - fulltest + stepca: image: nginxproxymanager/testca volumes: diff --git a/frontend/src/components/Form/AccessField.tsx b/frontend/src/components/Form/AccessField.tsx index 1c1004e711..ef955a033f 100644 --- a/frontend/src/components/Form/AccessField.tsx +++ b/frontend/src/components/Form/AccessField.tsx @@ -1,4 +1,4 @@ -import { IconLock, IconLockOpen2 } from "@tabler/icons-react"; +import { IconArrowBackUp, IconLock, IconLockOpen2 } from "@tabler/icons-react"; import { Field, useFormikContext } from "formik"; import type { ReactNode } from "react"; import Select, { type ActionMeta, components, type OptionProps } from "react-select"; @@ -32,8 +32,16 @@ interface Props { name?: string; label?: string; onFormChange?: (value: number) => void; + // When set, the 0 option inherits the host's access list instead of being public + inheritHost?: boolean; } -export function AccessField({ name = "accessListId", label = "access-list", id = "accessListId", onFormChange }: Props) { +export function AccessField({ + name = "accessListId", + label = "access-list", + id = "accessListId", + onFormChange, + inheritHost = false, +}: Props) { const { locale } = useLocaleState(); const { isLoading, isError, error, data } = useAccessLists(["owner", "items", "clients"]); const { setFieldValue } = useFormikContext(); @@ -60,13 +68,22 @@ export function AccessField({ name = "accessListId", label = "access-list", id = icon: , })) || []; - // Public option - options?.unshift({ - value: 0, - label: intl.formatMessage({ id: "access-list.public" }), - subLabel: intl.formatMessage({ id: "access-list.public.subtitle" }), - icon: , - }); + // Public or inherit option + options?.unshift( + inheritHost + ? { + value: 0, + label: intl.formatMessage({ id: "access-list.inherit" }), + subLabel: intl.formatMessage({ id: "access-list.inherit.subtitle" }), + icon: , + } + : { + value: 0, + label: intl.formatMessage({ id: "access-list.public" }), + subLabel: intl.formatMessage({ id: "access-list.public.subtitle" }), + icon: , + }, + ); return ( diff --git a/frontend/src/components/Form/LocationsFields.tsx b/frontend/src/components/Form/LocationsFields.tsx index 9c4d8b3a8a..a0f64c2393 100644 --- a/frontend/src/components/Form/LocationsFields.tsx +++ b/frontend/src/components/Form/LocationsFields.tsx @@ -312,6 +312,7 @@ export function LocationsFields({ initialValues, name = "locations" }: Props) { label="access-list" id={`locations-access-list-${row.id}`} onFormChange={(value) => handleAccessListChange(row.id, value)} + inheritHost /> {advVisible.includes(row.id) && (
diff --git a/frontend/src/locale/src/en.json b/frontend/src/locale/src/en.json index da8765a5e8..11d09ea711 100644 --- a/frontend/src/locale/src/en.json +++ b/frontend/src/locale/src/en.json @@ -71,6 +71,12 @@ "access-list.help.rules-order": { "defaultMessage": "Note that the allow and deny directives will be applied in the order they are defined." }, + "access-list.inherit": { + "defaultMessage": "Inherit from Proxy Host" + }, + "access-list.inherit.subtitle": { + "defaultMessage": "Uses the proxy host's access list" + }, "access-list.pass-auth": { "defaultMessage": "Pass Auth to Upstream" }, diff --git a/frontend/src/locale/src/et.json b/frontend/src/locale/src/et.json index 989a153aa1..316ede752e 100644 --- a/frontend/src/locale/src/et.json +++ b/frontend/src/locale/src/et.json @@ -71,6 +71,12 @@ "access-list.help.rules-order": { "defaultMessage": "Luba ja keela reeglid rakenduvad selles järjekorras, milles need on kirjas." }, + "access-list.inherit": { + "defaultMessage": "Päri puhverserverilt" + }, + "access-list.inherit.subtitle": { + "defaultMessage": "Kasutab puhverserveri juurdepääsuloendit" + }, "access-list.pass-auth": { "defaultMessage": "Edasta autentimine sihtserverile" }, diff --git a/scripts/ci/fulltest-cypress b/scripts/ci/fulltest-cypress index 8fb896967c..a43f420eb0 100755 --- a/scripts/ci/fulltest-cypress +++ b/scripts/ci/fulltest-cypress @@ -65,7 +65,8 @@ rm -rf "${LOCAL_RESOLVE}" printf "nameserver %s\noptions ndots:0" "${DNSROUTER_IP}" > "${LOCAL_RESOLVE}" # bring up all remaining containers, except cypress! -docker compose up -d --remove-orphans stepca squid +docker compose build examplesite +docker compose up -d --remove-orphans --no-build stepca squid examplesite docker compose pull db-mysql || true # ok to fail docker compose pull db-postgres || true # ok to fail docker compose pull authentik authentik-redis authentik-ldap || true # ok to fail diff --git a/test/cypress/e2e/api/AccessListLocations.cy.js b/test/cypress/e2e/api/AccessListLocations.cy.js new file mode 100644 index 0000000000..2ea2742ef8 --- /dev/null +++ b/test/cypress/e2e/api/AccessListLocations.cy.js @@ -0,0 +1,301 @@ +/// + +describe('Per-path Access Lists', () => { + const domain = 'website3.example.com'; + + const alpha = { + name: 'Path Alpha', + username: 'alpha-user', + password: 'alpha-pass', + }; + + const beta = { + name: 'Path Beta', + username: 'beta-user', + password: 'beta-pass', + }; + + let token; + let alphaListId; + let betaListId; + let hostId; + + /** + * Requests a path on the proxy host directly (bypassing squid) + * and yields the HTTP status code and response body + * + * @param {string} path + * @param {object} [creds] + * @param {string} creds.username + * @param {string} creds.password + */ + const request = (path, creds) => { + const auth = creds ? `-u '${creds.username}:${creds.password}'` : ''; + return cy.exec(`curl --noproxy '*' -s -w '\n%{http_code}' ${auth} http://${domain}${path}`) + .then((result) => { + expect(result.exitCode).to.eq(0); + const lines = result.stdout.trim().split('\n'); + const status = lines.pop(); + return { status: status, body: lines.join('\n') }; + }); + }; + + // nginx reloads are signalled and return immediately, so the old + // config can still be served for a moment after an API change. + // Retry until the expected response is seen. + const waitForResponse = (path, creds, check, description) => { + // Copy now, the callback runs later and creds may have been changed by then + const credsCopy = creds ? { ...creds } : null; + let last = null; + cy.waitUntil(() => request(path, credsCopy).then((res) => { + last = res; + return check(res); + }), { + timeout: 15000, + interval: 500, + errorMsg: () => `${path} did not return ${description}, last status: ${last?.status}`, + }); + }; + + const expectStatus = (path, creds, status) => { + waitForResponse(path, creds, (res) => res.status === status, status); + }; + + // Also checks the body so we know the page came from examplesite + // and not the NPM default site + const expectPage = (path, creds, text) => { + waitForResponse(path, creds, (res) => res.status === '200' && res.body.includes(text), `200 with "${text}"`); + }; + + const createAccessList = (list) => { + return cy.task('backendApiPost', { + token: token, + path: '/api/nginx/access-lists', + data: { + name: list.name, + satisfy_any: false, + pass_auth: false, + items: [ + { + username: list.username, + password: list.password, + } + ], + clients: [], + } + }).then((data) => { + cy.validateSwaggerSchema('post', 201, '/nginx/access-lists', data); + expect(data).to.have.property('id'); + expect(data.id).to.be.greaterThan(0); + return cy.wrap(data.id); + }); + }; + + const location = (path, accessListId) => { + return { + path: path, + forward_scheme: 'http', + forward_host: 'examplesite', + forward_port: 80, + access_list_id: accessListId, + }; + }; + + before(() => { + cy.resetUsers(); + cy.getToken().then((tok) => { + token = tok; + }); + }); + + it('Should be able to create multiple access lists with credentials', () => { + createAccessList(alpha).then((id) => { + alphaListId = id; + }); + createAccessList(beta).then((id) => { + betaListId = id; + expect(betaListId).to.not.equal(alphaListId); + }); + }); + + it('Should be able to create a proxy host with a different access list per location', () => { + cy.task('backendApiPost', { + token: token, + path: '/api/nginx/proxy-hosts', + data: { + domain_names: [domain], + forward_scheme: 'http', + forward_host: 'examplesite', + forward_port: 80, + access_list_id: 0, + certificate_id: 0, + meta: { + dns_challenge: false + }, + advanced_config: '', + locations: [ + location('/dashboard', alphaListId), + location('/profile', betaListId), + ], + block_exploits: false, + caching_enabled: false, + allow_websocket_upgrade: false, + http2_support: false, + hsts_enabled: false, + hsts_subdomains: false, + ssl_forced: false + } + }).then((data) => { + cy.validateSwaggerSchema('post', 201, '/nginx/proxy-hosts', data); + expect(data).to.have.property('id'); + expect(data.id).to.be.greaterThan(0); + hostId = data.id; + expect(data).to.have.property('enabled', true); + expect(data).to.have.property('access_list_id', 0); + expect(data.locations).to.have.length(2); + expect(data.locations[0]).to.have.property('access_list_id', alphaListId); + expect(data.locations[1]).to.have.property('access_list_id', betaListId); + }); + }); + + it('Should persist the location access lists on the proxy host', () => { + cy.task('backendApiGet', { + token: token, + path: `/api/nginx/proxy-hosts/${hostId}`, + }).then((data) => { + cy.validateSwaggerSchema('get', 200, '/nginx/proxy-hosts/{hostID}', data); + expect(data.locations[0]).to.have.property('path', '/dashboard'); + expect(data.locations[0]).to.have.property('access_list_id', alphaListId); + expect(data.locations[1]).to.have.property('path', '/profile'); + expect(data.locations[1]).to.have.property('access_list_id', betaListId); + }); + }); + + it('Should not require auth for the host root', () => { + expectPage('/', null, 'this is the index page'); + }); + + it('Should only accept the alpha credentials on /dashboard', () => { + expectStatus('/dashboard', null, '401'); + expectStatus('/dashboard', beta, '401'); + expectPage('/dashboard', alpha, 'this is the dashboard page'); + }); + + it('Should only accept the beta credentials on /profile', () => { + expectStatus('/profile', null, '401'); + expectStatus('/profile', alpha, '401'); + expectPage('/profile', beta, 'this is the profile page'); + }); + + it('Should apply access list credential changes to locations using it', () => { + const newPassword = 'alpha-pass-changed'; + + cy.task('backendApiPut', { + token: token, + path: `/api/nginx/access-lists/${alphaListId}`, + data: { + name: alpha.name, + satisfy_any: false, + pass_auth: false, + items: [ + { + username: alpha.username, + password: newPassword, + } + ], + clients: [], + } + }).then((data) => { + cy.validateSwaggerSchema('put', 200, '/nginx/access-lists/{listID}', data); + expect(data).to.have.property('id', alphaListId); + }); + + expectStatus('/dashboard', alpha, '401'); + expectPage('/dashboard', { username: alpha.username, password: newPassword }, 'this is the dashboard page'); + alpha.password = newPassword; + + // Other locations are unaffected + expectStatus('/profile', null, '401'); + expectPage('/profile', beta, 'this is the profile page'); + }); + + it('Should inherit the host access list on locations without their own', () => { + // Host uses beta, /dashboard overrides with alpha, /missing has none and should inherit beta + cy.task('backendApiPut', { + token: token, + path: `/api/nginx/proxy-hosts/${hostId}`, + data: { + access_list_id: betaListId, + locations: [ + location('/dashboard', alphaListId), + location('/profile', betaListId), + location('/missing', 0), + ], + } + }).then((data) => { + // No swagger validation here: with a host access list set, the expanded + // access_list in the response has no proxy_host_count, which the schema requires + expect(data).to.have.property('access_list_id', betaListId); + expect(data.locations[2]).to.have.property('access_list_id', 0); + }); + + expectStatus('/', null, '401'); + expectStatus('/', alpha, '401'); + expectPage('/', beta, 'this is the index page'); + + // examplesite returns 404 for this path, once past the access list + expectStatus('/missing', null, '401'); + expectStatus('/missing', alpha, '401'); + expectStatus('/missing', beta, '404'); + + expectStatus('/dashboard', beta, '401'); + expectPage('/dashboard', alpha, 'this is the dashboard page'); + }); + + it('Should remove a deleted access list from the host and locations using it', () => { + cy.task('backendApiDelete', { + token: token, + path: `/api/nginx/access-lists/${betaListId}`, + }).then((data) => { + cy.validateSwaggerSchema('delete', 200, '/nginx/access-lists/{listID}', data); + expect(data).to.be.equal(true); + }); + + cy.task('backendApiGet', { + token: token, + path: `/api/nginx/proxy-hosts/${hostId}`, + }).then((data) => { + expect(data).to.have.property('access_list_id', 0); + expect(data.locations[0]).to.have.property('access_list_id', alphaListId); + expect(data.locations[1]).to.have.property('access_list_id', 0); + expect(data.locations[2]).to.have.property('access_list_id', 0); + }); + + expectPage('/', null, 'this is the index page'); + expectPage('/profile', null, 'this is the profile page'); + expectStatus('/missing', null, '404'); + + // Remaining location access list must still be enforced + expectStatus('/dashboard', null, '401'); + expectPage('/dashboard', alpha, 'this is the dashboard page'); + }); + + it('Should be able to delete the proxy host and remaining access list', () => { + cy.task('backendApiDelete', { + token: token, + path: `/api/nginx/proxy-hosts/${hostId}`, + }).then((data) => { + cy.validateSwaggerSchema('delete', 200, '/nginx/proxy-hosts/{hostID}', data); + expect(data).to.be.equal(true); + }); + + cy.task('backendApiDelete', { + token: token, + path: `/api/nginx/access-lists/${alphaListId}`, + }).then((data) => { + cy.validateSwaggerSchema('delete', 200, '/nginx/access-lists/{listID}', data); + expect(data).to.be.equal(true); + }); + }); + +}); diff --git a/test/docker/Dockerfile.website b/test/docker/Dockerfile.website new file mode 100644 index 0000000000..311272d8c4 --- /dev/null +++ b/test/docker/Dockerfile.website @@ -0,0 +1,6 @@ +FROM nginx:stable + +RUN rm -rf /etc/nginx/conf.d +COPY nginx /etc/nginx +COPY www /www +RUN chown -R nginx:nginx /www diff --git a/test/docker/nginx/conf.d/website123.conf b/test/docker/nginx/conf.d/website123.conf new file mode 100644 index 0000000000..656f3ade42 --- /dev/null +++ b/test/docker/nginx/conf.d/website123.conf @@ -0,0 +1,29 @@ +server { + listen 80; + server_name website1.example.com website2.example.com website3.example.com; + root /www; + index index.html; + + # redirect requests for .html URLs to their extensionless form + if ($request_uri ~ ^/index\.html(\?.*)?$) { + return 301 /$1; + } + if ($request_uri ~ ^/(.+)\.html(\?.*)?$) { + return 301 /$1$2; + } + + location / { + try_files $uri $uri.html $uri/ =404; + } + + error_page 404 /404.html; + location = /404.html { + internal; + } + + # deny access to .htaccess files, if Apache's document root + # concurs with nginx's one + location ~ /\.ht { + deny all; + } +} diff --git a/test/docker/nginx/nginx.conf b/test/docker/nginx/nginx.conf new file mode 100644 index 0000000000..82366ca042 --- /dev/null +++ b/test/docker/nginx/nginx.conf @@ -0,0 +1,30 @@ +user nginx; +worker_processes auto; +error_log /var/log/nginx/error.log notice; +pid /run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + server_tokens off; + + log_format custom_combined '$remote_addr - $remote_user [$time_local] "$host" "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"'; + + access_log /var/log/nginx/access.log custom_combined; + sendfile on; + tcp_nopush on; + keepalive_timeout 65; + gzip on; + + set_real_ip_from 10.0.0.0/8; + set_real_ip_from 172.16.0.0/12; # Includes Docker subnet + set_real_ip_from 192.168.0.0/16; + + include include/*.conf; + include conf.d/*.conf; + include /sites/*/nginx.conf; +} diff --git a/test/docker/www/404.html b/test/docker/www/404.html new file mode 100644 index 0000000000..389d3cafb1 --- /dev/null +++ b/test/docker/www/404.html @@ -0,0 +1,9 @@ + + + 404 + + + 404 not found + + + diff --git a/test/docker/www/dashboard.html b/test/docker/www/dashboard.html new file mode 100644 index 0000000000..d26099e8f9 --- /dev/null +++ b/test/docker/www/dashboard.html @@ -0,0 +1,9 @@ + + + Dashboard + + + this is the dashboard page + + + diff --git a/test/docker/www/index.html b/test/docker/www/index.html new file mode 100644 index 0000000000..3a190926cb --- /dev/null +++ b/test/docker/www/index.html @@ -0,0 +1,9 @@ + + + Index + + + this is the index page + + + diff --git a/test/docker/www/profile.html b/test/docker/www/profile.html new file mode 100644 index 0000000000..1058ca4a15 --- /dev/null +++ b/test/docker/www/profile.html @@ -0,0 +1,9 @@ + + + Profile + + + this is the profile page + + +