diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index d6bb8779..38c9b858 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -5,10 +5,12 @@ on: branches: - main - dev + - 'release/**' pull_request: branches: - main - dev + - 'release/**' jobs: lint-web: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 62302763..a7bd2848 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,6 +5,7 @@ on: branches: - main - dev + - 'release/**' paths-ignore: - '*.md' - 'LICENSE' @@ -12,6 +13,7 @@ on: branches: - main - dev + - 'release/**' paths-ignore: - '*.md' - 'LICENSE' diff --git a/flake.lock b/flake.lock index 08ed6370..0384f507 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1751382304, - "narHash": "sha256-p+UruOjULI5lV16FkBqkzqgFasLqfx0bihLBeFHiZAs=", + "lastModified": 1752596105, + "narHash": "sha256-lFNVsu/mHLq3q11MuGkMhUUoSXEdQjCHvpReaGP1S2k=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "d31a91c9b3bee464d054633d5f8b84e17a637862", + "rev": "dab3a6e781554f965bde3def0aa2fda4eb8f1708", "type": "github" }, "original": { @@ -60,11 +60,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1751423951, - "narHash": "sha256-AowKhJGplXRkAngSvb+32598DTiI6LOzhAnzgvbCtYM=", + "lastModified": 1752633862, + "narHash": "sha256-Bj7ozT1+5P7NmvDcuAXJvj56txcXuAhk3Vd9FdWFQzk=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "1684ed5b15859b655caf41b467d046e29a994d04", + "rev": "8668ca94858206ac3db0860a9dec471de0d995f8", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 96fe9c9e..c83e4447 100644 --- a/flake.nix +++ b/flake.nix @@ -19,7 +19,7 @@ toolchain = pkgs.rust-bin.stable.latest.default.override { extensions = ["rust-analyzer" "rust-src" "rustfmt" "clippy"]; - targets = ["wasm32-unknown-unknown"]; + targets = ["wasm32-unknown-unknown" "x86_64-apple-darwin" "aarch64-apple-darwin" "x86_64-pc-windows-gnu"]; }; packages = with pkgs; [ cargo @@ -29,6 +29,8 @@ nodejs_20 nodePackages.pnpm trunk + sqlx-cli + vtsls ]; nativeBuildPackages = with pkgs; [ pkg-config diff --git a/src-tauri/.sqlx/query-7b6cba2ce07597ff499b692055f18241f97d604243f387ca9f1a12264b79fb16.json b/src-tauri/.sqlx/query-2d4e1873d7a9233ab5cad9021b230a898623b953ad721dcb42023729aed0e4a3.json similarity index 84% rename from src-tauri/.sqlx/query-7b6cba2ce07597ff499b692055f18241f97d604243f387ca9f1a12264b79fb16.json rename to src-tauri/.sqlx/query-2d4e1873d7a9233ab5cad9021b230a898623b953ad721dcb42023729aed0e4a3.json index d373fcd3..0cf3e9bd 100644 --- a/src-tauri/.sqlx/query-7b6cba2ce07597ff499b692055f18241f97d604243f387ca9f1a12264b79fb16.json +++ b/src-tauri/.sqlx/query-2d4e1873d7a9233ab5cad9021b230a898623b953ad721dcb42023729aed0e4a3.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "SELECT id \"id: _\", instance_id, name, address, pubkey, endpoint, allowed_ips, dns, network_id, route_all_traffic, mfa_enabled, keepalive_interval FROM location WHERE instance_id = $1", + "query": "SELECT id \"id: _\", instance_id, name, address, pubkey, endpoint, allowed_ips, dns, network_id, route_all_traffic, keepalive_interval, location_mfa_mode \"location_mfa_mode: LocationMfaMode\" FROM location WHERE instance_id = $1", "describe": { "columns": [ { @@ -54,12 +54,12 @@ "type_info": "Bool" }, { - "name": "mfa_enabled", + "name": "keepalive_interval", "ordinal": 10, - "type_info": "Bool" + "type_info": "Integer" }, { - "name": "keepalive_interval", + "name": "location_mfa_mode: LocationMfaMode", "ordinal": 11, "type_info": "Integer" } @@ -82,5 +82,5 @@ false ] }, - "hash": "7b6cba2ce07597ff499b692055f18241f97d604243f387ca9f1a12264b79fb16" + "hash": "2d4e1873d7a9233ab5cad9021b230a898623b953ad721dcb42023729aed0e4a3" } diff --git a/src-tauri/.sqlx/query-2d6a90bf82aa92118b36d90bf16ae9515952d077106d303f398167caf68a8a70.json b/src-tauri/.sqlx/query-2d6a90bf82aa92118b36d90bf16ae9515952d077106d303f398167caf68a8a70.json deleted file mode 100644 index 5db9905d..00000000 --- a/src-tauri/.sqlx/query-2d6a90bf82aa92118b36d90bf16ae9515952d077106d303f398167caf68a8a70.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "SQLite", - "query": "SELECT count(*) FROM tunnel_stats", - "describe": { - "columns": [ - { - "name": "count(*)", - "ordinal": 0, - "type_info": "Integer" - } - ], - "parameters": { - "Right": 0 - }, - "nullable": [ - false - ] - }, - "hash": "2d6a90bf82aa92118b36d90bf16ae9515952d077106d303f398167caf68a8a70" -} diff --git a/src-tauri/.sqlx/query-e50367bf0ea4627fb3125e541c2a2b2da96589b3aeb6b1c902f436ae98e9ffe9.json b/src-tauri/.sqlx/query-2d9b8eebfbc2651ae0038f73d5867706509a45ca570ebe750c6e26ec3fc78dd8.json similarity index 78% rename from src-tauri/.sqlx/query-e50367bf0ea4627fb3125e541c2a2b2da96589b3aeb6b1c902f436ae98e9ffe9.json rename to src-tauri/.sqlx/query-2d9b8eebfbc2651ae0038f73d5867706509a45ca570ebe750c6e26ec3fc78dd8.json index 0ed03e46..14e1a981 100644 --- a/src-tauri/.sqlx/query-e50367bf0ea4627fb3125e541c2a2b2da96589b3aeb6b1c902f436ae98e9ffe9.json +++ b/src-tauri/.sqlx/query-2d9b8eebfbc2651ae0038f73d5867706509a45ca570ebe750c6e26ec3fc78dd8.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "SELECT id \"id: _\", name, uuid, url, proxy_url, username, token, disable_all_traffic, enterprise_enabled, use_openid_for_mfa, openid_display_name FROM instance\n WHERE token IS NOT NULL;", + "query": "SELECT id \"id: _\", name, uuid, url, proxy_url, username, token, disable_all_traffic, enterprise_enabled, openid_display_name FROM instance\n WHERE token IS NOT NULL;", "describe": { "columns": [ { @@ -48,14 +48,9 @@ "ordinal": 8, "type_info": "Bool" }, - { - "name": "use_openid_for_mfa", - "ordinal": 9, - "type_info": "Bool" - }, { "name": "openid_display_name", - "ordinal": 10, + "ordinal": 9, "type_info": "Text" } ], @@ -72,9 +67,8 @@ true, false, false, - false, true ] }, - "hash": "e50367bf0ea4627fb3125e541c2a2b2da96589b3aeb6b1c902f436ae98e9ffe9" + "hash": "2d9b8eebfbc2651ae0038f73d5867706509a45ca570ebe750c6e26ec3fc78dd8" } diff --git a/src-tauri/.sqlx/query-a9ca7a4f46ce92ab02a213479797b24e04caad767c088dd490dc38663494c22d.json b/src-tauri/.sqlx/query-3421da72f01d726c2931071203d663b197cb518dd65ec73108f85b2cb7270741.json similarity index 57% rename from src-tauri/.sqlx/query-a9ca7a4f46ce92ab02a213479797b24e04caad767c088dd490dc38663494c22d.json rename to src-tauri/.sqlx/query-3421da72f01d726c2931071203d663b197cb518dd65ec73108f85b2cb7270741.json index ce79c660..a994e60f 100644 --- a/src-tauri/.sqlx/query-a9ca7a4f46ce92ab02a213479797b24e04caad767c088dd490dc38663494c22d.json +++ b/src-tauri/.sqlx/query-3421da72f01d726c2931071203d663b197cb518dd65ec73108f85b2cb7270741.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "UPDATE location SET instance_id = $1, name = $2, address = $3, pubkey = $4, endpoint = $5, allowed_ips = $6, dns = $7, network_id = $8, route_all_traffic = $9, mfa_enabled = $10, keepalive_interval = $11 WHERE id = $12", + "query": "UPDATE location SET instance_id = $1, name = $2, address = $3, pubkey = $4, endpoint = $5, allowed_ips = $6, dns = $7, network_id = $8, route_all_traffic = $9, keepalive_interval = $10, location_mfa_mode = $11 WHERE id = $12", "describe": { "columns": [], "parameters": { @@ -8,5 +8,5 @@ }, "nullable": [] }, - "hash": "a9ca7a4f46ce92ab02a213479797b24e04caad767c088dd490dc38663494c22d" + "hash": "3421da72f01d726c2931071203d663b197cb518dd65ec73108f85b2cb7270741" } diff --git a/src-tauri/.sqlx/query-5953a81f34f906e34aabec089dfe0cebf2afc3ad798638db9ea0aabcd506192b.json b/src-tauri/.sqlx/query-5953a81f34f906e34aabec089dfe0cebf2afc3ad798638db9ea0aabcd506192b.json deleted file mode 100644 index ab312bb2..00000000 --- a/src-tauri/.sqlx/query-5953a81f34f906e34aabec089dfe0cebf2afc3ad798638db9ea0aabcd506192b.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "db_name": "SQLite", - "query": "SELECT id, instance_id, name, address, pubkey, endpoint, allowed_ips, dns, network_id,route_all_traffic, mfa_enabled, keepalive_interval FROM location;", - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Integer" - }, - { - "name": "instance_id", - "ordinal": 1, - "type_info": "Integer" - }, - { - "name": "name", - "ordinal": 2, - "type_info": "Text" - }, - { - "name": "address", - "ordinal": 3, - "type_info": "Text" - }, - { - "name": "pubkey", - "ordinal": 4, - "type_info": "Text" - }, - { - "name": "endpoint", - "ordinal": 5, - "type_info": "Text" - }, - { - "name": "allowed_ips", - "ordinal": 6, - "type_info": "Text" - }, - { - "name": "dns", - "ordinal": 7, - "type_info": "Text" - }, - { - "name": "network_id", - "ordinal": 8, - "type_info": "Integer" - }, - { - "name": "route_all_traffic", - "ordinal": 9, - "type_info": "Bool" - }, - { - "name": "mfa_enabled", - "ordinal": 10, - "type_info": "Bool" - }, - { - "name": "keepalive_interval", - "ordinal": 11, - "type_info": "Integer" - } - ], - "parameters": { - "Right": 0 - }, - "nullable": [ - false, - false, - false, - false, - false, - false, - false, - true, - false, - false, - false, - false - ] - }, - "hash": "5953a81f34f906e34aabec089dfe0cebf2afc3ad798638db9ea0aabcd506192b" -} diff --git a/src-tauri/.sqlx/query-79c5c710bc12a1353875219d3cd2198b6c2cf5b476774034d3160a3f28df08d7.json b/src-tauri/.sqlx/query-64728ae44c896e304fef18fbe05194d89e17d2cde021fa36606deb6f7419000c.json similarity index 84% rename from src-tauri/.sqlx/query-79c5c710bc12a1353875219d3cd2198b6c2cf5b476774034d3160a3f28df08d7.json rename to src-tauri/.sqlx/query-64728ae44c896e304fef18fbe05194d89e17d2cde021fa36606deb6f7419000c.json index 565650b6..1db71c84 100644 --- a/src-tauri/.sqlx/query-79c5c710bc12a1353875219d3cd2198b6c2cf5b476774034d3160a3f28df08d7.json +++ b/src-tauri/.sqlx/query-64728ae44c896e304fef18fbe05194d89e17d2cde021fa36606deb6f7419000c.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "SELECT id \"id: _\", name, uuid, url, proxy_url, username, token \"token?\", disable_all_traffic, enterprise_enabled, use_openid_for_mfa, openid_display_name FROM instance;", + "query": "SELECT id \"id: _\", name, uuid, url, proxy_url, username, token \"token?\", disable_all_traffic, enterprise_enabled, openid_display_name FROM instance;", "describe": { "columns": [ { @@ -48,14 +48,9 @@ "ordinal": 8, "type_info": "Bool" }, - { - "name": "use_openid_for_mfa", - "ordinal": 9, - "type_info": "Bool" - }, { "name": "openid_display_name", - "ordinal": 10, + "ordinal": 9, "type_info": "Text" } ], @@ -72,9 +67,8 @@ true, false, false, - false, true ] }, - "hash": "79c5c710bc12a1353875219d3cd2198b6c2cf5b476774034d3160a3f28df08d7" + "hash": "64728ae44c896e304fef18fbe05194d89e17d2cde021fa36606deb6f7419000c" } diff --git a/src-tauri/.sqlx/query-a490103ccb68cc382bd1fc84c2d1ebd6f344bbda5618980943a62677683f0a85.json b/src-tauri/.sqlx/query-758d3c67336eecafab5fd20e4b03574995383092cdb4d7c3ebda6f933ea0f472.json similarity index 55% rename from src-tauri/.sqlx/query-a490103ccb68cc382bd1fc84c2d1ebd6f344bbda5618980943a62677683f0a85.json rename to src-tauri/.sqlx/query-758d3c67336eecafab5fd20e4b03574995383092cdb4d7c3ebda6f933ea0f472.json index 695d90f1..40a4087a 100644 --- a/src-tauri/.sqlx/query-a490103ccb68cc382bd1fc84c2d1ebd6f344bbda5618980943a62677683f0a85.json +++ b/src-tauri/.sqlx/query-758d3c67336eecafab5fd20e4b03574995383092cdb4d7c3ebda6f933ea0f472.json @@ -1,12 +1,12 @@ { "db_name": "SQLite", - "query": "UPDATE instance SET name = $1, uuid = $2, url = $3, proxy_url = $4, username = $5, disable_all_traffic = $6, enterprise_enabled = $7, token = $8, use_openid_for_mfa = $9, openid_display_name = $10 WHERE id = $11;", + "query": "UPDATE instance SET name = $1, uuid = $2, url = $3, proxy_url = $4, username = $5, disable_all_traffic = $6, enterprise_enabled = $7, token = $8, openid_display_name = $9 WHERE id = $10;", "describe": { "columns": [], "parameters": { - "Right": 11 + "Right": 10 }, "nullable": [] }, - "hash": "a490103ccb68cc382bd1fc84c2d1ebd6f344bbda5618980943a62677683f0a85" + "hash": "758d3c67336eecafab5fd20e4b03574995383092cdb4d7c3ebda6f933ea0f472" } diff --git a/src-tauri/.sqlx/query-7f1db6e3022b3bef4515d183feb6dc2e3b787c1fe5c4ce26c1c14c356d0c85d5.json b/src-tauri/.sqlx/query-aa7d2c4c2100151b6f555ade668e72ceef8e7d1e39fcf0bcef0b7433457d3d2a.json similarity index 83% rename from src-tauri/.sqlx/query-7f1db6e3022b3bef4515d183feb6dc2e3b787c1fe5c4ce26c1c14c356d0c85d5.json rename to src-tauri/.sqlx/query-aa7d2c4c2100151b6f555ade668e72ceef8e7d1e39fcf0bcef0b7433457d3d2a.json index dab05ae6..bfefdf36 100644 --- a/src-tauri/.sqlx/query-7f1db6e3022b3bef4515d183feb6dc2e3b787c1fe5c4ce26c1c14c356d0c85d5.json +++ b/src-tauri/.sqlx/query-aa7d2c4c2100151b6f555ade668e72ceef8e7d1e39fcf0bcef0b7433457d3d2a.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "SELECT id \"id: _\", name, uuid, url, proxy_url, username, token \"token?\", disable_all_traffic, enterprise_enabled, use_openid_for_mfa, openid_display_name FROM instance WHERE id = $1;", + "query": "SELECT id \"id: _\", name, uuid, url, proxy_url, username, token \"token?\", disable_all_traffic, enterprise_enabled, openid_display_name FROM instance WHERE id = $1;", "describe": { "columns": [ { @@ -48,14 +48,9 @@ "ordinal": 8, "type_info": "Bool" }, - { - "name": "use_openid_for_mfa", - "ordinal": 9, - "type_info": "Bool" - }, { "name": "openid_display_name", - "ordinal": 10, + "ordinal": 9, "type_info": "Text" } ], @@ -72,9 +67,8 @@ true, false, false, - false, true ] }, - "hash": "7f1db6e3022b3bef4515d183feb6dc2e3b787c1fe5c4ce26c1c14c356d0c85d5" + "hash": "aa7d2c4c2100151b6f555ade668e72ceef8e7d1e39fcf0bcef0b7433457d3d2a" } diff --git a/src-tauri/.sqlx/query-9d946237727089451a9bfc7ce2015d8b14eb0816c5c18cf81bb4a3b1c8e9aa6a.json b/src-tauri/.sqlx/query-ac02b04f6490a768571290d7dc77444eb0ca55a3a7e159c3b2e529ebf75f224f.json similarity index 84% rename from src-tauri/.sqlx/query-9d946237727089451a9bfc7ce2015d8b14eb0816c5c18cf81bb4a3b1c8e9aa6a.json rename to src-tauri/.sqlx/query-ac02b04f6490a768571290d7dc77444eb0ca55a3a7e159c3b2e529ebf75f224f.json index fac4f5fc..6df78777 100644 --- a/src-tauri/.sqlx/query-9d946237727089451a9bfc7ce2015d8b14eb0816c5c18cf81bb4a3b1c8e9aa6a.json +++ b/src-tauri/.sqlx/query-ac02b04f6490a768571290d7dc77444eb0ca55a3a7e159c3b2e529ebf75f224f.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "SELECT id \"id: _\", instance_id, name, address, pubkey, endpoint, allowed_ips, dns, network_id, route_all_traffic, mfa_enabled, keepalive_interval FROM location WHERE id = $1", + "query": "SELECT id \"id: _\", instance_id, name, address, pubkey, endpoint, allowed_ips, dns, network_id, route_all_traffic, keepalive_interval, location_mfa_mode \"location_mfa_mode: LocationMfaMode\" FROM location WHERE pubkey = $1;", "describe": { "columns": [ { @@ -54,12 +54,12 @@ "type_info": "Bool" }, { - "name": "mfa_enabled", + "name": "keepalive_interval", "ordinal": 10, - "type_info": "Bool" + "type_info": "Integer" }, { - "name": "keepalive_interval", + "name": "location_mfa_mode: LocationMfaMode", "ordinal": 11, "type_info": "Integer" } @@ -82,5 +82,5 @@ false ] }, - "hash": "9d946237727089451a9bfc7ce2015d8b14eb0816c5c18cf81bb4a3b1c8e9aa6a" + "hash": "ac02b04f6490a768571290d7dc77444eb0ca55a3a7e159c3b2e529ebf75f224f" } diff --git a/src-tauri/.sqlx/query-e034dbe839ed5cd19a8430ac5786e68ace8457b4983724957092db618b2535d4.json b/src-tauri/.sqlx/query-e02047df7deea862cceca537e49ae16a8237e91eff0ee684cacd2ec1c77adb58.json similarity index 65% rename from src-tauri/.sqlx/query-e034dbe839ed5cd19a8430ac5786e68ace8457b4983724957092db618b2535d4.json rename to src-tauri/.sqlx/query-e02047df7deea862cceca537e49ae16a8237e91eff0ee684cacd2ec1c77adb58.json index 0e926b52..3d77f025 100644 --- a/src-tauri/.sqlx/query-e034dbe839ed5cd19a8430ac5786e68ace8457b4983724957092db618b2535d4.json +++ b/src-tauri/.sqlx/query-e02047df7deea862cceca537e49ae16a8237e91eff0ee684cacd2ec1c77adb58.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "INSERT INTO location (instance_id, name, address, pubkey, endpoint, allowed_ips, dns, network_id, route_all_traffic, mfa_enabled, keepalive_interval) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING id \"id!\"", + "query": "INSERT INTO location (instance_id, name, address, pubkey, endpoint, allowed_ips, dns, network_id, route_all_traffic, keepalive_interval, location_mfa_mode) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING id \"id!\"", "describe": { "columns": [ { @@ -16,5 +16,5 @@ true ] }, - "hash": "e034dbe839ed5cd19a8430ac5786e68ace8457b4983724957092db618b2535d4" + "hash": "e02047df7deea862cceca537e49ae16a8237e91eff0ee684cacd2ec1c77adb58" } diff --git a/src-tauri/.sqlx/query-afab9e8172fcd2187e99f7222eb1394fbc68b54cf5ebf36764becbc42c89ad21.json b/src-tauri/.sqlx/query-e91278b90769f39e2cdf1677ffa1193580af693f9871a7162c47393daac8af11.json similarity index 85% rename from src-tauri/.sqlx/query-afab9e8172fcd2187e99f7222eb1394fbc68b54cf5ebf36764becbc42c89ad21.json rename to src-tauri/.sqlx/query-e91278b90769f39e2cdf1677ffa1193580af693f9871a7162c47393daac8af11.json index 8ab4e1e5..eb35ee44 100644 --- a/src-tauri/.sqlx/query-afab9e8172fcd2187e99f7222eb1394fbc68b54cf5ebf36764becbc42c89ad21.json +++ b/src-tauri/.sqlx/query-e91278b90769f39e2cdf1677ffa1193580af693f9871a7162c47393daac8af11.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "SELECT id \"id: _\", instance_id, name, address, pubkey, endpoint, allowed_ips, dns, network_id, route_all_traffic, mfa_enabled, keepalive_interval FROM location WHERE pubkey = $1;", + "query": "SELECT id \"id: _\", instance_id, name, address, pubkey, endpoint, allowed_ips, dns, network_id, route_all_traffic, keepalive_interval, location_mfa_mode \"location_mfa_mode: LocationMfaMode\" FROM location WHERE id = $1", "describe": { "columns": [ { @@ -54,12 +54,12 @@ "type_info": "Bool" }, { - "name": "mfa_enabled", + "name": "keepalive_interval", "ordinal": 10, - "type_info": "Bool" + "type_info": "Integer" }, { - "name": "keepalive_interval", + "name": "location_mfa_mode: LocationMfaMode", "ordinal": 11, "type_info": "Integer" } @@ -82,5 +82,5 @@ false ] }, - "hash": "afab9e8172fcd2187e99f7222eb1394fbc68b54cf5ebf36764becbc42c89ad21" + "hash": "e91278b90769f39e2cdf1677ffa1193580af693f9871a7162c47393daac8af11" } diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 9be7f380..abfef591 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -171,7 +171,7 @@ dependencies = [ "serde", "serde_repr", "url", - "zbus 5.7.1", + "zbus 5.8.0", ] [[package]] @@ -209,9 +209,9 @@ dependencies = [ [[package]] name = "async-channel" -version = "2.3.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" dependencies = [ "concurrent-queue", "event-listener-strategy", @@ -262,7 +262,7 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ - "async-channel 2.3.1", + "async-channel 2.5.0", "async-executor", "async-io 2.4.1", "async-lock 3.4.0", @@ -304,7 +304,7 @@ dependencies = [ "futures-lite 2.6.0", "parking", "polling 3.8.0", - "rustix 1.0.7", + "rustix 1.0.8", "slab", "tracing", "windows-sys 0.59.0", @@ -364,7 +364,7 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cde3f4e40e6021d7acffc90095cbd6dc54cb593903d1de5832f435eb274b85dc" dependencies = [ - "async-channel 2.3.1", + "async-channel 2.5.0", "async-io 2.4.1", "async-lock 3.4.0", "async-signal", @@ -373,7 +373,7 @@ dependencies = [ "cfg-if", "event-listener 5.4.0", "futures-lite 2.6.0", - "rustix 1.0.7", + "rustix 1.0.8", "tracing", ] @@ -400,7 +400,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 1.0.7", + "rustix 1.0.8", "signal-hook-registry", "slab", "windows-sys 0.59.0", @@ -673,11 +673,11 @@ dependencies = [ [[package]] name = "blocking" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" dependencies = [ - "async-channel 2.3.1", + "async-channel 2.5.0", "async-task", "futures-io", "futures-lite 2.6.0", @@ -840,9 +840,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.27" +version = "1.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" +checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362" dependencies = [ "jobserver", "libc", @@ -914,9 +914,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.40" +version = "4.5.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" +checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9" dependencies = [ "clap_builder", "clap_derive", @@ -924,9 +924,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.40" +version = "4.5.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" +checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d" dependencies = [ "anstream", "anstyle", @@ -936,9 +936,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.40" +version = "4.5.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" +checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -1166,9 +1166,9 @@ checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ "cfg-if", ] @@ -1271,9 +1271,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.1.3" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +checksum = "373b7c5dbd637569a2cca66e8d66b8c446a1e7bf064ea321d265d7b3dfe7c97e" dependencies = [ "cfg-if", "cpufeatures", @@ -1796,9 +1796,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.9" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24" [[package]] name = "field-offset" @@ -2383,9 +2383,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" dependencies = [ "bytes", "fnv", @@ -2618,7 +2618,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.3.26", + "h2 0.3.27", "http 0.2.12", "http-body 0.4.6", "httparse", @@ -2713,9 +2713,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc2fdfdbff08affe55bb779f33b053aa1fe5dd5b54c257343c17edfa55711bdb" +checksum = "7f66d5bd4c6f02bf0542fad85d626775bab9258cf795a4256dcaf3161114d1df" dependencies = [ "base64 0.22.1", "bytes", @@ -3334,9 +3334,9 @@ checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" [[package]] name = "mac-notification-sys" -version = "0.6.4" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b95dfb34071d1592b45622bf93e315e3a72d414b6782aca9a015c12bec367ef" +checksum = "119c8490084af61b44c9eda9d626475847a186737c0378c85e32d77c33a01cd4" dependencies = [ "cc", "objc2 0.6.1", @@ -3639,7 +3639,7 @@ dependencies = [ "mac-notification-sys", "serde", "tauri-winrt-notification", - "zbus 5.7.1", + "zbus 5.8.0", ] [[package]] @@ -4289,13 +4289,13 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "plist" -version = "1.7.2" +version = "1.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d77244ce2d584cd84f6a15f86195b8c9b2a0dfbfd817c09e0464244091a58ed" +checksum = "3af6b589e163c5a788fab00ce0c0366f6efbb9959c2f9874b224936af7fce7e1" dependencies = [ "base64 0.22.1", "indexmap 2.10.0", - "quick-xml", + "quick-xml 0.38.0", "serde", "time", ] @@ -4339,7 +4339,7 @@ dependencies = [ "concurrent-queue", "hermit-abi 0.5.2", "pin-project-lite", - "rustix 1.0.7", + "rustix 1.0.8", "tracing", "windows-sys 0.59.0", ] @@ -4539,6 +4539,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "quick-xml" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8927b0664f5c5a98265138b7e3f90aa19a6b21353182469ace36d4ac527b7b1b" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.40" @@ -4751,7 +4760,7 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2 0.3.26", + "h2 0.3.27", "http 0.2.12", "http-body 0.4.6", "hyper 0.14.32", @@ -4913,13 +4922,12 @@ dependencies = [ [[package]] name = "rust-ini" -version = "0.21.1" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e310ef0e1b6eeb79169a1171daf9abcb87a2e17c03bee2c4bb100b55c75409f" +checksum = "e7295b7ce3bf4806b419dc3420745998b447178b7005e2011947b38fc5aa6791" dependencies = [ "cfg-if", "ordered-multimap", - "trim-in-place", ] [[package]] @@ -4982,22 +4990,22 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" +checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" dependencies = [ "bitflags 2.9.1", "errno", "libc", "linux-raw-sys 0.9.4", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "rustls" -version = "0.23.28" +version = "0.23.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7160e3e10bf4535308537f3c4e1641468cd0e485175d6163087c0393c7d46643" +checksum = "2491382039b29b9b11ff08b76ff6c97cf287671dbb74f0be44bda389fffe9bd1" dependencies = [ "once_cell", "rustls-pki-types", @@ -5026,9 +5034,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.3" +version = "0.103.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435" +checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" dependencies = [ "ring", "rustls-pki-types", @@ -5079,9 +5087,9 @@ dependencies = [ [[package]] name = "schemars" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1375ba8ef45a6f15d83fa8748f1079428295d403d6ea991d09ab100155fbc06d" +checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" dependencies = [ "dyn-clone", "ref-cast", @@ -5236,7 +5244,7 @@ dependencies = [ "indexmap 1.9.3", "indexmap 2.10.0", "schemars 0.9.0", - "schemars 1.0.3", + "schemars 1.0.4", "serde", "serde_derive", "serde_json", @@ -6074,7 +6082,7 @@ dependencies = [ [[package]] name = "tauri-plugin-log" version = "0.0.0" -source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#a0a310756ab3d770ed554c9801d3bea5940eb31e" +source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#35fff903ad9f7c1ed6f9a8cead4210c36868ff0e" dependencies = [ "byte-unit", "fern", @@ -6089,7 +6097,7 @@ dependencies = [ [[package]] name = "tauri-plugin-single-instance" version = "0.0.0" -source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#a0a310756ab3d770ed554c9801d3bea5940eb31e" +source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#35fff903ad9f7c1ed6f9a8cead4210c36868ff0e" dependencies = [ "log", "serde", @@ -6103,7 +6111,7 @@ dependencies = [ [[package]] name = "tauri-plugin-window-state" version = "0.1.1" -source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#a0a310756ab3d770ed554c9801d3bea5940eb31e" +source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#35fff903ad9f7c1ed6f9a8cead4210c36868ff0e" dependencies = [ "bincode", "bitflags 2.9.1", @@ -6202,7 +6210,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b1e66e07de489fe43a46678dd0b8df65e0c973909df1b60ba33874e297ba9b9" dependencies = [ - "quick-xml", + "quick-xml 0.37.5", "thiserror 2.0.12", "windows 0.61.3", "windows-version", @@ -6217,7 +6225,7 @@ dependencies = [ "fastrand 2.3.0", "getrandom 0.3.3", "once_cell", - "rustix 1.0.7", + "rustix 1.0.8", "windows-sys 0.59.0", ] @@ -6367,9 +6375,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.46.0" +version = "1.46.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1140bb80481756a8cbe10541f37433b459c5aa1e727b4c020fbfebdc25bf3ec4" +checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17" dependencies = [ "backtrace", "bytes", @@ -6506,7 +6514,7 @@ dependencies = [ "serde_spanned", "toml_datetime", "toml_write", - "winnow 0.7.11", + "winnow 0.7.12", ] [[package]] @@ -6724,12 +6732,6 @@ dependencies = [ "petgraph 0.6.5", ] -[[package]] -name = "trim-in-place" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "343e926fc669bc8cde4fa3129ab681c63671bae288b1f1081ceee6d9d37904fc" - [[package]] name = "try-lock" version = "0.2.5" @@ -7127,7 +7129,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "896fdafd5d28145fce7958917d69f2fd44469b1d4e861cb5961bcbeebc6d1484" dependencies = [ "proc-macro2", - "quick-xml", + "quick-xml 0.37.5", "quote", ] @@ -7872,9 +7874,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" +checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" dependencies = [ "memchr", ] @@ -8037,7 +8039,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af3a19837351dc82ba89f8a125e22a3c475f05aba604acc023d62b2739ae2909" dependencies = [ "libc", - "rustix 1.0.7", + "rustix 1.0.8", ] [[package]] @@ -8117,9 +8119,9 @@ dependencies = [ [[package]] name = "zbus" -version = "5.7.1" +version = "5.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3a7c7cee313d044fca3f48fa782cb750c79e4ca76ba7bc7718cd4024cdf6f68" +checksum = "597f45e98bc7e6f0988276012797855613cd8269e23b5be62cc4e5d28b7e515d" dependencies = [ "async-broadcast 0.7.2", "async-executor", @@ -8142,10 +8144,10 @@ dependencies = [ "tracing", "uds_windows", "windows-sys 0.59.0", - "winnow 0.7.11", - "zbus_macros 5.7.1", + "winnow 0.7.12", + "zbus_macros 5.8.0", "zbus_names 4.2.0", - "zvariant 5.5.3", + "zvariant 5.6.0", ] [[package]] @@ -8164,16 +8166,16 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "5.7.1" +version = "5.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17e7e5eec1550f747e71a058df81a9a83813ba0f6a95f39c4e218bdc7ba366a" +checksum = "e5c8e4e14dcdd9d97a98b189cd1220f30e8394ad271e8c987da84f73693862c2" dependencies = [ "proc-macro-crate 3.3.0", "proc-macro2", "quote", "syn 2.0.104", "zbus_names 4.2.0", - "zvariant 5.5.3", + "zvariant 5.6.0", "zvariant_utils 3.2.0", ] @@ -8196,8 +8198,8 @@ checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97" dependencies = [ "serde", "static_assertions", - "winnow 0.7.11", - "zvariant 5.5.3", + "winnow 0.7.12", + "zvariant 5.6.0", ] [[package]] @@ -8310,16 +8312,16 @@ dependencies = [ [[package]] name = "zvariant" -version = "5.5.3" +version = "5.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d30786f75e393ee63a21de4f9074d4c038d52c5b1bb4471f955db249f9dffb1" +checksum = "d91b3680bb339216abd84714172b5138a4edac677e641ef17e1d8cb1b3ca6e6f" dependencies = [ "endi", "enumflags2", "serde", "url", - "winnow 0.7.11", - "zvariant_derive 5.5.3", + "winnow 0.7.12", + "zvariant_derive 5.6.0", "zvariant_utils 3.2.0", ] @@ -8338,9 +8340,9 @@ dependencies = [ [[package]] name = "zvariant_derive" -version = "5.5.3" +version = "5.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75fda702cd42d735ccd48117b1630432219c0e9616bf6cb0f8350844ee4d9580" +checksum = "3a8c68501be459a8dbfffbe5d792acdd23b4959940fc87785fb013b32edbc208" dependencies = [ "proc-macro-crate 3.3.0", "proc-macro2", @@ -8371,5 +8373,5 @@ dependencies = [ "serde", "static_assertions", "syn 2.0.104", - "winnow 0.7.11", + "winnow 0.7.12", ] diff --git a/src-tauri/migrations/20250716095940_add_location_mfa_settings.sql b/src-tauri/migrations/20250716095940_add_location_mfa_settings.sql new file mode 100644 index 00000000..f636a5c4 --- /dev/null +++ b/src-tauri/migrations/20250716095940_add_location_mfa_settings.sql @@ -0,0 +1,20 @@ +-- add nullable column to `location` table +-- since SQLite does not support native enums we'll store them as integers +-- 1 - MFA disabled +-- 2 - internal MFA +-- 3 - external MFA +ALTER TABLE location ADD COLUMN location_mfa_mode INTEGER NOT NULL DEFAULT 1; + +-- populate new column based on value in `mfa_enabled` column +-- previously only internal MFA was available +UPDATE location +SET location_mfa_mode = CASE + WHEN mfa_enabled = true THEN 2 + ELSE 1 +END; + +-- drop the `mfa_enabled` column since it's no longer needed +ALTER TABLE location DROP COLUMN mfa_enabled; + +-- remove `use_openid_for_mfa` setting +ALTER TABLE instance DROP COLUMN use_openid_for_mfa; diff --git a/src-tauri/proto b/src-tauri/proto index c0aef683..b9f24ac4 160000 --- a/src-tauri/proto +++ b/src-tauri/proto @@ -1 +1 @@ -Subproject commit c0aef68395720f46a7f038b6766de3bb30e02930 +Subproject commit b9f24ac41326bffe4c7e72019ccc8a785f6bd343 diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index ad222e3f..f418bd70 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -19,7 +19,7 @@ use crate::{ database::models::{ connection::{ActiveConnection, Connection, ConnectionInfo}, instance::{Instance, InstanceInfo}, - location::Location, + location::{Location, LocationMfaMode}, location_stats::LocationStats, tunnel::{Tunnel, TunnelConnection, TunnelConnectionInfo, TunnelStats}, wireguard_keys::WireguardKeys, @@ -308,7 +308,6 @@ pub async fn all_instances(app_state: State<'_, AppState>) -> Result { pub token: Option, pub disable_all_traffic: bool, pub enterprise_enabled: bool, - pub use_openid_for_mfa: bool, pub openid_display_name: Option, } @@ -39,7 +38,6 @@ impl From for Instance { token: None, disable_all_traffic: instance_info.disable_all_traffic, enterprise_enabled: instance_info.enterprise_enabled, - use_openid_for_mfa: instance_info.use_openid_for_mfa, openid_display_name: instance_info.openid_display_name, } } @@ -52,7 +50,7 @@ impl Instance { { query!( "UPDATE instance SET name = $1, uuid = $2, url = $3, proxy_url = $4, username = $5, \ - disable_all_traffic = $6, enterprise_enabled = $7, token = $8, use_openid_for_mfa = $9, openid_display_name = $10 WHERE id = $11;", + disable_all_traffic = $6, enterprise_enabled = $7, token = $8, openid_display_name = $9 WHERE id = $10;", self.name, self.uuid, self.url, @@ -61,7 +59,6 @@ impl Instance { self.disable_all_traffic, self.enterprise_enabled, self.token, - self.use_openid_for_mfa, self.openid_display_name, self.id ) @@ -77,7 +74,7 @@ impl Instance { let instances = query_as!( Self, "SELECT id \"id: _\", name, uuid, url, proxy_url, username, token \"token?\", \ - disable_all_traffic, enterprise_enabled, use_openid_for_mfa, openid_display_name FROM instance;" + disable_all_traffic, enterprise_enabled, openid_display_name FROM instance;" ) .fetch_all(executor) .await?; @@ -91,7 +88,7 @@ impl Instance { let instance = query_as!( Self, "SELECT id \"id: _\", name, uuid, url, proxy_url, username, token \"token?\", \ - disable_all_traffic, enterprise_enabled, use_openid_for_mfa, openid_display_name FROM instance WHERE id = $1;", + disable_all_traffic, enterprise_enabled, openid_display_name FROM instance WHERE id = $1;", id ) .fetch_optional(executor) @@ -125,7 +122,7 @@ impl Instance { let instances = query_as!( Self, "SELECT id \"id: _\", name, uuid, url, proxy_url, username, token, \ - disable_all_traffic, enterprise_enabled, use_openid_for_mfa, openid_display_name FROM instance + disable_all_traffic, enterprise_enabled, openid_display_name FROM instance WHERE token IS NOT NULL;" ) .fetch_all(executor) @@ -144,7 +141,6 @@ impl PartialEq for Instance { && self.username == other.username && self.disable_all_traffic == other.disable_all_traffic && self.enterprise_enabled == other.enterprise_enabled - && self.use_openid_for_mfa == other.use_openid_for_mfa && self.openid_display_name == other.openid_display_name } } @@ -181,7 +177,6 @@ impl Instance { token: self.token, disable_all_traffic: self.disable_all_traffic, enterprise_enabled: self.enterprise_enabled, - use_openid_for_mfa: self.use_openid_for_mfa, openid_display_name: self.openid_display_name, }) } @@ -198,7 +193,6 @@ pub struct InstanceInfo { pub pubkey: String, pub disable_all_traffic: bool, pub enterprise_enabled: bool, - pub use_openid_for_mfa: bool, pub openid_display_name: Option, } diff --git a/src-tauri/src/database/models/location.rs b/src-tauri/src/database/models/location.rs index 3bd1b5f3..7bf493c5 100644 --- a/src-tauri/src/database/models/location.rs +++ b/src-tauri/src/database/models/location.rs @@ -1,10 +1,31 @@ use std::fmt; use serde::{Deserialize, Serialize}; -use sqlx::{query, query_as, query_scalar, Error as SqlxError, SqliteExecutor}; +use sqlx::{prelude::Type, query, query_as, query_scalar, Error as SqlxError, SqliteExecutor}; use super::{Id, NoId}; -use crate::error::Error; +use crate::{error::Error, proto::LocationMfaMode as ProtoLocationMfaMode}; + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Hash, Type)] +#[repr(u32)] +#[serde(rename_all = "lowercase")] +pub enum LocationMfaMode { + Disabled = 1, + Internal = 2, + External = 3, +} + +impl From for LocationMfaMode { + fn from(value: ProtoLocationMfaMode) -> Self { + match value { + ProtoLocationMfaMode::Unspecified | ProtoLocationMfaMode::Disabled => { + LocationMfaMode::Disabled + } + ProtoLocationMfaMode::Internal => LocationMfaMode::Internal, + ProtoLocationMfaMode::External => LocationMfaMode::External, + } + } +} #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] pub struct Location { @@ -19,8 +40,8 @@ pub struct Location { pub allowed_ips: String, pub dns: Option, pub route_all_traffic: bool, - pub mfa_enabled: bool, pub keepalive_interval: i64, + pub location_mfa_mode: LocationMfaMode, } impl fmt::Display for Location { @@ -44,7 +65,7 @@ impl Location { query_as!( Self, "SELECT id, instance_id, name, address, pubkey, endpoint, allowed_ips, dns, network_id,\ - route_all_traffic, mfa_enabled, keepalive_interval \ + route_all_traffic, keepalive_interval, location_mfa_mode \"location_mfa_mode: LocationMfaMode\" \ FROM location;" ) .fetch_all(executor) @@ -59,7 +80,7 @@ impl Location { query!( "UPDATE location SET instance_id = $1, name = $2, address = $3, pubkey = $4, \ endpoint = $5, allowed_ips = $6, dns = $7, network_id = $8, route_all_traffic = $9, \ - mfa_enabled = $10, keepalive_interval = $11 WHERE id = $12", + keepalive_interval = $10, location_mfa_mode = $11 WHERE id = $12", self.instance_id, self.name, self.address, @@ -69,8 +90,8 @@ impl Location { self.dns, self.network_id, self.route_all_traffic, - self.mfa_enabled, self.keepalive_interval, + self.location_mfa_mode, self.id, ) .execute(executor) @@ -89,7 +110,7 @@ impl Location { query_as!( Self, "SELECT id \"id: _\", instance_id, name, address, pubkey, endpoint, allowed_ips, dns, \ - network_id, route_all_traffic, mfa_enabled, keepalive_interval \ + network_id, route_all_traffic, keepalive_interval, location_mfa_mode \"location_mfa_mode: LocationMfaMode\" \ FROM location WHERE id = $1", location_id ) @@ -107,7 +128,7 @@ impl Location { query_as!( Self, "SELECT id \"id: _\", instance_id, name, address, pubkey, endpoint, allowed_ips, dns, \ - network_id, route_all_traffic, mfa_enabled, keepalive_interval \ + network_id, route_all_traffic, keepalive_interval, location_mfa_mode \"location_mfa_mode: LocationMfaMode\" \ FROM location WHERE instance_id = $1", instance_id ) @@ -125,7 +146,7 @@ impl Location { query_as!( Self, "SELECT id \"id: _\", instance_id, name, address, pubkey, endpoint, allowed_ips, dns, \ - network_id, route_all_traffic, mfa_enabled, keepalive_interval \ + network_id, route_all_traffic, keepalive_interval, location_mfa_mode \"location_mfa_mode: LocationMfaMode\" \ FROM location WHERE pubkey = $1;", pubkey ) @@ -159,6 +180,13 @@ impl Location { .await?; Ok(()) } + + pub(crate) fn mfa_enabled(&self) -> bool { + match self.location_mfa_mode { + LocationMfaMode::Disabled => false, + LocationMfaMode::Internal | LocationMfaMode::External => true, + } + } } impl Location { @@ -169,7 +197,7 @@ impl Location { // Insert a new record when there is no ID let id = query_scalar!( "INSERT INTO location (instance_id, name, address, pubkey, endpoint, allowed_ips, \ - dns, network_id, route_all_traffic, mfa_enabled, keepalive_interval) \ + dns, network_id, route_all_traffic, keepalive_interval, location_mfa_mode) \ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) \ RETURNING id \"id!\"", self.instance_id, @@ -181,8 +209,8 @@ impl Location { self.dns, self.network_id, self.route_all_traffic, - self.mfa_enabled, - self.keepalive_interval + self.keepalive_interval, + self.location_mfa_mode ) .fetch_one(executor) .await?; @@ -198,8 +226,8 @@ impl Location { dns: self.dns, network_id: self.network_id, route_all_traffic: self.route_all_traffic, - mfa_enabled: self.mfa_enabled, keepalive_interval: self.keepalive_interval, + location_mfa_mode: self.location_mfa_mode, }) } } @@ -217,8 +245,8 @@ impl From> for Location { allowed_ips: location.allowed_ips, dns: location.dns, route_all_traffic: location.route_all_traffic, - mfa_enabled: location.mfa_enabled, keepalive_interval: location.keepalive_interval, + location_mfa_mode: location.location_mfa_mode, } } } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 4069d3d7..cbc40c68 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -21,13 +21,30 @@ pub mod utils; pub mod wg_config; pub mod proto { - use crate::database::models::{location::Location, Id, NoId}; + use crate::database::models::{ + location::{Location, LocationMfaMode as MfaMode}, + Id, NoId, + }; tonic::include_proto!("defguard.proxy"); impl DeviceConfig { #[must_use] pub(crate) fn into_location(self, instance_id: Id) -> Location { + let location_mfa_mode = match self.location_mfa_mode { + Some(_location_mfa_mode) => self.location_mfa_mode().into(), + None => { + // handle legacy core response + // DEPRECATED(1.5): superseeded by location_mfa_mode + #[allow(deprecated)] + if self.mfa_enabled { + MfaMode::Internal + } else { + MfaMode::Disabled + } + } + }; + Location { id: NoId, instance_id, @@ -39,8 +56,8 @@ pub mod proto { allowed_ips: self.allowed_ips, dns: self.dns, route_all_traffic: false, - mfa_enabled: self.mfa_enabled, keepalive_interval: self.keepalive_interval.into(), + location_mfa_mode, } } } diff --git a/src-tauri/src/periodic/connection.rs b/src-tauri/src/periodic/connection.rs index 6a08b668..618e6fdc 100644 --- a/src-tauri/src/periodic/connection.rs +++ b/src-tauri/src/periodic/connection.rs @@ -270,7 +270,7 @@ pub async fn verify_active_connections(app_handle: AppHandle) { .await; } else if // only try to reconnect when location is not protected behind MFA - location.mfa_enabled { + location.mfa_enabled() { warn!( "Automatic reconnect for location {}({}) is not possible due to \ enabled MFA. Interface will be disconnected.", diff --git a/src-tauri/src/service/mod.rs b/src-tauri/src/service/mod.rs index 41814c49..371a3e39 100644 --- a/src-tauri/src/service/mod.rs +++ b/src-tauri/src/service/mod.rs @@ -54,6 +54,7 @@ const DAEMON_HTTP_PORT: u16 = 54127; #[cfg(windows)] pub(super) const DAEMON_BASE_URL: &str = "http://localhost:54127"; +#[cfg(unix)] pub(super) const DAEMON_SOCKET_PATH: &str = "/var/run/defguard.socket"; #[derive(Error, Debug)] diff --git a/src-tauri/src/tray.rs b/src-tauri/src/tray.rs index 2768fc06..babc5e46 100644 --- a/src-tauri/src/tray.rs +++ b/src-tauri/src/tray.rs @@ -166,22 +166,22 @@ async fn handle_location_tray_menu(id: String, handle: &AppHandle) { .await; if active_locations_ids.contains(&location_id) { - info!("Disconnect location with id {id}"); + info!("Disconnect location with ID {id}"); let _ = disconnect(location_id, ConnectionType::Location, handle.clone()).await; } else { - info!("Connect location with id {id}"); + info!("Connect location with ID {id}"); // check is mfa enabled and trigger modal on frontend - if location.mfa_enabled { + if location.mfa_enabled() { info!( - "mfa enabled for location with id {:?}, trigger mfa modal", + "MFA enabled for location with ID {:?}, trigger MFA modal", location.id ); handle .emit_all( "mfa-trigger", Payload { - message: "Trigger mfa event".into(), + message: "Trigger MFA event".into(), }, ) .unwrap(); @@ -190,7 +190,7 @@ async fn handle_location_tray_menu(id: String, handle: &AppHandle) { .await { info!( - "Unable to connect location with id {}, error: {e:?}", + "Unable to connect location with ID {}, error: {e:?}", location.id ); } diff --git a/src/pages/client/pages/ClientInstancePage/components/LocationsList/components/LocationCardConnectButton/LocationCardConnectButton.tsx b/src/pages/client/pages/ClientInstancePage/components/LocationsList/components/LocationCardConnectButton/LocationCardConnectButton.tsx index cd0a8b91..a6343b4a 100644 --- a/src/pages/client/pages/ClientInstancePage/components/LocationsList/components/LocationCardConnectButton/LocationCardConnectButton.tsx +++ b/src/pages/client/pages/ClientInstancePage/components/LocationsList/components/LocationCardConnectButton/LocationCardConnectButton.tsx @@ -15,7 +15,7 @@ import { import SvgIconX from '../../../../../../../../shared/defguard-ui/components/svg/IconX'; import { useToaster } from '../../../../../../../../shared/defguard-ui/hooks/toasts/useToaster'; import { clientApi } from '../../../../../../clientAPI/clientApi'; -import { CommonWireguardFields } from '../../../../../../types'; +import { CommonWireguardFields, LocationMfaType } from '../../../../../../types'; import { useMFAModal } from '../../modals/MFAModal/useMFAModal'; const { connect, disconnect } = clientApi; @@ -38,6 +38,11 @@ export const LocationCardConnectButton = ({ location }: Props) => { connected: location?.active, }); + const mfaEnabled = + location?.location_mfa_mode && + (location.location_mfa_mode === LocationMfaType.INTERNAL || + location.location_mfa_mode === LocationMfaType.EXTERNAL); + const handleClick = async () => { setIsLoading(true); try { @@ -48,7 +53,7 @@ export const LocationCardConnectButton = ({ location }: Props) => { connectionType: location.connection_type, }); } else { - if (location.mfa_enabled) { + if (mfaEnabled) { openMFAModal(location); } else { await connect({ diff --git a/src/pages/client/pages/ClientInstancePage/components/LocationsList/modals/MFAModal/MFAModal.tsx b/src/pages/client/pages/ClientInstancePage/components/LocationsList/modals/MFAModal/MFAModal.tsx index b8aaca7d..81613cb3 100644 --- a/src/pages/client/pages/ClientInstancePage/components/LocationsList/modals/MFAModal/MFAModal.tsx +++ b/src/pages/client/pages/ClientInstancePage/components/LocationsList/modals/MFAModal/MFAModal.tsx @@ -25,7 +25,11 @@ import { ModalWithTitle } from '../../../../../../../../shared/defguard-ui/compo import { useToaster } from '../../../../../../../../shared/defguard-ui/hooks/toasts/useToaster'; import { clientApi } from '../../../../../../clientAPI/clientApi'; import { useClientStore } from '../../../../../../hooks/useClientStore'; -import { DefguardInstance, WireguardInstanceType } from '../../../../../../types'; +import { + DefguardInstance, + LocationMfaType, + WireguardInstanceType, +} from '../../../../../../types'; import { BrowserErrorIcon, BrowserPendingIcon, GoToBrowserIcon } from './Icons'; import { useMFAModal } from './useMFAModal'; @@ -161,8 +165,8 @@ export const MFAModal = () => { }; const useOpenIDMFA = useMemo(() => { - return selectedInstance?.use_openid_for_mfa || false; - }, [selectedInstance]); + return location?.location_mfa_mode === LocationMfaType.EXTERNAL; + }, [location]); const { mutate, isPending } = useMutation({ mutationFn: startMFA, diff --git a/src/pages/client/types.ts b/src/pages/client/types.ts index 45532a2f..7ca19991 100644 --- a/src/pages/client/types.ts +++ b/src/pages/client/types.ts @@ -8,10 +8,15 @@ export type DefguardInstance = { active: boolean; pubkey: string; disable_all_traffic: boolean; - use_openid_for_mfa: boolean; openid_display_name?: string; }; +export enum LocationMfaType { + DISABLED = 'disabled', + INTERNAL = 'internal', + EXTERNAL = 'external', +} + export type DefguardLocation = { instance_id: number; } & CommonWireguardFields; @@ -60,7 +65,7 @@ export type CommonWireguardFields = { // Tunnel or Location connection_type: WireguardInstanceType; // Available in Location only - mfa_enabled: boolean | undefined; + location_mfa_mode?: LocationMfaType; pubkey: string; instance_id: number; network_id: number;