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.
51 lines
1.5 KiB
Rust
51 lines
1.5 KiB
Rust
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
use std::sync::atomic::{AtomicU64, Ordering};
|
|
use std::time::{SystemTime, UNIX_EPOCH};
|
|
|
|
pub const REQUEST_INTERFACE: &str = "org.freedesktop.portal.Request";
|
|
|
|
pub fn request_path(unique_bus_name: &str, handle_token: &str) -> String {
|
|
let trimmed = unique_bus_name.strip_prefix(':').unwrap_or(unique_bus_name);
|
|
let mut out = String::with_capacity(40 + trimmed.len() + handle_token.len());
|
|
out.push_str("/org/freedesktop/portal/desktop/request/");
|
|
for ch in trimmed.chars() {
|
|
out.push(if ch == '.' { '_' } else { ch });
|
|
}
|
|
out.push('/');
|
|
out.push_str(handle_token);
|
|
out
|
|
}
|
|
|
|
static TOKEN_SEQ: AtomicU64 = AtomicU64::new(1);
|
|
|
|
pub fn mint_token(prefix: &str) -> String {
|
|
let seq = TOKEN_SEQ.fetch_add(1, Ordering::Relaxed);
|
|
let ms = SystemTime::now()
|
|
.duration_since(UNIX_EPOCH)
|
|
.map(|d| d.as_millis() as u64)
|
|
.unwrap_or(0);
|
|
format!("{prefix}_{ms:x}_{seq:x}")
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn request_path_sanitizes_unique_bus_name() {
|
|
assert_eq!(
|
|
request_path(":1.42", "fluxer_fc_open_1"),
|
|
"/org/freedesktop/portal/desktop/request/1_42/fluxer_fc_open_1"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn mint_token_is_distinct_and_prefixed() {
|
|
let a = mint_token("fluxer_fc_open");
|
|
let b = mint_token("fluxer_fc_open");
|
|
assert_ne!(a, b);
|
|
assert!(a.starts_with("fluxer_fc_open_"));
|
|
}
|
|
}
|