Initial commit: abyssVpn project
- Tauri desktop app (apps/desktop) - Python Django API service (services/api) - Deployment scripts and docs
@@ -0,0 +1,4 @@
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
/gen/schemas
|
||||
@@ -0,0 +1,29 @@
|
||||
[package]
|
||||
name = "app"
|
||||
version = "0.1.0"
|
||||
description = "A Tauri App"
|
||||
authors = ["you"]
|
||||
license = ""
|
||||
repository = ""
|
||||
edition = "2021"
|
||||
rust-version = "1.77.2"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[lib]
|
||||
name = "app_lib"
|
||||
crate-type = ["staticlib", "cdylib", "rlib"]
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "2.5.6", features = [] }
|
||||
|
||||
[dependencies]
|
||||
serde_json = "1.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
log = "0.4"
|
||||
tauri = { version = "2.10.3", features = ["tray-icon"] }
|
||||
tokio = { version = "1", features = ["rt-multi-thread"] }
|
||||
tauri-plugin-log = "2"
|
||||
tauri-plugin-deep-link = "2.4.3"
|
||||
tauri-plugin-opener = "2.5.3"
|
||||
md5 = "0.7"
|
||||
@@ -0,0 +1,40 @@
|
||||
fn main() {
|
||||
let mut windows = tauri_build::WindowsAttributes::new();
|
||||
|
||||
if !tauri_build::is_dev() {
|
||||
windows = windows.app_manifest(
|
||||
r#"
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
</assembly>
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
tauri_build::try_build(tauri_build::Attributes::new().windows_attributes(windows))
|
||||
.expect("failed to run build script");
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "../gen/schemas/desktop-schema.json",
|
||||
"identifier": "default",
|
||||
"description": "enables the default permissions",
|
||||
"windows": [
|
||||
"main",
|
||||
"logs"
|
||||
],
|
||||
"permissions": [
|
||||
"core:default",
|
||||
"core:event:default",
|
||||
"core:window:allow-hide",
|
||||
"core:window:allow-minimize",
|
||||
"core:window:allow-start-dragging",
|
||||
"core:window:allow-create",
|
||||
"core:window:allow-close",
|
||||
"core:window:allow-set-focus",
|
||||
"core:webview:allow-create-webview-window",
|
||||
"deep-link:default",
|
||||
"deep-link:allow-is-registered",
|
||||
"deep-link:allow-register",
|
||||
"opener:default",
|
||||
"opener:allow-open-url"
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 7.7 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 8.8 KiB |
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 42 KiB |
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
||||
@@ -0,0 +1 @@
|
||||
1 24 "resources/app.manifest"
|
||||
@@ -0,0 +1,14 @@
|
||||
# Netclient assets
|
||||
|
||||
Run `scripts/download-netclient-assets.bat` on Windows or `pwsh scripts/download-netclient-assets.ps1` before building the desktop app.
|
||||
|
||||
Expected files:
|
||||
|
||||
- `windows/netclientbundle.exe`
|
||||
- `windows/netclient-windows-amd64.exe`
|
||||
- `macos/Netclient-M1.pkg`
|
||||
- `macos/Netclient-Intel.pkg`
|
||||
- `macos/netclient-darwin-arm64`
|
||||
- `macos/netclient-darwin-amd64`
|
||||
|
||||
The app first looks for an installed `netclient`, then falls back to the bundled binary. If `netclient` is missing, the install button starts the bundled installer with administrator privileges.
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod vpn;
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
mod commands;
|
||||
mod tray;
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_opener::init())
|
||||
.plugin(tauri_plugin_deep_link::init())
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
commands::vpn::connect_vpn,
|
||||
commands::vpn::disconnect_vpn,
|
||||
commands::vpn::reset_vpn,
|
||||
commands::vpn::install_netclient,
|
||||
commands::vpn::vpn_status
|
||||
])
|
||||
.setup(|app| {
|
||||
tray::setup_tray(app)?;
|
||||
if cfg!(debug_assertions) {
|
||||
app.handle().plugin(
|
||||
tauri_plugin_log::Builder::default()
|
||||
.level(log::LevelFilter::Info)
|
||||
.build(),
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.on_window_event(|window, event| {
|
||||
tray::handle_window_event(window, event);
|
||||
})
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
fn main() {
|
||||
app_lib::run();
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
use tauri::{
|
||||
menu::{Menu, MenuItem},
|
||||
tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent},
|
||||
App, AppHandle, Manager, Runtime, WindowEvent,
|
||||
};
|
||||
|
||||
const MENU_SHOW: &str = "show";
|
||||
const MENU_HIDE: &str = "hide";
|
||||
const MENU_QUIT: &str = "quit";
|
||||
|
||||
pub fn setup_tray(app: &mut App) -> tauri::Result<()> {
|
||||
let show = MenuItem::with_id(app, MENU_SHOW, "显示窗口", true, None::<&str>)?;
|
||||
let hide = MenuItem::with_id(app, MENU_HIDE, "隐藏到托盘/菜单栏", true, None::<&str>)?;
|
||||
let quit = MenuItem::with_id(app, MENU_QUIT, "退出", true, None::<&str>)?;
|
||||
let menu = Menu::with_items(app, &[&show, &hide, &quit])?;
|
||||
|
||||
let mut builder = TrayIconBuilder::new()
|
||||
.tooltip("AbyssInfo VPN")
|
||||
.menu(&menu)
|
||||
.show_menu_on_left_click(false)
|
||||
.on_menu_event(|app, event| match event.id.as_ref() {
|
||||
MENU_SHOW => show_main_window(app),
|
||||
MENU_HIDE => hide_main_window(app),
|
||||
MENU_QUIT => app.exit(0),
|
||||
_ => {}
|
||||
})
|
||||
.on_tray_icon_event(|tray, event| match event {
|
||||
TrayIconEvent::Click {
|
||||
button: MouseButton::Left,
|
||||
button_state: MouseButtonState::Up,
|
||||
..
|
||||
}
|
||||
| TrayIconEvent::DoubleClick {
|
||||
button: MouseButton::Left,
|
||||
..
|
||||
} => show_main_window(tray.app_handle()),
|
||||
_ => {}
|
||||
});
|
||||
|
||||
if let Some(icon) = app.default_window_icon() {
|
||||
builder = builder.icon(icon.clone());
|
||||
}
|
||||
|
||||
builder.build(app)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn handle_window_event<R: Runtime>(window: &tauri::Window<R>, event: &WindowEvent) {
|
||||
if let WindowEvent::CloseRequested { api, .. } = event {
|
||||
api.prevent_close();
|
||||
let _ = window.hide();
|
||||
let _ = window.set_skip_taskbar(true);
|
||||
}
|
||||
}
|
||||
|
||||
fn show_main_window<R: Runtime>(app: &AppHandle<R>) {
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
let _ = window.set_skip_taskbar(false);
|
||||
let _ = window.show();
|
||||
let _ = window.set_focus();
|
||||
}
|
||||
}
|
||||
|
||||
fn hide_main_window<R: Runtime>(app: &AppHandle<R>) {
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
let _ = window.hide();
|
||||
let _ = window.set_skip_taskbar(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
|
||||
"productName": "AbyssInfo VPN",
|
||||
"version": "0.1.0",
|
||||
"identifier": "com.abyssinfo.homevpn",
|
||||
"build": {
|
||||
"frontendDist": "../dist",
|
||||
"devUrl": "http://localhost:5173",
|
||||
"beforeDevCommand": "npm run dev",
|
||||
"beforeBuildCommand": "npm run build"
|
||||
},
|
||||
"app": {
|
||||
"windows": [
|
||||
{
|
||||
"title": "AbyssInfo VPN",
|
||||
"width": 390,
|
||||
"height": 760,
|
||||
"minWidth": 360,
|
||||
"minHeight": 640,
|
||||
"maxWidth": 430,
|
||||
"resizable": true,
|
||||
"decorations": false,
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
|
||||
"fullscreen": false
|
||||
}
|
||||
],
|
||||
"security": {
|
||||
"csp": null
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"deep-link": {
|
||||
"desktop": {
|
||||
"schemes": [
|
||||
"myvpn"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"resources": [
|
||||
"resources/**/*"
|
||||
],
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
"icons/128x128@2x.png",
|
||||
"icons/icon.icns",
|
||||
"icons/icon.ico"
|
||||
]
|
||||
}
|
||||
}
|
||||