mirror of
https://github.com/nimbold/Firelink.git
synced 2026-08-24 09:46:29 +00:00
fix: resolve P3 audit findings
This commit is contained in:
@@ -52,6 +52,7 @@ tokio-tungstenite = "0.29.0"
|
|||||||
futures-util = { version = "0.3.32", features = ["sink"] }
|
futures-util = { version = "0.3.32", features = ["sink"] }
|
||||||
rusqlite = { version = "0.40.1", features = ["bundled"] }
|
rusqlite = { version = "0.40.1", features = ["bundled"] }
|
||||||
chrono = "0.4.38"
|
chrono = "0.4.38"
|
||||||
|
url = "2"
|
||||||
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
cocoa = "0.25"
|
cocoa = "0.25"
|
||||||
objc = "0.2.7"
|
objc = "0.2.7"
|
||||||
url = "2"
|
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
use rusqlite::{Connection, Result, params};
|
use rusqlite::{Connection, Result, params};
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
use std::path::PathBuf;
|
|
||||||
use tauri::Manager;
|
use tauri::Manager;
|
||||||
|
|
||||||
pub struct DbState {
|
pub struct DbState {
|
||||||
@@ -8,7 +8,7 @@ pub struct DbState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_db(app_handle: &tauri::AppHandle) -> Result<Connection> {
|
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() {
|
if !app_dir.exists() {
|
||||||
let _ = std::fs::create_dir_all(&app_dir);
|
let _ = std::fs::create_dir_all(&app_dir);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,16 +81,11 @@ pub async fn start_server(
|
|||||||
.layer(cors)
|
.layer(cors)
|
||||||
.with_state(state);
|
.with_state(state);
|
||||||
|
|
||||||
let mut listener = None;
|
let listener = tokio::net::TcpListener::bind(("127.0.0.1", EXTENSION_SERVER_PORT))
|
||||||
for port in EXTENSION_SERVER_PORT..=(EXTENSION_SERVER_PORT + 10) {
|
.await
|
||||||
if let Ok(l) = tokio::net::TcpListener::bind(("127.0.0.1", port)).await {
|
.map_err(|e| format!("Failed to bind extension server to port {}: {}", EXTENSION_SERVER_PORT, e))?;
|
||||||
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:{}", EXTENSION_SERVER_PORT);
|
||||||
println!("Browser extension server bound to 127.0.0.1:{}", bound_port);
|
|
||||||
|
|
||||||
axum::serve(listener, app)
|
axum::serve(listener, app)
|
||||||
.await
|
.await
|
||||||
|
|||||||
@@ -837,9 +837,13 @@ pub(crate) async fn start_media_download_internal(
|
|||||||
let stdout = child.stdout.take().ok_or("Failed to capture stdout")?;
|
let stdout = child.stdout.take().ok_or("Failed to capture stdout")?;
|
||||||
|
|
||||||
// yt-dlp parsing regex
|
// yt-dlp parsing regex
|
||||||
let pct_re = Regex::new(r"\[download\]\s+(\d+(?:\.\d+)?)%").unwrap();
|
static PCT_RE: std::sync::OnceLock<Regex> = std::sync::OnceLock::new();
|
||||||
let spd_re = Regex::new(r"at\s+([^\s]+)").unwrap();
|
static SPD_RE: std::sync::OnceLock<Regex> = std::sync::OnceLock::new();
|
||||||
let eta_re = Regex::new(r"ETA\s+([^\s]+)").unwrap();
|
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 _keep_alive = config_path;
|
||||||
let mut reader = BufReader::new(stdout).lines();
|
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 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 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")
|
let _tray = TrayIconBuilder::with_id("main")
|
||||||
.icon(tray_icon)
|
.icon(tray_icon)
|
||||||
.icon_as_template(true)
|
.icon_as_template(true)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use std::time::Duration;
|
|||||||
|
|
||||||
pub fn spawn_scheduler(app_handle: tauri::AppHandle) {
|
pub fn spawn_scheduler(app_handle: tauri::AppHandle) {
|
||||||
tauri::async_runtime::spawn(async move {
|
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 {
|
loop {
|
||||||
interval.tick().await;
|
interval.tick().await;
|
||||||
|
|
||||||
|
|||||||
+1
-113
@@ -1,113 +1 @@
|
|||||||
.logo.vite:hover {
|
/* Boilerplate styles cleared */
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -531,7 +531,7 @@ export const AddDownloadsModal = () => {
|
|||||||
let newName = finalFile;
|
let newName = finalFile;
|
||||||
let exists = true;
|
let exists = true;
|
||||||
|
|
||||||
while (exists) {
|
while (exists && count < 1000) {
|
||||||
newName = `${base} (${count})${ext}`;
|
newName = `${base} (${count})${ext}`;
|
||||||
const storeHas = useDownloadStore.getState().downloads.some(d => {
|
const storeHas = useDownloadStore.getState().downloads.some(d => {
|
||||||
const dest = d.destination || useSettingsStore.getState().defaultDownloadPath || '~/Downloads';
|
const dest = d.destination || useSettingsStore.getState().defaultDownloadPath || '~/Downloads';
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ export const DownloadTable: React.FC<DownloadTableProps> = ({ filter }) => {
|
|||||||
} else if (dir === '~') {
|
} else if (dir === '~') {
|
||||||
resolvedDir = await homeDir();
|
resolvedDir = await homeDir();
|
||||||
}
|
}
|
||||||
return resolvedDir + '/' + file;
|
const separator = resolvedDir.endsWith('/') ? '' : '/';
|
||||||
|
return resolvedDir + separator + file;
|
||||||
};
|
};
|
||||||
|
|
||||||
const filteredDownloads = downloads.filter((d: DownloadItem) => {
|
const filteredDownloads = downloads.filter((d: DownloadItem) => {
|
||||||
|
|||||||
@@ -247,7 +247,10 @@ export const Sidebar: React.FC<SidebarProps> = (props) => {
|
|||||||
{contextMenu && (
|
{contextMenu && (
|
||||||
<div
|
<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"
|
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()}
|
onClick={e => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
|
|||||||
Reference in New Issue
Block a user