mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-08-27 21:30:23 +02:00
refactor: cleanup
This commit is contained in:
@@ -1759,8 +1759,7 @@ mod tests {
|
|||||||
assert_eq!(xs.value, "sessionvalue");
|
assert_eq!(xs.value, "sessionvalue");
|
||||||
|
|
||||||
// Raw DB checks against the Firefox schema — these would catch the bugs
|
// Raw DB checks against the Firefox schema — these would catch the bugs
|
||||||
// that caused issue #265 on the Chrome path (plaintext, correct expiry,
|
// on the Chrome path (plaintext, correct expiry, correct schemeMap).
|
||||||
// correct schemeMap).
|
|
||||||
let conn = Connection::open(&ff_db).unwrap();
|
let conn = Connection::open(&ff_db).unwrap();
|
||||||
let now = std::time::SystemTime::now()
|
let now = std::time::SystemTime::now()
|
||||||
.duration_since(std::time::UNIX_EPOCH)
|
.duration_since(std::time::UNIX_EPOCH)
|
||||||
|
|||||||
@@ -1827,7 +1827,7 @@ pub fn run() {
|
|||||||
// so the background loop respects portable mode and the
|
// so the background loop respects portable mode and the
|
||||||
// disable_auto_updates setting. Previously it bypassed both, so a
|
// disable_auto_updates setting. Previously it bypassed both, so a
|
||||||
// portable install would auto-download and run the NSIS installer,
|
// portable install would auto-download and run the NSIS installer,
|
||||||
// clobbering the portable folder instead of updating in place (#468).
|
// clobbering the portable folder instead of updating in place.
|
||||||
match app_auto_updater::check_for_app_updates().await {
|
match app_auto_updater::check_for_app_updates().await {
|
||||||
Ok(Some(update_info)) => {
|
Ok(Some(update_info)) => {
|
||||||
log::info!(
|
log::info!(
|
||||||
@@ -2073,7 +2073,7 @@ pub fn run() {
|
|||||||
// (window closed by the user). The explicit kill path in
|
// (window closed by the user). The explicit kill path in
|
||||||
// browser_runner.rs already releases it, but this branch did
|
// browser_runner.rs already releases it, but this branch did
|
||||||
// not — leaking the lock, which the 30s heartbeat then renews
|
// not — leaking the lock, which the 30s heartbeat then renews
|
||||||
// indefinitely (issue #474). No-op for non-sync/non-paid
|
// indefinitely. No-op for non-sync/non-paid
|
||||||
// profiles thanks to the guards inside the helper.
|
// profiles thanks to the guards inside the helper.
|
||||||
if !is_running {
|
if !is_running {
|
||||||
crate::team_lock::release_team_lock_if_needed(&profile).await;
|
crate::team_lock::release_team_lock_if_needed(&profile).await;
|
||||||
|
|||||||
@@ -1729,8 +1729,8 @@ const DIRECT_CONNECT_TIMEOUT: std::time::Duration = std::time::Duration::from_se
|
|||||||
/// handshake). Without it, an upstream that accepts TCP but stalls before
|
/// handshake). Without it, an upstream that accepts TCP but stalls before
|
||||||
/// replying hangs the worker task forever and holds a connection slot; under
|
/// replying hangs the worker task forever and holds a connection slot; under
|
||||||
/// load (e.g. two profiles sharing one proxy) the slots exhaust and the browser
|
/// load (e.g. two profiles sharing one proxy) the slots exhaust and the browser
|
||||||
/// sees `ERR_PROXY_CONNECTION_FAILED` until the profile is restarted (issue
|
/// sees `ERR_PROXY_CONNECTION_FAILED` until the profile is restarted. A
|
||||||
/// #439). A bounded dial fails fast and releases the slot.
|
/// bounded dial fails fast and releases the slot.
|
||||||
const UPSTREAM_DIAL_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(20);
|
const UPSTREAM_DIAL_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(20);
|
||||||
|
|
||||||
/// Per-host failure state (last failure instant, consecutive failure count) for
|
/// Per-host failure state (last failure instant, consecutive failure count) for
|
||||||
|
|||||||
@@ -706,7 +706,7 @@ impl SyncEngine {
|
|||||||
// deleted local files), the manifest generated at the START of the sync is
|
// deleted local files), the manifest generated at the START of the sync is
|
||||||
// now stale. Uploading it would advertise wrong hashes/mtimes for the files
|
// now stale. Uploading it would advertise wrong hashes/mtimes for the files
|
||||||
// we just pulled, so the peer keeps computing a non-empty diff and the two
|
// we just pulled, so the peer keeps computing a non-empty diff and the two
|
||||||
// devices ping-pong re-uploads forever (issue #470). Regenerate from the
|
// devices ping-pong re-uploads forever. Regenerate from the
|
||||||
// actual on-disk files before uploading. When only uploads happened, the
|
// actual on-disk files before uploading. When only uploads happened, the
|
||||||
// on-disk state is unchanged and the original manifest is still accurate.
|
// on-disk state is unchanged and the original manifest is still accurate.
|
||||||
let local_changed =
|
let local_changed =
|
||||||
@@ -2399,7 +2399,7 @@ impl SyncEngine {
|
|||||||
let metadata_raw = self.client.download_bytes(&metadata_presign.url).await?;
|
let metadata_raw = self.client.download_bytes(&metadata_presign.url).await?;
|
||||||
// Unseal E2E-encrypted metadata before parsing — otherwise an encrypted
|
// Unseal E2E-encrypted metadata before parsing — otherwise an encrypted
|
||||||
// envelope fails to deserialize and the missing profile never downloads to
|
// envelope fails to deserialize and the missing profile never downloads to
|
||||||
// this device (issue #466). Plaintext (legacy) metadata passes through.
|
// this device. Plaintext (legacy) metadata passes through.
|
||||||
let metadata_data = encryption::maybe_unseal_after_download(&metadata_raw).map_err(|e| {
|
let metadata_data = encryption::maybe_unseal_after_download(&metadata_raw).map_err(|e| {
|
||||||
if e.contains("ENCRYPTION_PASSWORD_REQUIRED") {
|
if e.contains("ENCRYPTION_PASSWORD_REQUIRED") {
|
||||||
let _ = events::emit("profile-sync-e2e-password-required", ());
|
let _ = events::emit("profile-sync-e2e-password-required", ());
|
||||||
@@ -3212,7 +3212,7 @@ pub async fn enable_extension_group_sync_if_needed(extension_group_id: &str) ->
|
|||||||
|
|
||||||
// Enabling sync only flips a local flag; without queueing a sync run the
|
// Enabling sync only flips a local flag; without queueing a sync run the
|
||||||
// group and its extensions are never uploaded, so the other device never
|
// group and its extensions are never uploaded, so the other device never
|
||||||
// receives them (issue #477). Queue them now.
|
// receives them. Queue them now.
|
||||||
if let Some(scheduler) = crate::sync::get_global_scheduler() {
|
if let Some(scheduler) = crate::sync::get_global_scheduler() {
|
||||||
scheduler
|
scheduler
|
||||||
.queue_extension_group_sync(extension_group_id.to_string())
|
.queue_extension_group_sync(extension_group_id.to_string())
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ impl SyncSubscription {
|
|||||||
// Refresh the sync token before reconnecting. The token may have
|
// Refresh the sync token before reconnecting. The token may have
|
||||||
// expired while the stream was open (tokens last ~15 min); reusing
|
// expired while the stream was open (tokens last ~15 min); reusing
|
||||||
// the construction-time token otherwise produces an endless 401
|
// the construction-time token otherwise produces an endless 401
|
||||||
// reconnect loop until the app is restarted (issue #440).
|
// reconnect loop until the app is restarted.
|
||||||
match Self::fetch_sync_token(source, &app_handle).await {
|
match Self::fetch_sync_token(source, &app_handle).await {
|
||||||
Ok(Some(fresh)) => token = fresh,
|
Ok(Some(fresh)) => token = fresh,
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
|
|||||||
@@ -447,7 +447,7 @@ impl WireGuardSocks5Server {
|
|||||||
.port();
|
.port();
|
||||||
|
|
||||||
// Update config with actual port and local_url. Prefer the explicit
|
// Update config with actual port and local_url. Prefer the explicit
|
||||||
// config path the worker was started with — see issue #287, where
|
// config path the worker was started with — a case where
|
||||||
// get_storage_dir() in the worker process resolved to a different
|
// get_storage_dir() in the worker process resolved to a different
|
||||||
// directory than in the parent (Qubes/sandboxed Linux), causing the
|
// directory than in the parent (Qubes/sandboxed Linux), causing the
|
||||||
// write-back to land in the wrong place and the parent to time out.
|
// write-back to land in the wrong place and the parent to time out.
|
||||||
@@ -776,15 +776,23 @@ impl WireGuardSocks5Server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
0x04 => {
|
0x04 => {
|
||||||
// IPv6
|
// IPv6-literal CONNECT. The WireGuard tunnel is IPv4-only
|
||||||
|
// (parse_cidr_address keeps only the first/IPv4 address and no
|
||||||
|
// default IPv6 route is installed), so an IPv6 destination can
|
||||||
|
// never be reached. Attempting the connect would leave the
|
||||||
|
// smoltcp socket in SynSent until it times out — a visible hang —
|
||||||
|
// so fail fast with "host unreachable" instead.
|
||||||
|
// Normal navigation never lands here: Chromium uses remote DNS
|
||||||
|
// over the SOCKS proxy and domain CONNECT requests resolve A-only, so
|
||||||
|
// this only guards direct literal-IPv6 destinations.
|
||||||
if conn.read_buf.len() < 22 {
|
if conn.read_buf.len() < 22 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let mut octets = [0u8; 16];
|
let _ = conn
|
||||||
octets.copy_from_slice(&conn.read_buf[4..20]);
|
.tcp_stream
|
||||||
let ip = std::net::Ipv6Addr::from(octets);
|
.try_write(&[0x05, 0x04, 0x00, 0x01, 0, 0, 0, 0, 0, 0]);
|
||||||
let port = u16::from_be_bytes([conn.read_buf[20], conn.read_buf[21]]);
|
completed.push(idx);
|
||||||
(SocketAddr::new(std::net::IpAddr::V6(ip), port), 22)
|
continue;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
completed.push(idx);
|
completed.push(idx);
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ pub fn save_vpn_worker_config(config: &VpnWorkerConfig) -> Result<(), Box<dyn st
|
|||||||
/// `--config-path`) and must write back to the same location regardless of
|
/// `--config-path`) and must write back to the same location regardless of
|
||||||
/// how `get_storage_dir()` resolves in the worker process — which can
|
/// how `get_storage_dir()` resolves in the worker process — which can
|
||||||
/// differ from the parent on Linux distros that sandbox the GUI (Qubes,
|
/// differ from the parent on Linux distros that sandbox the GUI (Qubes,
|
||||||
/// flatpak, etc.) and is the cause of issue #287.
|
/// flatpak, etc.).
|
||||||
pub fn save_vpn_worker_config_to_path(
|
pub fn save_vpn_worker_config_to_path(
|
||||||
config: &VpnWorkerConfig,
|
config: &VpnWorkerConfig,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
|
|||||||
@@ -2395,7 +2395,7 @@ export function ProfilesDataTable({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Hidden, sort-only column so profiles can be sorted by creation date
|
// Hidden, sort-only column so profiles can be sorted by creation date
|
||||||
// without showing a Created column in the table (issue #454). Kept
|
// without showing a Created column in the table. Kept
|
||||||
// hidden via columnVisibility; sorting still works on hidden columns.
|
// hidden via columnVisibility; sorting still works on hidden columns.
|
||||||
id: "created_at",
|
id: "created_at",
|
||||||
accessorFn: (row) => row.created_at ?? 0,
|
accessorFn: (row) => row.created_at ?? 0,
|
||||||
@@ -3067,7 +3067,7 @@ export function ProfilesDataTable({
|
|||||||
setContainerWidth(Math.round(w / 8) * 8);
|
setContainerWidth(Math.round(w / 8) * 8);
|
||||||
setColumnVisibility((prev) => {
|
setColumnVisibility((prev) => {
|
||||||
const next: VisibilityState = {
|
const next: VisibilityState = {
|
||||||
// Always hidden — sort-only column (issue #454).
|
// Always hidden — sort-only column.
|
||||||
created_at: false,
|
created_at: false,
|
||||||
dns: w >= 768,
|
dns: w >= 768,
|
||||||
ext: w >= 672,
|
ext: w >= 672,
|
||||||
|
|||||||
@@ -1050,8 +1050,7 @@ export function SettingsDialog({
|
|||||||
// Await the rollover so the user sees an error if
|
// Await the rollover so the user sees an error if
|
||||||
// re-syncing fails. Previously the rollover was
|
// re-syncing fails. Previously the rollover was
|
||||||
// fire-and-forget (`void invoke(...)`) which left
|
// fire-and-forget (`void invoke(...)`) which left
|
||||||
// half-removed state on screen with no feedback —
|
// half-removed state on screen with no feedback.
|
||||||
// the source of issue #360 "completely bugged".
|
|
||||||
await invoke("delete_e2e_password");
|
await invoke("delete_e2e_password");
|
||||||
setHasE2ePassword(false);
|
setHasE2ePassword(false);
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user