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 3a10387b2..d365897ab 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 84f42793e..20d628ca9 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 20d628ca9..c46e5743e 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 0f41aea86..ca6b6539e 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 | 340 +++++++++++++++++++++--------------------- 2 files changed, 174 insertions(+), 174 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 769a2a770..1fa055e35 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 d5f803762..3c116af36 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-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-win32-x64@1.1.1": +"@formatjs/cli-native-darwin-arm64@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-darwin-arm64/-/cli-native-darwin-arm64-1.1.1.tgz#abf5d12040511bbb9225ae6835fb6107f3e7f866" + integrity sha512-G2IfmxwDN1kUMIbM9ec5HfJTNR89X11+U3bt4lewfrRqoHOc9bQAkkVHLsY8gNVLjyQIXch58Ewd+AAHkg6cag== -"@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-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== 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== +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.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/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 80ae74b45..2c91ca441 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 427e834fa..49c54d1c5 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 769a2a770..0ddaf220b 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 d5f803762..f55a563af 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 5fcb4e09b..55513fe1e 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 ca6b6539e..f4bd7ca23 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 002c9fe17..a592fda5c 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 6f5875595..5fe787ee2 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 c46e5743e..c0418e170 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 8593fd5ef..56875fd84 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 cdd749f58..b335f01af 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 b8c424466..90245ed39 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 6130f82e3..1bb3c7450 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 877e51dda..452609bcb 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 d2e62f3bb..172290eae 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 000000000..3807c7d76 --- /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 36387a98d..e37d11cfa 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 bcf5552b3..de23c903b 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 92bf19d9c..32d457044 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 3ab04ce25..a93a1a4d0 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 503d6a908..7ca017686 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 ea203a89e..86c0a80df 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 f4bd7ca23..a2ccda8e1 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 5fe787ee2..e4ccf077a 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 fe84607f9..bd405d802 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 f4bd7ca23..46214bbc5 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 c75694827..f8c7568b2 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 3a2ae9e8f..d44ec466d 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 | 407 ++++++++++++------ frontend/src/locale/src/en.json | 9 + frontend/src/locale/src/tr.json | 9 + 4 files changed, 343 insertions(+), 132 deletions(-) diff --git a/frontend/src/components/Form/LocationsFields.module.css b/frontend/src/components/Form/LocationsFields.module.css index 4b48ef3cb..9551e0d4e 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 4240b1f98..23198c10c 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 (
-
- -
-
-
- - -
-
-
-
- - handleChange(idx, "forwardHost", e.target.value)} - /> -
-
-
-
- - handleChange(idx, "forwardPort", e.target.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", - }} - /> -
- )} - - ))} -
-
+ {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)} + > +
+ + {item.advancedConfig ? ( + // Deliberately the same icon as the advanced-config toggle in the + // body below, so the marker reads as "this row has that section + // filled in" rather than as a decoration of its own. + + + + ) : null} + +
+ {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", + }} + /> +
+ )} +
+ )} +
+ ); + }) + )} ); } diff --git a/frontend/src/locale/src/en.json b/frontend/src/locale/src/en.json index bb00ac332..88fdd724e 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 972fa895e..cc2d48881 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 88bf9df52..413ac067a 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 2c159d48a..96cfab480 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; + row.enabled = 1; - 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; + await proxyHostModel + .query() + .where("id", row.id) + .patch({ + enabled: 1, + }); + + await fetchLocationAccessLists(row); + + // 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 7045a195c..ef62cf835 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 3ac646213..90e6e23bb 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 000000000..91944c9d7 --- /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 40cb4142f..6be435b6a 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 2ae0b0834..4818f7769 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 afcbd0cf7..1c1004e71 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 4240b1f98..9422bd893 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 bb00ac332..b5043fc83 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 000000000..a0df04ee7 --- /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 a06a0c0d7..902d0d73d 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 5af58081a..ad6714b79 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 5d6602e2d..7845fb029 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 413ac067a..f8c454794 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 96cfab480..6bd0be1a6 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 c0418e170..362cbdfe4 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 220819404..b0f4469ff 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 f654e1085..6cdb64cf3 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 220819404..346288636 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 a5fb956c0..0c8580d84 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 220819404..03545f7bc 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 a4dec5c4d..1ecaf250c 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 | 725 ++++++++++-------- 27 files changed, 676 insertions(+), 742 deletions(-) diff --git a/backend/biome.json b/backend/biome.json index a0164fd99..5d1794b5a 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 bf540f8a2..5b18d3a9a 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 43307e02c..db1c3385e 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 88bf9df52..fc9e8dbab 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 02700dc5d..5155028c8 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 ee27e53cc..1afb6c671 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 fe84607f9..80cb0c290 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 126283e2d..67255b213 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 56a5ea859..d4080dd78 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 607552f6f..0e7e5e5af 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 a4dec5c4d..ffe12b714 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 a491c190e..71205013a 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 188df2779..457c954d2 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 9c29ba272..5035d8fdd 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 6c738d509..f4981a80c 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 5f2586fd6..5d9f8f38a 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 a6cbe2c99..471d0b857 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 9f5f9d064..a15f3e3f3 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 c32c6fb69..24c50e8d4 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 56f7dc5aa..1fbef374c 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 d87847178..cc6eac2cc 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 2c91ca441..8eda0451c 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 c40b1628d..54edef6e3 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 99f429b44..dea809423 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 7c3da8c1d..3f972223b 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 c0418e170..f6b145443 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 49c54d1c5..5050c5848 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.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.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-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.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-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.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-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.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-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.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-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.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-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.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-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.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-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.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-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-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 | 1536 +++++++++-------- 36 files changed, 1221 insertions(+), 1051 deletions(-) create mode 100644 frontend/src/components/Table/features.ts diff --git a/frontend/biome.json b/frontend/biome.json index 13f21e36b..e84969d2b 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 a592fda5c..ceacd3e70 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 46a9664c2..104c8a361 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 9dda8c3de..bac445840 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 ecf23d26f..ebfe38a65 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 f00d38d6e..bf28640a0 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 265150bb5..565fa01bf 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 2daee952a..ada39e3e1 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 d8fe9bf3a..a3114196b 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 dd409d59d..f656c4656 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 0df329c80..a6302e09b 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 630340919..5db64bafc 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 000000000..9b79e1d59 --- /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 d471d45d5..84b64610a 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 a5fb956c0..a001a231b 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 d42242773..ff5cb3b63 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 d0178a5d3..a9bb46ba7 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 7d4af5f5d..2fb04aea1 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 33e015cc8..a9bb46ba7 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 33e015cc8..a9bb46ba7 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 f062e24de..bca8df8d3 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 a06df2c62..d7ec75190 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 1bd7877f4..9a0d95ce8 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 6d5534889..b87a259c4 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 b5dd480c3..fa46c89cc 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 433c077b3..1783a2cff 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 f61809a56..2be8e72bf 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 7eaeb7770..2312a9bdf 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 ebf7eeb37..d65b2dc84 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 17143e750..e5c1b184f 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 5af58081a..bddac2700 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 8e2d90f55..2457a4738 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 341317bf4..ec181b209 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 d07fc9bcf..a5a61057b 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 5fe787ee2..493088c86 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== + 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.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== +"@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.28.6" - "@babel/parser" "^7.28.6" - "@babel/types" "^7.28.6" + "@babel/code-frame" "^7.29.7" + "@babel/parser" "^7.29.7" + "@babel/types" "^7.29.7" -"@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== +"@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.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" + "@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.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.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-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.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-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.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-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.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-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.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-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.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-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.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-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.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-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== + 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.7.4" - "@floating-ui/utils" "^0.2.10" + "@floating-ui/core" "^1.8.0" + "@floating-ui/utils" "^0.2.12" -"@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== +"@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.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-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@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-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-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-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-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-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@^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== +"@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/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.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/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.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/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.9" + "@formatjs/icu-skeleton-parser" "2.1.11" -"@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== +"@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.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== +"@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.5" - "@formatjs/icu-messageformat-parser" "3.5.10" - intl-messageformat "11.2.7" + "@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: + "@swc/helpers" "^0.5.0" + +"@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" + +"@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: + "@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.146.0": + version "0.146.0" + resolved "https://registry.yarnpkg.com/@oxc-project/types/-/types-0.146.0.tgz#d57a2591abbf1f6e50981b07ee24ab269530d87a" + integrity sha512-XC0QsnnhVe7sLIWmYmdPw7x5P0h4W8vUU3Nv1ySgWXtvCz8NizoAEpGXA0sOYoJQV2Rl13LgURAHQ5cI5ILCSA== -"@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.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-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.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-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.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-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.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-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.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-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.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-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.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-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.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-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.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-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.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-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.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-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== +"@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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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.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-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.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/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.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-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.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-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.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-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.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-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.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-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.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-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.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-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.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-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.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-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.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-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.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-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.32.0: - version "1.32.0" - resolved "https://registry.yarnpkg.com/lightningcss/-/lightningcss-1.32.0.tgz#b85aae96486dcb1bf49a7c8571221273f4f1e4a9" - integrity sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ== +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" + "@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.8.0: - version "9.8.0" - resolved "https://registry.yarnpkg.com/rooks/-/rooks-9.8.0.tgz#bf4790f1d379cb9d2f60570202e39d297ed88f8a" - integrity sha512-S6FqnmERx5zgl8ZUEcnyTe1jgjwE5xeFCgOV4bzgQHKp26P7YA7uPnzzOgacojtoX6E7pQTcewSGqN83wVyz+g== +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== +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.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/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 71205013a..59cb6598d 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 fa9465189..4236c90a2 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 220819404..7bb60ca91 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 ceacd3e70..e7c7363c3 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 493088c86..6304819a2 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 fa46c89cc..2b8639fa9 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 aa0b47f5e..da8765a5e 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 9fd0f74d1..989a153aa 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 cc4fc603e..7a9b4cd6b 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 bac0c1a41..1fdd65b6a 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 4b0b2b3c6..a50e0780d 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 6bd0be1a6..eac0c148a 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 f4981a80c..0597ef635 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 5d9f8f38a..767353f61 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 427d447d6..192f045b9 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 602073cec..3a1cd5210 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 1bb3c7450..be6f517d3 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 1c1004e71..ef955a033 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 9c4d8b3a8..a0f64c239 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 da8765a5e..11d09ea71 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 989a153aa..316ede752 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 8fb896967..a43f420eb 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 000000000..2ea2742ef --- /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 000000000..311272d8c --- /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 000000000..656f3ade4 --- /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 000000000..82366ca04 --- /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 000000000..389d3cafb --- /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 000000000..d26099e8f --- /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 000000000..3a190926c --- /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 000000000..1058ca4a1 --- /dev/null +++ b/test/docker/www/profile.html @@ -0,0 +1,9 @@ + + + Profile + + + this is the profile page + + +