mirror of
https://github.com/lone-cloud/prism
synced 2026-06-04 04:04:44 -07:00
more code cleanup
This commit is contained in:
parent
f4df9dcf2e
commit
136ad038a5
4 changed files with 99 additions and 76 deletions
|
|
@ -16,16 +16,20 @@ import { withAuth, withFormAuth } from './utils/auth';
|
||||||
|
|
||||||
let daemon: ReturnType<typeof Bun.spawn> | null = null;
|
let daemon: ReturnType<typeof Bun.spawn> | null = null;
|
||||||
|
|
||||||
daemon = await startDaemon();
|
try {
|
||||||
|
daemon = await startDaemon();
|
||||||
|
const isLinked = await checkSignalCli();
|
||||||
|
const hasAccount = isLinked && (await initSignal({}));
|
||||||
|
|
||||||
const isLinked = await checkSignalCli();
|
if (hasAccount) {
|
||||||
const hasAccount = isLinked && (await initSignal({}));
|
console.log(chalk.green('✓ Signal account linked'));
|
||||||
|
} else {
|
||||||
if (hasAccount) {
|
console.log(chalk.yellow('⚠ No Signal account linked'));
|
||||||
console.log(chalk.green('✓ Signal account linked'));
|
console.log(chalk.dim(` Visit http://localhost:${PORT}/link to link your device`));
|
||||||
} else {
|
}
|
||||||
console.log(chalk.yellow('⚠ No Signal account linked'));
|
} catch (error) {
|
||||||
console.log(chalk.dim(` Visit http://localhost:${PORT}/link to link your device`));
|
console.error(chalk.red('✗ Failed to start signal-cli daemon'));
|
||||||
|
console.error(chalk.dim(` ${error instanceof Error ? error.message : String(error)}`));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!API_KEY) {
|
if (!API_KEY) {
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,12 @@ import { DAEMON_START_MAX_ATTEMPTS, DEVICE_NAME, VERBOSE } from '../constants/co
|
||||||
import { SIGNAL_CLI, SIGNAL_CLI_DATA, SIGNAL_CLI_SOCKET } from '../constants/paths';
|
import { SIGNAL_CLI, SIGNAL_CLI_DATA, SIGNAL_CLI_SOCKET } from '../constants/paths';
|
||||||
import type { ListAccountsResult, StartLinkResult, UpdateGroupResult } from '../types';
|
import type { ListAccountsResult, StartLinkResult, UpdateGroupResult } from '../types';
|
||||||
import { log } from '../utils/log';
|
import { log } from '../utils/log';
|
||||||
|
import { call } from '../utils/rpc';
|
||||||
|
|
||||||
log(`Running signal-cli from ${SIGNAL_CLI}`);
|
log(`Running signal-cli from ${SIGNAL_CLI}`);
|
||||||
|
|
||||||
const MESSAGE_DELIMITER = '\n';
|
|
||||||
let account: string | null = null;
|
let account: string | null = null;
|
||||||
let currentLinkUri: string | null = null;
|
let currentLinkUri: string | null = null;
|
||||||
let rpcId = 1;
|
|
||||||
|
|
||||||
export async function initSignal({ accountOverride }: { accountOverride?: string }) {
|
export async function initSignal({ accountOverride }: { accountOverride?: string }) {
|
||||||
if (accountOverride) {
|
if (accountOverride) {
|
||||||
|
|
@ -18,7 +17,7 @@ export async function initSignal({ accountOverride }: { accountOverride?: string
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = (await rpcCall('listAccounts', {})) as ListAccountsResult;
|
const result = (await call('listAccounts', {}, account)) as ListAccountsResult;
|
||||||
const [firstAccount] = result;
|
const [firstAccount] = result;
|
||||||
if (firstAccount) {
|
if (firstAccount) {
|
||||||
account = firstAccount;
|
account = firstAccount;
|
||||||
|
|
@ -28,57 +27,14 @@ export async function initSignal({ accountOverride }: { accountOverride?: string
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function rpcCall(method: string, params: Record<string, unknown>) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let response = '';
|
|
||||||
|
|
||||||
Bun.connect({
|
|
||||||
unix: SIGNAL_CLI_SOCKET,
|
|
||||||
socket: {
|
|
||||||
data(socket, data) {
|
|
||||||
response += new TextDecoder().decode(data);
|
|
||||||
|
|
||||||
const isComplete = response.includes(MESSAGE_DELIMITER);
|
|
||||||
if (isComplete) {
|
|
||||||
socket.end();
|
|
||||||
|
|
||||||
const parsed = JSON.parse(response.trim());
|
|
||||||
|
|
||||||
if (parsed.error) {
|
|
||||||
reject(new Error(`signal-cli RPC error: ${parsed.error.message}`));
|
|
||||||
} else {
|
|
||||||
resolve(parsed.result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error(_socket, error) {
|
|
||||||
reject(error);
|
|
||||||
},
|
|
||||||
close() {
|
|
||||||
const isComplete = response.includes(MESSAGE_DELIMITER);
|
|
||||||
if (!isComplete) {
|
|
||||||
reject(new Error('Connection closed before response received'));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
open(socket) {
|
|
||||||
const request = JSON.stringify({
|
|
||||||
jsonrpc: '2.0',
|
|
||||||
id: rpcId++,
|
|
||||||
method,
|
|
||||||
params: account ? { account, ...params } : params,
|
|
||||||
});
|
|
||||||
|
|
||||||
socket.write(`${request}${MESSAGE_DELIMITER}`);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function generateLinkQR() {
|
export async function generateLinkQR() {
|
||||||
const result = (await rpcCall('startLink', {
|
const result = (await call(
|
||||||
deviceName: DEVICE_NAME,
|
'startLink',
|
||||||
})) as StartLinkResult;
|
{
|
||||||
|
deviceName: DEVICE_NAME,
|
||||||
|
},
|
||||||
|
account,
|
||||||
|
)) as StartLinkResult;
|
||||||
const uri = result.deviceLinkUri;
|
const uri = result.deviceLinkUri;
|
||||||
|
|
||||||
if (!uri) {
|
if (!uri) {
|
||||||
|
|
@ -94,10 +50,14 @@ export async function finishLink() {
|
||||||
throw new Error('No link in progress');
|
throw new Error('No link in progress');
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await rpcCall('finishLink', {
|
const result = await call(
|
||||||
deviceLinkUri: currentLinkUri,
|
'finishLink',
|
||||||
deviceName: DEVICE_NAME,
|
{
|
||||||
});
|
deviceLinkUri: currentLinkUri,
|
||||||
|
deviceName: DEVICE_NAME,
|
||||||
|
},
|
||||||
|
account,
|
||||||
|
);
|
||||||
currentLinkUri = null;
|
currentLinkUri = null;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -112,10 +72,14 @@ export async function unlinkDevice() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createGroup(name: string, members: string[] = []) {
|
export async function createGroup(name: string, members: string[] = []) {
|
||||||
const result = (await rpcCall('updateGroup', {
|
const result = (await call(
|
||||||
name,
|
'updateGroup',
|
||||||
member: members,
|
{
|
||||||
})) as UpdateGroupResult;
|
name,
|
||||||
|
member: members,
|
||||||
|
},
|
||||||
|
account,
|
||||||
|
)) as UpdateGroupResult;
|
||||||
|
|
||||||
if (!result?.groupId) {
|
if (!result?.groupId) {
|
||||||
throw new Error('Failed to create group');
|
throw new Error('Failed to create group');
|
||||||
|
|
@ -125,15 +89,19 @@ export async function createGroup(name: string, members: string[] = []) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function sendGroupMessage(groupId: string, message: string) {
|
export async function sendGroupMessage(groupId: string, message: string) {
|
||||||
await rpcCall('send', {
|
await call(
|
||||||
groupId,
|
'send',
|
||||||
message,
|
{
|
||||||
});
|
groupId,
|
||||||
|
message,
|
||||||
|
},
|
||||||
|
account,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function checkSignalCli() {
|
export async function checkSignalCli() {
|
||||||
try {
|
try {
|
||||||
await rpcCall('listAccounts', {});
|
await call('listAccounts', {}, account);
|
||||||
return true;
|
return true;
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -142,7 +110,7 @@ export async function checkSignalCli() {
|
||||||
|
|
||||||
export async function hasValidAccount() {
|
export async function hasValidAccount() {
|
||||||
try {
|
try {
|
||||||
const result = (await rpcCall('listAccounts', {})) as ListAccountsResult;
|
const result = (await call('listAccounts', {}, account)) as ListAccountsResult;
|
||||||
return result.length > 0;
|
return result.length > 0;
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ export const handleLink = async () => {
|
||||||
|
|
||||||
export const handleLinkQR = async () => {
|
export const handleLinkQR = async () => {
|
||||||
const qrDataUrl = await generateLinkQR();
|
const qrDataUrl = await generateLinkQR();
|
||||||
|
|
||||||
return new Response(qrDataUrl, {
|
return new Response(qrDataUrl, {
|
||||||
headers: { 'content-type': 'text/plain' },
|
headers: { 'content-type': 'text/plain' },
|
||||||
});
|
});
|
||||||
|
|
|
||||||
50
server/utils/rpc.ts
Normal file
50
server/utils/rpc.ts
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
import { SIGNAL_CLI_SOCKET } from '../constants/paths';
|
||||||
|
|
||||||
|
const MESSAGE_DELIMITER = '\n';
|
||||||
|
let rpcId = 1;
|
||||||
|
|
||||||
|
export const call = (method: string, params: Record<string, unknown>, account: string | null) =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
let response = '';
|
||||||
|
|
||||||
|
Bun.connect({
|
||||||
|
unix: SIGNAL_CLI_SOCKET,
|
||||||
|
socket: {
|
||||||
|
data(socket, data) {
|
||||||
|
response += new TextDecoder().decode(data);
|
||||||
|
|
||||||
|
const isComplete = response.includes(MESSAGE_DELIMITER);
|
||||||
|
if (isComplete) {
|
||||||
|
socket.end();
|
||||||
|
|
||||||
|
const parsed = JSON.parse(response.trim());
|
||||||
|
|
||||||
|
if (parsed.error) {
|
||||||
|
reject(new Error(`signal-cli RPC error: ${parsed.error.message}`));
|
||||||
|
} else {
|
||||||
|
resolve(parsed.result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error(_socket, error) {
|
||||||
|
reject(error);
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
const isComplete = response.includes(MESSAGE_DELIMITER);
|
||||||
|
if (!isComplete) {
|
||||||
|
reject(new Error('Connection closed before response received'));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
open(socket) {
|
||||||
|
const request = JSON.stringify({
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
id: rpcId++,
|
||||||
|
method,
|
||||||
|
params: account ? { account, ...params } : params,
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.write(`${request}${MESSAGE_DELIMITER}`);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Add table
Reference in a new issue