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
@@ -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,
);
});