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:
@@ -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)
|
||||
}
|
||||
Reference in New Issue
Block a user