From 9f1a1033686451deea6342d5739b09c429b7424c Mon Sep 17 00:00:00 2001 From: Egor Date: Sun, 18 Jan 2026 23:04:03 -0800 Subject: [PATCH] fix and improve qr linking --- README.md | 2 +- .env.example => server/.env.example | 0 server/index.ts | 6 +++++- server/modules/signal.ts | 31 +++++++++++++++++++++++----- server/routes/link.ts | 11 ++++++++-- server/templates/link.html | 32 +++++++++++++++++++---------- server/utils/rpc.ts | 3 +++ 7 files changed, 65 insertions(+), 20 deletions(-) rename .env.example => server/.env.example (100%) diff --git a/README.md b/README.md index 3966f89..b875f51 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Download the latest APK from [GitHub Releases](https://github.com/lone-cloud/sup curl -L -O https://raw.githubusercontent.com/lone-cloud/sup/master/docker-compose.yml # Download .env.example (optional) -curl -L -O https://raw.githubusercontent.com/lone-cloud/sup/master/.env.example +curl -L -O https://raw.githubusercontent.com/lone-cloud/sup/master/server/.env.example # Configure (optional) cp .env.example .env diff --git a/.env.example b/server/.env.example similarity index 100% rename from .env.example rename to server/.env.example diff --git a/server/index.ts b/server/index.ts index 3367eeb..ea17afc 100644 --- a/server/index.ts +++ b/server/index.ts @@ -60,7 +60,11 @@ const server = Bun.serve({ }, [ROUTES.LINK_QR]: { - GET: handleLinkQR, + GET: () => + handleLinkQR(async () => { + daemon?.kill(); + daemon = await startDaemon(); + }), }, [ROUTES.LINK_STATUS]: { diff --git a/server/modules/signal.ts b/server/modules/signal.ts index e7c0e1d..ae97a68 100644 --- a/server/modules/signal.ts +++ b/server/modules/signal.ts @@ -1,3 +1,4 @@ +import { existsSync, unlinkSync } from 'node:fs'; import { rm } from 'node:fs/promises'; import { DEVICE_NAME, VERBOSE } from '../constants/config'; import { SIGNAL_CLI, SIGNAL_CLI_DATA, SIGNAL_CLI_SOCKET } from '../constants/paths'; @@ -10,6 +11,8 @@ logVerbose(`Running signal-cli from ${SIGNAL_CLI}`); let account: string | null = null; let currentLinkUri: string | null = null; +export const hasLinkUri = () => currentLinkUri !== null; + export async function initSignal({ accountOverride }: { accountOverride?: string }) { if (accountOverride) { account = accountOverride; @@ -49,15 +52,18 @@ export async function finishLink() { throw new Error('No link in progress'); } + const uri = currentLinkUri; + currentLinkUri = null; + const result = await call( 'finishLink', { - deviceLinkUri: currentLinkUri, + deviceLinkUri: uri, deviceName: DEVICE_NAME, }, account, ); - currentLinkUri = null; + logSuccess('✓ Device linked successfully'); return result; } @@ -65,9 +71,15 @@ export async function unlinkDevice() { account = null; currentLinkUri = null; - try { - await rm(SIGNAL_CLI_DATA, { recursive: true, force: true }); - } catch {} + if (existsSync(SIGNAL_CLI_DATA)) { + logWarn('⚠ Unlinking device and removing account data...'); + + try { + await rm(SIGNAL_CLI_DATA, { recursive: true, force: true }); + } catch (error) { + logWarn('❌ Failed to remove account data directory:', error); + } + } } export async function createGroup(name: string, members: string[] = []) { @@ -120,6 +132,15 @@ export async function startDaemon() { let authError = false; let cleaned = false; + if (existsSync(SIGNAL_CLI_SOCKET)) { + try { + unlinkSync(SIGNAL_CLI_SOCKET); + logVerbose('Removed stale socket file'); + } catch (error) { + logError('Failed to remove stale socket file:', error); + } + } + const proc = Bun.spawn([SIGNAL_CLI, 'daemon', '--socket', SIGNAL_CLI_SOCKET], { stdout: 'pipe', stderr: 'pipe', diff --git a/server/routes/link.ts b/server/routes/link.ts index c79e4a6..4266ceb 100644 --- a/server/routes/link.ts +++ b/server/routes/link.ts @@ -3,6 +3,7 @@ import { ROUTES, TEMPLATES } from '../constants/server'; import { finishLink, generateLinkQR, + hasLinkUri, hasValidAccount, initSignal, unlinkDevice, @@ -26,7 +27,13 @@ export const handleLink = async () => { }); }; -export const handleLinkQR = async () => { +export const handleLinkQR = async (restartDaemon: () => Promise) => { + const linked = await hasValidAccount(); + if (!linked) { + await unlinkDevice(); + await restartDaemon(); + } + const qrDataUrl = await generateLinkQR(); return new Response(qrDataUrl, { @@ -37,7 +44,7 @@ export const handleLinkQR = async () => { export const handleLinkStatus = async () => { let linked = await hasValidAccount(); - if (!linked) { + if (!linked && hasLinkUri()) { try { await finishLink(); await initSignal({}); diff --git a/server/templates/link.html b/server/templates/link.html index 5a6ab18..d2d12e3 100644 --- a/server/templates/link.html +++ b/server/templates/link.html @@ -12,17 +12,27 @@

Settings Linked Devices Link New Device

Generating QR code...
diff --git a/server/utils/rpc.ts b/server/utils/rpc.ts index 7ec85d2..ae1e745 100644 --- a/server/utils/rpc.ts +++ b/server/utils/rpc.ts @@ -29,6 +29,9 @@ export const call = (method: string, params: Record, account: s error(_socket, error) { reject(error); }, + connectError(_socket, error) { + reject(error); + }, close() { const isComplete = response.includes(MESSAGE_DELIMITER); if (!isComplete) {