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,31 @@
param(
[Parameter(Mandatory = $true)][string]$Command,
[string]$OutFile = 'C:\tools\vm_test_out.txt',
[int]$TimeoutSec = 120
)
$taskName = 'FluxerVmTest'
if (Test-Path $OutFile) { Remove-Item -Force $OutFile }
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction SilentlyContinue
$action = New-ScheduledTaskAction -Execute 'cmd.exe' -Argument ('/c ' + $Command + ' > "' + $OutFile + '" 2>&1')
$principal = New-ScheduledTaskPrincipal -UserId 'hampus' -LogonType Interactive
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit (New-TimeSpan -Minutes 10)
Register-ScheduledTask -TaskName $taskName -Action $action -Principal $principal -Settings $settings -Force | Out-Null
Start-ScheduledTask -TaskName $taskName
$deadline = (Get-Date).AddSeconds($TimeoutSec)
do {
Start-Sleep -Milliseconds 500
$state = (Get-ScheduledTask -TaskName $taskName).State
} while ($state -ne 'Ready' -and (Get-Date) -lt $deadline)
$info = Get-ScheduledTaskInfo -TaskName $taskName
Write-Output ('TASK-STATE: ' + $state + ' LAST-RESULT: ' + $info.LastTaskResult)
if (Test-Path $OutFile) {
Write-Output '--- OUTPUT ---'
Get-Content $OutFile
} else {
Write-Output 'NO OUTPUT FILE'
}
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction SilentlyContinue
@@ -0,0 +1,22 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
import ctypes
import sys
device_path = sys.argv[1].encode() if len(sys.argv) > 1 else b"/dev/hidraw4"
pin = sys.argv[2].encode() if len(sys.argv) > 2 else b"123456"
lib = ctypes.CDLL("libfido2.so.1")
lib.fido_init(0)
lib.fido_dev_new.restype = ctypes.c_void_p
lib.fido_strerr.restype = ctypes.c_char_p
dev = lib.fido_dev_new()
rc = lib.fido_dev_open(ctypes.c_void_p(dev), device_path)
if rc != 0:
print(f"open failed rc={rc} {lib.fido_strerr(rc).decode()}")
sys.exit(1)
rc = lib.fido_dev_set_pin(ctypes.c_void_p(dev), pin, None)
print(f"set_pin rc={rc} {lib.fido_strerr(rc).decode()}")
lib.fido_dev_close(ctypes.c_void_p(dev))
sys.exit(0 if rc == 0 else 1)
@@ -0,0 +1,89 @@
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"crypto/x509"
"crypto/x509/pkix"
"fmt"
"io"
"math/big"
"os"
"time"
virtual_fido "github.com/bulwarkid/virtual-fido"
"github.com/bulwarkid/virtual-fido/fido_client"
)
type autoApproveSupport struct {
vaultFilename string
}
func (support *autoApproveSupport) ApproveClientAction(action fido_client.ClientAction, params fido_client.ClientActionRequestParams) bool {
fmt.Printf("auto-approving action=%d relyingParty=%q user=%q\n", action, params.RelyingParty, params.UserName)
return true
}
func (support *autoApproveSupport) SaveData(data []byte) {
err := os.WriteFile(support.vaultFilename, data, 0o600)
if err != nil {
panic(fmt.Sprintf("could not write vault: %s", err))
}
}
func (support *autoApproveSupport) RetrieveData() []byte {
f, err := os.Open(support.vaultFilename)
if os.IsNotExist(err) {
return nil
}
if err != nil {
panic(fmt.Sprintf("could not open vault: %s", err))
}
defer f.Close()
data, err := io.ReadAll(f)
if err != nil {
panic(fmt.Sprintf("could not read vault: %s", err))
}
return data
}
func (support *autoApproveSupport) Passphrase() string {
return "vm-test-passphrase"
}
func main() {
vault := os.Getenv("VFIDO_VAULT")
if vault == "" {
vault = "/tmp/vfido-vault.json"
}
authority := &x509.Certificate{
SerialNumber: big.NewInt(0),
Subject: pkix.Name{
Organization: []string{"Fluxer VM Test Virtual FIDO"},
Country: []string{"US"},
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(10, 0, 0),
IsCA: true,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
BasicConstraintsValid: true,
}
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
panic(err)
}
authorityCertBytes, err := x509.CreateCertificate(rand.Reader, authority, authority, &privateKey.PublicKey, privateKey)
if err != nil {
panic(err)
}
encryptionKey := sha256.Sum256([]byte("fluxer-vm-test"))
virtual_fido.SetLogOutput(os.Stdout)
support := &autoApproveSupport{vaultFilename: vault}
client := fido_client.NewDefaultClient(authorityCertBytes, privateKey, encryptionKey, support, support)
fmt.Println("virtual-fido USBIP server starting on 127.0.0.1:3240 (bus 2-2)")
virtual_fido.Start(client)
}