fix: resolve P3 audit findings

This commit is contained in:
NimBold
2026-06-15 14:24:34 +03:30
parent 789a8161b2
commit 1b04860c94
9 changed files with 27 additions and 134 deletions
+2 -1
View File
@@ -52,6 +52,7 @@ tokio-tungstenite = "0.29.0"
futures-util = { version = "0.3.32", features = ["sink"] }
rusqlite = { version = "0.40.1", features = ["bundled"] }
chrono = "0.4.38"
url = "2"
[target.'cfg(target_os = "macos")'.dependencies]
cocoa = "0.25"
objc = "0.2.7"
url = "2"
+2 -2
View File
@@ -1,6 +1,6 @@
use rusqlite::{Connection, Result, params};
use tokio::sync::Mutex;
use std::path::PathBuf;
use tauri::Manager;
pub struct DbState {
@@ -8,7 +8,7 @@ pub struct DbState {
}
pub fn init_db(app_handle: &tauri::AppHandle) -> Result<Connection> {
let app_dir = app_handle.path().app_data_dir().unwrap_or_else(|_| PathBuf::from("."));
let app_dir = app_handle.path().app_data_dir().expect("Cannot get app data dir");
if !app_dir.exists() {
let _ = std::fs::create_dir_all(&app_dir);
}
+5 -10
View File
@@ -81,16 +81,11 @@ pub async fn start_server(
.layer(cors)
.with_state(state);
let mut listener = None;
for port in EXTENSION_SERVER_PORT..=(EXTENSION_SERVER_PORT + 10) {
if let Ok(l) = tokio::net::TcpListener::bind(("127.0.0.1", port)).await {
listener = Some((l, port));
break;
}
}
let (listener, bound_port) = listener.ok_or_else(|| "Failed to bind extension server to any port".to_string())?;
println!("Browser extension server bound to 127.0.0.1:{}", bound_port);
let listener = tokio::net::TcpListener::bind(("127.0.0.1", EXTENSION_SERVER_PORT))
.await
.map_err(|e| format!("Failed to bind extension server to port {}: {}", EXTENSION_SERVER_PORT, e))?;
println!("Browser extension server bound to 127.0.0.1:{}", EXTENSION_SERVER_PORT);
axum::serve(listener, app)
.await
+9 -4
View File
@@ -837,9 +837,13 @@ pub(crate) async fn start_media_download_internal(
let stdout = child.stdout.take().ok_or("Failed to capture stdout")?;
// yt-dlp parsing regex
let pct_re = Regex::new(r"\[download\]\s+(\d+(?:\.\d+)?)%").unwrap();
let spd_re = Regex::new(r"at\s+([^\s]+)").unwrap();
let eta_re = Regex::new(r"ETA\s+([^\s]+)").unwrap();
static PCT_RE: std::sync::OnceLock<Regex> = std::sync::OnceLock::new();
static SPD_RE: std::sync::OnceLock<Regex> = std::sync::OnceLock::new();
static ETA_RE: std::sync::OnceLock<Regex> = std::sync::OnceLock::new();
let pct_re = PCT_RE.get_or_init(|| Regex::new(r"\[download\]\s+(\d+(?:\.\d+)?)%").unwrap());
let spd_re = SPD_RE.get_or_init(|| Regex::new(r"at\s+([^\s]+)").unwrap());
let eta_re = ETA_RE.get_or_init(|| Regex::new(r"ETA\s+([^\s]+)").unwrap());
let _keep_alive = config_path;
let mut reader = BufReader::new(stdout).lines();
@@ -1195,7 +1199,8 @@ fn toggle_tray_icon(app_handle: tauri::AppHandle, show: bool) -> Result<(), Stri
let show_i = MenuItem::with_id(&app_handle, "show", "Show Firelink", true, None::<&str>).map_err(|e| e.to_string())?;
let menu = Menu::with_items(&app_handle, &[&show_i, &quit_i]).map_err(|e| e.to_string())?;
let tray_icon = tauri::image::Image::from_bytes(include_bytes!("../icons/trayTemplate.png")).unwrap();
let tray_icon = tauri::image::Image::from_bytes(include_bytes!("../icons/trayTemplate.png"))
.map_err(|e| e.to_string())?;
let _tray = TrayIconBuilder::with_id("main")
.icon(tray_icon)
.icon_as_template(true)
+1 -1
View File
@@ -6,7 +6,7 @@ use std::time::Duration;
pub fn spawn_scheduler(app_handle: tauri::AppHandle) {
tauri::async_runtime::spawn(async move {
let mut interval = tokio::time::interval(Duration::from_secs(10));
let mut interval = tokio::time::interval(Duration::from_secs(1));
loop {
interval.tick().await;
+1 -113
View File
@@ -1,113 +1 @@
.logo.vite:hover {
filter: drop-shadow(0 0 2em #747bff);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafb);
}
:root {
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 24px;
font-weight: 400;
color: #0f0f0f;
background-color: #f6f6f6;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
.container {
margin: 0;
padding-top: 10vh;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: 0.75s;
}
.logo.tauri:hover {
filter: drop-shadow(0 0 2em #24c8db);
}
.row {
display: flex;
justify-content: center;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
h1 {
text-align: center;
}
input,
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
color: #0f0f0f;
background-color: #ffffff;
transition: border-color 0.25s;
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
}
button {
cursor: pointer;
}
button:hover {
border-color: #396cd8;
}
button:active {
border-color: #396cd8;
background-color: #e8e8e8;
}
input,
button {
outline: none;
}
@media (prefers-color-scheme: dark) {
:root {
color: #f6f6f6;
background-color: #2f2f2f;
}
a:hover {
color: #24c8db;
}
input,
button {
color: #ffffff;
background-color: #0f0f0f98;
}
button:active {
background-color: #0f0f0f69;
}
}
/* Boilerplate styles cleared */
+1 -1
View File
@@ -531,7 +531,7 @@ export const AddDownloadsModal = () => {
let newName = finalFile;
let exists = true;
while (exists) {
while (exists && count < 1000) {
newName = `${base} (${count})${ext}`;
const storeHas = useDownloadStore.getState().downloads.some(d => {
const dest = d.destination || useSettingsStore.getState().defaultDownloadPath || '~/Downloads';
+2 -1
View File
@@ -57,7 +57,8 @@ export const DownloadTable: React.FC<DownloadTableProps> = ({ filter }) => {
} else if (dir === '~') {
resolvedDir = await homeDir();
}
return resolvedDir + '/' + file;
const separator = resolvedDir.endsWith('/') ? '' : '/';
return resolvedDir + separator + file;
};
const filteredDownloads = downloads.filter((d: DownloadItem) => {
+4 -1
View File
@@ -247,7 +247,10 @@ export const Sidebar: React.FC<SidebarProps> = (props) => {
{contextMenu && (
<div
className="fixed z-50 w-48 py-1 rounded-xl shadow-lg border border-border-modal bg-bg-context-menu backdrop-blur-xl animate-fade-in text-[13px] text-text-primary overflow-hidden"
style={{ top: contextMenu.y, left: contextMenu.x }}
style={{
top: Math.min(contextMenu.y, window.innerHeight - 200),
left: Math.min(contextMenu.x, window.innerWidth - 200)
}}
onClick={e => e.stopPropagation()}
>
<button