Add native self-hosted instance connection to fluxer_desktop

Trimmed monorepo checkout (fluxer_desktop + packages/voice_engine_v2 +
tools/ci) with a "Connect to a Different Server" menu item and popout
that lets the desktop app switch to any self-hosted Fluxer instance,
plus fixes for well-known discovery on single-domain self-hosted
deployments and a false-positive ERR_ABORTED on same-origin client
redirects during the switch. Defaults to chat.fluxr.chat and uses an
isolated userData directory from the official build.
This commit is contained in:
2026-07-01 18:22:43 -04:00
commit 682afacd30
1763 changed files with 613720 additions and 0 deletions
+233
View File
@@ -0,0 +1,233 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "arbitrary"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
dependencies = [
"derive_arbitrary",
]
[[package]]
name = "block-buffer"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be"
dependencies = [
"hybrid-array",
]
[[package]]
name = "cc"
version = "1.2.62"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98"
dependencies = [
"find-msvc-tools",
"jobserver",
"libc",
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "const-oid"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c"
[[package]]
name = "cpufeatures"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
dependencies = [
"libc",
]
[[package]]
name = "crypto-common"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453"
dependencies = [
"hybrid-array",
]
[[package]]
name = "derive_arbitrary"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "digest"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2"
dependencies = [
"block-buffer",
"const-oid",
"crypto-common",
]
[[package]]
name = "find-msvc-tools"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
[[package]]
name = "fluxer_desktop_native"
version = "0.1.0"
dependencies = [
"sha2",
]
[[package]]
name = "fluxer_desktop_native_fuzz"
version = "0.0.0"
dependencies = [
"arbitrary",
"fluxer_desktop_native",
"libfuzzer-sys",
]
[[package]]
name = "getrandom"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasip2",
]
[[package]]
name = "hybrid-array"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da"
dependencies = [
"typenum",
]
[[package]]
name = "jobserver"
version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
dependencies = [
"getrandom",
"libc",
]
[[package]]
name = "libc"
version = "0.2.186"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
[[package]]
name = "libfuzzer-sys"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f12a681b7dd8ce12bff52488013ba614b869148d54dd79836ab85aafdd53f08d"
dependencies = [
"arbitrary",
"cc",
]
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "sha2"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "syn"
version = "2.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "typenum"
version = "1.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de"
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "wasip2"
version = "1.0.3+wasi-0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6"
dependencies = [
"wit-bindgen",
]
[[package]]
name = "wit-bindgen"
version = "0.57.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
@@ -0,0 +1,46 @@
[package]
name = "fluxer_desktop_native_fuzz"
version = "0.0.0"
edition = "2024"
publish = false
[workspace]
resolver = "2"
[package.metadata]
cargo-fuzz = true
[dependencies]
arbitrary = {version = "1.4", features = ["derive"]}
fluxer_desktop_native = {path = ".."}
libfuzzer-sys = "0.4"
[[bin]]
name = "routing"
path = "fuzz_targets/routing.rs"
test = false
doc = false
[[bin]]
name = "pid_payload"
path = "fuzz_targets/pid_payload.rs"
test = false
doc = false
[[bin]]
name = "audio_converter"
path = "fuzz_targets/audio_converter.rs"
test = false
doc = false
[[bin]]
name = "evdev_event"
path = "fuzz_targets/evdev_event.rs"
test = false
doc = false
[[bin]]
name = "process_tree"
path = "fuzz_targets/process_tree.rs"
test = false
doc = false
@@ -0,0 +1,40 @@
#![no_main]
// SPDX-License-Identifier: AGPL-3.0-or-later
use arbitrary::Arbitrary;
use fluxer_desktop_native::mac_app_audio::audio_converter::{
AudioBuffer, AudioBufferListN, build_input_asbd, convert_buffer_list_to_interleaved_f32,
};
use libfuzzer_sys::fuzz_target;
#[derive(Arbitrary, Debug)]
struct Input {
samples: Vec<f32>,
sample_rate: f64,
output_rate: f64,
channels: u8,
}
fuzz_target!(|input: Input| {
let channels = u32::from(input.channels.clamp(1, 2));
let sample_rate = if input.sample_rate.is_finite() && input.sample_rate > 0.0 {
input.sample_rate.min(384_000.0)
} else {
48_000.0
};
let output_rate = if input.output_rate.is_finite() && input.output_rate > 0.0 {
input.output_rate.min(384_000.0)
} else {
48_000.0
};
let frame_count = (input.samples.len() as u32 / channels).min(4096);
let list = AudioBufferListN {
m_number_buffers: 1,
buffers: [AudioBuffer::from_slice(channels, &input.samples)],
};
let asbd = build_input_asbd(sample_rate, channels, false);
let mut out = vec![0.0_f32; frame_count as usize * 4 + 16];
let _ =
convert_buffer_list_to_interleaved_f32(asbd, &list, frame_count, output_rate, 2, &mut out);
});
@@ -0,0 +1,20 @@
#![no_main]
// SPDX-License-Identifier: AGPL-3.0-or-later
use fluxer_desktop_native::linux_evdev::event::{
InputEvent, parse_input_event, parse_input_events,
};
use libfuzzer_sys::fuzz_target;
fuzz_target!(|data: &[u8]| {
let _ = parse_input_event(data);
let mut count = 0_usize;
for event in parse_input_events(data) {
let _ = event.time_sec ^ event.time_usec;
let _ = event.event_type ^ event.code;
let _ = event.value;
count += 1;
}
assert_eq!(data.len() / InputEvent::BYTE_LEN, count);
});
@@ -0,0 +1,12 @@
#![no_main]
// SPDX-License-Identifier: AGPL-3.0-or-later
use fluxer_desktop_native::linux_portals::pid_payload::parse_shell_eval_pid_payload;
use libfuzzer_sys::fuzz_target;
fuzz_target!(|data: &[u8]| {
if let Ok(payload) = std::str::from_utf8(data) {
let _ = parse_shell_eval_pid_payload(payload);
}
});
@@ -0,0 +1,62 @@
#![no_main]
// SPDX-License-Identifier: AGPL-3.0-or-later
use arbitrary::Arbitrary;
use fluxer_desktop_native::mac_app_audio::process_tree::{
Info, collect_related_pids_with_resolver, is_same_launch_tree_with_resolver,
};
use libfuzzer_sys::fuzz_target;
#[derive(Arbitrary, Debug)]
struct RawInfo {
pid: i32,
parent_pid: i32,
process_group_id: i32,
}
#[derive(Arbitrary, Debug)]
struct Input {
target_pid: i32,
max_count: u8,
infos: Vec<RawInfo>,
candidates: Vec<i32>,
}
fuzz_target!(|input: Input| {
let infos: Vec<Info> = input
.infos
.into_iter()
.take(128)
.map(|raw| Info {
pid: raw.pid,
parent_pid: raw.parent_pid,
process_group_id: raw.process_group_id,
})
.collect();
let candidates: Vec<i32> = input.candidates.into_iter().take(128).collect();
let target_info = infos
.iter()
.copied()
.find(|info| info.pid == input.target_pid);
let resolver = |pid| infos.iter().copied().find(|info| info.pid == pid);
let related = collect_related_pids_with_resolver(
input.target_pid,
target_info,
&candidates,
usize::from(input.max_count),
resolver,
);
assert!(related.len() <= usize::from(input.max_count));
if input.target_pid <= 0 || input.max_count == 0 {
assert!(related.is_empty());
} else {
assert_eq!(Some(&input.target_pid), related.first());
}
for candidate in candidates.into_iter().take(16) {
let resolver = |pid| infos.iter().copied().find(|info| info.pid == pid);
let _ =
is_same_launch_tree_with_resolver(candidate, input.target_pid, target_info, resolver);
}
});
@@ -0,0 +1,60 @@
#![no_main]
// SPDX-License-Identifier: AGPL-3.0-or-later
use arbitrary::Arbitrary;
use fluxer_desktop_native::linux_audio::routing::{
MEDIA_CLASS_PLAYBACK_STREAM, RoutingRule, SelfIdentity, should_route_node,
};
use libfuzzer_sys::fuzz_target;
use std::collections::BTreeMap;
#[derive(Arbitrary, Debug)]
struct Input {
id: u32,
sink_id: u32,
default_name: String,
default_id: String,
include_name: String,
app_name: String,
process_id: String,
binary: String,
has_device_id: bool,
media_class_is_playback: bool,
}
fuzz_target!(|input: Input| {
let mut props = BTreeMap::new();
props.insert(
"media.class".to_owned(),
if input.media_class_is_playback {
MEDIA_CLASS_PLAYBACK_STREAM.to_owned()
} else {
"Audio/Source".to_owned()
},
);
props.insert("application.name".to_owned(), input.app_name);
props.insert("application.process.id".to_owned(), input.process_id);
props.insert("application.process.binary".to_owned(), input.binary);
props.insert("target.object".to_owned(), input.default_name.clone());
if input.has_device_id {
props.insert("device.id".to_owned(), "5".to_owned());
}
let mut include = BTreeMap::new();
include.insert("application.name".to_owned(), input.include_name);
let rule = RoutingRule {
include_when: vec![include],
skip_hardware_devices: true,
..RoutingRule::default()
};
let self_identity = SelfIdentity::default();
let _ = should_route_node(
input.id,
&props,
&rule,
&input.default_name,
&input.default_id,
input.sink_id,
&self_identity,
);
});