Skip to content

Commit

Permalink
Merge pull request #198 from DefGuard/dev
Browse files Browse the repository at this point in the history
Merge dev into main
  • Loading branch information
wojcik91 authored Feb 6, 2024
2 parents 75f41de + 2841a7b commit 1a6bc56
Show file tree
Hide file tree
Showing 11 changed files with 58 additions and 32 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "defguard-client",
"private": false,
"version": "0.2.0",
"version": "0.2.1",
"type": "module",
"scripts": {
"dev": "npm-run-all --parallel vite typesafe-i18n",
Expand Down
6 changes: 3 additions & 3 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "defguard-client"
version = "0.2.0"
version = "0.2.1"
description = "Defguard desktop client"
license = "Apache-2.0"
homepage = "https://github.com/DefGuard/client"
Expand All @@ -19,7 +19,7 @@ anyhow = "1.0"
base64 = "0.21"
clap = { version = "4.4", features = ["derive", "env"] }
chrono = { version = "0.4", features = ["serde"] }
defguard_wireguard_rs = { git = "https://github.com/DefGuard/wireguard-rs.git", rev = "v0.4.0" }
defguard_wireguard_rs = { git = "https://github.com/DefGuard/wireguard-rs.git", rev = "v0.4.1" }
dirs = "5.0"
lazy_static = "1.4"
local-ip-address = "0.5"
Expand Down
5 changes: 4 additions & 1 deletion src-tauri/src/appstate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,10 @@ impl AppState {
}

pub async fn close_all_connections(&self) -> Result<(), crate::error::Error> {
for connection in self.get_connections() {
info!("Closing all active connections...");
let active_connections = self.get_connections();
info!("Found {} active connections", active_connections.len());
for connection in active_connections {
debug!("Found active connection");
trace!("Connection: {connection:#?}");
debug!("Removing interface");
Expand Down
22 changes: 19 additions & 3 deletions src-tauri/src/bin/defguard-client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,25 @@ async fn main() {
);

// run app
app.run(|_app_handle, event| {
if let tauri::RunEvent::ExitRequested { api, .. } = event {
api.prevent_exit();
app.run(|app_handle, event| match event {
// prevent shutdown on window close
tauri::RunEvent::ExitRequested { api, .. } => {
debug!("Received exit request");
api.prevent_exit()
}
// handle shutdown
tauri::RunEvent::Exit => {
info!("Exiting event loop...");
let app_state: State<AppState> = app_handle.state();
tokio::task::block_in_place(|| {
tokio::runtime::Handle::current().block_on(async {
let _ = app_state.close_all_connections().await;
app_handle.exit(0);
});
});
}
_ => {
trace!("Received event: {event:?}")
}
});
}
1 change: 1 addition & 0 deletions src-tauri/src/tray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ pub fn handle_tray_event(app: &AppHandle, event: SystemTrayEvent) {
}
SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() {
"quit" => {
info!("Received QUIT request. Initiating shutdown...");
let app_state: State<AppState> = app.state();
tokio::task::block_in_place(|| {
tokio::runtime::Handle::current().block_on(async {
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"package": {
"productName": "defguard-client",
"version": "0.2.0"
"version": "0.2.1"
},
"tauri": {
"systemTray": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import {
cidrRegex,
patternValidEndpoint,
patternValidIp,
patternValidIpV6,
patternValidIpV6WithPort,
patternValidWireguardKey,
} from '../../../../../../shared/patterns';
import { routes } from '../../../../../../shared/routes';
Expand Down Expand Up @@ -100,13 +102,15 @@ export const AddTunnelFormCard = () => {
return patternValidWireguardKey.test(value);
}, LL.form.errors.invalid()),
address: z.string().refine((value) => {
return patternValidIp.test(value);
return patternValidIp.test(value) || patternValidIpV6.test(value);
}, LL.form.errors.invalid()),
endpoint: z
.string()
.min(1, LL.form.errors.required())
.refine((value) => {
return patternValidEndpoint.test(value);
return (
patternValidEndpoint.test(value) || patternValidIpV6WithPort.test(value)
);
}, LL.form.errors.invalid()),
dns: z
.string()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {
cidrRegex,
patternValidEndpoint,
patternValidIp,
patternValidIpV6,
patternValidIpV6WithPort,
patternValidWireguardKey,
} from '../../../../../shared/patterns';
import { routes } from '../../../../../shared/routes';
Expand Down Expand Up @@ -137,18 +139,20 @@ export const EditTunnelFormCard = ({ tunnel, submitRef }: Props) => {
return patternValidWireguardKey.test(value);
}, LL.form.errors.invalid()),
address: z.string().refine((value) => {
return patternValidIp.test(value);
return patternValidIp.test(value) || patternValidIpV6.test(value);
}, LL.form.errors.invalid()),
endpoint: z
.string()
.min(1, LL.form.errors.required())
.refine((value) => {
return patternValidEndpoint.test(value);
return (
patternValidEndpoint.test(value) || patternValidIpV6WithPort.test(value)
);
}, LL.form.errors.invalid()),
dns: z
.string()
.refine((value) => {
if (value) {
if (value && value.length != 0) {
return validateIpOrDomainList(value, ',', true);
}
return true;
Expand Down
8 changes: 8 additions & 0 deletions src/shared/patterns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,11 @@ export const cidrRegex =
// Regular expression to match IPv4, IPv6, domain name, or localhost with port
export const patternValidEndpoint =
/^(localhost|\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b|\b(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}\b)(?::(\d+))?$/;

// Copied from zod source code and added optional mask at the end to match WireguardRequirements
export const patternValidIpV6 =
/^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))(?:\/128)?$/;

// Reuse pattern from above to support format [ipv6]:port
export const patternValidIpV6WithPort =
/^\[((([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))(\/128)?)\]:(\d{1,5})$/;
22 changes: 6 additions & 16 deletions src/shared/validators/tunnel.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { patternValidDomain, patternValidIp } from '../patterns';
import { patternValidDomain, patternValidIp, patternValidIpV6 } from '../patterns';

// Returns flase when invalid
export const validateIpOrDomain = (val: string, allowMask = false): boolean => {
Expand All @@ -13,12 +13,7 @@ export const validateIpList = (
): boolean => {
const trimed = val.replace(' ', '');
const split = trimed.split(splitWith);
for (const value of split) {
if (!validateIp(value, allowMasks)) {
return false;
}
}
return true;
return split.every((value) => validateIp(value, allowMasks));
};

// Returns flase when invalid
Expand All @@ -27,14 +22,9 @@ export const validateIpOrDomainList = (
splitWith = ',',
allowMasks = false,
): boolean => {
const trimed = val.replace(' ', '');
const split = trimed.split(splitWith);
for (const value of split) {
if (!(validateIp(value, allowMasks) && patternValidDomain.test(value))) {
return false;
}
}
return true;
// split and trim values
const split = val.split(splitWith).map((value) => value.trim());
return split.every((value) => validateIpOrDomain(value, allowMasks));
};

// Returns flase when invalid
Expand All @@ -50,5 +40,5 @@ export const validateIp = (ip: string, allowMask = false): boolean => {
return ipValid && maskValid;
}
}
return patternValidIp.test(ip);
return patternValidIp.test(ip) || patternValidIpV6.test(ip);
};

0 comments on commit 1a6bc56

Please sign in to comment.