diff --git a/.github/workflows/build-nym-vpn-app-windows.yml b/.github/workflows/build-nym-vpn-app-windows.yml index 1b86f3cfbd..929f518912 100644 --- a/.github/workflows/build-nym-vpn-app-windows.yml +++ b/.github/workflows/build-nym-vpn-app-windows.yml @@ -7,6 +7,10 @@ on: required: true type: boolean default: false + core_release_tag: + description: "nym-vpn-core release tag to use for Windows build (as it bundles the daemon)" + required: false + type: string workflow_call: inputs: # set to true when it is a 'dev' build @@ -14,6 +18,9 @@ on: required: true type: boolean default: false + core_release_tag: + required: false + type: string secrets: WINDOWS_SIGNING_PFX_BASE64: required: true @@ -128,7 +135,13 @@ jobs: winget list MikeFarah.yq || winget install --disable-interactivity --id MikeFarah.yq - name: Get nym-vpn-core release tag - if: inputs.dev_mode == false + if: inputs.core_release_tag + run: | + echo "core_release_tag: ${{ inputs.core_release_tag }}" + "core_release_tag=${{ inputs.core_release_tag }}" >> $env:GITHUB_ENV + + - name: Get nym-vpn-core release tag + if: ${{ !inputs.core_release_tag && !inputs.dev_mode }} run: | $release_tag = curl -sSL -H "Accept: application/vnd.github+json" ` https://api.github.com/repos/nymtech/nym-vpn-client/releases | @@ -137,7 +150,7 @@ jobs: "core_release_tag=$release_tag" >> $env:GITHUB_ENV - name: Get nym-vpn-core release tag (dev) - if: inputs.dev_mode == true + if: ${{ !inputs.core_release_tag && inputs.dev_mode }} run: | echo "core_release_tag: nym-vpn-core-nightly" "core_release_tag=nym-vpn-core-nightly" >> $env:GITHUB_ENV diff --git a/.github/workflows/publish-nym-vpn-app.yml b/.github/workflows/publish-nym-vpn-app.yml index de5a7137cc..cabd3252b9 100644 --- a/.github/workflows/publish-nym-vpn-app.yml +++ b/.github/workflows/publish-nym-vpn-app.yml @@ -13,6 +13,10 @@ on: required: true type: boolean default: false + core_release_tag: + description: "nym-vpn-core release tag to use for Windows build (as it bundles the daemon)" + required: false + type: string push: tags: - nym-vpn-app-v[0-9]+.[0-9]+.[0-9]+* @@ -27,6 +31,7 @@ jobs: uses: ./.github/workflows/build-nym-vpn-app-windows.yml with: dev_mode: ${{ github.event_name == 'schedule' || contains(github.ref_name, 'dev') || contains(github.ref_name, 'nightly') || inputs.dev_mode == true }} + core_release_tag: ${{ inputs.core_release_tag }} secrets: inherit generate-build-info-nym-vpn-app: diff --git a/nym-vpn-app/.pkg/app.desktop b/nym-vpn-app/.pkg/app.desktop index dbe4286869..c4558ffea4 100644 --- a/nym-vpn-app/.pkg/app.desktop +++ b/nym-vpn-app/.pkg/app.desktop @@ -3,7 +3,7 @@ Name=NymVPN Type=Application Version=1.0 Comment=Decentralized, mixnet, and zero-knowledge VPN -Exec=run.sh %U +Exec=env LOG_FILE=1 RUST_LOG=info,nym_vpn_app=debug nym-vpn-app %U Icon=nym-vpn Terminal=false Categories=Network; diff --git a/nym-vpn-app/.pkg/aur/PKGBUILD b/nym-vpn-app/.pkg/aur/PKGBUILD index 200b73fec8..f21472b415 100644 --- a/nym-vpn-app/.pkg/aur/PKGBUILD +++ b/nym-vpn-app/.pkg/aur/PKGBUILD @@ -18,7 +18,6 @@ provides=('nym-vpn-app') conflicts=('nymvpn-x' 'nym-vpn-app') options=(!debug) source=("$pkgname-$pkgver.tar.gz::$url/archive/refs/tags/$_release_tag.tar.gz" - 'nym-vpn-wrapper.sh' 'nym-vpn.desktop' 'nym-vpn.svg') sha256sums=() @@ -27,7 +26,7 @@ _srcdir="nym-vpn-client-$_release_tag" prepare() { pushd "$_srcdir" - # rip off all useless sources + # rip off useless sources rm -rf nym-vpn-android rm -rf nym-vpn-apple popd @@ -58,8 +57,7 @@ package() { install -Dm755 "src-tauri/target/release/nym-vpn-app" "$pkgdir/usr/bin/nym-vpn-app" popd - install -Dm755 "nym-vpn-wrapper.sh" "$pkgdir/usr/bin/nym-vpn-wrapper.sh" - install -Dm644 "nym-vpn.desktop" "$pkgdir/usr/share/applications/nym-vpn.desktop" - install -Dm644 "nym-vpn.svg" "$pkgdir/usr/share/icons/nym-vpn.svg" + install -Dm644 "nym-vpn.desktop" "$pkgdir/usr/share/applications/nym-vpn.desktop" + install -Dm644 "nym-vpn.svg" "$pkgdir/usr/share/icons/hicolor/scalable/apps/nym-vpn.svg" } diff --git a/nym-vpn-app/.pkg/aur/PKGBUILD-bin b/nym-vpn-app/.pkg/aur/PKGBUILD-bin index f726edf68e..defd8ba41c 100644 --- a/nym-vpn-app/.pkg/aur/PKGBUILD-bin +++ b/nym-vpn-app/.pkg/aur/PKGBUILD-bin @@ -18,15 +18,14 @@ provides=('nym-vpn-app') conflicts=('nymvpn-x' 'nym-vpn-app') options=(!debug) source=("$url/releases/download/$_release_tag/nym-vpn_${_pkgver}_linux_x64" - 'nym-vpn-wrapper.sh' 'nym-vpn.desktop' 'nym-vpn.svg') sha256sums=() package() { install -Dm755 "nym-vpn_${_pkgver}_linux_x64" "$pkgdir/usr/bin/nym-vpn-app" - install -Dm755 "nym-vpn-wrapper.sh" "$pkgdir/usr/bin/nym-vpn-wrapper.sh" - install -Dm644 "nym-vpn.desktop" "$pkgdir/usr/share/applications/nym-vpn.desktop" - install -Dm644 "nym-vpn.svg" "$pkgdir/usr/share/icons/nym-vpn.svg" + install -Dm644 "nym-vpn.desktop" "$pkgdir/usr/share/applications/nym-vpn.desktop" + install -Dm644 "nym-vpn.svg" "$pkgdir/usr/share/icons/hicolor/scalable/apps/nym-vpn.svg" } + diff --git a/nym-vpn-app/.pkg/aur/nym-vpn-wrapper.sh b/nym-vpn-app/.pkg/aur/nym-vpn-wrapper.sh deleted file mode 100755 index 2cd4cbb524..0000000000 --- a/nym-vpn-app/.pkg/aur/nym-vpn-wrapper.sh +++ /dev/null @@ -1,7 +0,0 @@ -#! /bin/bash - -# fix an issue with NVIDIA gpu -# https://github.com/nymtech/nym-vpn-client/issues/305 -export WEBKIT_DISABLE_DMABUF_RENDERER=1 - -LOG_FILE=1 RUST_LOG=info,nym_vpn_app=trace /usr/bin/nym-vpn-app diff --git a/nym-vpn-app/.pkg/aur/nym-vpn.desktop b/nym-vpn-app/.pkg/aur/nym-vpn.desktop deleted file mode 100644 index 8f93dc3ff0..0000000000 --- a/nym-vpn-app/.pkg/aur/nym-vpn.desktop +++ /dev/null @@ -1,10 +0,0 @@ -[Desktop Entry] -Name=NymVPN -Type=Application -Version=1.0 -Comment=Decentralized, mixnet, and zero-knowledge VPN -Exec=/usr/bin/nym-vpn-wrapper.sh %U -Icon=/usr/share/icons/nym-vpn.svg -Terminal=false -Categories=Network; - diff --git a/nym-vpn-app/.pkg/aur/nym-vpn.svg b/nym-vpn-app/.pkg/aur/nym-vpn.svg deleted file mode 100644 index b99ab734dc..0000000000 --- a/nym-vpn-app/.pkg/aur/nym-vpn.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/nym-vpn-app/.pkg/flatpak/net.nymtech.NymVPN.yml b/nym-vpn-app/.pkg/flatpak/net.nymtech.NymVPN.yml index e8eacddf36..48719e173a 100644 --- a/nym-vpn-app/.pkg/flatpak/net.nymtech.NymVPN.yml +++ b/nym-vpn-app/.pkg/flatpak/net.nymtech.NymVPN.yml @@ -28,23 +28,12 @@ modules: path: net.nymtech.NymVPN.metainfo.xml - type: file path: ../app.desktop - - type: script - dest-filename: run.sh - # wrapper script to set the needed environment variables - commands: - # use `WEBKIT_DISABLE_DMABUF_RENDERER=1` to fix an issue with NVIDIA gpu - # https://github.com/nymtech/nym-vpn-client/issues/305 - - | - if [ -c /dev/nvidia0 ]; then - export WEBKIT_DISABLE_DMABUF_RENDERER=1 - fi - LOG_FILE=1 /app/bin/nym-vpn "$@" - type: file path: ../icon.svg build-commands: - install -Dm755 nym-vpn /app/bin/nym-vpn - - install -Dm755 run.sh /app/bin/run.sh - - sed -i "s/^Icon=.*/Icon=net.nymtech.NymVPN/" app.desktop + - desktop-file-edit --set-key=Exec --set-value='env LOG_FILE=1 RUST_LOG=info nym-vpn %U' app.desktop + - desktop-file-edit --set-icon=net.nymtech.NymVPN app.desktop - install -Dm644 app.desktop /app/share/applications/net.nymtech.NymVPN.desktop - install -Dm644 icon.svg /app/share/icons/hicolor/scalable/apps/net.nymtech.NymVPN.svg - install -Dm644 net.nymtech.NymVPN.metainfo.xml /app/share/metainfo/net.nymtech.NymVPN.metainfo.xml diff --git a/nym-vpn-app/README.md b/nym-vpn-app/README.md index bca2a54219..24b966bd39 100644 --- a/nym-vpn-app/README.md +++ b/nym-vpn-app/README.md @@ -1,14 +1,14 @@ # nym-vpn-app Desktop client application for [NymVPN](https://nymvpn.com/en), built with -[tauri](https://v2.tauri.app/). +[tauri](https://v2.tauri.app/). Supports Linux and Windows. -For more information about NymVPN, its features, latest announcements, Help Center, or to download the latest stable release, visit [nymvpn.com](https://nymvpn.com/en). +For more information about NymVPN, its features, latest announcements, +Help Center, or to download the latest stable release, visit +[nymvpn.com](https://nymvpn.com/en). ## Installation -### Linux - The following install methods are available: ### Arch Linux (AUR) @@ -39,26 +39,25 @@ sudo dpkg -i /tmp/nym-repo-setup_1.0.1_amd64.deb sudo apt install nym-vpn ``` -### Other Linux +### Flatpak (client app only) -For most Linux distributions, you can install both the client -application and the daemon (`vpnd`) via the installer script: +The app is available on [Flathub](https://flathub.org/apps/net.nymtech.NymVPN) ```shell -curl -fsSL https://nymtech.net/go/github/nym-vpn-client/raw/main/.pkg/linux/install | bash +flatpak install flathub net.nymtech.NymVPN ``` -It will install from the latest releases the client as AppImage -and the daemon as a systemd service. +### AppImage (client app only) -note: it's a good practice to check the -[script](https://github.com/nymtech/nym-vpn-client/blob/main/.pkg/linux/install) -before running it. +The _AppImage_ is available in the +[releases](https://github.com/nymtech/nym-vpn-client/releases), +look for release tag `nym-vpn-app-v*` and download `NymVPN.AppImage`. ### Windows -Download the installer from the [releases](https://github.com/nymtech/nym-vpn-client/releases).\ -Look for the latest release `nym-vpn-app-v*`, download +The installer is available in the +[releases](https://github.com/nymtech/nym-vpn-client/releases).\ +Look for release tag `nym-vpn-app-v*`, download `NymVPN-setup.exe` and launch it. --- diff --git a/nym-vpn-app/package-lock.json b/nym-vpn-app/package-lock.json index bbd79e8e0a..34ad04e69d 100644 --- a/nym-vpn-app/package-lock.json +++ b/nym-vpn-app/package-lock.json @@ -90,9 +90,9 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.0.tgz", - "integrity": "sha512-INCKxTtbXtcNbUZ3YXutwMpEleqttcswhAdee7dhuoVrD2cnuc3PqtERBtxkX5nziX9vnBL8WXmSGwv8CuPV6g==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, "license": "MIT", "dependencies": { @@ -105,9 +105,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.0.tgz", - "integrity": "sha512-qETICbZSLe7uXv9VE8T/RWOdIE5qqyTucOt4zLYMafj2MRO271VGgLd4RACJMeBO37UPWhXiKMBk7YlJ0fOzQA==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", + "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", "dev": true, "license": "MIT", "engines": { @@ -146,13 +146,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.0.tgz", - "integrity": "sha512-/AIkAmInnWwgEAJGQr9vY0c66Mj6kjkE2ZPB1PurTRaRAh3U+J45sAQMjQDJdh4WbR3l0x5xkimXBKyBXXAu2w==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.26.0", + "@babel/parser": "^7.26.2", "@babel/types": "^7.26.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", @@ -266,9 +266,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.26.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.1.tgz", - "integrity": "sha512-reoQYNiAJreZNsJzyrDNzFQ+IQ5JFiIzAHJg9bn94S3l+4++J7RsIhNMoB+lgP/9tpmiAQqspv+xfdxTSzREOw==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", "dev": true, "license": "MIT", "dependencies": { @@ -847,9 +847,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.13.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.13.0.tgz", - "integrity": "sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA==", + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.14.0.tgz", + "integrity": "sha512-pFoEtFWCPyDOl+C6Ift+wC7Ro89otjigCf5vcuWqWgqNSQbRrpjSvdeE6ofLz4dHmyxD5f7gIdGT4+p36L6Twg==", "dev": true, "license": "MIT", "engines": { @@ -867,9 +867,9 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.1.tgz", - "integrity": "sha512-HFZ4Mp26nbWk9d/BpvP0YNL6W4UoZF0VFcTw/aPPA8RpOxeFQgK+ClABGgAUXs9Y/RGX/l1vOmrqz1MQt9MNuw==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.2.tgz", + "integrity": "sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -889,9 +889,9 @@ } }, "node_modules/@floating-ui/dom": { - "version": "1.6.11", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.11.tgz", - "integrity": "sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ==", + "version": "1.6.12", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz", + "integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==", "license": "MIT", "dependencies": { "@floating-ui/core": "^1.6.0", @@ -899,9 +899,9 @@ } }, "node_modules/@floating-ui/react": { - "version": "0.26.25", - "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.25.tgz", - "integrity": "sha512-hZOmgN0NTOzOuZxI1oIrDu3Gcl8WViIkvPMpB4xdd4QD6xAMtwgwr3VPoiyH/bLtRcS1cDnhxLSD1NsMJmwh/A==", + "version": "0.26.27", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.27.tgz", + "integrity": "sha512-jLP72x0Kr2CgY6eTYi/ra3VA9LOkTo4C+DUTrbFgFOExKy3omYVmwMjNKqxAHdsnyLS96BIDLcO2SlnsNf8KUQ==", "license": "MIT", "dependencies": { "@floating-ui/react-dom": "^2.1.2", @@ -975,6 +975,20 @@ "node": ">=18.18.0" } }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -990,9 +1004,9 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1075,15 +1089,15 @@ } }, "node_modules/@mui/base": { - "version": "5.0.0-beta.60", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.60.tgz", - "integrity": "sha512-w8twR3qCUI+uJHO5xDOuc1yB5l46KFbvNsTwIvEW9tQkKxVaiEFf2GAXHuvFJiHfZLqjzett6drZjghy8D1Z1A==", + "version": "5.0.0-beta.61", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.61.tgz", + "integrity": "sha512-YaMOTXS3ecDNGsPKa6UdlJ8loFLvcL9+VbpCK3hfk71OaNauZRp4Yf7KeXDYr7Ms3M/XBD3SaiR6JMr6vYtfDg==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.25.7", + "@babel/runtime": "^7.26.0", "@floating-ui/react-dom": "^2.1.1", - "@mui/types": "^7.2.18", - "@mui/utils": "^6.1.5", + "@mui/types": "^7.2.19", + "@mui/utils": "^6.1.6", "@popperjs/core": "^2.11.8", "clsx": "^2.1.1", "prop-types": "^15.8.1" @@ -1107,9 +1121,9 @@ } }, "node_modules/@mui/types": { - "version": "7.2.18", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.18.tgz", - "integrity": "sha512-uvK9dWeyCJl/3ocVnTOS6nlji/Knj8/tVqVX03UVTpdmTJYu/s4jtDd9Kvv0nRGE0CUSNW1UYAci7PYypjealg==", + "version": "7.2.19", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.19.tgz", + "integrity": "sha512-6XpZEM/Q3epK9RN8ENoXuygnqUQxE+siN/6rGRi2iwJPgBUR25mphYQ9ZI87plGh58YoZ5pp40bFvKYOCDJ3tA==", "license": "MIT", "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -1121,13 +1135,13 @@ } }, "node_modules/@mui/utils": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.1.5.tgz", - "integrity": "sha512-vp2WfNDY+IbKUIGg+eqX1Ry4t/BilMjzp6p9xO1rfqpYjH1mj8coQxxDfKxcQLzBQkmBJjymjoGOak5VUYwXug==", + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.1.6.tgz", + "integrity": "sha512-sBS6D9mJECtELASLM+18WUcXF6RH3zNxBRFeyCRg8wad6NbyNrdxLuwK+Ikvc38sTZwBzAz691HmSofLqHd9sQ==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.25.7", - "@mui/types": "^7.2.18", + "@babel/runtime": "^7.26.0", + "@mui/types": "^7.2.19", "@types/prop-types": "^15.7.13", "clsx": "^2.1.1", "prop-types": "^15.8.1", @@ -1293,9 +1307,9 @@ } }, "node_modules/@remix-run/router": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.20.0.tgz", - "integrity": "sha512-mUnk8rPJBI9loFDZ+YzPGdeniYK+FTmRD1TMCz7ev2SNIozyKKpnGgsxO34u6Z4z/t0ITuu7voi/AshfsGsgFg==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.21.0.tgz", + "integrity": "sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA==", "license": "MIT", "engines": { "node": ">=14.0.0" @@ -1338,9 +1352,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.2.tgz", - "integrity": "sha512-ufoveNTKDg9t/b7nqI3lwbCG/9IJMhADBNjjz/Jn6LxIZxD7T5L8l2uO/wD99945F1Oo8FvgbbZJRguyk/BdzA==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.26.0.tgz", + "integrity": "sha512-gJNwtPDGEaOEgejbaseY6xMFu+CPltsc8/T+diUTTbOQLqD+bnrJq9ulH6WD69TqwqWmrfRAtUv30cCFZlbGTQ==", "cpu": [ "arm" ], @@ -1352,9 +1366,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.2.tgz", - "integrity": "sha512-iZoYCiJz3Uek4NI0J06/ZxUgwAfNzqltK0MptPDO4OR0a88R4h0DSELMsflS6ibMCJ4PnLvq8f7O1d7WexUvIA==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.26.0.tgz", + "integrity": "sha512-YJa5Gy8mEZgz5JquFruhJODMq3lTHWLm1fOy+HIANquLzfIOzE9RA5ie3JjCdVb9r46qfAQY/l947V0zfGJ0OQ==", "cpu": [ "arm64" ], @@ -1366,9 +1380,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.2.tgz", - "integrity": "sha512-/UhrIxobHYCBfhi5paTkUDQ0w+jckjRZDZ1kcBL132WeHZQ6+S5v9jQPVGLVrLbNUebdIRpIt00lQ+4Z7ys4Rg==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.26.0.tgz", + "integrity": "sha512-ErTASs8YKbqTBoPLp/kA1B1Um5YSom8QAc4rKhg7b9tyyVqDBlQxy7Bf2wW7yIlPGPg2UODDQcbkTlruPzDosw==", "cpu": [ "arm64" ], @@ -1380,9 +1394,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.2.tgz", - "integrity": "sha512-1F/jrfhxJtWILusgx63WeTvGTwE4vmsT9+e/z7cZLKU8sBMddwqw3UV5ERfOV+H1FuRK3YREZ46J4Gy0aP3qDA==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.26.0.tgz", + "integrity": "sha512-wbgkYDHcdWW+NqP2mnf2NOuEbOLzDblalrOWcPyY6+BRbVhliavon15UploG7PpBRQ2bZJnbmh8o3yLoBvDIHA==", "cpu": [ "x64" ], @@ -1394,9 +1408,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.2.tgz", - "integrity": "sha512-1YWOpFcGuC6iGAS4EI+o3BV2/6S0H+m9kFOIlyFtp4xIX5rjSnL3AwbTBxROX0c8yWtiWM7ZI6mEPTI7VkSpZw==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.26.0.tgz", + "integrity": "sha512-Y9vpjfp9CDkAG4q/uwuhZk96LP11fBz/bYdyg9oaHYhtGZp7NrbkQrj/66DYMMP2Yo/QPAsVHkV891KyO52fhg==", "cpu": [ "arm64" ], @@ -1408,9 +1422,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.2.tgz", - "integrity": "sha512-3qAqTewYrCdnOD9Gl9yvPoAoFAVmPJsBvleabvx4bnu1Kt6DrB2OALeRVag7BdWGWLhP1yooeMLEi6r2nYSOjg==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.26.0.tgz", + "integrity": "sha512-A/jvfCZ55EYPsqeaAt/yDAG4q5tt1ZboWMHEvKAH9Zl92DWvMIbnZe/f/eOXze65aJaaKbL+YeM0Hz4kLQvdwg==", "cpu": [ "x64" ], @@ -1422,9 +1436,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.2.tgz", - "integrity": "sha512-ArdGtPHjLqWkqQuoVQ6a5UC5ebdX8INPuJuJNWRe0RGa/YNhVvxeWmCTFQ7LdmNCSUzVZzxAvUznKaYx645Rig==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.26.0.tgz", + "integrity": "sha512-paHF1bMXKDuizaMODm2bBTjRiHxESWiIyIdMugKeLnjuS1TCS54MF5+Y5Dx8Ui/1RBPVRE09i5OUlaLnv8OGnA==", "cpu": [ "arm" ], @@ -1436,9 +1450,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.2.tgz", - "integrity": "sha512-B6UHHeNnnih8xH6wRKB0mOcJGvjZTww1FV59HqJoTJ5da9LCG6R4SEBt6uPqzlawv1LoEXSS0d4fBlHNWl6iYw==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.26.0.tgz", + "integrity": "sha512-cwxiHZU1GAs+TMxvgPfUDtVZjdBdTsQwVnNlzRXC5QzIJ6nhfB4I1ahKoe9yPmoaA/Vhf7m9dB1chGPpDRdGXg==", "cpu": [ "arm" ], @@ -1450,9 +1464,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.2.tgz", - "integrity": "sha512-kr3gqzczJjSAncwOS6i7fpb4dlqcvLidqrX5hpGBIM1wtt0QEVtf4wFaAwVv8QygFU8iWUMYEoJZWuWxyua4GQ==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.26.0.tgz", + "integrity": "sha512-4daeEUQutGRCW/9zEo8JtdAgtJ1q2g5oHaoQaZbMSKaIWKDQwQ3Yx0/3jJNmpzrsScIPtx/V+1AfibLisb3AMQ==", "cpu": [ "arm64" ], @@ -1464,9 +1478,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.2.tgz", - "integrity": "sha512-TDdHLKCWgPuq9vQcmyLrhg/bgbOvIQ8rtWQK7MRxJ9nvaxKx38NvY7/Lo6cYuEnNHqf6rMqnivOIPIQt6H2AoA==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.26.0.tgz", + "integrity": "sha512-eGkX7zzkNxvvS05ROzJ/cO/AKqNvR/7t1jA3VZDi2vRniLKwAWxUr85fH3NsvtxU5vnUUKFHKh8flIBdlo2b3Q==", "cpu": [ "arm64" ], @@ -1478,9 +1492,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.2.tgz", - "integrity": "sha512-xv9vS648T3X4AxFFZGWeB5Dou8ilsv4VVqJ0+loOIgDO20zIhYfDLkk5xoQiej2RiSQkld9ijF/fhLeonrz2mw==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.26.0.tgz", + "integrity": "sha512-Odp/lgHbW/mAqw/pU21goo5ruWsytP7/HCC/liOt0zcGG0llYWKrd10k9Fj0pdj3prQ63N5yQLCLiE7HTX+MYw==", "cpu": [ "ppc64" ], @@ -1492,9 +1506,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.2.tgz", - "integrity": "sha512-tbtXwnofRoTt223WUZYiUnbxhGAOVul/3StZ947U4A5NNjnQJV5irKMm76G0LGItWs6y+SCjUn/Q0WaMLkEskg==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.26.0.tgz", + "integrity": "sha512-MBR2ZhCTzUgVD0OJdTzNeF4+zsVogIR1U/FsyuFerwcqjZGvg2nYe24SAHp8O5sN8ZkRVbHwlYeHqcSQ8tcYew==", "cpu": [ "riscv64" ], @@ -1506,9 +1520,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.2.tgz", - "integrity": "sha512-gc97UebApwdsSNT3q79glOSPdfwgwj5ELuiyuiMY3pEWMxeVqLGKfpDFoum4ujivzxn6veUPzkGuSYoh5deQ2Q==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.26.0.tgz", + "integrity": "sha512-YYcg8MkbN17fMbRMZuxwmxWqsmQufh3ZJFxFGoHjrE7bv0X+T6l3glcdzd7IKLiwhT+PZOJCblpnNlz1/C3kGQ==", "cpu": [ "s390x" ], @@ -1520,9 +1534,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.2.tgz", - "integrity": "sha512-jOG/0nXb3z+EM6SioY8RofqqmZ+9NKYvJ6QQaa9Mvd3RQxlH68/jcB/lpyVt4lCiqr04IyaC34NzhUqcXbB5FQ==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.26.0.tgz", + "integrity": "sha512-ZuwpfjCwjPkAOxpjAEjabg6LRSfL7cAJb6gSQGZYjGhadlzKKywDkCUnJ+KEfrNY1jH5EEoSIKLCb572jSiglA==", "cpu": [ "x64" ], @@ -1534,9 +1548,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.2.tgz", - "integrity": "sha512-XAo7cJec80NWx9LlZFEJQxqKOMz/lX3geWs2iNT5CHIERLFfd90f3RYLLjiCBm1IMaQ4VOX/lTC9lWfzzQm14Q==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.26.0.tgz", + "integrity": "sha512-+HJD2lFS86qkeF8kNu0kALtifMpPCZU80HvwztIKnYwym3KnA1os6nsX4BGSTLtS2QVAGG1P3guRgsYyMA0Yhg==", "cpu": [ "x64" ], @@ -1548,9 +1562,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.2.tgz", - "integrity": "sha512-A+JAs4+EhsTjnPQvo9XY/DC0ztaws3vfqzrMNMKlwQXuniBKOIIvAAI8M0fBYiTCxQnElYu7mLk7JrhlQ+HeOw==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.26.0.tgz", + "integrity": "sha512-WUQzVFWPSw2uJzX4j6YEbMAiLbs0BUysgysh8s817doAYhR5ybqTI1wtKARQKo6cGop3pHnrUJPFCsXdoFaimQ==", "cpu": [ "arm64" ], @@ -1562,9 +1576,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.2.tgz", - "integrity": "sha512-ZhcrakbqA1SCiJRMKSU64AZcYzlZ/9M5LaYil9QWxx9vLnkQ9Vnkve17Qn4SjlipqIIBFKjBES6Zxhnvh0EAEw==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.26.0.tgz", + "integrity": "sha512-D4CxkazFKBfN1akAIY6ieyOqzoOoBV1OICxgUblWxff/pSjCA2khXlASUx7mK6W1oP4McqhgcCsu6QaLj3WMWg==", "cpu": [ "ia32" ], @@ -1576,9 +1590,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.2.tgz", - "integrity": "sha512-2mLH46K1u3r6uwc95hU+OR9q/ggYMpnS7pSp83Ece1HUQgF9Nh/QwTK5rcgbFnV9j+08yBrU5sA/P0RK2MSBNA==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.26.0.tgz", + "integrity": "sha512-2x8MO1rm4PGEP0xWbubJW5RtbNLk3puzAMaLQd3B3JHVw4KcHlmXcO+Wewx9zCoo7EUFiMlu/aZbCJ7VjMzAag==", "cpu": [ "x64" ], @@ -1590,104 +1604,104 @@ ] }, "node_modules/@sentry-internal/browser-utils": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.35.0.tgz", - "integrity": "sha512-uj9nwERm7HIS13f/Q52hF/NUS5Al8Ma6jkgpfYGeppYvU0uSjPkwMogtqoJQNbOoZg973tV8qUScbcWY616wNA==", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.38.0.tgz", + "integrity": "sha512-5QMVcssrAcmjKT0NdFYcX0b0wwZovGAZ9L2GajErXtHkBenjI2sgR2+5J7n+QZGuk2SC1qhGmT1O9i3p3UEwew==", "license": "MIT", "dependencies": { - "@sentry/core": "8.35.0", - "@sentry/types": "8.35.0", - "@sentry/utils": "8.35.0" + "@sentry/core": "8.38.0", + "@sentry/types": "8.38.0", + "@sentry/utils": "8.38.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/feedback": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.35.0.tgz", - "integrity": "sha512-7bjSaUhL0bDArozre6EiIhhdWdT/1AWNWBC1Wc5w1IxEi5xF7nvF/FfvjQYrONQzZAI3HRxc45J2qhLUzHBmoQ==", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.38.0.tgz", + "integrity": "sha512-AW5HCCAlc3T1jcSuNhbFVNO1CHyJ5g5tsGKEP4VKgu+D1Gg2kZ5S2eFatLBUP/BD5JYb1A7p6XPuzYp1XfMq0A==", "license": "MIT", "dependencies": { - "@sentry/core": "8.35.0", - "@sentry/types": "8.35.0", - "@sentry/utils": "8.35.0" + "@sentry/core": "8.38.0", + "@sentry/types": "8.38.0", + "@sentry/utils": "8.38.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.35.0.tgz", - "integrity": "sha512-3wkW03vXYMyWtTLxl9yrtkV+qxbnKFgfASdoGWhXzfLjycgT6o4/04eb3Gn71q9aXqRwH17ISVQbVswnRqMcmA==", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.38.0.tgz", + "integrity": "sha512-mQPShKnIab7oKwkwrRxP/D8fZYHSkDY+cvqORzgi+wAwgnunytJQjz9g6Ww2lJu98rHEkr5SH4V4rs6PZYZmnQ==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "8.35.0", - "@sentry/core": "8.35.0", - "@sentry/types": "8.35.0", - "@sentry/utils": "8.35.0" + "@sentry-internal/browser-utils": "8.38.0", + "@sentry/core": "8.38.0", + "@sentry/types": "8.38.0", + "@sentry/utils": "8.38.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay-canvas": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.35.0.tgz", - "integrity": "sha512-TUrH6Piv19kvHIiRyIuapLdnuwxk/Un/l1WDCQfq7mK9p1Pac0FkQ7Uufjp6zY3lyhDDZQ8qvCS4ioCMibCwQg==", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.38.0.tgz", + "integrity": "sha512-OxmlWzK9J8mRM+KxdSnQ5xuxq+p7TiBzTz70FT3HltxmeugvDkyp6803UcFqHOPHR35OYeVLOalym+FmvNn9kw==", "license": "MIT", "dependencies": { - "@sentry-internal/replay": "8.35.0", - "@sentry/core": "8.35.0", - "@sentry/types": "8.35.0", - "@sentry/utils": "8.35.0" + "@sentry-internal/replay": "8.38.0", + "@sentry/core": "8.38.0", + "@sentry/types": "8.38.0", + "@sentry/utils": "8.38.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry/browser": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.35.0.tgz", - "integrity": "sha512-WHfI+NoZzpCsmIvtr6ChOe7yWPLQyMchPnVhY3Z4UeC70bkYNdKcoj/4XZbX3m0D8+71JAsm0mJ9s9OC3Ue6MQ==", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.38.0.tgz", + "integrity": "sha512-AZR+b0EteNZEGv6JSdBD22S9VhQ7nrljKsSnzxobBULf3BpwmhmCzTbDrqWszKDAIDYmL+yQJIR2glxbknneWQ==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "8.35.0", - "@sentry-internal/feedback": "8.35.0", - "@sentry-internal/replay": "8.35.0", - "@sentry-internal/replay-canvas": "8.35.0", - "@sentry/core": "8.35.0", - "@sentry/types": "8.35.0", - "@sentry/utils": "8.35.0" + "@sentry-internal/browser-utils": "8.38.0", + "@sentry-internal/feedback": "8.38.0", + "@sentry-internal/replay": "8.38.0", + "@sentry-internal/replay-canvas": "8.38.0", + "@sentry/core": "8.38.0", + "@sentry/types": "8.38.0", + "@sentry/utils": "8.38.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry/core": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.35.0.tgz", - "integrity": "sha512-Ci0Nmtw5ETWLqQJGY4dyF+iWh7PWKy6k303fCEoEmqj2czDrKJCp7yHBNV0XYbo00prj2ZTbCr6I7albYiyONA==", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.38.0.tgz", + "integrity": "sha512-sGD+5TEHU9G7X7zpyaoJxpOtwjTjvOd1f/MKBrWW2vf9UbYK+GUJrOzLhMoSWp/pHSYgvObkJkDb/HwieQjvhQ==", "license": "MIT", "dependencies": { - "@sentry/types": "8.35.0", - "@sentry/utils": "8.35.0" + "@sentry/types": "8.38.0", + "@sentry/utils": "8.38.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry/react": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@sentry/react/-/react-8.35.0.tgz", - "integrity": "sha512-8Y+s4pE9hvT2TwSo5JS/Enw2cNFlwiLcJDNGCj/Hho+FePFYA59hbN06ouTHWARnO+swANHKZQj24Wp57p1/tg==", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@sentry/react/-/react-8.38.0.tgz", + "integrity": "sha512-5396tewO00wbJFHUkmU+ikmp4A+wuBpStNc7UDyAm642jfbPajj51+GWld/ZYNFiQaZ/8I9tvvpHqVLnUh21gg==", "license": "MIT", "dependencies": { - "@sentry/browser": "8.35.0", - "@sentry/core": "8.35.0", - "@sentry/types": "8.35.0", - "@sentry/utils": "8.35.0", + "@sentry/browser": "8.38.0", + "@sentry/core": "8.38.0", + "@sentry/types": "8.38.0", + "@sentry/utils": "8.38.0", "hoist-non-react-statics": "^3.3.2" }, "engines": { @@ -1698,21 +1712,21 @@ } }, "node_modules/@sentry/types": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.35.0.tgz", - "integrity": "sha512-AVEZjb16MlYPifiDDvJ19dPQyDn0jlrtC1PHs6ZKO+Rzyz+2EX2BRdszvanqArldexPoU1p5Bn2w81XZNXThBA==", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.38.0.tgz", + "integrity": "sha512-fP5H9ZX01W4Z/EYctk3mkSHi7d06cLcX2/UWqwdWbyPWI+pL2QpUPICeO/C+8SnmYx//wFj3qWDhyPCh1PdFAA==", "license": "MIT", "engines": { "node": ">=14.18" } }, "node_modules/@sentry/utils": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.35.0.tgz", - "integrity": "sha512-MdMb6+uXjqND7qIPWhulubpSeHzia6HtxeJa8jYI09OCvIcmNGPydv/Gx/LZBwosfMHrLdTWcFH7Y7aCxrq7cg==", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.38.0.tgz", + "integrity": "sha512-3X7MgIKIx+2q5Al7QkhaRB4wV6DvzYsaeIwdqKUzGLuRjXmNgJrLoU87TAwQRmZ6Wr3IoEpThZZMNrzYPXxArw==", "license": "MIT", "dependencies": { - "@sentry/types": "8.35.0" + "@sentry/types": "8.38.0" }, "engines": { "node": ">=14.18" @@ -1944,15 +1958,15 @@ } }, "node_modules/@swc/core": { - "version": "1.7.40", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.7.40.tgz", - "integrity": "sha512-0HIzM5vigVT5IvNum+pPuST9p8xFhN6mhdIKju7qYYeNuZG78lwms/2d8WgjTJJlzp6JlPguXGrMMNzjQw0qNg==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.9.2.tgz", + "integrity": "sha512-dYyEkO6mRYtZFpnOsnYzv9rY69fHAHoawYOjGOEcxk9WYtaJhowMdP/w6NcOKnz2G7GlZaenjkzkMa6ZeQeMsg==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.3", - "@swc/types": "^0.1.13" + "@swc/types": "^0.1.15" }, "engines": { "node": ">=10" @@ -1962,16 +1976,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.7.40", - "@swc/core-darwin-x64": "1.7.40", - "@swc/core-linux-arm-gnueabihf": "1.7.40", - "@swc/core-linux-arm64-gnu": "1.7.40", - "@swc/core-linux-arm64-musl": "1.7.40", - "@swc/core-linux-x64-gnu": "1.7.40", - "@swc/core-linux-x64-musl": "1.7.40", - "@swc/core-win32-arm64-msvc": "1.7.40", - "@swc/core-win32-ia32-msvc": "1.7.40", - "@swc/core-win32-x64-msvc": "1.7.40" + "@swc/core-darwin-arm64": "1.9.2", + "@swc/core-darwin-x64": "1.9.2", + "@swc/core-linux-arm-gnueabihf": "1.9.2", + "@swc/core-linux-arm64-gnu": "1.9.2", + "@swc/core-linux-arm64-musl": "1.9.2", + "@swc/core-linux-x64-gnu": "1.9.2", + "@swc/core-linux-x64-musl": "1.9.2", + "@swc/core-win32-arm64-msvc": "1.9.2", + "@swc/core-win32-ia32-msvc": "1.9.2", + "@swc/core-win32-x64-msvc": "1.9.2" }, "peerDependencies": { "@swc/helpers": "*" @@ -1983,9 +1997,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.7.40", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.40.tgz", - "integrity": "sha512-LRRrCiRJLb1kpQtxMNNsr5W82Inr0dy5Imho+4HQzVx/Ismi0qX4hQBgzJAnyOBNLK1+OBVb/912UVhKXppdfQ==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.9.2.tgz", + "integrity": "sha512-nETmsCoY29krTF2PtspEgicb3tqw7Ci5sInTI03EU5zpqYbPjoPH99BVTjj0OsF53jP5MxwnLI5Hm21lUn1d6A==", "cpu": [ "arm64" ], @@ -2000,9 +2014,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.7.40", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.7.40.tgz", - "integrity": "sha512-Lpl0XK/4fLzS5jsK48opUuGXrqJXwqJckYYPwyGbCfCXm4MsBe+7dX2hq/Kc4YMY25+NeTmzAXhla8TT4WYD/g==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.9.2.tgz", + "integrity": "sha512-9gD+bwBz8ZByjP6nZTXe/hzd0tySIAjpDHgkFiUrc+5zGF+rdTwhcNrzxNHJmy6mw+PW38jqII4uspFHUqqxuQ==", "cpu": [ "x64" ], @@ -2017,9 +2031,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.7.40", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.40.tgz", - "integrity": "sha512-4bEvvjptpoc5BRPr/R419h6fXTEuub+frpxxlxBOEKxgXjAF/S3xdxyPijUAakmW/xXBF0u7OC4KYI+38yQp6g==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.9.2.tgz", + "integrity": "sha512-kYq8ief1Qrn+WmsTWAYo4r+Coul4dXN6cLFjiPZ29Cv5pyU+GFvSPAB4bEdMzwy99rCR0u2P10UExaeCjurjvg==", "cpu": [ "arm" ], @@ -2034,9 +2048,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.7.40", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.40.tgz", - "integrity": "sha512-v2fBlHJ/6Ovz0L2xFAI9TRiKyl9DTdx139PuAHD9gyzp16Utl/W0MPd4t2cYdkI6hPXE9PsJCSzMOrduh+YoDg==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.9.2.tgz", + "integrity": "sha512-n0W4XiXlmEIVqxt+rD3ZpkogsEWUk1jJ+i5bQNgB+1JuWh0fBE8c/blDgTQXa0GB5lTPVDZQussgdNOCnAZwiA==", "cpu": [ "arm64" ], @@ -2051,9 +2065,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.7.40", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.40.tgz", - "integrity": "sha512-uMkduQuU4LFVkW6txv8AVArT8GjJVJ5IHoWloXaUBMT447iE8NALmpePdZWhMyj6KV7j0y23CM5rzV/I2eNGLg==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.9.2.tgz", + "integrity": "sha512-8xzrOmsyCC1zrx2Wzx/h8dVsdewO1oMCwBTLc1gSJ/YllZYTb04pNm6NsVbzUX2tKddJVRgSJXV10j/NECLwpA==", "cpu": [ "arm64" ], @@ -2068,9 +2082,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.7.40", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.40.tgz", - "integrity": "sha512-4LZdY1MBSnXyTpW5fpBU/+JGAhkuHT+VnFTDNegRboN5nSPh7y0Yvn4LmIioESV+sWzjKkEXujJPGjrp+oSp5w==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.9.2.tgz", + "integrity": "sha512-kZrNz/PjRQKcchWF6W292jk3K44EoVu1ad5w+zbS4jekIAxsM8WwQ1kd+yjUlN9jFcF8XBat5NKIs9WphJCVXg==", "cpu": [ "x64" ], @@ -2085,9 +2099,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.7.40", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.40.tgz", - "integrity": "sha512-FPjOwT3SgI6PAwH1O8bhOGBPzuvzOlzKeCtxLaCjruHJu9V8KKBrMTWOZT/FJyYC9mX5Ip1+l9j30UqUZdQxtA==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.9.2.tgz", + "integrity": "sha512-TTIpR4rjMkhX1lnFR+PSXpaL83TrQzp9znRdp2TzYrODlUd/R20zOwSo9vFLCyH6ZoD47bccY7QeGZDYT3nlRg==", "cpu": [ "x64" ], @@ -2102,9 +2116,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.7.40", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.40.tgz", - "integrity": "sha512-//ovXdD9GsTmhPmXJlXnIbRQkeuL6PSrYSr7uCMNcclrUdJG0YkO0GMM2afUKYbdJcunylDDWsSS8PFWn0QxmA==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.9.2.tgz", + "integrity": "sha512-+Eg2d4icItKC0PMjZxH7cSYFLWk0aIp94LNmOw6tPq0e69ax6oh10upeq0D1fjWsKLmOJAWEvnXlayZcijEXDw==", "cpu": [ "arm64" ], @@ -2119,9 +2133,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.7.40", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.40.tgz", - "integrity": "sha512-iD/1auVhHGlhWAPrWmfRWL3w4AvXIWGVXZiSA109/xnRIPiHKb/HqqTp/qB94E/ZHMPRgLKkLTNwamlkueUs8g==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.9.2.tgz", + "integrity": "sha512-nLWBi4vZDdM/LkiQmPCakof8Dh1/t5EM7eudue04V1lIcqx9YHVRS3KMwEaCoHLGg0c312Wm4YgrWQd9vwZ5zQ==", "cpu": [ "ia32" ], @@ -2136,9 +2150,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.7.40", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.40.tgz", - "integrity": "sha512-ZlFAV1WFPhhWQ/8esiygmetkb905XIcMMtHRRG0FBGCllO+HVL5nikUaLDgTClz1onmEY9sMXUFQeoPtvliV+w==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.9.2.tgz", + "integrity": "sha512-ik/k+JjRJBFkXARukdU82tSVx0CbExFQoQ78qTO682esbYXzjdB5eLVkoUbwen299pnfr88Kn4kyIqFPTje8Xw==", "cpu": [ "x64" ], @@ -2160,18 +2174,18 @@ "license": "Apache-2.0" }, "node_modules/@swc/helpers": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz", - "integrity": "sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==", + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.4.0" + "tslib": "^2.8.0" } }, "node_modules/@swc/types": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.13.tgz", - "integrity": "sha512-JL7eeCk6zWCbiYQg2xQSdLXQJl8Qoc9rXmG2cEKvHe3CKwMHwHGpfOb8frzNLmbycOo6I51qxnLnn9ESf4I20Q==", + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.15.tgz", + "integrity": "sha512-XKaZ+dzDIQ9Ot9o89oJQ/aluI17+VvUnIpYJTcZtvv1iYX6MzHh3Ik2CSR7MdPKpPwfZXHBeCingb2b4PoDVdw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2179,12 +2193,12 @@ } }, "node_modules/@tanstack/react-virtual": { - "version": "3.10.8", - "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.10.8.tgz", - "integrity": "sha512-VbzbVGSsZlQktyLrP5nxE+vE1ZR+U0NFAWPbJLoG2+DKPwd2D7dVICTVIIaYlJqX1ZCEnYDbaOpmMwbsyhBoIA==", + "version": "3.10.9", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.10.9.tgz", + "integrity": "sha512-OXO2uBjFqA4Ibr2O3y0YMnkrRWGVNqcvHQXmGvMu6IK8chZl3PrDxFXdGZ2iZkSrKh3/qUYoFqYe+Rx23RoU0g==", "license": "MIT", "dependencies": { - "@tanstack/virtual-core": "3.10.8" + "@tanstack/virtual-core": "3.10.9" }, "funding": { "type": "github", @@ -2196,9 +2210,9 @@ } }, "node_modules/@tanstack/virtual-core": { - "version": "3.10.8", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.10.8.tgz", - "integrity": "sha512-PBu00mtt95jbKFi6Llk9aik8bnR3tR/oQP1o3TSi+iG//+Q2RTIzCEgKkHG8BB86kxMNW6O8wku+Lmi+QFR6jA==", + "version": "3.10.9", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.10.9.tgz", + "integrity": "sha512-kBknKOKzmeR7lN+vSadaKWXaLS0SZZG+oqpQ/k80Q6g9REn6zRHS/ZYdrIzHnpHgy/eWs00SujveUN/GJT2qTw==", "license": "MIT", "funding": { "type": "github", @@ -2206,9 +2220,9 @@ } }, "node_modules/@tauri-apps/api": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.0.3.tgz", - "integrity": "sha512-840qk6n8rbXBXMA5/aAgTYsg5JAubKO0nXw5wf7IzGnUuYKGbB4oFBIZtXOIWy+E0kNTDI3qhq5iqsoMJfwp8g==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.1.1.tgz", + "integrity": "sha512-fzUfFFKo4lknXGJq8qrCidkUcKcH2UHhfaaCNt4GzgzGaW2iS26uFOg4tS3H4P8D6ZEeUxtiD5z0nwFF0UN30A==", "license": "Apache-2.0 OR MIT", "funding": { "type": "opencollective", @@ -2216,9 +2230,9 @@ } }, "node_modules/@tauri-apps/cli": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.0.4.tgz", - "integrity": "sha512-Hl9eFXz+O366+6su9PfaSzu2EJdFe1p8K8ghkWmi40dz8VmSE7vsMTaOStD0I71ckSOkh2ICDX7FQTBgjlpjWw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.1.0.tgz", + "integrity": "sha512-K2VhcKqBhAeS5pNOVdnR/xQRU6jwpgmkSL2ejHXcl0m+kaTggT0WRDQnFtPq6NljA7aE03cvwsbCAoFG7vtkJw==", "dev": true, "license": "Apache-2.0 OR MIT", "bin": { @@ -2232,22 +2246,22 @@ "url": "https://opencollective.com/tauri" }, "optionalDependencies": { - "@tauri-apps/cli-darwin-arm64": "2.0.4", - "@tauri-apps/cli-darwin-x64": "2.0.4", - "@tauri-apps/cli-linux-arm-gnueabihf": "2.0.4", - "@tauri-apps/cli-linux-arm64-gnu": "2.0.4", - "@tauri-apps/cli-linux-arm64-musl": "2.0.4", - "@tauri-apps/cli-linux-x64-gnu": "2.0.4", - "@tauri-apps/cli-linux-x64-musl": "2.0.4", - "@tauri-apps/cli-win32-arm64-msvc": "2.0.4", - "@tauri-apps/cli-win32-ia32-msvc": "2.0.4", - "@tauri-apps/cli-win32-x64-msvc": "2.0.4" + "@tauri-apps/cli-darwin-arm64": "2.1.0", + "@tauri-apps/cli-darwin-x64": "2.1.0", + "@tauri-apps/cli-linux-arm-gnueabihf": "2.1.0", + "@tauri-apps/cli-linux-arm64-gnu": "2.1.0", + "@tauri-apps/cli-linux-arm64-musl": "2.1.0", + "@tauri-apps/cli-linux-x64-gnu": "2.1.0", + "@tauri-apps/cli-linux-x64-musl": "2.1.0", + "@tauri-apps/cli-win32-arm64-msvc": "2.1.0", + "@tauri-apps/cli-win32-ia32-msvc": "2.1.0", + "@tauri-apps/cli-win32-x64-msvc": "2.1.0" } }, "node_modules/@tauri-apps/cli-darwin-arm64": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.0.4.tgz", - "integrity": "sha512-siH7rOHobb16rPbc11k64p1mxIpiRCkWmzs2qmL5IX21Gx9K5onI3Tk67Oqpf2uNupbYzItrOttaDT4NHFC7tw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.1.0.tgz", + "integrity": "sha512-ESc6J6CE8hl1yKH2vJ+ALF+thq4Be+DM1mvmTyUCQObvezNCNhzfS6abIUd3ou4x5RGH51ouiANeT3wekU6dCw==", "cpu": [ "arm64" ], @@ -2262,9 +2276,9 @@ } }, "node_modules/@tauri-apps/cli-darwin-x64": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.0.4.tgz", - "integrity": "sha512-zIccfbCoZMfmUpnk6PFCV0keFyfVj1A9XV3Oiiitj/dkTZ9CQvzjhX3XC0XcK4rsTWegfr2PjSrK06aiPAROAw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.1.0.tgz", + "integrity": "sha512-TasHS442DFs8cSH2eUQzuDBXUST4ECjCd0yyP+zZzvAruiB0Bg+c8A+I/EnqCvBQ2G2yvWLYG8q/LI7c87A5UA==", "cpu": [ "x64" ], @@ -2279,9 +2293,9 @@ } }, "node_modules/@tauri-apps/cli-linux-arm-gnueabihf": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.0.4.tgz", - "integrity": "sha512-fgQqJzefOGWCBNg4yrVA82Rg4s1XQr5K0dc2rCxBhJfa696e8dQ1LDrnWq/AiO5r+uHfVaoQTIUvxxpFicYRSA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.1.0.tgz", + "integrity": "sha512-aP7ZBGNL4ny07Cbb6kKpUOSrmhcIK2KhjviTzYlh+pPhAptxnC78xQGD3zKQkTi2WliJLPmBYbOHWWQa57lQ9w==", "cpu": [ "arm" ], @@ -2296,9 +2310,9 @@ } }, "node_modules/@tauri-apps/cli-linux-arm64-gnu": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.0.4.tgz", - "integrity": "sha512-u8wbt5tPA9pI6j+d7jGrfOz9UVCiTp+IYzKNiIqlrDsAjqAUFaNXYHKqOUboeFWEmI4zoCWj6LgpS2OJTQ5FKg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.1.0.tgz", + "integrity": "sha512-ZTdgD5gLeMCzndMT2f358EkoYkZ5T+Qy6zPzU+l5vv5M7dHVN9ZmblNAYYXmoOuw7y+BY4X/rZvHV9pcGrcanQ==", "cpu": [ "arm64" ], @@ -2313,9 +2327,9 @@ } }, "node_modules/@tauri-apps/cli-linux-arm64-musl": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.0.4.tgz", - "integrity": "sha512-hntF1V8e3V1hlrESm93PsghDhf3lA5pbvFrRfYxU1c+fVD/jRXGVw8BH3O1lW8MWwhEg1YdhKk01oAgsuHLuig==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.1.0.tgz", + "integrity": "sha512-NzwqjUCilhnhJzusz3d/0i0F1GFrwCQbkwR6yAHUxItESbsGYkZRJk0yMEWkg3PzFnyK4cWTlQJMEU52TjhEzA==", "cpu": [ "arm64" ], @@ -2330,9 +2344,9 @@ } }, "node_modules/@tauri-apps/cli-linux-x64-gnu": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.0.4.tgz", - "integrity": "sha512-Iq1GGJb+oT1T0ZV8izrgf0cBtlzPCJaWcNueRbf1ZXquMf+FSTyQv+/Lo8rq5T6buOIJOH7cAOTuEWWqiCZteg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.1.0.tgz", + "integrity": "sha512-TyiIpMEtZxNOQmuFyfJwaaYbg3movSthpBJLIdPlKxSAB2BW0VWLY3/ZfIxm/G2YGHyREkjJvimzYE0i37PnMA==", "cpu": [ "x64" ], @@ -2347,9 +2361,9 @@ } }, "node_modules/@tauri-apps/cli-linux-x64-musl": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.0.4.tgz", - "integrity": "sha512-9NTk6Pf0bSwXqCBdAA+PDYts9HeHebZzIo8mbRzRyUbER6QngG5HZb9Ka36Z1QWtJjdRy6uxSb4zb/9NuTeHfA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.1.0.tgz", + "integrity": "sha512-/dQd0TlaxBdJACrR72DhynWftzHDaX32eBtS5WBrNJ+nnNb+znM3gON6nJ9tSE9jgDa6n1v2BkI/oIDtypfUXw==", "cpu": [ "x64" ], @@ -2364,9 +2378,9 @@ } }, "node_modules/@tauri-apps/cli-win32-arm64-msvc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.0.4.tgz", - "integrity": "sha512-OF2e9oxiBFR8A8wVMOhUx9QGN/I1ZkquWC7gVQBnA56nx9PabJlDT08QBy5UD8USqZFVznnfNr2ehlheQahb3g==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.1.0.tgz", + "integrity": "sha512-NdQJO7SmdYqOcE+JPU7bwg7+odfZMWO6g8xF9SXYCMdUzvM2Gv/AQfikNXz5yS7ralRhNFuW32i5dcHlxh4pDg==", "cpu": [ "arm64" ], @@ -2381,9 +2395,9 @@ } }, "node_modules/@tauri-apps/cli-win32-ia32-msvc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.0.4.tgz", - "integrity": "sha512-T+hCKB3rFP6q0saHHtR02hm6wr1ZPJ0Mkii3oRTxjPG6BBXoVzHNCYzvdgEGJPTA2sFuAQtJH764NRtNlDMifw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.1.0.tgz", + "integrity": "sha512-f5h8gKT/cB8s1ticFRUpNmHqkmaLutT62oFDB7N//2YTXnxst7EpMIn1w+QimxTvTk2gcx6EcW6bEk/y2hZGzg==", "cpu": [ "ia32" ], @@ -2398,9 +2412,9 @@ } }, "node_modules/@tauri-apps/cli-win32-x64-msvc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.0.4.tgz", - "integrity": "sha512-GVaiI3KWRFLomjJmApHqihhYlkJ+7FqhumhVfBO6Z2tWzZjQyVQgTdNp0kYEuW2WoAYEj0dKY6qd4YM33xYcUA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.1.0.tgz", + "integrity": "sha512-P/+LrdSSb5Xbho1LRP4haBjFHdyPdjWvGgeopL96OVtrFpYnfC+RctB45z2V2XxqFk3HweDDxk266btjttfjGw==", "cpu": [ "x64" ], @@ -2529,9 +2543,9 @@ "license": "MIT" }, "node_modules/@types/lodash": { - "version": "4.17.12", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.12.tgz", - "integrity": "sha512-sviUmCE8AYdaF/KIHLDJBQgeYzPBI0vf/17NaYehBJfYD1j6/L95Slh07NlyK2iNyBNaEkb3En2jRt+a8y3xZQ==", + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.13.tgz", + "integrity": "sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==", "dev": true, "license": "MIT" }, @@ -2546,9 +2560,9 @@ } }, "node_modules/@types/node": { - "version": "22.8.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.8.1.tgz", - "integrity": "sha512-k6Gi8Yyo8EtrNtkHXutUu2corfDf9su95VYVP10aGYMMROM6SAItZi0w1XszA6RtWTHSVp5OeFof37w0IEqCQg==", + "version": "22.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", + "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2616,17 +2630,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.11.0.tgz", - "integrity": "sha512-KhGn2LjW1PJT2A/GfDpiyOfS4a8xHQv2myUagTM5+zsormOmBlYsnQ6pobJ8XxJmh6hnHwa2Mbe3fPrDJoDhbA==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.14.0.tgz", + "integrity": "sha512-tqp8H7UWFaZj0yNO6bycd5YjMwxa6wIHOLZvWPkidwbgLCsBMetQoGj7DPuAlWa2yGO3H48xmPwjhsSPPCGU5w==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.11.0", - "@typescript-eslint/type-utils": "8.11.0", - "@typescript-eslint/utils": "8.11.0", - "@typescript-eslint/visitor-keys": "8.11.0", + "@typescript-eslint/scope-manager": "8.14.0", + "@typescript-eslint/type-utils": "8.14.0", + "@typescript-eslint/utils": "8.14.0", + "@typescript-eslint/visitor-keys": "8.14.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -2650,16 +2664,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.11.0.tgz", - "integrity": "sha512-lmt73NeHdy1Q/2ul295Qy3uninSqi6wQI18XwSpm8w0ZbQXUpjCAWP1Vlv/obudoBiIjJVjlztjQ+d/Md98Yxg==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.14.0.tgz", + "integrity": "sha512-2p82Yn9juUJq0XynBXtFCyrBDb6/dJombnz6vbo6mgQEtWHfvHbQuEa9kAOVIt1c9YFwi7H6WxtPj1kg+80+RA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "8.11.0", - "@typescript-eslint/types": "8.11.0", - "@typescript-eslint/typescript-estree": "8.11.0", - "@typescript-eslint/visitor-keys": "8.11.0", + "@typescript-eslint/scope-manager": "8.14.0", + "@typescript-eslint/types": "8.14.0", + "@typescript-eslint/typescript-estree": "8.14.0", + "@typescript-eslint/visitor-keys": "8.14.0", "debug": "^4.3.4" }, "engines": { @@ -2679,14 +2693,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.11.0.tgz", - "integrity": "sha512-Uholz7tWhXmA4r6epo+vaeV7yjdKy5QFCERMjs1kMVsLRKIrSdM6o21W2He9ftp5PP6aWOVpD5zvrvuHZC0bMQ==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.14.0.tgz", + "integrity": "sha512-aBbBrnW9ARIDn92Zbo7rguLnqQ/pOrUguVpbUwzOhkFg2npFDwTgPGqFqE0H5feXcOoJOfX3SxlJaKEVtq54dw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.11.0", - "@typescript-eslint/visitor-keys": "8.11.0" + "@typescript-eslint/types": "8.14.0", + "@typescript-eslint/visitor-keys": "8.14.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2697,14 +2711,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.11.0.tgz", - "integrity": "sha512-ItiMfJS6pQU0NIKAaybBKkuVzo6IdnAhPFZA/2Mba/uBjuPQPet/8+zh5GtLHwmuFRShZx+8lhIs7/QeDHflOg==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.14.0.tgz", + "integrity": "sha512-Xcz9qOtZuGusVOH5Uk07NGs39wrKkf3AxlkK79RBK6aJC1l03CobXjJbwBPSidetAOV+5rEVuiT1VSBUOAsanQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.11.0", - "@typescript-eslint/utils": "8.11.0", + "@typescript-eslint/typescript-estree": "8.14.0", + "@typescript-eslint/utils": "8.14.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -2722,9 +2736,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.11.0.tgz", - "integrity": "sha512-tn6sNMHf6EBAYMvmPUaKaVeYvhUsrE6x+bXQTxjQRp360h1giATU0WvgeEys1spbvb5R+VpNOZ+XJmjD8wOUHw==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.14.0.tgz", + "integrity": "sha512-yjeB9fnO/opvLJFAsPNYlKPnEM8+z4og09Pk504dkqonT02AyL5Z9SSqlE0XqezS93v6CXn49VHvB2G7XSsl0g==", "dev": true, "license": "MIT", "engines": { @@ -2736,14 +2750,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.11.0.tgz", - "integrity": "sha512-yHC3s1z1RCHoCz5t06gf7jH24rr3vns08XXhfEqzYpd6Hll3z/3g23JRi0jM8A47UFKNc3u/y5KIMx8Ynbjohg==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.14.0.tgz", + "integrity": "sha512-OPXPLYKGZi9XS/49rdaCbR5j/S14HazviBlUQFvSKz3npr3NikF+mrgK7CFVur6XEt95DZp/cmke9d5i3vtVnQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "8.11.0", - "@typescript-eslint/visitor-keys": "8.11.0", + "@typescript-eslint/types": "8.14.0", + "@typescript-eslint/visitor-keys": "8.14.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -2804,16 +2818,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.11.0.tgz", - "integrity": "sha512-CYiX6WZcbXNJV7UNB4PLDIBtSdRmRI/nb0FMyqHPTQD1rMjA0foPLaPUV39C/MxkTd/QKSeX+Gb34PPsDVC35g==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.14.0.tgz", + "integrity": "sha512-OGqj6uB8THhrHj0Fk27DcHPojW7zKwKkPmHXHvQ58pLYp4hy8CSUdTKykKeh+5vFqTTVmjz0zCOOPKRovdsgHA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.11.0", - "@typescript-eslint/types": "8.11.0", - "@typescript-eslint/typescript-estree": "8.11.0" + "@typescript-eslint/scope-manager": "8.14.0", + "@typescript-eslint/types": "8.14.0", + "@typescript-eslint/typescript-estree": "8.14.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2827,13 +2841,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.11.0.tgz", - "integrity": "sha512-EaewX6lxSjRJnc+99+dqzTeoDZUfyrA52d2/HRrkI830kgovWsmIiTfmr0NZorzqic7ga+1bS60lRBUgR3n/Bw==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.14.0.tgz", + "integrity": "sha512-vG0XZo8AdTH9OE6VFRwAZldNc7qtJ/6NLGWak+BtENuEUXGZgFpihILPiBvKXvJ2nFu27XNGC6rKiwuaoMbYzQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.11.0", + "@typescript-eslint/types": "8.14.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -3296,9 +3310,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001673", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001673.tgz", - "integrity": "sha512-WTrjUCSMp3LYX0nE12ECkV0a+e6LC85E0Auz75555/qr78Oc8YWhEPNfDd6SHdtlCMSzqtuXY0uyEMNRcsKpKw==", + "version": "1.0.30001680", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz", + "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==", "dev": true, "funding": [ { @@ -3481,9 +3495,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.5.tgz", + "integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", "dev": true, "license": "MIT", "dependencies": { @@ -3682,9 +3696,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.47", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.47.tgz", - "integrity": "sha512-zS5Yer0MOYw4rtK2iq43cJagHZ8sXN0jDHDKzB+86gSBSAI4v07S97mcq+Gs2vclAxSh1j7vOAHxSVgduiiuVQ==", + "version": "1.5.57", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.57.tgz", + "integrity": "sha512-xS65H/tqgOwUBa5UmOuNSLuslDo7zho0y/lgQw35pnrqiZh7UOWHCeL/Bt6noJATbA6tpQJGCifsFsIRZj1Fqg==", "dev": true, "license": "ISC" }, @@ -3719,9 +3733,9 @@ } }, "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "version": "1.23.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.4.tgz", + "integrity": "sha512-HR1gxH5OaiN7XH7uiWH0RLw0RcFySiSoW1ctxmD1ahTw3uGBtkmm/ng0tDU1OtYx5OK6EOL5Y6O21cDflG3Jcg==", "dev": true, "license": "MIT", "dependencies": { @@ -3740,7 +3754,7 @@ "function.prototype.name": "^1.1.6", "get-intrinsic": "^1.2.4", "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", + "globalthis": "^1.0.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2", "has-proto": "^1.0.3", @@ -3756,10 +3770,10 @@ "is-string": "^1.0.7", "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", + "object-inspect": "^1.13.3", "object-keys": "^1.1.1", "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", + "regexp.prototype.flags": "^1.5.3", "safe-array-concat": "^1.1.2", "safe-regex-test": "^1.0.3", "string.prototype.trim": "^1.2.9", @@ -3803,9 +3817,9 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.1.0.tgz", - "integrity": "sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.0.tgz", + "integrity": "sha512-tpxqxncxnpw3c93u8n3VOzACmRFoVmWJqbWXvX/JfKbkhBw1oslgPrUfeSt2psuqyEJFD6N/9lg5i7bsKpoq+Q==", "dev": true, "license": "MIT", "dependencies": { @@ -3817,6 +3831,7 @@ "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "globalthis": "^1.0.4", + "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2", "has-proto": "^1.0.3", "has-symbols": "^1.0.3", @@ -3947,22 +3962,22 @@ } }, "node_modules/eslint": { - "version": "9.13.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.13.0.tgz", - "integrity": "sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==", + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.14.0.tgz", + "integrity": "sha512-c2FHsVBr87lnUtjP4Yhvk4yEhKrQavGafRA/Se1ouse8PfbfC/Qh9Mxa00yWsZRlqeUB9raXip0aiiUZkgnr9g==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.11.0", + "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.18.0", "@eslint/core": "^0.7.0", "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.13.0", + "@eslint/js": "9.14.0", "@eslint/plugin-kit": "^0.2.0", - "@humanfs/node": "^0.16.5", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.1", + "@humanwhocodes/retry": "^0.4.0", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", @@ -3970,9 +3985,9 @@ "cross-spawn": "^7.0.2", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.1.0", - "eslint-visitor-keys": "^4.1.0", - "espree": "^10.2.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -4067,9 +4082,9 @@ } }, "node_modules/eslint-scope": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz", - "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -4084,9 +4099,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", - "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, "license": "Apache-2.0", "engines": { @@ -4097,15 +4112,15 @@ } }, "node_modules/espree": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.2.0.tgz", - "integrity": "sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.12.0", + "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.1.0" + "eslint-visitor-keys": "^4.2.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4334,9 +4349,9 @@ } }, "node_modules/framer-motion": { - "version": "11.11.10", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.11.10.tgz", - "integrity": "sha512-061Bt1jL/vIm+diYIiA4dP/Yld7vD47ROextS7ESBW5hr4wQFhxB5D5T5zAc3c/5me3cOa+iO5LqhA38WDln/A==", + "version": "11.11.15", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.11.15.tgz", + "integrity": "sha512-fib+OpUe4nap4W1vhaDohnPU+42B5s1q+jNkNkb6TfzmDYtRhDyvn4mkRCAD5a2cQKOI3nJZP7yqGYtxnlmleg==", "license": "MIT", "dependencies": { "tslib": "^2.4.0" @@ -4521,9 +4536,9 @@ } }, "node_modules/globals": { - "version": "15.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.11.0.tgz", - "integrity": "sha512-yeyNSjdbyVaWurlwCpcA6XNBrHTMIeDdj0/hnvX/OLJ9ekOXYbLsLinH/MucQyGvNnXhidTdNhTtJaffL2sMfw==", + "version": "15.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.12.0.tgz", + "integrity": "sha512-1+gLErljJFhbOVyaetcwJiJ4+eLe45S2E7P5UiZ9xGfeq3ATQf5DOv9G7MH3gGbKQLkzmNh2DxfZwLdw+j6oTQ==", "dev": true, "license": "MIT", "engines": { @@ -4697,9 +4712,9 @@ } }, "node_modules/i18next": { - "version": "23.16.4", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.16.4.tgz", - "integrity": "sha512-9NIYBVy9cs4wIqzurf7nLXPyf3R78xYbxExVqHLK9od3038rjpyOEzW+XB130kZ1N4PZ9inTtJ471CRJ4Ituyg==", + "version": "23.16.5", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.16.5.tgz", + "integrity": "sha512-KTlhE3EP9x6pPTAW7dy0WKIhoCpfOGhRQlO+jttQLgzVaoOjWwBWramu7Pp0i+8wDNduuzXfe3kkVbzrKyrbTA==", "funding": [ { "type": "individual", @@ -5843,9 +5858,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", "dev": true, "license": "MIT", "engines": { @@ -6151,9 +6166,9 @@ } }, "node_modules/postcss": { - "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", "dev": true, "funding": [ { @@ -6172,7 +6187,7 @@ "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.1.0", + "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, "engines": { @@ -6431,9 +6446,9 @@ } }, "node_modules/react-i18next": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.1.0.tgz", - "integrity": "sha512-zj3nJynMnZsy2gPZiOTC7XctCY5eQGqT3tcKMmfJWC9FMvgd+960w/adq61j8iPzpwmsXejqID9qC3Mqu1Xu2Q==", + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.1.1.tgz", + "integrity": "sha512-R/Vg9wIli2P3FfeI8o1eNJUJue5LWpFsQePCHdQDmX0Co3zkr6kdT8gAseb/yGeWbNz1Txc4bKDQuZYsC0kQfw==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.0", @@ -6459,12 +6474,12 @@ "license": "MIT" }, "node_modules/react-router": { - "version": "6.27.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.27.0.tgz", - "integrity": "sha512-YA+HGZXz4jaAkVoYBE98VQl+nVzI+cVI2Oj/06F5ZM+0u3TgedN9Y9kmMRo2mnkSK2nCpNQn0DVob4HCsY/WLw==", + "version": "6.28.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.28.0.tgz", + "integrity": "sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg==", "license": "MIT", "dependencies": { - "@remix-run/router": "1.20.0" + "@remix-run/router": "1.21.0" }, "engines": { "node": ">=14.0.0" @@ -6474,13 +6489,13 @@ } }, "node_modules/react-router-dom": { - "version": "6.27.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.27.0.tgz", - "integrity": "sha512-+bvtFWMC0DgAFrfKXKG9Fc+BcXWRUO1aJIihbB79xaeq0v5UzfvnM5houGUm1Y461WVRcgAQ+Clh5rdb1eCx4g==", + "version": "6.28.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.28.0.tgz", + "integrity": "sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg==", "license": "MIT", "dependencies": { - "@remix-run/router": "1.20.0", - "react-router": "6.27.0" + "@remix-run/router": "1.21.0", + "react-router": "6.28.0" }, "engines": { "node": ">=14.0.0" @@ -6642,9 +6657,9 @@ } }, "node_modules/rollup": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.2.tgz", - "integrity": "sha512-do/DFGq5g6rdDhdpPq5qb2ecoczeK6y+2UAjdJ5trjQJj5f1AiVdLRWRc9A9/fFukfvJRgM0UXzxBIYMovm5ww==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.26.0.tgz", + "integrity": "sha512-ilcl12hnWonG8f+NxU6BlgysVA0gvY2l8N0R84S1HcINbW20bvwuCngJkkInV6LXhwRpucsW5k1ovDwEdBVrNg==", "dev": true, "license": "MIT", "dependencies": { @@ -6658,24 +6673,24 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.24.2", - "@rollup/rollup-android-arm64": "4.24.2", - "@rollup/rollup-darwin-arm64": "4.24.2", - "@rollup/rollup-darwin-x64": "4.24.2", - "@rollup/rollup-freebsd-arm64": "4.24.2", - "@rollup/rollup-freebsd-x64": "4.24.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.24.2", - "@rollup/rollup-linux-arm-musleabihf": "4.24.2", - "@rollup/rollup-linux-arm64-gnu": "4.24.2", - "@rollup/rollup-linux-arm64-musl": "4.24.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.24.2", - "@rollup/rollup-linux-riscv64-gnu": "4.24.2", - "@rollup/rollup-linux-s390x-gnu": "4.24.2", - "@rollup/rollup-linux-x64-gnu": "4.24.2", - "@rollup/rollup-linux-x64-musl": "4.24.2", - "@rollup/rollup-win32-arm64-msvc": "4.24.2", - "@rollup/rollup-win32-ia32-msvc": "4.24.2", - "@rollup/rollup-win32-x64-msvc": "4.24.2", + "@rollup/rollup-android-arm-eabi": "4.26.0", + "@rollup/rollup-android-arm64": "4.26.0", + "@rollup/rollup-darwin-arm64": "4.26.0", + "@rollup/rollup-darwin-x64": "4.26.0", + "@rollup/rollup-freebsd-arm64": "4.26.0", + "@rollup/rollup-freebsd-x64": "4.26.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.26.0", + "@rollup/rollup-linux-arm-musleabihf": "4.26.0", + "@rollup/rollup-linux-arm64-gnu": "4.26.0", + "@rollup/rollup-linux-arm64-musl": "4.26.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.26.0", + "@rollup/rollup-linux-riscv64-gnu": "4.26.0", + "@rollup/rollup-linux-s390x-gnu": "4.26.0", + "@rollup/rollup-linux-x64-gnu": "4.26.0", + "@rollup/rollup-linux-x64-musl": "4.26.0", + "@rollup/rollup-win32-arm64-msvc": "4.26.0", + "@rollup/rollup-win32-ia32-msvc": "4.26.0", + "@rollup/rollup-win32-x64-msvc": "4.26.0", "fsevents": "~2.3.2" } }, @@ -7331,9 +7346,9 @@ } }, "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.0.tgz", + "integrity": "sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==", "dev": true, "license": "MIT", "engines": { @@ -7351,9 +7366,9 @@ "license": "Apache-2.0" }, "node_modules/tslib": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", - "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, "node_modules/type-check": { @@ -7461,15 +7476,15 @@ } }, "node_modules/typescript-eslint": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.11.0.tgz", - "integrity": "sha512-cBRGnW3FSlxaYwU8KfAewxFK5uzeOAp0l2KebIlPDOT5olVi65KDG/yjBooPBG0kGW/HLkoz1c/iuBFehcS3IA==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.14.0.tgz", + "integrity": "sha512-K8fBJHxVL3kxMmwByvz8hNdBJ8a0YqKzKDX6jRlrjMuNXyd5T2V02HIq37+OiWXvUUOXgOOGiSSOh26Mh8pC3w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.11.0", - "@typescript-eslint/parser": "8.11.0", - "@typescript-eslint/utils": "8.11.0" + "@typescript-eslint/eslint-plugin": "8.14.0", + "@typescript-eslint/parser": "8.14.0", + "@typescript-eslint/utils": "8.14.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7567,9 +7582,9 @@ } }, "node_modules/vite": { - "version": "5.4.10", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz", - "integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==", + "version": "5.4.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", + "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", "dev": true, "license": "MIT", "dependencies": { @@ -7627,18 +7642,18 @@ } }, "node_modules/vite-plugin-svgr": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-4.2.0.tgz", - "integrity": "sha512-SC7+FfVtNQk7So0XMjrrtLAbEC8qjFPifyD7+fs/E6aaNdVde6umlVVh0QuwDLdOMu7vp5RiGFsB70nj5yo0XA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-4.3.0.tgz", + "integrity": "sha512-Jy9qLB2/PyWklpYy0xk0UU3TlU0t2UMpJXZvf+hWII1lAmRHrOUKi11Uw8N3rxoNk7atZNYO3pR3vI1f7oi+6w==", "dev": true, "license": "MIT", "dependencies": { - "@rollup/pluginutils": "^5.0.5", + "@rollup/pluginutils": "^5.1.3", "@svgr/core": "^8.1.0", "@svgr/plugin-jsx": "^8.1.0" }, "peerDependencies": { - "vite": "^2.6.0 || 3 || 4 || 5" + "vite": ">=2.6.0" } }, "node_modules/void-elements": { diff --git a/nym-vpn-app/src-tauri/Cargo.lock b/nym-vpn-app/src-tauri/Cargo.lock index 3f1f131ef6..c28ca0152d 100644 --- a/nym-vpn-app/src-tauri/Cargo.lock +++ b/nym-vpn-app/src-tauri/Cargo.lock @@ -32,12 +32,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "aligned-vec" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" - [[package]] name = "alloc-no-stdlib" version = "2.0.4" @@ -150,23 +144,6 @@ dependencies = [ "x11rb", ] -[[package]] -name = "arg_enum_proc_macro" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "arrayvec" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" - [[package]] name = "ashpd" version = "0.9.1" @@ -294,7 +271,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -334,7 +311,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -351,7 +328,7 @@ checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -389,29 +366,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" -[[package]] -name = "av1-grain" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" -dependencies = [ - "anyhow", - "arrayvec", - "log", - "nom", - "num-rational", - "v_frame", -] - -[[package]] -name = "avif-serialize" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2" -dependencies = [ - "arrayvec", -] - [[package]] name = "axum" version = "0.6.20" @@ -493,12 +447,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bit_field" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" - [[package]] name = "bitflags" version = "1.3.2" @@ -514,12 +462,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bitstream-io" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b81e1519b0d82120d2fd469d5bfb2919a9361c48b02d82d04befc1cdd2002452" - [[package]] name = "block" version = "0.1.6" @@ -559,9 +501,9 @@ dependencies = [ [[package]] name = "brotli" -version = "6.0.0" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" +checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -647,16 +589,10 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.77", + "syn 2.0.87", "zstd", ] -[[package]] -name = "built" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "236e6289eda5a812bc6b53c3b024039382a2895fbbeef2d748b2931546d392c4" - [[package]] name = "bumpalo" version = "3.16.0" @@ -701,7 +637,7 @@ dependencies = [ "glib", "libc", "once_cell", - "thiserror", + "thiserror 1.0.64", ] [[package]] @@ -744,7 +680,7 @@ dependencies = [ "semver", "serde", "serde_json", - "thiserror", + "thiserror 1.0.64", ] [[package]] @@ -853,7 +789,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -901,12 +837,6 @@ dependencies = [ "objc", ] -[[package]] -name = "color_quant" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" - [[package]] name = "colorchoice" version = "1.0.2" @@ -938,6 +868,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "time", + "version_check", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -1039,16 +979,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "crossbeam-deque" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - [[package]] name = "crossbeam-epoch" version = "0.9.18" @@ -1064,12 +994,6 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - [[package]] name = "crypto-common" version = "0.1.6" @@ -1104,7 +1028,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -1135,7 +1059,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" dependencies = [ "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -1159,7 +1083,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -1170,7 +1094,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -1191,7 +1115,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -1204,7 +1128,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -1224,7 +1148,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", "unicode-xid", ] @@ -1300,7 +1224,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -1332,7 +1256,7 @@ checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -1448,7 +1372,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -1504,22 +1428,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "exr" -version = "1.72.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" -dependencies = [ - "bit_field", - "flume", - "half", - "lebe", - "miniz_oxide 0.7.4", - "rayon-core", - "smallvec", - "zune-inflate", -] - [[package]] name = "fastrand" version = "2.1.1" @@ -1573,24 +1481,6 @@ dependencies = [ "miniz_oxide 0.8.0", ] -[[package]] -name = "fluent-uri" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17c704e9dbe1ddd863da1e6ff3567795087b1eb201ce80d8fa81162e1516500d" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "flume" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" -dependencies = [ - "spin", -] - [[package]] name = "fnv" version = "1.0.7" @@ -1615,7 +1505,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -1722,7 +1612,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -1915,16 +1805,6 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] -[[package]] -name = "gif" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" -dependencies = [ - "color_quant", - "weezl", -] - [[package]] name = "gimli" version = "0.29.0" @@ -1947,7 +1827,7 @@ dependencies = [ "once_cell", "pin-project-lite", "smallvec", - "thiserror", + "thiserror 1.0.64", ] [[package]] @@ -1996,7 +1876,7 @@ dependencies = [ "memchr", "once_cell", "smallvec", - "thiserror", + "thiserror 1.0.64", ] [[package]] @@ -2010,7 +1890,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -2089,7 +1969,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -2111,16 +1991,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "half" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" -dependencies = [ - "cfg-if", - "crunchy", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -2395,37 +2265,11 @@ checksum = "99314c8a2152b8ddb211f924cdae532d8c5e4c8bb54728e12fff1b0cd5963a10" dependencies = [ "bytemuck", "byteorder-lite", - "color_quant", - "exr", - "gif", - "image-webp", "num-traits", "png", - "qoi", - "ravif", - "rayon", - "rgb", "tiff", - "zune-core", - "zune-jpeg", ] -[[package]] -name = "image-webp" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f79afb8cbee2ef20f59ccd477a218c12a93943d075b492015ecb1bb81f8ee904" -dependencies = [ - "byteorder-lite", - "quick-error", -] - -[[package]] -name = "imgref" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126" - [[package]] name = "indexmap" version = "1.9.3" @@ -2466,17 +2310,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "interpolate_name" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - [[package]] name = "ipnet" version = "2.10.0" @@ -2583,7 +2416,7 @@ dependencies = [ "combine", "jni-sys", "log", - "thiserror", + "thiserror 1.0.64", "walkdir", "windows-sys 0.45.0", ] @@ -2620,23 +2453,22 @@ dependencies = [ [[package]] name = "json-patch" -version = "2.0.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b1fb8864823fad91877e6caea0baca82e49e8db50f8e5c9f9a453e27d3330fc" +checksum = "863726d7afb6bc2590eeff7135d923545e5e964f004c2ccf8716c25e70a86f08" dependencies = [ "jsonptr", "serde", "serde_json", - "thiserror", + "thiserror 1.0.64", ] [[package]] name = "jsonptr" -version = "0.4.7" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c6e529149475ca0b2820835d3dce8fcc41c6b943ca608d32f35b449255e4627" +checksum = "5dea2b27dd239b2556ed7a25ba842fe47fd602e7fc7433c2a8d6106d4d9edd70" dependencies = [ - "fluent-uri", "serde", "serde_json", ] @@ -2671,12 +2503,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -[[package]] -name = "lebe" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" - [[package]] name = "libappindicator" version = "0.9.0" @@ -2707,17 +2533,6 @@ version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" -[[package]] -name = "libfuzzer-sys" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" -dependencies = [ - "arbitrary", - "cc", - "once_cell", -] - [[package]] name = "libgit2-sys" version = "0.17.0+1.8.1" @@ -2785,15 +2600,6 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" -[[package]] -name = "loop9" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" -dependencies = [ - "imgref", -] - [[package]] name = "mac" version = "0.1.1" @@ -2857,15 +2663,6 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" -[[package]] -name = "maybe-rayon" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" -dependencies = [ - "cfg-if", -] - [[package]] name = "memchr" version = "2.7.4" @@ -2887,12 +2684,6 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "minisign-verify" version = "0.2.2" @@ -2946,7 +2737,7 @@ dependencies = [ "once_cell", "png", "serde", - "thiserror", + "thiserror 1.0.64", "windows-sys 0.59.0", ] @@ -2968,7 +2759,7 @@ dependencies = [ "ndk-sys", "num_enum", "raw-window-handle", - "thiserror", + "thiserror 1.0.64", ] [[package]] @@ -3011,22 +2802,6 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "noop_proc_macro" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" - [[package]] name = "notify-rust" version = "4.11.1" @@ -3066,17 +2841,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" -[[package]] -name = "num-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - [[package]] name = "num-integer" version = "0.1.46" @@ -3086,17 +2850,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-rational" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -3124,7 +2877,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -3158,7 +2911,7 @@ dependencies = [ "tauri-plugin-single-instance", "tauri-plugin-updater", "tauri-plugin-window-state", - "thiserror", + "thiserror 2.0.3", "time", "tokio", "toml 0.8.19", @@ -3173,7 +2926,7 @@ dependencies = [ [[package]] name = "nym-vpn-proto" -version = "1.0.0-dev" +version = "1.0.0-rc.3" dependencies = [ "prost", "prost-types", @@ -3592,12 +3345,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - [[package]] name = "pathdiff" version = "0.2.1" @@ -3724,7 +3471,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -3771,7 +3518,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -3882,7 +3629,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" dependencies = [ "proc-macro2", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -3970,7 +3717,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -3988,25 +3735,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "profiling" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" -dependencies = [ - "profiling-procmacros", -] - -[[package]] -name = "profiling-procmacros" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" -dependencies = [ - "quote", - "syn 2.0.77", -] - [[package]] name = "prost" version = "0.12.6" @@ -4024,7 +3752,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ "bytes", - "heck 0.4.1", + "heck 0.5.0", "itertools 0.12.1", "log", "multimap", @@ -4034,7 +3762,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.77", + "syn 2.0.87", "tempfile", ] @@ -4048,7 +3776,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -4060,21 +3788,6 @@ dependencies = [ "prost", ] -[[package]] -name = "qoi" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" -dependencies = [ - "bytemuck", -] - -[[package]] -name = "quick-error" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" - [[package]] name = "quick-xml" version = "0.31.0" @@ -4115,7 +3828,7 @@ dependencies = [ "rustc-hash", "rustls", "socket2", - "thiserror", + "thiserror 1.0.64", "tokio", "tracing", ] @@ -4132,7 +3845,7 @@ dependencies = [ "rustc-hash", "rustls", "slab", - "thiserror", + "thiserror 1.0.64", "tinyvec", "tracing", ] @@ -4240,81 +3953,12 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "rav1e" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" -dependencies = [ - "arbitrary", - "arg_enum_proc_macro", - "arrayvec", - "av1-grain", - "bitstream-io", - "built", - "cfg-if", - "interpolate_name", - "itertools 0.12.1", - "libc", - "libfuzzer-sys", - "log", - "maybe-rayon", - "new_debug_unreachable", - "noop_proc_macro", - "num-derive", - "num-traits", - "once_cell", - "paste", - "profiling", - "rand 0.8.5", - "rand_chacha 0.3.1", - "simd_helpers", - "system-deps", - "thiserror", - "v_frame", - "wasm-bindgen", -] - -[[package]] -name = "ravif" -version = "0.11.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f0bfd976333248de2078d350bfdf182ff96e168a24d23d2436cef320dd4bdd" -dependencies = [ - "avif-serialize", - "imgref", - "loop9", - "quick-error", - "rav1e", - "rgb", -] - [[package]] name = "raw-window-handle" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" -[[package]] -name = "rayon" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - [[package]] name = "redox_syscall" version = "0.2.16" @@ -4341,7 +3985,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom 0.2.15", "libredox", - "thiserror", + "thiserror 1.0.64", ] [[package]] @@ -4455,15 +4099,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "rgb" -version = "0.8.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" -dependencies = [ - "bytemuck", -] - [[package]] name = "ring" version = "0.17.8" @@ -4611,7 +4246,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -4683,7 +4318,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -4694,7 +4329,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -4717,7 +4352,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -4768,7 +4403,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -4865,15 +4500,6 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" -[[package]] -name = "simd_helpers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" -dependencies = [ - "quote", -] - [[package]] name = "siphasher" version = "0.3.11" @@ -4974,9 +4600,6 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] [[package]] name = "stable_deref_trait" @@ -5041,7 +4664,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -5074,9 +4697,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.77" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -5122,9 +4745,9 @@ dependencies = [ [[package]] name = "tao" -version = "0.30.3" +version = "0.30.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0dbbebe82d02044dfa481adca1550d6dd7bd16e086bc34fa0fbecceb5a63751" +checksum = "6682a07cf5bab0b8a2bd20d0a542917ab928b5edb75ebd4eda6b05cbaab872da" dependencies = [ "bitflags 2.6.0", "cocoa", @@ -5167,7 +4790,7 @@ checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -5189,9 +4812,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tauri" -version = "2.0.4" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44438500b50708bfc1e6083844e135d1b516325aae58710dcd8fb67e050ae87c" +checksum = "e545de0a2dfe296fa67db208266cd397c5a55ae782da77973ef4c4fac90e9f2c" dependencies = [ "anyhow", "bytes", @@ -5227,7 +4850,7 @@ dependencies = [ "tauri-runtime", "tauri-runtime-wry", "tauri-utils", - "thiserror", + "thiserror 2.0.3", "tokio", "tray-icon", "url", @@ -5240,9 +4863,9 @@ dependencies = [ [[package]] name = "tauri-build" -version = "2.0.1" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "935f9b3c49b22b3e2e485a57f46d61cd1ae07b1cbb2ba87387a387caf2d8c4e7" +checksum = "7bd2a4bcfaf5fb9f4be72520eefcb61ae565038f8ccba2a497d8c28f463b8c01" dependencies = [ "anyhow", "cargo_toml", @@ -5262,9 +4885,9 @@ dependencies = [ [[package]] name = "tauri-codegen" -version = "2.0.1" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95d7443dd4f0b597704b6a14b964ee2ed16e99928d8e6292ae9825f09fbcd30e" +checksum = "bf79faeecf301d3e969b1fae977039edb77a4c1f25cc0a961be298b54bff97cf" dependencies = [ "base64 0.22.1", "brotli", @@ -5278,9 +4901,9 @@ dependencies = [ "serde", "serde_json", "sha2", - "syn 2.0.77", + "syn 2.0.87", "tauri-utils", - "thiserror", + "thiserror 2.0.3", "time", "url", "uuid", @@ -5289,14 +4912,14 @@ dependencies = [ [[package]] name = "tauri-macros" -version = "2.0.1" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d2c0963ccfc3f5194415f2cce7acc975942a8797fbabfb0aa1ed6f59326ae7f" +checksum = "c52027c8c5afb83166dacddc092ee8fff50772f9646d461d8c33ee887e447a03" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", "tauri-codegen", "tauri-utils", ] @@ -5320,25 +4943,24 @@ dependencies = [ [[package]] name = "tauri-plugin-clipboard-manager" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b7d556886c15849198c0948fd7f4c880492f0461539176da0a8a70272e2904" +checksum = "2a66feaa0fb7fce8e5073323d11ca381c9da7ac06f458e42b9ff77364b76a360" dependencies = [ "arboard", - "image", "log", "serde", "serde_json", "tauri", "tauri-plugin", - "thiserror", + "thiserror 1.0.64", ] [[package]] name = "tauri-plugin-dialog" -version = "2.0.1" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddb2fe88b602461c118722c574e2775ab26a4e68886680583874b2f6520608b7" +checksum = "4307310e1d2c09ab110235834722e7c2b85099b683e1eb7342ab351b0be5ada3" dependencies = [ "log", "raw-window-handle", @@ -5348,15 +4970,15 @@ dependencies = [ "tauri", "tauri-plugin", "tauri-plugin-fs", - "thiserror", + "thiserror 1.0.64", "url", ] [[package]] name = "tauri-plugin-fs" -version = "2.0.1" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab300488ebec3487ca5f56289692e7e45feb07eea8d5e1dba497f7dc9dd9c407" +checksum = "96ba7d46e86db8c830d143ef90ab5a453328365b0cc834c24edea4267b16aba0" dependencies = [ "anyhow", "dunce", @@ -5368,7 +4990,7 @@ dependencies = [ "serde_repr", "tauri", "tauri-plugin", - "thiserror", + "thiserror 1.0.64", "url", "uuid", ] @@ -5387,7 +5009,7 @@ dependencies = [ "serde_repr", "tauri", "tauri-plugin", - "thiserror", + "thiserror 1.0.64", "time", "url", ] @@ -5407,7 +5029,7 @@ dependencies = [ "sys-locale", "tauri", "tauri-plugin", - "thiserror", + "thiserror 1.0.64", ] [[package]] @@ -5422,9 +5044,9 @@ dependencies = [ [[package]] name = "tauri-plugin-shell" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "371fb9aca2823990a2d0db7970573be5fdf07881fcaa2b835b29631feb84aec1" +checksum = "0ad7880c5586b6b2104be451e3d7fc0f3800c84bda69e9ba81c828f87cb34267" dependencies = [ "encoding_rs", "log", @@ -5437,7 +5059,7 @@ dependencies = [ "shared_child", "tauri", "tauri-plugin", - "thiserror", + "thiserror 1.0.64", "tokio", ] @@ -5451,7 +5073,7 @@ dependencies = [ "serde", "serde_json", "tauri", - "thiserror", + "thiserror 1.0.64", "windows-sys 0.59.0", "zbus", ] @@ -5478,7 +5100,7 @@ dependencies = [ "tauri", "tauri-plugin", "tempfile", - "thiserror", + "thiserror 1.0.64", "time", "tokio", "url", @@ -5488,9 +5110,9 @@ dependencies = [ [[package]] name = "tauri-plugin-window-state" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd1cef203a15b4772898e7bc8e57c1f34696e39848987dfcd294d51ba0525650" +checksum = "683c8764751fbbcebf3a594bcee24cf84c62773fa0080d1b40fc80698472421e" dependencies = [ "bitflags 2.6.0", "log", @@ -5498,14 +5120,14 @@ dependencies = [ "serde_json", "tauri", "tauri-plugin", - "thiserror", + "thiserror 1.0.64", ] [[package]] name = "tauri-runtime" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8f437293d6f5e5dce829250f4dbdce4e0b52905e297a6689cc2963eb53ac728" +checksum = "cce18d43f80d4aba3aa8a0c953bbe835f3d0f2370aca75e8dbb14bd4bab27958" dependencies = [ "dpi", "gtk", @@ -5515,16 +5137,16 @@ dependencies = [ "serde", "serde_json", "tauri-utils", - "thiserror", + "thiserror 2.0.3", "url", "windows 0.58.0", ] [[package]] name = "tauri-runtime-wry" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1431602bcc71f2f840ad623915c9842ecc32999b867c4a787d975a17a9625cc6" +checksum = "9f442a38863e10129ffe2cec7bd09c2dcf8a098a3a27801a476a304d5bb991d2" dependencies = [ "gtk", "http 1.1.0", @@ -5548,9 +5170,9 @@ dependencies = [ [[package]] name = "tauri-utils" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c38b0230d6880cf6dd07b6d7dd7789a0869f98ac12146e0d18d1c1049215a045" +checksum = "9271a88f99b4adea0dc71d0baca4505475a0bbd139fb135f62958721aaa8fe54" dependencies = [ "brotli", "cargo_metadata", @@ -5558,6 +5180,7 @@ dependencies = [ "dunce", "glob", "html5ever", + "http 1.1.0", "infer", "json-patch", "kuchikiki", @@ -5574,7 +5197,7 @@ dependencies = [ "serde_json", "serde_with", "swift-rs", - "thiserror", + "thiserror 2.0.3", "toml 0.8.19", "url", "urlpattern", @@ -5659,7 +5282,16 @@ version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.64", +] + +[[package]] +name = "thiserror" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" +dependencies = [ + "thiserror-impl 2.0.3", ] [[package]] @@ -5670,7 +5302,18 @@ checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", ] [[package]] @@ -5776,7 +5419,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -5921,7 +5564,7 @@ dependencies = [ "proc-macro2", "prost-build", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -5988,7 +5631,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" dependencies = [ "crossbeam-channel", - "thiserror", + "thiserror 1.0.64", "time", "tracing-subscriber", ] @@ -6001,7 +5644,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -6060,7 +5703,7 @@ dependencies = [ "once_cell", "png", "serde", - "thiserror", + "thiserror 1.0.64", "windows-sys 0.59.0", ] @@ -6078,7 +5721,7 @@ checksum = "3a2f31991cee3dce1ca4f929a8a04fdd11fd8801aac0f2030b0fa8a0a3fef6b9" dependencies = [ "chrono", "lazy_static", - "thiserror", + "thiserror 1.0.64", "ts-rs-macros", ] @@ -6090,7 +5733,7 @@ checksum = "0ea0b99e8ec44abd6f94a18f28f7934437809dd062820797c52401298116f70e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", "termcolor", ] @@ -6249,17 +5892,6 @@ dependencies = [ "serde", ] -[[package]] -name = "v_frame" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" -dependencies = [ - "aligned-vec", - "num-traits", - "wasm-bindgen", -] - [[package]] name = "valuable" version = "0.1.0" @@ -6357,7 +5989,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", "wasm-bindgen-shared", ] @@ -6391,7 +6023,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6560,7 +6192,7 @@ checksum = "1d228f15bba3b9d56dde8bddbee66fa24545bd17b48d5128ccf4a8742b18e431" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -6569,7 +6201,7 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3a3e2eeb58f82361c93f9777014668eb3d07e7d174ee4c819575a9208011886" dependencies = [ - "thiserror", + "thiserror 1.0.64", "windows 0.58.0", "windows-core 0.58.0", ] @@ -6687,7 +6319,7 @@ checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -6698,7 +6330,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -6709,7 +6341,7 @@ checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -6720,7 +6352,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -7015,12 +6647,13 @@ dependencies = [ [[package]] name = "wry" -version = "0.46.2" +version = "0.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fa1c8c760041c64ce6be99f83d6cb55fe3fcd85a1ad46d32895f6e65cee87ba" +checksum = "553ca1ce149982123962fac2506aa75b8b76288779a77e72b12fa2fc34938647" dependencies = [ "base64 0.22.1", "block2", + "cookie", "crossbeam-channel", "dpi", "dunce", @@ -7044,7 +6677,8 @@ dependencies = [ "sha2", "soup3", "tao-macros", - "thiserror", + "thiserror 1.0.64", + "url", "webkit2gtk", "webkit2gtk-sys", "webview2-com", @@ -7167,7 +6801,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", "zvariant_utils", ] @@ -7200,7 +6834,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] [[package]] @@ -7221,7 +6855,7 @@ dependencies = [ "displaydoc", "indexmap 2.5.0", "memchr", - "thiserror", + "thiserror 1.0.64", ] [[package]] @@ -7252,30 +6886,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "zune-core" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" - -[[package]] -name = "zune-inflate" -version = "0.2.54" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" -dependencies = [ - "simd-adler32", -] - -[[package]] -name = "zune-jpeg" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768" -dependencies = [ - "zune-core", -] - [[package]] name = "zvariant" version = "4.2.0" @@ -7299,7 +6909,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", "zvariant_utils", ] @@ -7311,5 +6921,5 @@ checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.87", ] diff --git a/nym-vpn-app/src-tauri/Cargo.toml b/nym-vpn-app/src-tauri/Cargo.toml index 789ced6362..6ddada7210 100644 --- a/nym-vpn-app/src-tauri/Cargo.toml +++ b/nym-vpn-app/src-tauri/Cargo.toml @@ -17,7 +17,7 @@ tauri-build = { version = "2.0.0", features = [] } build-info-build = "0.0.39" [dependencies] -tauri = { version = "2.0.0", features = ["tray-icon", "image-png"] } +tauri = { version = "2.1.1", features = ["tray-icon", "image-png"] } tokio = { version = "1.39", features = ["rt", "sync", "time", "fs", "macros"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" @@ -29,7 +29,7 @@ tracing-subscriber = { version = "0.3.1", features = [ tracing-appender = "0.2" anyhow = "1.0" dotenvy = "0.15.7" -thiserror = "1.0" +thiserror = "2.0.0" ts-rs = { version = "10.0", features = ["chrono-impl"] } once_cell = "1.18.0" toml = "0.8.5" diff --git a/nym-vpn-app/src-tauri/gen/schemas/desktop-schema.json b/nym-vpn-app/src-tauri/gen/schemas/desktop-schema.json index 0e0b62f417..9e2d9c82b9 100644 --- a/nym-vpn-app/src-tauri/gen/schemas/desktop-schema.json +++ b/nym-vpn-app/src-tauri/gen/schemas/desktop-schema.json @@ -37,7 +37,7 @@ ], "definitions": { "Capability": { - "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, \"platforms\": [\"macOS\",\"windows\"] } ```", + "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, ], \"platforms\": [\"macOS\",\"windows\"] } ```", "type": "object", "required": [ "identifier", @@ -84,7 +84,7 @@ } }, "permissions": { - "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ```", + "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ] ```", "type": "array", "items": { "$ref": "#/definitions/PermissionEntry" diff --git a/nym-vpn-app/src-tauri/gen/schemas/linux-schema.json b/nym-vpn-app/src-tauri/gen/schemas/linux-schema.json index 0e0b62f417..9e2d9c82b9 100644 --- a/nym-vpn-app/src-tauri/gen/schemas/linux-schema.json +++ b/nym-vpn-app/src-tauri/gen/schemas/linux-schema.json @@ -37,7 +37,7 @@ ], "definitions": { "Capability": { - "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, \"platforms\": [\"macOS\",\"windows\"] } ```", + "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, ], \"platforms\": [\"macOS\",\"windows\"] } ```", "type": "object", "required": [ "identifier", @@ -84,7 +84,7 @@ } }, "permissions": { - "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ```", + "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ] ```", "type": "array", "items": { "$ref": "#/definitions/PermissionEntry" diff --git a/nym-vpn-app/src-tauri/src/cli.rs b/nym-vpn-app/src-tauri/src/cli.rs index d27f134845..1fb52fef36 100644 --- a/nym-vpn-app/src-tauri/src/cli.rs +++ b/nym-vpn-app/src-tauri/src/cli.rs @@ -73,6 +73,10 @@ pub struct Cli { #[arg(short = 's', long)] pub nosplash: bool, + /// Enable zknyms credentials mode + #[arg(long, hide = true)] + pub credentials_mode: bool, + #[command(subcommand)] pub command: Option, } @@ -147,8 +151,11 @@ pub fn db_command(command: &DbCommands) -> Result<()> { DbCommands::Del { key: k } => { info!("cli db del {k}"); let key = Key::from_str(k).map_err(|_| anyhow!("invalid key"))?; - db.remove(key)?; - println!("key removed"); + if let Some(value) = db.remove(key)? { + println!("key removed, previous value {value}"); + } else { + println!("key is not set"); + } Ok(()) } } diff --git a/nym-vpn-app/src-tauri/src/commands/account.rs b/nym-vpn-app/src-tauri/src/commands/account.rs index 773f22c755..2bb7d7f020 100644 --- a/nym-vpn-app/src-tauri/src/commands/account.rs +++ b/nym-vpn-app/src-tauri/src/commands/account.rs @@ -2,6 +2,7 @@ use serde_json::Value as JsonValue; use tauri::State; use tracing::{debug, error, info, instrument}; +use crate::grpc::account_links::AccountLinks; use crate::{error::BackendError, grpc::client::GrpcClient}; #[instrument(skip_all)] @@ -10,7 +11,6 @@ pub async fn add_account( mnemonic: String, grpc: State<'_, GrpcClient>, ) -> Result<(), BackendError> { - debug!("add_account"); grpc.store_account(mnemonic) .await .map_err(|e| { @@ -40,8 +40,6 @@ pub async fn delete_account(grpc: State<'_, GrpcClient>) -> Result<(), BackendEr #[instrument(skip_all)] #[tauri::command] pub async fn is_account_stored(grpc: State<'_, GrpcClient>) -> Result { - debug!("is_account_stored"); - grpc.is_account_stored() .await .map_err(|e| { @@ -56,8 +54,6 @@ pub async fn is_account_stored(grpc: State<'_, GrpcClient>) -> Result) -> Result { - debug!("get_account_info"); - grpc.get_account_summary() .await .map_err(|e| { @@ -71,3 +67,15 @@ pub async fn get_account_info(grpc: State<'_, GrpcClient>) -> Result, + locale: String, +) -> Result { + grpc.account_links(&locale).await.map_err(|e| { + error!("failed to get account link: {e}"); + e.into() + }) +} diff --git a/nym-vpn-app/src-tauri/src/commands/cli.rs b/nym-vpn-app/src-tauri/src/commands/cli.rs index a0c86a5a27..a4023218ca 100644 --- a/nym-vpn-app/src-tauri/src/commands/cli.rs +++ b/nym-vpn-app/src-tauri/src/commands/cli.rs @@ -1,11 +1,10 @@ use tauri::State; -use tracing::{debug, instrument}; +use tracing::instrument; use crate::{cli::Cli, error::BackendError}; #[instrument(skip_all)] #[tauri::command] pub fn cli_args(cli: State<'_, Cli>) -> Result<&Cli, BackendError> { - debug!("cli_args"); Ok(cli.inner()) } diff --git a/nym-vpn-app/src-tauri/src/commands/connection.rs b/nym-vpn-app/src-tauri/src/commands/connection.rs index fcda5afbdb..cf48f97012 100644 --- a/nym-vpn-app/src-tauri/src/commands/connection.rs +++ b/nym-vpn-app/src-tauri/src/commands/connection.rs @@ -32,7 +32,6 @@ pub async fn get_connection_state( state: State<'_, SharedAppState>, grpc: State<'_, GrpcClient>, ) -> Result { - debug!("get_connection_state"); let res = grpc.vpn_status().await?; let status = ConnectionState::from(res.status()); let mut app_state = state.lock().await; @@ -53,7 +52,6 @@ pub async fn connect( entry: NodeLocation, exit: NodeLocation, ) -> Result { - debug!("connect"); { let mut app_state = state.lock().await; if app_state.state != ConnectionState::Disconnected { @@ -176,7 +174,6 @@ pub async fn disconnect( state: State<'_, SharedAppState>, grpc: State<'_, GrpcClient>, ) -> Result { - debug!("disconnect"); let mut app_state = state.lock().await; if !matches!(app_state.state, ConnectionState::Connected) { return Err(BackendError::new_internal( @@ -198,7 +195,6 @@ pub async fn disconnect( pub async fn get_connection_start_time( state: State<'_, SharedAppState>, ) -> Result, BackendError> { - debug!("get_connection_start_time"); let app_state = state.lock().await; Ok(app_state.connection_start_time.map(|t| t.unix_timestamp())) } @@ -210,8 +206,6 @@ pub async fn set_vpn_mode( db: State<'_, Db>, mode: VpnMode, ) -> Result<(), BackendError> { - debug!("set_vpn_mode"); - #[cfg(windows)] if matches!(mode, VpnMode::TwoHop) { return Err(BackendError::new_internal( @@ -231,7 +225,6 @@ pub async fn set_vpn_mode( state.vpn_mode = mode.clone(); drop(state); - debug!("saving vpn mode in db"); db.insert(Key::VpnMode, &mode) .map_err(|_| BackendError::new_internal("Failed to save vpn mode in db", None))?; Ok(()) diff --git a/nym-vpn-app/src-tauri/src/commands/country.rs b/nym-vpn-app/src-tauri/src/commands/country.rs index d5c225579a..1dcd44ce76 100644 --- a/nym-vpn-app/src-tauri/src/commands/country.rs +++ b/nym-vpn-app/src-tauri/src/commands/country.rs @@ -1,7 +1,7 @@ use nym_vpn_proto::GatewayType; use serde::{Deserialize, Serialize}; use tauri::State; -use tracing::{debug, instrument}; +use tracing::instrument; use ts_rs::TS; use crate::grpc::client::GrpcClient; @@ -24,7 +24,6 @@ pub async fn get_countries( node_type: Option, grpc: State<'_, GrpcClient>, ) -> Result, BackendError> { - debug!("get_countries"); let gw_type = match vpn_mode { VpnMode::Mixnet => match node_type.ok_or_else(|| { BackendError::new_internal("node type must be provided for Mixnet mode", None) diff --git a/nym-vpn-app/src-tauri/src/commands/daemon.rs b/nym-vpn-app/src-tauri/src/commands/daemon.rs index c838d5d41e..a6ce7caadc 100644 --- a/nym-vpn-app/src-tauri/src/commands/daemon.rs +++ b/nym-vpn-app/src-tauri/src/commands/daemon.rs @@ -1,6 +1,6 @@ use crate::env::NETWORK_ENV_SELECT; use crate::error::BackendError; -use crate::grpc::client::{GrpcClient, VpndStatus}; +use crate::grpc::client::{FeatureFlags, GrpcClient, SystemMessage, VpndStatus}; use crate::states::SharedAppState; use serde::{Deserialize, Serialize}; use tauri::State; @@ -31,7 +31,6 @@ pub async fn daemon_status( app_state: State<'_, SharedAppState>, grpc_client: State<'_, GrpcClient>, ) -> Result { - debug!("daemon_status"); let status = grpc_client .check(app_state.inner()) .await @@ -46,7 +45,6 @@ pub async fn daemon_status( #[instrument(skip_all)] #[tauri::command] pub async fn daemon_info(grpc_client: State<'_, GrpcClient>) -> Result { - debug!("daemon_info"); let res = grpc_client.vpnd_info().await.inspect_err(|e| { warn!("failed to get daemon info: {:?}", e); })?; @@ -71,7 +69,6 @@ pub async fn set_network( grpc_client: State<'_, GrpcClient>, network: NetworkEnv, ) -> Result<(), BackendError> { - debug!("set_network"); if !*NETWORK_ENV_SELECT { warn!("network env selector is disabled"); return Err(BackendError::new_internal("nope", None)); @@ -87,3 +84,31 @@ pub async fn set_network( info!("vpnd network set to {} ⚠ restart vpnd!", network.as_ref()); }) } + +#[instrument(skip_all)] +#[tauri::command] +pub async fn system_messages( + grpc_client: State<'_, GrpcClient>, +) -> Result, BackendError> { + grpc_client + .system_messages() + .await + .inspect_err(|e| { + warn!("failed to get system messages: {:?}", e); + }) + .map_err(|e| e.into()) +} + +#[instrument(skip_all)] +#[tauri::command] +pub async fn feature_flags( + grpc_client: State<'_, GrpcClient>, +) -> Result { + grpc_client + .feature_flags() + .await + .inspect_err(|e| { + warn!("failed to get feature flags: {:?}", e); + }) + .map_err(|e| e.into()) +} diff --git a/nym-vpn-app/src-tauri/src/commands/db.rs b/nym-vpn-app/src-tauri/src/commands/db.rs index e0f1b6a489..dcd6f7410f 100644 --- a/nym-vpn-app/src-tauri/src/commands/db.rs +++ b/nym-vpn-app/src-tauri/src/commands/db.rs @@ -1,5 +1,5 @@ use tauri::State; -use tracing::{debug, instrument}; +use tracing::instrument; use crate::{ db::{Db, DbError, JsonValue, Key}, @@ -9,7 +9,6 @@ use crate::{ #[instrument(skip(db))] #[tauri::command] pub async fn db_get(db: State<'_, Db>, key: Key) -> Result, BackendError> { - debug!("db_get"); db.get(key) .map_err(|_| BackendError::new_internal(&format!("Failed to get key [{key}]"), None)) } @@ -21,7 +20,6 @@ pub async fn db_set( key: Key, value: JsonValue, ) -> Result, BackendError> { - debug!("db_set"); db.insert(key, &value).map_err(|e| match e { DbError::Serialize(e) => { BackendError::new_internal(&format!("Failed to insert key, bad JSON input: {e}"), None) @@ -33,7 +31,6 @@ pub async fn db_set( #[instrument(skip(db))] #[tauri::command] pub async fn db_flush(db: State<'_, Db>) -> Result { - debug!("db_flush"); db.flush() .await .map_err(|_| BackendError::new_internal("Failed to flush db", None)) diff --git a/nym-vpn-app/src-tauri/src/commands/env.rs b/nym-vpn-app/src-tauri/src/commands/env.rs index 90b64d873b..19a4e3858a 100644 --- a/nym-vpn-app/src-tauri/src/commands/env.rs +++ b/nym-vpn-app/src-tauri/src/commands/env.rs @@ -1,6 +1,6 @@ use crate::env::NETWORK_ENV_SELECT; use serde::Serialize; -use tracing::{debug, instrument}; +use tracing::instrument; use ts_rs::TS; #[derive(Serialize, Debug, Clone, TS)] @@ -13,7 +13,6 @@ pub struct Env { #[instrument(skip_all)] #[tauri::command] pub async fn env() -> Env { - debug!("env"); Env { network_env_select: *NETWORK_ENV_SELECT, } diff --git a/nym-vpn-app/src-tauri/src/commands/fs.rs b/nym-vpn-app/src-tauri/src/commands/fs.rs index a98ee54a69..2322518df8 100644 --- a/nym-vpn-app/src-tauri/src/commands/fs.rs +++ b/nym-vpn-app/src-tauri/src/commands/fs.rs @@ -6,7 +6,6 @@ use crate::fs::path::APP_LOG_DIR; #[instrument] #[tauri::command] pub async fn log_dir() -> Result { - debug!("log_dir"); let log_path = APP_LOG_DIR.clone().ok_or_else(|| { let err = "Failed to get log directory path"; error!(err); diff --git a/nym-vpn-app/src-tauri/src/commands/startup.rs b/nym-vpn-app/src-tauri/src/commands/startup.rs index fc4b3b2e55..3c9e37d8e6 100644 --- a/nym-vpn-app/src-tauri/src/commands/startup.rs +++ b/nym-vpn-app/src-tauri/src/commands/startup.rs @@ -1,11 +1,10 @@ -use tracing::{debug, instrument, trace}; +use tracing::{instrument, trace}; use crate::startup_error::{StartupError, STARTUP_ERROR}; #[instrument(skip_all)] #[tauri::command] pub fn startup_error() -> Option { - debug!("startup_error"); STARTUP_ERROR.get().cloned().inspect(|e| { trace!("{:#?}", e); }) diff --git a/nym-vpn-app/src-tauri/src/commands/window.rs b/nym-vpn-app/src-tauri/src/commands/window.rs index 31d3ccaf75..858bc33ea2 100644 --- a/nym-vpn-app/src-tauri/src/commands/window.rs +++ b/nym-vpn-app/src-tauri/src/commands/window.rs @@ -6,7 +6,6 @@ use crate::{error::BackendError, MAIN_WINDOW_LABEL}; #[instrument(skip_all)] #[tauri::command] pub fn show_main_window(app: AppHandle) -> Result<(), BackendError> { - debug!("show_window"); let main_window = app.get_webview_window(MAIN_WINDOW_LABEL) .ok_or(BackendError::new_internal( diff --git a/nym-vpn-app/src-tauri/src/env.rs b/nym-vpn-app/src-tauri/src/env.rs index 7f54acb71f..bd1e84470e 100644 --- a/nym-vpn-app/src-tauri/src/env.rs +++ b/nym-vpn-app/src-tauri/src/env.rs @@ -1,7 +1,16 @@ use once_cell::sync::Lazy; +use std::env; pub static NETWORK_ENV_SELECT: Lazy = Lazy::new(|| { option_env!("NETWORK_ENV_SELECT") - .map(|v| v.to_lowercase() == "true" || v == "1") + .map(|v| v == "1" || v.to_lowercase() == "true") .unwrap_or(false) }); + +/// Check if an environment variable is truthy, e.g. set to "1" | "true" | "TRUE" +pub fn is_truthy(var: &str) -> bool { + match env::var(var) { + Ok(val) => val == "1" || val.to_lowercase() == "true", + Err(_) => false, + } +} diff --git a/nym-vpn-app/src-tauri/src/envi.rs b/nym-vpn-app/src-tauri/src/envi.rs deleted file mode 100644 index d26917bcdf..0000000000 --- a/nym-vpn-app/src-tauri/src/envi.rs +++ /dev/null @@ -1,9 +0,0 @@ -use std::env; - -/// Check if an environment variable is truthy, i.e. set to "1" or "true" -pub fn is_truthy(var: &str) -> bool { - match env::var(var) { - Ok(val) => val == "1" || val == "true", - Err(_) => false, - } -} diff --git a/nym-vpn-app/src-tauri/src/fs/config.rs b/nym-vpn-app/src-tauri/src/fs/config.rs index 7424fdf822..00f8ff2228 100644 --- a/nym-vpn-app/src-tauri/src/fs/config.rs +++ b/nym-vpn-app/src-tauri/src/fs/config.rs @@ -4,8 +4,6 @@ use serde::{Deserialize, Serialize}; #[derive(Default, Serialize, Deserialize, Debug, Clone)] pub struct AppConfig { - /// Path to a file to load a custom network environment - pub network_env_file: Option, /// Unix socket path of gRPC endpoint in IPC mode pub grpc_socket_endpoint: Option, /// Enable HTTP transport for gRPC connection diff --git a/nym-vpn-app/src-tauri/src/grpc/account_links.rs b/nym-vpn-app/src-tauri/src/grpc/account_links.rs new file mode 100644 index 0000000000..f69fdbf395 --- /dev/null +++ b/nym-vpn-app/src-tauri/src/grpc/account_links.rs @@ -0,0 +1,21 @@ +use serde::Serialize; +use ts_rs::TS; + +#[derive(Clone, Serialize, TS)] +#[serde(rename_all = "camelCase")] +#[ts(export)] +pub struct AccountLinks { + pub sign_up: Option, + pub sign_in: Option, + pub account: Option, +} + +impl From for AccountLinks { + fn from(links: nym_vpn_proto::AccountManagement) -> Self { + AccountLinks { + sign_up: links.sign_up.map(|link| link.url.to_string()), + sign_in: links.sign_in.map(|link| link.url.to_string()), + account: links.account.map(|link| link.url.to_string()), + } + } +} diff --git a/nym-vpn-app/src-tauri/src/grpc/client.rs b/nym-vpn-app/src-tauri/src/grpc/client.rs index ba15181249..f85431ce09 100644 --- a/nym-vpn-app/src-tauri/src/grpc/client.rs +++ b/nym-vpn-app/src-tauri/src/grpc/client.rs @@ -4,15 +4,15 @@ use std::path::PathBuf; use anyhow::{anyhow, Result}; use itertools::Itertools; use nym_vpn_proto::{ - health_check_response::ServingStatus, health_client::HealthClient, + get_account_links_response, health_check_response::ServingStatus, health_client::HealthClient, is_account_stored_response::Resp as IsAccountStoredResp, nym_vpnd_client::NymVpndClient, ConnectRequest, ConnectionStatus, DisconnectRequest, Dns, Empty, EntryNode, ExitNode, - FetchRawAccountSummaryRequest, GatewayType, HealthCheckRequest, InfoRequest, InfoResponse, + FetchRawAccountSummaryRequest, GatewayType, GetAccountLinksRequest, GetFeatureFlagsRequest, + GetSystemMessagesRequest, HealthCheckRequest, InfoRequest, InfoResponse, IsAccountStoredRequest, ListCountriesRequest, Location, RemoveAccountRequest, SetNetworkRequest, StatusRequest, StatusResponse, StoreAccountRequest, UserAgent, }; use parity_tokio_ipc::Endpoint as IpcEndpoint; -use serde::{Deserialize, Serialize}; use tauri::{AppHandle, Manager, PackageInfo}; use thiserror::Error; use time::OffsetDateTime; @@ -20,18 +20,23 @@ use tokio::sync::mpsc; use tonic::transport::Endpoint as TonicEndpoint; use tonic::{transport::Channel, Request}; use tracing::{debug, error, info, instrument, warn}; -use ts_rs::TS; use crate::cli::Cli; use crate::country::Country; use crate::error::BackendError; use crate::fs::config::AppConfig; +pub use crate::grpc::account_links::AccountLinks; +pub use crate::grpc::feature_flags::FeatureFlags; +pub use crate::grpc::system_message::SystemMessage; +pub use crate::grpc::vpnd_status::VpndStatus; use crate::states::app::ConnectionState; -use crate::vpn_status; +use crate::{env, vpn_status}; use crate::{events::AppHandleEventEmitter, states::SharedAppState}; const VPND_SERVICE: &str = "nym.vpn.NymVpnd"; -#[cfg(not(windows))] +#[cfg(target_os = "linux")] +const DEFAULT_SOCKET_PATH: &str = "/run/nym-vpn.sock"; +#[cfg(target_os = "macos")] const DEFAULT_SOCKET_PATH: &str = "/var/run/nym-vpn.sock"; #[cfg(windows)] const DEFAULT_SOCKET_PATH: &str = r"\\.\pipe\nym-vpn"; @@ -43,13 +48,6 @@ enum Transport { Ipc(PathBuf), } -#[derive(Serialize, Deserialize, Default, Clone, Debug, TS)] -pub enum VpndStatus { - Ok, - #[default] - NotOk, -} - #[derive(Error, Debug)] pub enum VpndError { #[error("gRPC call error")] @@ -66,6 +64,7 @@ pub enum VpndError { pub struct GrpcClient { transport: Transport, user_agent: UserAgent, + credentials_mode: bool, } impl GrpcClient { @@ -74,6 +73,7 @@ impl GrpcClient { let client = GrpcClient { transport: Transport::from((config, cli)), user_agent: GrpcClient::user_agent(pkg, None), + credentials_mode: cli.credentials_mode || env::is_truthy("ENABLE_CREDENTIALS_MODE"), }; match &client.transport { Transport::Http(endpoint) => { @@ -178,7 +178,7 @@ impl GrpcClient { let request = Request::new(InfoRequest {}); let response = vpnd.info(request).await.map_err(|e| { - error!("grpc info: {}", e); + error!("grpc: {}", e); VpndError::GrpcError(e) })?; @@ -210,7 +210,7 @@ impl GrpcClient { let request = Request::new(StatusRequest {}); let response = vpnd.vpn_status(request).await.map_err(|e| { - error!("grpc vpn_status: {}", e); + error!("grpc: {}", e); VpndError::GrpcError(e) })?; debug!("grpc response: {:?}", response); @@ -345,9 +345,11 @@ impl GrpcClient { two_hop_mod: bool, dns: Option, ) -> Result<(), VpndError> { - debug!("vpn_connect"); let mut vpnd = self.vpnd().await?; + if self.credentials_mode { + info!("credentials mode enabled"); + } let request = Request::new(ConnectRequest { entry: Some(entry_node), exit: Some(exit_node), @@ -355,7 +357,7 @@ impl GrpcClient { enable_two_hop: two_hop_mod, disable_poisson_rate: false, disable_background_cover_traffic: false, - enable_credentials_mode: false, + enable_credentials_mode: self.credentials_mode, dns, user_agent: Some(self.user_agent.clone()), min_mixnode_performance: None, @@ -366,7 +368,7 @@ impl GrpcClient { .vpn_connect(request) .await .map_err(|e| { - error!("grpc vpn_connect: {}", e); + error!("grpc: {}", e); VpndError::GrpcError(e) })? .into_inner(); @@ -391,12 +393,11 @@ impl GrpcClient { /// Disconnect from the VPN #[instrument(skip_all)] pub async fn vpn_disconnect(&self) -> Result { - debug!("vpn_disconnect"); let mut vpnd = self.vpnd().await?; let request = Request::new(DisconnectRequest {}); let response = vpnd.vpn_disconnect(request).await.map_err(|e| { - error!("grpc vpn_disconnect: {}", e); + error!("grpc: {}", e); VpndError::GrpcError(e) })?; debug!("grpc response: {:?}", response); @@ -407,12 +408,11 @@ impl GrpcClient { /// Store an account #[instrument(skip_all)] pub async fn store_account(&self, mnemonic: String) -> Result<(), VpndError> { - debug!("store_account"); let mut vpnd = self.vpnd().await?; let request = Request::new(StoreAccountRequest { mnemonic, nonce: 0 }); let response = vpnd.store_account(request).await.map_err(|e| { - error!("grpc store_account: {}", e); + error!("grpc: {}", e); VpndError::GrpcError(e) })?; debug!("grpc response: {:?}", response); @@ -437,12 +437,11 @@ impl GrpcClient { /// Remove the stored account #[instrument(skip_all)] pub async fn remove_account(&self) -> Result<(), VpndError> { - debug!("remove_account"); let mut vpnd = self.vpnd().await?; let request = Request::new(RemoveAccountRequest {}); let response = vpnd.remove_account(request).await.map_err(|e| { - error!("grpc remove_account: {}", e); + error!("grpc: {}", e); VpndError::GrpcError(e) })?; debug!("grpc response: {:?}", response); @@ -467,12 +466,11 @@ impl GrpcClient { /// Check if an account is stored #[instrument(skip_all)] pub async fn is_account_stored(&self) -> Result { - debug!("is_account_stored"); let mut vpnd = self.vpnd().await?; let request = Request::new(IsAccountStoredRequest {}); let response = vpnd.is_account_stored(request).await.map_err(|e| { - error!("grpc is_account_stored: {}", e); + error!("grpc: {}", e); VpndError::GrpcError(e) })?; debug!("grpc response: {:?}", response); @@ -492,7 +490,6 @@ impl GrpcClient { /// Note: if no account is stored yet, the call will fail #[instrument(skip_all)] pub async fn get_account_summary(&self) -> Result { - debug!("get_account_summary"); let mut vpnd = self.vpnd().await?; let request = Request::new(FetchRawAccountSummaryRequest {}); @@ -500,7 +497,7 @@ impl GrpcClient { .fetch_raw_account_summary(request) .await .map_err(|e| { - error!("grpc get_account_summary: {}", e); + error!("grpc: {}", e); VpndError::GrpcError(e) })? .into_inner(); @@ -513,10 +510,35 @@ impl GrpcClient { Ok(response.json) } + /// Get the account links + #[instrument(skip_all)] + pub async fn account_links(&self, _locale: &str) -> Result { + let mut vpnd = self.vpnd().await?; + + let request = Request::new(GetAccountLinksRequest { + // TODO use the locale set at app level once website is i18n ready + locale: "en".to_string(), + }); + let response = vpnd.get_account_links(request).await.map_err(|e| { + error!("grpc: {}", e); + VpndError::GrpcError(e) + })?; + let response = response.into_inner(); + debug!("grpc response: {:?}", response.res); + match response.res.ok_or_else(|| { + error!("failed to get account links: invalid response"); + VpndError::GrpcError(tonic::Status::internal( + "failed to get account links: invalid response", + )) + })? { + get_account_links_response::Res::Links(l) => Ok(l.into()), + get_account_links_response::Res::Error(e) => Err(VpndError::Response(e.into())), + } + } + /// Get the list of available countries for entry gateways #[instrument(skip(self))] pub async fn countries(&self, gw_type: GatewayType) -> Result, VpndError> { - debug!("countries"); let mut vpnd = self.vpnd().await?; let request = Request::new(ListCountriesRequest { @@ -526,7 +548,7 @@ impl GrpcClient { min_vpn_performance: None, }); let response = vpnd.list_countries(request).await.map_err(|e| { - error!("grpc list_countries: {}", e); + error!("grpc: {}", e); VpndError::GrpcError(e) })?; debug!("countries count: {}", response.get_ref().countries.len()); @@ -594,7 +616,6 @@ impl GrpcClient { /// ⚠ This requires to restart the daemon to take effect. #[instrument(skip(self))] pub async fn set_network(&self, network: &str) -> Result<(), VpndError> { - debug!("set_network"); let mut vpnd = self.vpnd().await?; let request = Request::new(SetNetworkRequest { @@ -604,7 +625,7 @@ impl GrpcClient { .set_network(request) .await .map_err(|e| { - error!("grpc set_network: {}", e); + error!("grpc: {}", e); VpndError::GrpcError(e) })? .into_inner(); @@ -615,14 +636,35 @@ impl GrpcClient { } Ok(()) } -} -impl From for VpndStatus { - fn from(status: ServingStatus) -> Self { - match status { - ServingStatus::Serving => VpndStatus::Ok, - _ => VpndStatus::NotOk, - } + /// Get messages affecting the whole system, fetched from nym-vpn-api + #[instrument(skip_all)] + pub async fn system_messages(&self) -> Result, VpndError> { + let mut vpnd = self.vpnd().await?; + + let request = Request::new(GetSystemMessagesRequest {}); + let response = vpnd.get_system_messages(request).await.map_err(|e| { + error!("grpc: {}", e); + VpndError::GrpcError(e) + })?; + debug!("grpc response: {:?}", response); + let response = response.into_inner(); + Ok(response.messages.iter().map(Into::into).collect()) + } + + /// Get the feature flags, fetched from nym-vpn-api + #[instrument(skip_all)] + pub async fn feature_flags(&self) -> Result { + let mut vpnd = self.vpnd().await?; + + let request = Request::new(GetFeatureFlagsRequest {}); + let response = vpnd.get_feature_flags(request).await.map_err(|e| { + error!("grpc: {}", e); + VpndError::GrpcError(e) + })?; + debug!("grpc response: {:?}", response); + let response = response.into_inner(); + Ok(FeatureFlags::from(&response)) } } diff --git a/nym-vpn-app/src-tauri/src/grpc/feature_flags.rs b/nym-vpn-app/src-tauri/src/grpc/feature_flags.rs new file mode 100644 index 0000000000..1b6230fb69 --- /dev/null +++ b/nym-vpn-app/src-tauri/src/grpc/feature_flags.rs @@ -0,0 +1,34 @@ +use serde::Serialize; +use std::collections::HashMap; +use ts_rs::TS; + +#[derive(Clone, Serialize, TS)] +#[ts(export)] +pub struct FeatureFlags { + pub flags: HashMap, + pub groups: HashMap, +} + +#[derive(Clone, Serialize, TS)] +#[ts(export)] +pub struct FeatureFlagGroup(HashMap); + +impl From<&nym_vpn_proto::GetFeatureFlagsResponse> for FeatureFlags { + fn from(feature_flags: &nym_vpn_proto::GetFeatureFlagsResponse) -> Self { + let mut flags = HashMap::new(); + for (key, value) in &feature_flags.flags { + flags.insert(key.clone(), value.clone()); + } + + let mut groups = HashMap::new(); + for (group_key, group) in &feature_flags.groups { + let mut group_flags = HashMap::new(); + for (key, value) in &group.map { + group_flags.insert(key.clone(), value.clone()); + } + groups.insert(group_key.clone(), FeatureFlagGroup(group_flags)); + } + + FeatureFlags { flags, groups } + } +} diff --git a/nym-vpn-app/src-tauri/src/grpc/mod.rs b/nym-vpn-app/src-tauri/src/grpc/mod.rs index b9babe5bc1..9cbb45386f 100644 --- a/nym-vpn-app/src-tauri/src/grpc/mod.rs +++ b/nym-vpn-app/src-tauri/src/grpc/mod.rs @@ -1 +1,5 @@ +pub mod account_links; pub mod client; +pub mod feature_flags; +pub mod system_message; +pub mod vpnd_status; diff --git a/nym-vpn-app/src-tauri/src/grpc/system_message.rs b/nym-vpn-app/src-tauri/src/grpc/system_message.rs new file mode 100644 index 0000000000..80340631cc --- /dev/null +++ b/nym-vpn-app/src-tauri/src/grpc/system_message.rs @@ -0,0 +1,21 @@ +use serde::Serialize; +use std::collections::HashMap; +use ts_rs::TS; + +#[derive(Clone, Serialize, TS)] +#[ts(export)] +pub struct SystemMessage { + pub name: String, + pub message: String, + pub properties: HashMap, +} + +impl From<&nym_vpn_proto::SystemMessage> for SystemMessage { + fn from(msg: &nym_vpn_proto::SystemMessage) -> Self { + SystemMessage { + name: msg.name.clone(), + message: msg.message.clone(), + properties: msg.properties.clone(), + } + } +} diff --git a/nym-vpn-app/src-tauri/src/grpc/vpnd_status.rs b/nym-vpn-app/src-tauri/src/grpc/vpnd_status.rs new file mode 100644 index 0000000000..ad6f0bb7ce --- /dev/null +++ b/nym-vpn-app/src-tauri/src/grpc/vpnd_status.rs @@ -0,0 +1,19 @@ +use nym_vpn_proto::health_check_response::ServingStatus; +use serde::Serialize; +use ts_rs::TS; + +#[derive(Serialize, Default, Clone, Debug, TS)] +pub enum VpndStatus { + Ok, + #[default] + NotOk, +} + +impl From for VpndStatus { + fn from(status: ServingStatus) -> Self { + match status { + ServingStatus::Serving => VpndStatus::Ok, + _ => VpndStatus::NotOk, + } + } +} diff --git a/nym-vpn-app/src-tauri/src/log.rs b/nym-vpn-app/src-tauri/src/log.rs index 0b5d574465..d8c6997cf9 100644 --- a/nym-vpn-app/src-tauri/src/log.rs +++ b/nym-vpn-app/src-tauri/src/log.rs @@ -1,8 +1,7 @@ use std::{fs, path::PathBuf}; -use crate::envi; use crate::fs::path::APP_LOG_DIR; -use crate::Cli; +use crate::{env, Cli}; use anyhow::{anyhow, Result}; use tracing::{debug, info}; @@ -37,7 +36,7 @@ pub async fn setup_tracing(cli: &Cli) -> Result> { .add_directive("hyper::proto=info".parse()?) .add_directive("netlink_proto=info".parse()?); - if cli.log_file || envi::is_truthy(ENV_LOG_FILE) { + if cli.log_file || env::is_truthy(ENV_LOG_FILE) { let log_dir = APP_LOG_DIR .clone() .ok_or(anyhow!("failed to get log dir"))?; diff --git a/nym-vpn-app/src-tauri/src/main.rs b/nym-vpn-app/src-tauri/src/main.rs index db288619bd..13cf83c396 100644 --- a/nym-vpn-app/src-tauri/src/main.rs +++ b/nym-vpn-app/src-tauri/src/main.rs @@ -40,12 +40,12 @@ mod commands; mod country; mod db; mod env; -mod envi; mod error; mod events; mod fs; mod grpc; mod log; +mod misc; mod startup_error; mod states; mod tray; @@ -75,6 +75,9 @@ async fn main() -> Result<()> { let _guard = log::setup_tracing(&cli).await?; trace!("cli args: {:#?}", cli); + #[cfg(unix)] + misc::nvidia_check(); + #[cfg(windows)] if cli.console { use windows::Win32::System::Console::AllocConsole; @@ -175,7 +178,7 @@ async fn main() -> Result<()> { // if splash-screen is disabled, remove it and show // the main window without waiting for frontend signal - if cli.nosplash || envi::is_truthy(ENV_APP_NOSPLASH) { + if cli.nosplash || env::is_truthy(ENV_APP_NOSPLASH) { debug!("splash screen disabled, showing main window"); app_win.no_splash(); } @@ -237,9 +240,12 @@ async fn main() -> Result<()> { account::delete_account, account::is_account_stored, account::get_account_info, + account::account_links, cmd_daemon::daemon_status, cmd_daemon::daemon_info, cmd_daemon::set_network, + cmd_daemon::system_messages, + cmd_daemon::feature_flags, cmd_fs::log_dir, startup::startup_error, cmd_env::env, diff --git a/nym-vpn-app/src-tauri/src/misc.rs b/nym-vpn-app/src-tauri/src/misc.rs new file mode 100644 index 0000000000..cf0c678239 --- /dev/null +++ b/nym-vpn-app/src-tauri/src/misc.rs @@ -0,0 +1,22 @@ +#[cfg(unix)] +use tracing::{info, warn}; + +// under X11 with nvidia gpu, there is an upstream issue with +// webkit dmabuf renderer +// see https://github.com/tauri-apps/tauri/issues/9304 +#[cfg(unix)] +pub fn nvidia_check() { + if std::fs::exists("/dev/nvidia0") + .inspect_err(|e| warn!("unable to check for nvidia gpu {}", e)) + .unwrap_or(false) + && std::env::var("XDG_SESSION_TYPE") + .unwrap_or_default() + .to_lowercase() + == "x11" + { + info!("X11 and nvidia gpu detected, disabling webkit dmabuf renderer"); + unsafe { + std::env::set_var("WEBKIT_DISABLE_DMABUF_RENDERER", "1"); + } + } +} diff --git a/nym-vpn-app/src/App.tsx b/nym-vpn-app/src/App.tsx index f3093483ea..7f1baa81a8 100644 --- a/nym-vpn-app/src/App.tsx +++ b/nym-vpn-app/src/App.tsx @@ -74,7 +74,12 @@ function App() { }> - + diff --git a/nym-vpn-app/src/cache/index.ts b/nym-vpn-app/src/cache/index.ts new file mode 100644 index 0000000000..4f06db13a0 --- /dev/null +++ b/nym-vpn-app/src/cache/index.ts @@ -0,0 +1,82 @@ +// simple memory cache + +export type Cached = { + value: T; + // timestamp in ms + expiry?: number; +}; + +export type CKey = 'mn-entry-countries' | 'mn-exit-countries' | 'wg-countries'; +const cache = new Map>(); + +/** + * In-memory cache, with optional expiry + */ +export const MCache = { + /** + * Get a key + * + * @param key - Key + * @param stale - Accept stale (expired) data + * @returns The cached value if any + */ + get: (key: CKey, stale = false): T | null => { + const cached = cache.get(key); + if (!cached) { + console.log(`no cache data for [${key}]`); + return null; + } + if (!cached.expiry) { + console.log(`cache data [${key}]`, cached.value); + return cached.value as T; + } + if (Date.now() < cached.expiry) { + console.log(`cache data [${key}]`, cached.value); + return cached.value as T; + } + console.log(`cache data is stale [${key}]`); + if (stale) { + console.log(`cache data [${key}]`, cached.value); + cache.delete(key); + return cached.value as T; + } + cache.delete(key); + return null; + }, + /** + * Set a key + * + * @param key - Key + * @param value - The date to cache + * @param ttl - The time to live from now in seconds + */ + set: (key: CKey, value: T, ttl?: number): void => { + if (!ttl) { + console.log(`set cache [${key}]`, value); + cache.set(key, { value: value as never }); + return; + } + const expiry = Date.now() + ttl * 1000; + console.log( + `set cache [${key}], expiry ${new Date(expiry).toString()}`, + value, + ); + cache.set(key, { value: value as never, expiry }); + }, + /** + * Remove a key + * + * @param key - Key + */ + del: (key: CKey): void => { + console.log(`delete cache [${key}]`); + cache.delete(key); + }, + /** + * Clear all cache + */ + clear: (): void => { + console.log(`clear cache`); + cache.clear(); + }, +} as const; diff --git a/nym-vpn-app/src/constants.ts b/nym-vpn-app/src/constants.ts index a466ec0add..6602d0bacf 100644 --- a/nym-vpn-app/src/constants.ts +++ b/nym-vpn-app/src/constants.ts @@ -35,12 +35,5 @@ export const PrivacyPolicyUrl = 'https://nymvpn.com/en/privacy?type=apps'; export const LocationDetailsArticle = 'https://support.nymvpn.com/hc/en-us/articles/26448676449297-How-is-server-location-determined-by-NymVPN'; export const SentryHomePage = 'https://sentry.io/'; -export const AccountCreateUrlPath = '/account/create'; -export const AccountLoginUrlPath = '/account/login'; -export const NymDotComUrl = 'https://nymvpn.com'; -export const NymDotComCanaryUrl = - 'https://nym-dot-com-git-deploy-canary-nyx-network-staging.vercel.app'; -export const NymDotComQAUrl = - 'https://nym-dot-com-git-deploy-qa-nyx-network-staging.vercel.app'; -export const CountryCacheDuration = 120000; // 2 minutes +export const CountryCacheDuration = 120; // seconds export const HomeThrottleDelay = 6000; diff --git a/nym-vpn-app/src/contexts/main/provider.tsx b/nym-vpn-app/src/contexts/main/provider.tsx index 46f78c3ee9..60bf6c8f88 100644 --- a/nym-vpn-app/src/contexts/main/provider.tsx +++ b/nym-vpn-app/src/contexts/main/provider.tsx @@ -8,7 +8,6 @@ import { useInAppNotify, } from '../index'; import { sleep } from '../../helpers'; -import { useThrottle } from '../../hooks'; import { kvSet } from '../../kvStore'; import { BackendError, @@ -16,12 +15,15 @@ import { Country, NodeHop, NodeLocation, + SystemMessage, + VpnMode, isCountry, } from '../../types'; import { initFirstBatch, initSecondBatch } from '../../state/init'; import { initialState, reducer } from '../../state'; import { useTauriEvents } from '../../state/useTauriEvents'; import { S_STATE } from '../../static'; +import { MCache } from '../../cache'; let initialized = false; @@ -37,6 +39,7 @@ function MainStateProvider({ children }: Props) { entryNodeLocation, exitNodeLocation, vpnMode, + networkEnv, } = state; useTauriEvents(dispatch); @@ -86,78 +89,74 @@ function MainStateProvider({ children }: Props) { }); }, []); + // whenever the vpn mode changes, refresh the countries or use cached ones useEffect(() => { if (!S_STATE.vpnModeInit) { return; } if (vpnMode === 'Mixnet') { - fetchCountries('entry'); - fetchCountries('exit'); + fetchCountries(vpnMode, 'entry'); + fetchCountries(vpnMode, 'exit'); } else { - fetchCountries('entry'); + fetchCountries(vpnMode, 'entry'); } - // eslint-disable-next-line react-hooks/exhaustive-deps }, [vpnMode]); - const fetchMxEntryCountries = useThrottle( - async () => fetchCountries('entry'), - CountryCacheDuration, - [vpnMode], - ); - - const fetchMxExitCountries = useThrottle( - async () => fetchCountries('exit'), - CountryCacheDuration, - [vpnMode], - ); + // whenever the network environment changes (e.i. daemon has been reconfigured), + // clear cache + useEffect(() => { + if (!S_STATE.networkEnvInit) { + return; + } + console.info(`network env changed ${networkEnv}, clearing cache`); + MCache.clear(); + }, [networkEnv]); - const fetchWgCountries = useThrottle( - // does not matter if entry or exit, the list is the same - async () => fetchCountries('entry'), - CountryCacheDuration, - [vpnMode], - ); + useEffect(() => { + if (S_STATE.systemMessageInit) { + return; + } + S_STATE.systemMessageInit = true; + const querySystemMessages = async () => { + try { + const messages = await invoke('system_messages'); + if (messages.length > 0) { + console.info('system messages', messages); + push({ + text: messages + .map(({ name, message }) => `${name}: ${message}`) + .join('\n'), + position: 'top', + closeIcon: true, + autoHideDuration: 10000, + }); + } + } catch (e) { + console.warn('failed to query system messages:', e); + } + }; + querySystemMessages(); + }, [push]); - const fetchCountries = useCallback( - async (node: NodeHop) => { + // use cached values if any, otherwise query from daemon + const fetchCountries = async (vpnMode: VpnMode, node: NodeHop) => { + // first try to load from cache + let countries = MCache.get( + vpnMode === 'Mixnet' ? `mn-${node}-countries` : 'wg-countries', + ); + // fallback to daemon query + if (!countries) { + console.info(`fetching countries for ${vpnMode} ${node}`); try { - const countries = await invoke('get_countries', { + countries = await invoke('get_countries', { vpnMode, nodeType: node === 'entry' ? 'Entry' : 'Exit', }); - if (vpnMode === 'Mixnet') { - dispatch({ - type: 'set-country-list', - payload: { - hop: node, - countries, - }, - }); - // reset any previous error - dispatch({ - type: - node === 'entry' - ? 'set-entry-countries-error' - : 'set-exit-countries-error', - payload: null, - }); - } else { - // in 2hop mode, the country list is the same for both entry and exit - dispatch({ - type: 'set-fast-country-list', - payload: { - countries, - }, - }); - dispatch({ - type: 'set-entry-countries-error', - payload: null, - }); - dispatch({ - type: 'set-exit-countries-error', - payload: null, - }); - } + MCache.set( + vpnMode === 'Mixnet' ? `mn-${node}-countries` : 'wg-countries', + countries, + CountryCacheDuration, + ); } catch (e) { console.warn(`Failed to fetch ${node} countries:`, e); dispatch({ @@ -167,10 +166,56 @@ function MainStateProvider({ children }: Props) { : 'set-exit-countries-error', payload: e as BackendError, }); + if (vpnMode === 'TwoHop') { + // in 2hop mode, the error must be set for both entry and exit + dispatch({ + type: + node === 'entry' + ? 'set-exit-countries-error' + : 'set-entry-countries-error', + payload: e as BackendError, + }); + } } - }, - [vpnMode], - ); + } + if (!countries) { + console.warn('no countries found'); + return; + } + if (vpnMode === 'Mixnet') { + dispatch({ + type: 'set-country-list', + payload: { + hop: node, + countries, + }, + }); + // reset any previous error + dispatch({ + type: + node === 'entry' + ? 'set-entry-countries-error' + : 'set-exit-countries-error', + payload: null, + }); + } else { + // in 2hop mode, the country list is the same for both entry and exit + dispatch({ + type: 'set-fast-country-list', + payload: { + countries, + }, + }); + dispatch({ + type: 'set-entry-countries-error', + payload: null, + }); + dispatch({ + type: 'set-exit-countries-error', + payload: null, + }); + } + }; const checkSelectedCountry = useCallback( async (hop: NodeHop, countries: Country[], selected: NodeLocation) => { @@ -231,12 +276,21 @@ function MainStateProvider({ children }: Props) { exitCountryList, ]); + const fetchMnCountries = useCallback( + async (node: NodeHop) => fetchCountries(vpnMode, node), + [vpnMode], + ); + + const fetchWgCountries = useCallback( + async () => fetchCountries(vpnMode, 'entry'), + [vpnMode], + ); + return ( diff --git a/nym-vpn-app/src/data/licenses.ts b/nym-vpn-app/src/data/licenses.ts index 1a5dec6384..6a2746c773 100644 --- a/nym-vpn-app/src/data/licenses.ts +++ b/nym-vpn-app/src/data/licenses.ts @@ -11,7 +11,9 @@ export async function getRustLicenses(): Promise { const response = await fetch(LicensesRust); json = (await response.json()) as RustLicensesJson; } catch (e) { - console.warn('Failed to fetch Rust licenses data', e); + if (import.meta.env.MODE === 'production') { + console.warn('Failed to fetch Rust licenses data', e); + } return; } @@ -38,7 +40,9 @@ export async function getJsLicenses(): Promise { const response = await fetch(LicensesJs); json = (await response.json()) as JsLicensesJson; } catch (e) { - console.warn('Failed to fetch Js licenses data', e); + if (import.meta.env.MODE === 'production') { + console.warn('Failed to fetch Js licenses data', e); + } return; } diff --git a/nym-vpn-app/src/helpers.ts b/nym-vpn-app/src/helpers.ts index 05c05a1f2a..889e3e1601 100644 --- a/nym-vpn-app/src/helpers.ts +++ b/nym-vpn-app/src/helpers.ts @@ -1,12 +1,3 @@ -import { NetworkEnv } from './types'; -import { - AccountCreateUrlPath, - AccountLoginUrlPath, - NymDotComCanaryUrl, - NymDotComQAUrl, - NymDotComUrl, -} from './constants'; - export function sleep(ms: number) { return new Promise((resolve) => setTimeout(resolve, ms)); } @@ -20,29 +11,3 @@ export function capFirst(string: string) { export function setToString(obj: Record): string { return Object.values(obj).reduce((prev, s) => `${prev} ${s}`, ''); } - -export function getCreateAccountUrl(env: NetworkEnv) { - switch (env) { - case 'mainnet': - return `${NymDotComUrl}${AccountCreateUrlPath}`; - case 'canary': - return `${NymDotComCanaryUrl}${AccountCreateUrlPath}`; - case 'qa': - return `${NymDotComQAUrl}${AccountCreateUrlPath}`; - default: - return null; - } -} - -export function getLoginAccountUrl(env: NetworkEnv) { - switch (env) { - case 'mainnet': - return `${NymDotComUrl}${AccountLoginUrlPath}`; - case 'canary': - return `${NymDotComCanaryUrl}${AccountLoginUrlPath}`; - case 'qa': - return `${NymDotComQAUrl}${AccountLoginUrlPath}`; - default: - return null; - } -} diff --git a/nym-vpn-app/src/i18n/es/errors.json b/nym-vpn-app/src/i18n/es/errors.json index aab52e91be..32ecce87df 100644 --- a/nym-vpn-app/src/i18n/es/errors.json +++ b/nym-vpn-app/src/i18n/es/errors.json @@ -71,7 +71,8 @@ }, "add-ipv6-route": "Fallo al añadir la ruta por defecto al ipv6 para capturar tráfico ipv6", "tun-device": "Fallo del dispositivo Tun", - "routing": "Error de enrutamiento" + "routing": "Error de enrutamiento", + "ready-to-connect": "在检查过程中还无法确定我们是否已准备好连接" }, "out-of-bandwidth": "Fuera del ancho de banda asignado", "exit-node": { diff --git a/nym-vpn-app/src/i18n/es/glossary.json b/nym-vpn-app/src/i18n/es/glossary.json index 938e7c62d4..e06bfca40a 100644 --- a/nym-vpn-app/src/i18n/es/glossary.json +++ b/nym-vpn-app/src/i18n/es/glossary.json @@ -3,5 +3,8 @@ "left": "quedan", "ok": "Ok", "selected": "seleccionado", - "account": "cuenta" + "account": "cuenta", + "cancel": "cancelar", + "login": "iniciar sesión", + "logout": "cerrar sesión" } diff --git a/nym-vpn-app/src/i18n/es/notifications.json b/nym-vpn-app/src/i18n/es/notifications.json index 493cf6e3bd..b688611236 100644 --- a/nym-vpn-app/src/i18n/es/notifications.json +++ b/nym-vpn-app/src/i18n/es/notifications.json @@ -3,5 +3,9 @@ "connected": "Túnel VPN conectado", "disconnected": "NymVPN se ha desconectado. Para salvaguardar su privacidad, vuelva a conectarse.", "failed": "¡Ha fallado la conexión al túnel VPN!" + }, + "logout": { + "success": "A cerrado sesión satisfactoriamente", + "error": "A ocurrido un error mientras iniciaba sesión. Por favor intente nuevamente." } } diff --git a/nym-vpn-app/src/i18n/es/settings.json b/nym-vpn-app/src/i18n/es/settings.json index 7b04daead1..cbf51f6aa8 100644 --- a/nym-vpn-app/src/i18n/es/settings.json +++ b/nym-vpn-app/src/i18n/es/settings.json @@ -44,5 +44,9 @@ "daemon-version": "Versión Demonio", "network-name": "Red", "client-version": "Versión de cliente" + }, + "logout-confirmation": { + "title": "¿Estás seguro?", + "description": "Necesitarás tu frase de recuperación para iniciar sesión nuevamente." } } diff --git a/nym-vpn-app/src/i18n/fa/add-credential.json b/nym-vpn-app/src/i18n/fa/add-credential.json index 9d3b4a8022..420ddbe571 100644 --- a/nym-vpn-app/src/i18n/fa/add-credential.json +++ b/nym-vpn-app/src/i18n/fa/add-credential.json @@ -1,13 +1,14 @@ { "welcome": "به NymVPN خوش آمدید!", - "description1": "اعتبارنامه خود را برای شروع وارد کنید", - "description2": "اعتبارنامه خود را فعال کنید، سپس QR Code را اسکن کنید. اعتبارنامه ندارید؟ در nymvpn.com عضو شوید و بلافاصله آن را دریافت کنید.", - "input-label": "اعتبارنامه", + "description1": "عبارت ۲۴ کلمه‌ای بازیابی NymVPN خود را وارد کنید تا به حساب خود وارد شوید", + "description2": "فقط می‌توانید از عبارت بازیابی ایجاد شده در NymVPN استفاده کنید، نه Nym Wallet.", + "input-label": "عبارت بازیابی", "login-button": "افزودن اعتبارنامه", - "error": "اعتبارنامه نامعتبر", - "added-notification": "اعتبارنامه با موفقیت اضافه شد!", + "error": "عبارت بازیابی نامعتبر است", + "added-notification": "دستگاه با موفقیت به حساب شما اضافه شد", "create-account": { "text": "در NymVPN تازه واردید؟", "link": "ایجاد حساب کاربری" - } + }, + "input-placeholder": "مثال: smoke artefact velvet skull pop palace tortoise damage rough…" } diff --git a/nym-vpn-app/src/i18n/fa/errors.json b/nym-vpn-app/src/i18n/fa/errors.json index a1548ef19f..671b29732b 100644 --- a/nym-vpn-app/src/i18n/fa/errors.json +++ b/nym-vpn-app/src/i18n/fa/errors.json @@ -75,10 +75,19 @@ }, "daemon": { "not-connected": "به daemon متصل نیست", - "internal": "خطای داخلی Daemon" + "internal": "خطای داخلی Daemon", + "invalid-network": "شبکه نامعتبر است" }, "grpc": "خطای gRPC داخلی", "account": { - "invalid-recovery-phrase": "عبارت بازیابی نامعتبر است" + "invalid-recovery-phrase": "عبارت بازیابی نامعتبر است", + "storage": "خطای بخش پشتیبان ذخیره‌سازی", + "no-account-stored": "هیچ عبارت بازیابی حسابی ذخیره نشده است", + "not-active": "حساب فعال نیست", + "no-active-subscription": "حساب دارای اشتراک فعال نیست", + "device": { + "not-registered": "دستگاه ثبت نشده است", + "not-active": "دستگاه فعال نیست" + } } } diff --git a/nym-vpn-app/src/i18n/fa/glossary.json b/nym-vpn-app/src/i18n/fa/glossary.json index 56e43b8e6e..5c11fc8452 100644 --- a/nym-vpn-app/src/i18n/fa/glossary.json +++ b/nym-vpn-app/src/i18n/fa/glossary.json @@ -3,5 +3,8 @@ "left": "مانده", "ok": "قبول", "selected": "انتخاب‌شده", - "account": "اکانت" + "account": "اکانت", + "cancel": "لغو", + "login": "ورود", + "logout": "خروج" } diff --git a/nym-vpn-app/src/i18n/fa/notifications.json b/nym-vpn-app/src/i18n/fa/notifications.json index 9e99f53c20..60f3658896 100644 --- a/nym-vpn-app/src/i18n/fa/notifications.json +++ b/nym-vpn-app/src/i18n/fa/notifications.json @@ -3,5 +3,9 @@ "connected": "تونل VPN متصل شد", "disconnected": "NymVPN قطع شده است. برای حفظ حریم شخصی دوباره وصل شوید.", "failed": "اتصال تونل VPN ناموفق بود!" + }, + "logout": { + "success": "خروج با موفقیت انجام شد", + "error": "هنگام خروج خطایی رخ داد. لطفا دوباره تلاش کنید." } } diff --git a/nym-vpn-app/src/i18n/fa/settings.json b/nym-vpn-app/src/i18n/fa/settings.json index 08b8e1abef..6c56c4184c 100644 --- a/nym-vpn-app/src/i18n/fa/settings.json +++ b/nym-vpn-app/src/i18n/fa/settings.json @@ -44,5 +44,9 @@ "client-version": "نسخه مشترک", "daemon-version": "نسخه Daemon", "network-name": "شبکه" + }, + "logout-confirmation": { + "title": "مطمئن هستید؟", + "description": "برای ورود مجدد به عبارت بازیابی خود نیاز خواهید داشت." } } diff --git a/nym-vpn-app/src/i18n/fr/add-credential.json b/nym-vpn-app/src/i18n/fr/add-credential.json index fa72f0968a..89fa8882ce 100644 --- a/nym-vpn-app/src/i18n/fr/add-credential.json +++ b/nym-vpn-app/src/i18n/fr/add-credential.json @@ -1,9 +1,14 @@ { - "added-notification": "L'identifiant a été ajouté !", - "welcome": "Bienvenue !", - "description1": "Saisissez votre identifiant pour démarrer", - "description2": "Pour générer un identifiant, merci d'utiliser le lien fourni dans l'email d'invitation à la phase de tests.", - "input-label": "Identifiant", - "login-button": "Ajouter un identifiant", - "error": "Identifiant invalide" + "added-notification": "Appareil ajouté à votre compte avec succès", + "welcome": "Bienvenue sur NymVPN !", + "description1": "Entrez les 24 mots de votre phrase de récupération NymVPN pour vous connecter à votre compte", + "description2": "Vous ne pouvez utiliser que la phrase de récupération créée dans NymVPN, pas le portefeuille Nym.", + "input-label": "Phrase de récupération", + "login-button": "S'identifier", + "error": "Phrase de récupération invalide", + "create-account": { + "text": "Nouveau sur NymVPN ?", + "link": "Créer un compte" + }, + "input-placeholder": "p.e. smoke artefact velvet skull pop palace tortoise damage rough…" } diff --git a/nym-vpn-app/src/i18n/fr/errors.json b/nym-vpn-app/src/i18n/fr/errors.json index c2d8c32c4c..327524ad23 100644 --- a/nym-vpn-app/src/i18n/fr/errors.json +++ b/nym-vpn-app/src/i18n/fr/errors.json @@ -3,7 +3,8 @@ "internal": "Erreur interne", "daemon": { "not-connected": "Non connecté au daemon", - "internal": "Erreur interne du daemon" + "internal": "Erreur interne du daemon", + "invalid-network": "Réseau invalide" }, "grpc": "Erreur interne gRPC", "connection": { @@ -65,7 +66,8 @@ "add-ipv6-route": "Échec de l'ajout d'une route par défaut ipv6 pour capturer le trafic ipv6", "tun-device": "Échec du périphérique Tun", "routing": "Échec du routage", - "unhandled-exit": "Le VPN a échoué à la sortie avec une erreur, probablement à cause d'un bug." + "unhandled-exit": "Le VPN a échoué à la sortie avec une erreur, probablement à cause d'un bug.", + "ready-to-connect": "Il n'a pas encore été possible de déterminer si nous sommes prêts à nous connecter lors de la vérification" }, "countries-request": { "entry": "Échec de la recherche des pays de nœuds d'entrée disponibles", @@ -77,5 +79,15 @@ "exit-node": { "routing": "Le nœud de sortie ne relai pas le trafic {{protocol}}", "ping": "Échec du ping sur le nœud de sortie pour le trafic {{protocol}}" + }, + "account": { + "invalid-recovery-phrase": "Phrase de récupération invalide", + "device": { + "not-registered": "L'appareil n'est pas enregistré", + "not-active": "L'appareil n'est pas actif" + }, + "no-account-stored": "Aucune phrase de récupération stockée", + "not-active": "The compte n'est pas actif", + "no-active-subscription": "Le compte n'a pas d'abonnement actif" } } diff --git a/nym-vpn-app/src/i18n/fr/glossary.json b/nym-vpn-app/src/i18n/fr/glossary.json index 8ae0681028..d5bec7a776 100644 --- a/nym-vpn-app/src/i18n/fr/glossary.json +++ b/nym-vpn-app/src/i18n/fr/glossary.json @@ -3,5 +3,8 @@ "via": "via", "left": "restant", "ok": "ok", - "selected": "choisi" + "selected": "choisi", + "cancel": "annuler", + "login": "se connecter", + "logout": "se déconnecter" } diff --git a/nym-vpn-app/src/i18n/fr/notifications.json b/nym-vpn-app/src/i18n/fr/notifications.json index f0149d3f7a..16216fefd4 100644 --- a/nym-vpn-app/src/i18n/fr/notifications.json +++ b/nym-vpn-app/src/i18n/fr/notifications.json @@ -3,5 +3,9 @@ "connected": "connecté au tunnel VPN", "disconnected": "NymVPN s'est déconnecté. Pour protéger votre vie privée, veuillez vous reconnecter.", "failed": "la connexion au tunnel VPN a échoué !" + }, + "logout": { + "success": "Déconnexion réussie", + "error": "Une erreur est survenue lors de la déconnexion. Veuillez réessayer." } } diff --git a/nym-vpn-app/src/i18n/fr/settings.json b/nym-vpn-app/src/i18n/fr/settings.json index c8dc73e8ef..02c904bb54 100644 --- a/nym-vpn-app/src/i18n/fr/settings.json +++ b/nym-vpn-app/src/i18n/fr/settings.json @@ -29,7 +29,7 @@ "licenses-js": "Licences (JavaScript)" }, "display-theme": "Apparence", - "login-button": "Ajoutez un identifiant pour vous connecter", + "login-button": "S'identifier", "monitoring-alert": "Redémarrez l'application pour que le changement s'applique.", "faq": "F.A.Q.", "quit": "Quitter NymVPN", @@ -44,5 +44,9 @@ "client-version": "Version du client", "daemon-version": "Version du daemon", "network-name": "Réseau" + }, + "logout-confirmation": { + "title": "Etes-vous sûr ?", + "description": "Vous aurez besoin de votre phrase de récupération pour vous reconnecter." } } diff --git a/nym-vpn-app/src/i18n/hi/add-credential.json b/nym-vpn-app/src/i18n/hi/add-credential.json index 09b1aa20ba..fd298e41f2 100644 --- a/nym-vpn-app/src/i18n/hi/add-credential.json +++ b/nym-vpn-app/src/i18n/hi/add-credential.json @@ -1,13 +1,14 @@ { - "welcome": "स्वागत है!", - "description1": "शुरू करने के लिए अपने क्रेडेंशियल दर्ज करें", - "input-label": "क्रेडेंशियल", - "description2": "नया क्रेडेंशियल उत्पन्न करने के लिए, कृपया अल्फा चरण के निमंत्रण ईमेल में दिए गए लिंक का उपयोग करें।", + "welcome": "NymVPN में आपका स्वागत है!", + "description1": "शुरू करने के लिए अपने चौबीस शब्द का क्रेडेंशियल दर्ज करें", + "input-label": "रिकवरी वाक्यांश", + "description2": "आप NymVPN में बनाई गई रिकवरी वाक्यांश ही उपयोग कर सकते हैं, Nym वॉलेट की नहीं।", "login-button": "क्रेडेंशियल जोड़ें", - "error": "अमान्य क्रेडेंशियल", - "added-notification": "क्रेडेंशियल सफलतापूर्वक दर्ज हो गया है!", + "error": "अमान्य रिकवरी वाक्यांश", + "added-notification": "डिवाइस सफलतापूर्वक आपके खाते में जोड़ा गया है", "create-account": { "text": "NymVPN में नए हैं?", "link": "खाता बनाएं" - } + }, + "input-placeholder": "e.g. smoke artefact velvet skull pop palace tortoise damage rough…" } diff --git a/nym-vpn-app/src/i18n/hi/errors.json b/nym-vpn-app/src/i18n/hi/errors.json index bd9c49f441..f4067fa0ca 100644 --- a/nym-vpn-app/src/i18n/hi/errors.json +++ b/nym-vpn-app/src/i18n/hi/errors.json @@ -73,12 +73,21 @@ "internal": "अंदरूनी त्रुटि", "daemon": { "not-connected": "Daemon से कनेक्ट नहीं है", - "internal": "Daemon अंदरूनी त्रुटि" + "internal": "Daemon अंदरूनी त्रुटि", + "invalid-network": "अमान्य नेटवर्क" }, "grpc": "अंदरूनी gRPC त्रुटि", "entry-node-routing": "प्रवेश नोड ट्रैफ़िक को रूट नहीं कर रहा है (क्या इंटरनेट कनेक्शन बंद है?)", "out-of-bandwidth": "निर्धारित बैंडविड्थ समाप्त", "account": { - "invalid-recovery-phrase": "अमान्य रिकवरी फ्रेज़" + "invalid-recovery-phrase": "अमान्य रिकवरी फ्रेज़", + "no-account-stored": "कोई खाता रिकवरी वाक्यांश संग्रहीत नहीं है", + "not-active": "यह खाता सक्रिय नहीं है", + "device": { + "not-registered": "यह डिवाइस पंजीकृत नहीं है", + "not-active": "यह डिवाइस सक्रिय नहीं है" + }, + "storage": "स्टोरेज बैकएंड एरर", + "no-active-subscription": "खाते में सक्रिय सब्सक्रिप्शन नहीं है" } } diff --git a/nym-vpn-app/src/i18n/hi/glossary.json b/nym-vpn-app/src/i18n/hi/glossary.json index 4cbd5ce941..0f2914f441 100644 --- a/nym-vpn-app/src/i18n/hi/glossary.json +++ b/nym-vpn-app/src/i18n/hi/glossary.json @@ -2,5 +2,6 @@ "via": "के माध्यम से", "selected": "चुना गया", "ok": "ok", - "left": "बचा हुआ" + "left": "बचा हुआ", + "account": "खाता" } diff --git a/nym-vpn-app/src/i18n/it/add-credential.json b/nym-vpn-app/src/i18n/it/add-credential.json index ebcd1aec48..f587e125da 100644 --- a/nym-vpn-app/src/i18n/it/add-credential.json +++ b/nym-vpn-app/src/i18n/it/add-credential.json @@ -4,5 +4,9 @@ "error": "Credenziali invalide", "welcome": "Benvenuto/a!", "description1": "Inserisci le credenziali per iniziare", - "description2": "Per generare delle nuove credenziali, usa il link che hai ricevuto nell'email di invito all'Alfa." + "description2": "Per generare delle nuove credenziali, usa il link che hai ricevuto nell'email di invito all'Alfa.", + "added-notification": "Dispositivo aggiunto con successo al tuo account", + "create-account": { + "link": "Crea un account" + } } diff --git a/nym-vpn-app/src/i18n/it/errors.json b/nym-vpn-app/src/i18n/it/errors.json index 0967ef424b..94d2f2940a 100644 --- a/nym-vpn-app/src/i18n/it/errors.json +++ b/nym-vpn-app/src/i18n/it/errors.json @@ -1 +1,5 @@ -{} +{ + "account": { + "invalid-recovery-phrase": "Frase di recupero non valida" + } +} diff --git a/nym-vpn-app/src/i18n/it/home.json b/nym-vpn-app/src/i18n/it/home.json index 36b39a7bf2..2e424eee57 100644 --- a/nym-vpn-app/src/i18n/it/home.json +++ b/nym-vpn-app/src/i18n/it/home.json @@ -5,7 +5,8 @@ "connected": "Connesso", "disconnected": "Disconnesso", "disconnecting": "Disconnessione", - "unknown": "Sconosciuto" + "unknown": "Sconosciuto", + "connecting": "Connessione in corso" }, "last-hop": "Ultimo hop", "first-hop": "Primo hop", diff --git a/nym-vpn-app/src/i18n/it/settings.json b/nym-vpn-app/src/i18n/it/settings.json index 09c6035ffe..84c28f69e9 100644 --- a/nym-vpn-app/src/i18n/it/settings.json +++ b/nym-vpn-app/src/i18n/it/settings.json @@ -9,21 +9,43 @@ }, "support": { "title": "Supporto", - "faq": "Controlla le FAQ" + "faq": "Controlla le FAQ", + "contact": "Contatta il supporto" }, "auto-connect": { - "title": "Auto-connect" + "title": "Auto-connect", + "desc": "Connessione automatica all'avvio dell'app" }, "legal": { "title": "Legale", "policy": "Privacy policy", - "tos": "Termini di utilizzo" + "tos": "Termini di utilizzo", + "license": "Licenza", + "licenses-rust": "Licenze (Rust)", + "licenses-js": "Licenze (JS)", + "emptyData": "Dati sulla licenza non disponibili" }, "login-button": "Aggiungi le credenziali per connetterti", "logs": { - "title": "Logs" + "title": "Logs", + "desc": "Copia o elimina i log" }, "error-monitoring": { - "title": "Report degli errori anonimo" + "title": "Report degli errori anonimo", + "desc": "si applica al riavvio dell'app" + }, + "info": { + "daemon-version": "Versione del daemon", + "client-version": "Versione del cliente", + "network-name": "Rete" + }, + "notifications": { + "title": "Notifiche desktop" + }, + "monitoring-alert": "Devi riavviare l'app per applicare la modifica.", + "faq": "FAQ", + "quit": "Chiudi NymVPN", + "logout-confirmation": { + "description": "Avrai bisogno della tua frase di recupero per riaccedere." } } diff --git a/nym-vpn-app/src/i18n/it/welcome.json b/nym-vpn-app/src/i18n/it/welcome.json index 606b839edb..364a773dda 100644 --- a/nym-vpn-app/src/i18n/it/welcome.json +++ b/nym-vpn-app/src/i18n/it/welcome.json @@ -1,7 +1,17 @@ { "title": { - "part1": "Benvenuto/a" + "part1": "Benvenuto/a", + "part2": "alla beta di NymVPN" }, "continue-button": "Continua", - "experimental": "Questo prodotto è in fase di sperimentazione. Non affidartici per un'anonimità completa (per ora)." + "experimental": "Questo prodotto è in fase di sperimentazione. Non affidartici per un'anonimità completa (per ora).", + "description": { + "part2": "Il tuo feedback è fondamentale", + "part3": "per identificare e risolvere i problemi. Abilita il monitoraggio anonimo degli errori", + "part4": "e l'analisi, puoi disattivarlo in qualsiasi momento. Grazie per il tuo supporto!", + "part1": "Aiutaci a migliorare la nostra app durante la fase beta!" + }, + "tos": { + "part3": "." + } } diff --git a/nym-vpn-app/src/i18n/ja/add-credential.json b/nym-vpn-app/src/i18n/ja/add-credential.json index 02016f7194..1d4268047a 100644 --- a/nym-vpn-app/src/i18n/ja/add-credential.json +++ b/nym-vpn-app/src/i18n/ja/add-credential.json @@ -1,6 +1,6 @@ { "input-label": "リカバリーフレーズ", - "login-button": "認証情報を追加", + "login-button": "ログイン", "error": "無効なリカバリーフレーズ", "added-notification": "デバイスがアカウントに正常に追加されました", "welcome": "NymVPNへようこそ!", diff --git a/nym-vpn-app/src/i18n/ja/glossary.json b/nym-vpn-app/src/i18n/ja/glossary.json index 71914c882a..0260bec2e5 100644 --- a/nym-vpn-app/src/i18n/ja/glossary.json +++ b/nym-vpn-app/src/i18n/ja/glossary.json @@ -3,5 +3,8 @@ "left": "残り時間", "ok": "ok", "selected": "選択済み", - "account": "アカウント" + "account": "アカウント", + "cancel": "キャンセル", + "login": "ログイン", + "logout": "ログアウト" } diff --git a/nym-vpn-app/src/i18n/ja/notifications.json b/nym-vpn-app/src/i18n/ja/notifications.json index 1c226ea097..766007e0d0 100644 --- a/nym-vpn-app/src/i18n/ja/notifications.json +++ b/nym-vpn-app/src/i18n/ja/notifications.json @@ -3,5 +3,9 @@ "connected": "VPNトンネルに接続済", "disconnected": "NymVPNが切断されました。プライバシーを保護するために、再接続してください。", "failed": "VPNトンネルの接続に失敗しました!" + }, + "logout": { + "success": "正常にログアウトできました", + "error": "ログアウト中にエラーが発生しました。もう一度お試しください。" } } diff --git a/nym-vpn-app/src/i18n/ja/settings.json b/nym-vpn-app/src/i18n/ja/settings.json index e196d752c0..2c020d5ca3 100644 --- a/nym-vpn-app/src/i18n/ja/settings.json +++ b/nym-vpn-app/src/i18n/ja/settings.json @@ -38,11 +38,15 @@ "faq": "よくある質問", "display-theme": "ディスプレイモード", "quit": "NymVPNを終了する", - "login-button": "接続するには、認証情報を追加してください", + "login-button": "ログイン", "monitoring-alert": "変更を反映させるには、アプリを再起動する必要があります。", "info": { "client-version": "クライアントバージョン", "daemon-version": "デーモンバージョン", "network-name": "ネットワーク" + }, + "logout-confirmation": { + "title": "実行しますか?", + "description": "再ログインするにはリカバリーフレーズが必要です。" } } diff --git a/nym-vpn-app/src/i18n/pt-BR/glossary.json b/nym-vpn-app/src/i18n/pt-BR/glossary.json index ae831b0636..91501deb20 100644 --- a/nym-vpn-app/src/i18n/pt-BR/glossary.json +++ b/nym-vpn-app/src/i18n/pt-BR/glossary.json @@ -3,5 +3,8 @@ "left": "restante", "ok": "ok", "selected": "selecionado", - "account": "conta" + "account": "conta", + "cancel": "cancelar", + "login": "fazer login", + "logout": "encerrar sessão" } diff --git a/nym-vpn-app/src/i18n/pt-BR/notifications.json b/nym-vpn-app/src/i18n/pt-BR/notifications.json index 52061655b0..498a60e3f9 100644 --- a/nym-vpn-app/src/i18n/pt-BR/notifications.json +++ b/nym-vpn-app/src/i18n/pt-BR/notifications.json @@ -3,5 +3,9 @@ "connected": "Túnel VPN conectado", "disconnected": "A NymVPN foi desconectada. Para proteger sua privacidade, reconecte-se.", "failed": "A conexão do túnel VPN falhou!" + }, + "logout": { + "success": "Logout bem-sucedido", + "error": "Ocorreu um erro ao fazer o logout. Tente novamente." } } diff --git a/nym-vpn-app/src/i18n/pt-BR/settings.json b/nym-vpn-app/src/i18n/pt-BR/settings.json index 4efcdb1cd0..5c0550e5df 100644 --- a/nym-vpn-app/src/i18n/pt-BR/settings.json +++ b/nym-vpn-app/src/i18n/pt-BR/settings.json @@ -44,5 +44,9 @@ "daemon-version": "Versão do Daemon", "network-name": "Rede", "client-version": "Versão do cliente" + }, + "logout-confirmation": { + "description": "Você precisará da frase de recuperação para fazer login novamente.", + "title": "Você tem certeza?" } } diff --git a/nym-vpn-app/src/i18n/pt-PT/glossary.json b/nym-vpn-app/src/i18n/pt-PT/glossary.json index 370e71bc3b..271b72df8a 100644 --- a/nym-vpn-app/src/i18n/pt-PT/glossary.json +++ b/nym-vpn-app/src/i18n/pt-PT/glossary.json @@ -3,5 +3,8 @@ "left": "resta", "ok": "ok", "selected": "selecionado", - "account": "conta" + "account": "conta", + "cancel": "cancelar", + "login": "login", + "logout": "Terminar sessão" } diff --git a/nym-vpn-app/src/i18n/pt-PT/notifications.json b/nym-vpn-app/src/i18n/pt-PT/notifications.json index 5a5990b5d2..8af81922ad 100644 --- a/nym-vpn-app/src/i18n/pt-PT/notifications.json +++ b/nym-vpn-app/src/i18n/pt-PT/notifications.json @@ -3,5 +3,9 @@ "connected": "Túnel VPN conectado", "disconnected": "NymVPN foi desconectada. Para proteger a sua privacidade, por favor reconecte-se.", "failed": "A ligação do túnel VPN falhou!" + }, + "logout": { + "success": "Terminar sessão com sucesso", + "error": "Ocorreu um erro ao terminar a sessão. Por favor, tente novamente." } } diff --git a/nym-vpn-app/src/i18n/pt-PT/settings.json b/nym-vpn-app/src/i18n/pt-PT/settings.json index f18079b2ac..ac680ce942 100644 --- a/nym-vpn-app/src/i18n/pt-PT/settings.json +++ b/nym-vpn-app/src/i18n/pt-PT/settings.json @@ -44,5 +44,9 @@ "client-version": "Versão cliente", "daemon-version": "Versão do daemon", "network-name": "Rede" + }, + "logout-confirmation": { + "title": "Tens a certeza?", + "description": "Necessitará da sua frase de recuperação para iniciar sessão novamente." } } diff --git a/nym-vpn-app/src/i18n/ru/errors.json b/nym-vpn-app/src/i18n/ru/errors.json index a50d1eca7d..030c9721c7 100644 --- a/nym-vpn-app/src/i18n/ru/errors.json +++ b/nym-vpn-app/src/i18n/ru/errors.json @@ -63,7 +63,8 @@ }, "add-ipv6-route": "Не удалось добавить маршрут ipv6 по умолчанию для захвата трафика ipv6", "tun-device": "Ошибка устройства Tun", - "routing": "Маршрутизация не удалась" + "routing": "Маршрутизация не удалась", + "ready-to-connect": "Ещё не удалось определить, готовы ли мы к подключению во время проверки" }, "countries-request": { "exit": "Сбой при получении списка стран для выхода", diff --git a/nym-vpn-app/src/i18n/ru/glossary.json b/nym-vpn-app/src/i18n/ru/glossary.json index 882d0bf673..87bdc73061 100644 --- a/nym-vpn-app/src/i18n/ru/glossary.json +++ b/nym-vpn-app/src/i18n/ru/glossary.json @@ -3,5 +3,8 @@ "left": "осталось", "ok": "ок", "selected": "выбрано", - "account": "аккаунт" + "account": "аккаунт", + "cancel": "отмена", + "login": "войти", + "logout": "выйти" } diff --git a/nym-vpn-app/src/i18n/ru/notifications.json b/nym-vpn-app/src/i18n/ru/notifications.json index d5362902e5..e24685b21b 100644 --- a/nym-vpn-app/src/i18n/ru/notifications.json +++ b/nym-vpn-app/src/i18n/ru/notifications.json @@ -3,5 +3,9 @@ "connected": "VPN-туннель подключён", "disconnected": "NymVPN отключен. Для защиты вашей конфиденциальности, пожалуйста, подключитесь снова.", "failed": "Соединение с VPN-туннелем не удалось!" + }, + "logout": { + "error": "Произошла ошибка при выходе. Пожалуйста попробуйте снова.", + "success": "Успешный выход" } } diff --git a/nym-vpn-app/src/i18n/ru/settings.json b/nym-vpn-app/src/i18n/ru/settings.json index 0749fc84f3..23f93bdf86 100644 --- a/nym-vpn-app/src/i18n/ru/settings.json +++ b/nym-vpn-app/src/i18n/ru/settings.json @@ -44,5 +44,9 @@ "client-version": "Версия клиента", "daemon-version": "Версия демона", "network-name": "Сеть" + }, + "logout-confirmation": { + "title": "Вы уверены?", + "description": "Чтобы войти снова, вам понадобится фраза восстановления." } } diff --git a/nym-vpn-app/src/i18n/tr/glossary.json b/nym-vpn-app/src/i18n/tr/glossary.json index 950645a0d8..ae0d331f75 100644 --- a/nym-vpn-app/src/i18n/tr/glossary.json +++ b/nym-vpn-app/src/i18n/tr/glossary.json @@ -3,5 +3,8 @@ "left": "kaldı", "ok": "tamam", "selected": "seçildi", - "account": "hesap" + "account": "hesap", + "cancel": "iptal et", + "login": "giriş yap", + "logout": "çıkış yap" } diff --git a/nym-vpn-app/src/i18n/tr/notifications.json b/nym-vpn-app/src/i18n/tr/notifications.json index f5723e722b..c042b593c2 100644 --- a/nym-vpn-app/src/i18n/tr/notifications.json +++ b/nym-vpn-app/src/i18n/tr/notifications.json @@ -3,5 +3,9 @@ "connected": "VPN tüneli bağlandı", "disconnected": "NymVPN bağlantısı kesildi. Gizliliğinizi korumak için lütfen yeniden bağlanın.", "failed": "VPN tünel bağlantısı başarısız oldu!" + }, + "logout": { + "success": "Oturum kapatma başarılı", + "error": "Oturumu kaparken bir hata oluştu. Lütfen tekrar deneyin." } } diff --git a/nym-vpn-app/src/i18n/tr/settings.json b/nym-vpn-app/src/i18n/tr/settings.json index 47ddac58ac..a81baca379 100644 --- a/nym-vpn-app/src/i18n/tr/settings.json +++ b/nym-vpn-app/src/i18n/tr/settings.json @@ -44,5 +44,9 @@ "daemon-version": "Daemon sürümü", "client-version": "İstemci sürümü", "network-name": "Ağ" + }, + "logout-confirmation": { + "title": "Emin misiniz?", + "description": "Tekrar giriş yapmak için kurtarma ifadenize ihtiyacınız olacak." } } diff --git a/nym-vpn-app/src/i18n/uk/glossary.json b/nym-vpn-app/src/i18n/uk/glossary.json index bb18142fac..f5493ddc1d 100644 --- a/nym-vpn-app/src/i18n/uk/glossary.json +++ b/nym-vpn-app/src/i18n/uk/glossary.json @@ -3,5 +3,8 @@ "left": "Час до завершення", "ok": "ок", "selected": "вибрано", - "account": "обліковий запис" + "account": "акаунт", + "cancel": "скасувати", + "login": "логін", + "logout": "вихід" } diff --git a/nym-vpn-app/src/i18n/uk/notifications.json b/nym-vpn-app/src/i18n/uk/notifications.json index 7b6da77bcd..6f15b89160 100644 --- a/nym-vpn-app/src/i18n/uk/notifications.json +++ b/nym-vpn-app/src/i18n/uk/notifications.json @@ -3,5 +3,9 @@ "connected": "VPN-тунель підключено", "disconnected": "NymVPN відключився. Щоб захистити вашу конфіденційність, будь ласка, підключіться знову.", "failed": "Не вдалося з'єднання з тунелем VPN!" + }, + "logout": { + "success": "Успішний вихід з системи", + "error": "Виникла помилка при виході з системи. Будь ласка, спробуйте ще раз." } } diff --git a/nym-vpn-app/src/i18n/uk/settings.json b/nym-vpn-app/src/i18n/uk/settings.json index e7b8f85dc3..2e745667e5 100644 --- a/nym-vpn-app/src/i18n/uk/settings.json +++ b/nym-vpn-app/src/i18n/uk/settings.json @@ -44,5 +44,9 @@ "daemon-version": "Версія Daemon", "network-name": "Мережа", "client-version": "Версія клієнту" + }, + "logout-confirmation": { + "description": "Для повторного входу вам знадобиться фраза відновлення.", + "title": "Ти впевнений?" } } diff --git a/nym-vpn-app/src/i18n/zh-Hans/errors.json b/nym-vpn-app/src/i18n/zh-Hans/errors.json index 3c7ca9bd8c..12824ee154 100644 --- a/nym-vpn-app/src/i18n/zh-Hans/errors.json +++ b/nym-vpn-app/src/i18n/zh-Hans/errors.json @@ -66,7 +66,8 @@ }, "add-ipv6-route": "添加 ipv6 默认路由捕获 ipv6 流量失败", "tun-device": "Tun 设备故障", - "routing": "路由选择失败" + "routing": "路由选择失败", + "ready-to-connect": "在检查过程中还无法确定我们是否已准备好连接" }, "countries-request": { "entry": "获取可用条目节点国家失败", @@ -80,7 +81,7 @@ "ping": "{{protocol}} 流量的出口节点 ping 失败" }, "account": { - "invalid-recovery-phrase": "恢复短语无效", + "invalid-recovery-phrase": "助记词无效", "storage": "存储后端错误", "no-account-stored": "未存储帐户恢复短语", "not-active": "账户未激活", diff --git a/nym-vpn-app/src/i18n/zh-Hans/glossary.json b/nym-vpn-app/src/i18n/zh-Hans/glossary.json index 2c65566156..caef069ec9 100644 --- a/nym-vpn-app/src/i18n/zh-Hans/glossary.json +++ b/nym-vpn-app/src/i18n/zh-Hans/glossary.json @@ -3,5 +3,8 @@ "via": "通过", "ok": "ok", "selected": "选定的", - "account": "账户" + "account": "账户", + "cancel": "取消", + "login": "登录", + "logout": "注销" } diff --git a/nym-vpn-app/src/i18n/zh-Hans/notifications.json b/nym-vpn-app/src/i18n/zh-Hans/notifications.json index 13c2a5cf69..be60cffb38 100644 --- a/nym-vpn-app/src/i18n/zh-Hans/notifications.json +++ b/nym-vpn-app/src/i18n/zh-Hans/notifications.json @@ -3,5 +3,9 @@ "connected": "已连接 VPN 隧道", "disconnected": "NymVPN 已断开连接。为了保护您的隐私,请重新连接。", "failed": "VPN 隧道连接失败!" + }, + "logout": { + "success": "注销成功", + "error": "退出登录时发生错误。 请重试。" } } diff --git a/nym-vpn-app/src/i18n/zh-Hans/settings.json b/nym-vpn-app/src/i18n/zh-Hans/settings.json index 3e917216aa..860535b604 100644 --- a/nym-vpn-app/src/i18n/zh-Hans/settings.json +++ b/nym-vpn-app/src/i18n/zh-Hans/settings.json @@ -44,5 +44,9 @@ "client-version": "客户端版本", "daemon-version": "守护进程版本", "network-name": "网络" + }, + "logout-confirmation": { + "title": "你确定吗?", + "description": "您需要使用助记词才能再次登录。" } } diff --git a/nym-vpn-app/src/router.tsx b/nym-vpn-app/src/router.tsx index 0f3ceaebd7..4169879fbf 100644 --- a/nym-vpn-app/src/router.tsx +++ b/nym-vpn-app/src/router.tsx @@ -50,123 +50,135 @@ const createRouterFn = Sentry.wrapCreateBrowserRouter(createBrowserRouter); // ⚠ router instance creation must remain outside of React // tree with routes statically defined -const router = createRouterFn([ +const router = createRouterFn( + [ + { + path: routes.root, + element: , + children: [ + { + element: , + errorElement: , + index: true, + }, + { + path: routes.login, + element: , + errorElement: , + }, + { + path: routes.settings, + element: , + errorElement: , + children: [ + { + element: , + errorElement: , + index: true, + }, + { + path: routes.appearance, + element: , + errorElement: , + children: [ + { + element: , + errorElement: , + index: true, + }, + { + path: routes.lang, + element: , + errorElement: , + }, + { + path: routes.display, + element: , + errorElement: , + }, + ], + }, + { + path: routes.feedback, + element: , + errorElement: , + children: [ + { + path: routes.feedbackSend, + // To be implemented + element:
, + errorElement: , + }, + ], + }, + { + path: routes.support, + element: , + errorElement: , + }, + { + path: routes.legal, + element: , + errorElement: , + children: [ + { + element: , + errorElement: , + index: true, + }, + { + path: routes.licensesRust, + element: , + errorElement: , + }, + { + path: routes.licensesJs, + element: , + errorElement: , + }, + { + path: routes.licenseDetails, + element: , + errorElement: , + }, + ], + }, + ], + }, + { + path: routes.entryNodeLocation, + element: , + errorElement: , + }, + { + path: routes.exitNodeLocation, + element: , + errorElement: , + }, + ], + }, + { + path: routes.hideout, + element: , + children: [ + { + path: routes.welcome, + element: , + errorElement: , + }, + ], + }, + ], { - path: routes.root, - element: , - children: [ - { - element: , - errorElement: , - index: true, - }, - { - path: routes.login, - element: , - errorElement: , - }, - { - path: routes.settings, - element: , - errorElement: , - children: [ - { - element: , - errorElement: , - index: true, - }, - { - path: routes.appearance, - element: , - errorElement: , - children: [ - { - element: , - errorElement: , - index: true, - }, - { - path: routes.lang, - element: , - errorElement: , - }, - { - path: routes.display, - element: , - errorElement: , - }, - ], - }, - { - path: routes.feedback, - element: , - errorElement: , - children: [ - { - path: routes.feedbackSend, - // To be implemented - element:
, - errorElement: , - }, - ], - }, - { - path: routes.support, - element: , - errorElement: , - }, - { - path: routes.legal, - element: , - errorElement: , - children: [ - { - element: , - errorElement: , - index: true, - }, - { - path: routes.licensesRust, - element: , - errorElement: , - }, - { - path: routes.licensesJs, - element: , - errorElement: , - }, - { - path: routes.licenseDetails, - element: , - errorElement: , - }, - ], - }, - ], - }, - { - path: routes.entryNodeLocation, - element: , - errorElement: , - }, - { - path: routes.exitNodeLocation, - element: , - errorElement: , - }, - ], + future: { + v7_relativeSplatPath: true, + v7_fetcherPersist: true, + v7_normalizeFormMethod: true, + v7_partialHydration: true, + v7_skipActionStatusRevalidation: true, + v7_skipActionErrorRevalidation: true, + }, }, - { - path: routes.hideout, - element: , - children: [ - { - path: routes.welcome, - element: , - errorElement: , - }, - ], - }, -]); +); export default router; diff --git a/nym-vpn-app/src/screens/home/NetworkModeSelect.tsx b/nym-vpn-app/src/screens/home/NetworkModeSelect.tsx index b8cf0b9aac..47796cdfe0 100644 --- a/nym-vpn-app/src/screens/home/NetworkModeSelect.tsx +++ b/nym-vpn-app/src/screens/home/NetworkModeSelect.tsx @@ -35,6 +35,7 @@ function NetworkModeSelect() { try { await invoke('set_vpn_mode', { mode: value }); dispatch({ type: 'set-vpn-mode', mode: value }); + console.info('vpn mode set to', value); } catch (e) { console.warn(e); } finally { diff --git a/nym-vpn-app/src/screens/location/NodeLocation.tsx b/nym-vpn-app/src/screens/location/NodeLocation.tsx index c70578cc45..0ed45b6f4f 100644 --- a/nym-vpn-app/src/screens/location/NodeLocation.tsx +++ b/nym-vpn-app/src/screens/location/NodeLocation.tsx @@ -32,8 +32,7 @@ function NodeLocation({ node }: { node: NodeHop }) { fastestNodeLocation, entryCountriesLoading, exitCountriesLoading, - fetchMxEntryCountries, - fetchMxExitCountries, + fetchMnCountries, fetchWgCountries, entryCountriesError, exitCountriesError, @@ -58,22 +57,14 @@ function NodeLocation({ node }: { node: NodeHop }) { const dispatch = useMainDispatch() as StateDispatch; const navigate = useNavigate(); - // request backend to refresh cache + // refresh cache (if stale) useEffect(() => { - if (vpnMode === 'Mixnet' && node === 'entry') { - fetchMxEntryCountries(); - } else if (vpnMode === 'Mixnet' && node === 'exit') { - fetchMxExitCountries(); + if (vpnMode === 'Mixnet') { + fetchMnCountries(node); } else { fetchWgCountries(); } - }, [ - node, - vpnMode, - fetchMxEntryCountries, - fetchMxExitCountries, - fetchWgCountries, - ]); + }, [node, vpnMode, fetchWgCountries, fetchMnCountries]); // update the UI country list whenever the country list or // fastest country change (likely from the backend) @@ -138,7 +129,7 @@ function NodeLocation({ node }: { node: NodeHop }) { const renderError = (e: AppError) => (
-

{`${tE(e.key)}: ${e.data?.details || '-'}`}

+

{`${tE(e.key)}: ${e.message} ${e.data?.details || '-'}`}

); diff --git a/nym-vpn-app/src/screens/login/Login.tsx b/nym-vpn-app/src/screens/login/Login.tsx index 16d97b00f3..5668512495 100644 --- a/nym-vpn-app/src/screens/login/Login.tsx +++ b/nym-vpn-app/src/screens/login/Login.tsx @@ -10,7 +10,6 @@ import { useI18nError } from '../../hooks'; import { routes } from '../../router'; import { BackendError, StateDispatch } from '../../types'; import { Button, Link, PageAnim, TextArea } from '../../ui'; -import { getCreateAccountUrl } from '../../helpers'; type AddError = { error: string; @@ -18,7 +17,7 @@ type AddError = { }; function Login() { - const { uiTheme, daemonStatus, networkEnv } = useMainState(); + const { uiTheme, daemonStatus, accountLinks } = useMainState(); const [phrase, setPhrase] = useState(''); const [error, setError] = useState(null); @@ -27,8 +26,7 @@ function Login() { const { t } = useTranslation('addCredential'); const { tE } = useI18nError(); const dispatch = useMainDispatch() as StateDispatch; - - const createAccountUrl = networkEnv && getCreateAccountUrl(networkEnv); + const signUpUrl = accountLinks?.signUp; const onChange = (phrase: string) => { setPhrase(phrase); @@ -116,12 +114,12 @@ function Login() { > {t('login-button')} - {createAccountUrl && ( + {signUpUrl && (
{t('create-account.text')} - +
)}
diff --git a/nym-vpn-app/src/screens/settings/Logout.tsx b/nym-vpn-app/src/screens/settings/Logout.tsx index fe091f1332..6f5ab47cc6 100644 --- a/nym-vpn-app/src/screens/settings/Logout.tsx +++ b/nym-vpn-app/src/screens/settings/Logout.tsx @@ -13,7 +13,7 @@ import { StateDispatch } from '../../types'; function Logout() { const [isOpen, setIsOpen] = useState(false); - const { account } = useMainState(); + const { account, daemonStatus } = useMainState(); const dispatch = useMainDispatch() as StateDispatch; const { t } = useTranslation('settings'); const navigate = useNavigate(); @@ -49,7 +49,11 @@ function Logout() { return ( <> - setIsOpen(true)} /> + setIsOpen(true)} + disabled={daemonStatus === 'NotOk'} + />
{ const checkAccount = async () => { diff --git a/nym-vpn-app/src/screens/settings/info-data/InfoData.tsx b/nym-vpn-app/src/screens/settings/info-data/InfoData.tsx index a685b66208..e4d014d962 100644 --- a/nym-vpn-app/src/screens/settings/info-data/InfoData.tsx +++ b/nym-vpn-app/src/screens/settings/info-data/InfoData.tsx @@ -2,7 +2,7 @@ import { useState } from 'react'; import clsx from 'clsx'; import { useTranslation } from 'react-i18next'; import { useMainState } from '../../../contexts'; -import NetworkEnvSelect from './NetworkEnvSelect.tsx'; +import NetworkEnvSelect from './NetworkEnvSelect'; import { S_STATE } from '../../../static'; function InfoData() { diff --git a/nym-vpn-app/src/state/init.ts b/nym-vpn-app/src/state/init.ts index 1e0666935c..0bfe1fdb95 100644 --- a/nym-vpn-app/src/state/init.ts +++ b/nym-vpn-app/src/state/init.ts @@ -1,7 +1,9 @@ +import i18n from 'i18next'; import { invoke } from '@tauri-apps/api/core'; import { getVersion } from '@tauri-apps/api/app'; import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; import { + CountryCacheDuration, DefaultCountry, DefaultRootFontSize, DefaultThemeMode, @@ -10,6 +12,7 @@ import { import { getJsLicenses, getRustLicenses } from '../data'; import { kvGet } from '../kvStore'; import { + AccountLinks, CodeDependency, ConnectionStateResponse, Country, @@ -23,6 +26,7 @@ import { } from '../types'; import fireRequests, { TauriReq } from './helper'; import { S_STATE } from '../static'; +import { MCache } from '../cache'; // initialize connection state const getInitialConnectionState = async () => { @@ -44,18 +48,20 @@ const getSessionStartTime = async () => { // init country list const getEntryCountries = async () => { - const mode = await kvGet('VpnMode'); - return await invoke('get_countries', { - vpnMode: mode || DefaultVpnMode, + const mode = (await kvGet('VpnMode')) || DefaultVpnMode; + const countries = await invoke('get_countries', { + vpnMode: mode, nodeType: 'Entry', }); + return { countries, mode }; }; const getExitCountries = async () => { - const mode = await kvGet('VpnMode'); - return await invoke('get_countries', { - vpnMode: mode || DefaultVpnMode, + const mode = (await kvGet('VpnMode')) || DefaultVpnMode; + const countries = await invoke('get_countries', { + vpnMode: mode, nodeType: 'Exit', }); + return { countries, mode }; }; const getTheme = async () => { @@ -90,6 +96,9 @@ export async function initFirstBatch(dispatch: StateDispatch) { request: () => getDaemonInfo(), onFulfilled: (info) => { dispatch({ type: 'set-daemon-info', info }); + if (info.network) { + S_STATE.networkEnvInit = true; + } }, }; @@ -264,7 +273,7 @@ export async function initSecondBatch(dispatch: StateDispatch) { const getEntryCountriesRq: TauriReq = { name: 'get_countries', request: () => getEntryCountries(), - onFulfilled: (countries) => { + onFulfilled: ({ countries, mode }) => { dispatch({ type: 'set-country-list', payload: { @@ -272,6 +281,11 @@ export async function initSecondBatch(dispatch: StateDispatch) { countries, }, }); + MCache.set( + mode === 'Mixnet' ? `mn-entry-countries` : 'wg-countries', + countries, + CountryCacheDuration, + ); dispatch({ type: 'set-countries-loading', payload: { hop: 'entry', loading: false }, @@ -282,7 +296,7 @@ export async function initSecondBatch(dispatch: StateDispatch) { const getExitCountriesRq: TauriReq = { name: 'get_countries', request: () => getExitCountries(), - onFulfilled: (countries) => { + onFulfilled: ({ countries, mode }) => { dispatch({ type: 'set-country-list', payload: { @@ -290,6 +304,11 @@ export async function initSecondBatch(dispatch: StateDispatch) { countries, }, }); + MCache.set( + mode === 'Mixnet' ? `mn-exit-countries` : 'wg-countries', + countries, + CountryCacheDuration, + ); dispatch({ type: 'set-countries-loading', payload: { hop: 'exit', loading: false }, @@ -297,5 +316,21 @@ export async function initSecondBatch(dispatch: StateDispatch) { }, }; - await fireRequests([getEntryCountriesRq, getExitCountriesRq]); + const getAccountLinksRq: TauriReq<() => Promise> = { + name: 'getAccountLinksRq', + request: () => + invoke('account_links', { locale: i18n.language }), + onFulfilled: (links) => { + dispatch({ + type: 'set-account-links', + links: links as AccountLinks | null, + }); + }, + }; + + await fireRequests([ + getEntryCountriesRq, + getExitCountriesRq, + getAccountLinksRq, + ]); } diff --git a/nym-vpn-app/src/state/reducer.ts b/nym-vpn-app/src/state/reducer.ts index 56348c4a9f..b0955bcd1e 100644 --- a/nym-vpn-app/src/state/reducer.ts +++ b/nym-vpn-app/src/state/reducer.ts @@ -6,6 +6,7 @@ import { DefaultVpnMode, } from '../constants'; import { + AccountLinks, AppError, AppState, CodeDependency, @@ -65,7 +66,8 @@ export type StateAction = | { type: 'set-code-deps-rust'; dependencies: CodeDependency[] } | { type: 'set-account'; stored: boolean } | { type: 'set-entry-countries-error'; payload: AppError | null } - | { type: 'set-exit-countries-error'; payload: AppError | null }; + | { type: 'set-exit-countries-error'; payload: AppError | null } + | { type: 'set-account-links'; links: AccountLinks | null }; export const initialState: AppState = { initialized: false, @@ -93,12 +95,9 @@ export const initialState: AppState = { codeDepsRust: [], codeDepsJs: [], account: false, - fetchMxEntryCountries: async () => { + fetchMnCountries: async () => { /* SCARECROW */ }, - fetchMxExitCountries: async () => { - /* SCARECROW */ - }, fetchWgCountries: async () => { /* SCARECROW */ }, @@ -286,6 +285,11 @@ export function reducer(state: AppState, action: StateAction): AppState { ...state, exitCountriesError: action.payload, }; + case 'set-account-links': + return { + ...state, + accountLinks: action.links, + }; case 'reset': return initialState; diff --git a/nym-vpn-app/src/state/useTauriEvents.ts b/nym-vpn-app/src/state/useTauriEvents.ts index 2b79c1f5ee..74ee552e90 100644 --- a/nym-vpn-app/src/state/useTauriEvents.ts +++ b/nym-vpn-app/src/state/useTauriEvents.ts @@ -1,9 +1,11 @@ import { useCallback, useEffect } from 'react'; import { listen } from '@tauri-apps/api/event'; import { invoke } from '@tauri-apps/api/core'; +import i18n from 'i18next'; import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; import dayjs from 'dayjs'; import { + AccountLinks, BackendError, ConnectionEvent as ConnectionEventData, DaemonInfo, @@ -19,6 +21,7 @@ import { ProgressEvent, StatusUpdateEvent, } from '../constants'; +import { S_STATE } from '../static'; function handleError(dispatch: StateDispatch, error?: BackendError | null) { if (!error) { @@ -43,11 +46,22 @@ export function useTauriEvents(dispatch: StateDispatch) { try { const info = await invoke('daemon_info'); dispatch({ type: 'set-daemon-info', info }); + if (info.network) { + S_STATE.networkEnvInit = true; + } const stored = await invoke('is_account_stored'); dispatch({ type: 'set-account', stored: stored || false }); } catch (e: unknown) { console.error('failed to refresh daemon info', e); } + try { + const links = await invoke('account_links', { + locale: i18n.language, + }); + dispatch({ type: 'set-account-links', links }); + } catch (e: unknown) { + console.warn('failed to get account links', e); + } } }); }, [dispatch]); diff --git a/nym-vpn-app/src/static.ts b/nym-vpn-app/src/static.ts index 91f61e28c6..086861aeac 100644 --- a/nym-vpn-app/src/static.ts +++ b/nym-vpn-app/src/static.ts @@ -2,5 +2,7 @@ export const S_STATE = { // Either the vpn mode has been initialized or not vpnModeInit: false, + networkEnvInit: false, + systemMessageInit: false, networkEnvSelect: false, }; diff --git a/nym-vpn-app/src/types/app-state.ts b/nym-vpn-app/src/types/app-state.ts index ee24933b0e..fb4570ed94 100644 --- a/nym-vpn-app/src/types/app-state.ts +++ b/nym-vpn-app/src/types/app-state.ts @@ -1,8 +1,8 @@ import { Dispatch } from 'react'; import { Dayjs } from 'dayjs'; import { StateAction } from '../state'; -import { Country, NodeLocation, ThemeMode, UiTheme } from './common'; -import { BackendError, ErrorKey, NetworkEnv } from './tauri-ipc'; +import { Country, NodeHop, NodeLocation, ThemeMode, UiTheme } from './common'; +import { AccountLinks, BackendError, ErrorKey, NetworkEnv } from './tauri-ipc'; export type ConnectionState = | 'Connected' @@ -59,8 +59,8 @@ export type AppState = { codeDepsRust: CodeDependency[]; // TODO just a boolean for now to indicate if the user has added an account account: boolean; - fetchMxEntryCountries: FetchMxCountriesFn; - fetchMxExitCountries: FetchMxCountriesFn; + accountLinks?: AccountLinks | null; + fetchMnCountries: FetchMnCountriesFn; fetchWgCountries: FetchWgCountriesFn; }; @@ -82,7 +82,7 @@ export type ProgressEventPayload = { export type StateDispatch = Dispatch; -export type FetchMxCountriesFn = () => Promise | undefined; +export type FetchMnCountriesFn = (node: NodeHop) => Promise | undefined; export type FetchWgCountriesFn = () => Promise | undefined; export type AppError = { diff --git a/nym-vpn-app/src/types/tauri-ipc.ts b/nym-vpn-app/src/types/tauri-ipc.ts index 5edb3e6ec9..e8c1b3a211 100644 --- a/nym-vpn-app/src/types/tauri-ipc.ts +++ b/nym-vpn-app/src/types/tauri-ipc.ts @@ -106,3 +106,15 @@ export type ConnectionStateResponse = { }; export type DaemonInfo = { version: string; network: NetworkEnv }; + +export type SystemMessage = { + name: string; + message: string; + properties: Partial>; +}; + +export type AccountLinks = { + signUp?: string | null; + signIn?: string | null; + account?: string | null; +};