diff --git a/app/src/daemon.ts b/app/src/daemon.ts index 25907ae..eb20f6b 100644 --- a/app/src/daemon.ts +++ b/app/src/daemon.ts @@ -8,7 +8,13 @@ import { Readable } from "stream"; import { DecodeTransform, EncodeTransform } from "./transforms"; -export function init(port: number, serverPassword?: string) { +interface DaemonOpts { + host: string; + port: number; + password: string; +} + +export function init(opts: DaemonOpts) { const server = http.createServer(); const wss = new WebSocket.Server({ noServer: true }); @@ -65,14 +71,14 @@ export function init(port: number, serverPassword?: string) { * server password specified in launch options. */ function authenticate(req: IncomingMessage) { - if (!serverPassword) return true; + if (!opts.password) return true; const password = new URL( req.url!, `http://${req.headers.host}` ).searchParams.get("password"); - return password === serverPassword; + return password === opts.password; } server.on("upgrade", (req, socket, head) => { @@ -113,5 +119,5 @@ export function init(port: number, serverPassword?: string) { res.end(); }); - server.listen(port); + server.listen({ port: opts.port, host: opts.host }); } diff --git a/app/src/main.ts b/app/src/main.ts index 33fab91..1ab3eaa 100644 --- a/app/src/main.ts +++ b/app/src/main.ts @@ -6,16 +6,19 @@ import { __applicationVersion } from "../package.json"; const argv = minimist(process.argv.slice(2), { boolean: ["daemon", "help", "version"], - string: ["__name", "port", "password"], + string: ["__name", "host", "port", "password"], alias: { d: "daemon", h: "help", v: "version", - p: "port" + n: "host", + p: "port", + P: "password" }, default: { __name: path.basename(process.argv[0]), daemon: false, + host: "localhost", port: "9556" } }); @@ -32,15 +35,17 @@ Options: -h, --help Print usage info -v, --version Print version info -d, --daemon Launch in daemon mode. This starts a WebSocket server that - the extension can be configured to connect to under bridge - options. - -p, --port Set port number for WebSocket server. This must match the - port set in the extension options. - --password Set an optional password for the WebSocket server. This must - match the password set in the extension options. - WARNING: This password is intended only as a basic access - control measure and is transmitted in plain text even over - remote connections! + the extension can be configured to connect to under bridge + options. + -n, --host Host for daemon WebSocket server. This must match the host + set in the extension options. + -p, --port Port number for daemon WebSocket server. This must match the + port set in the extension options. + -P, --password Set an optional password for the daemon WebSocket server. + This must match the password set in the extension options. + WARNING: This password is intended only as a basic access + control measure and is transmitted in plain text even over + remote connections! ` ); } else if (argv.daemon) { @@ -51,7 +56,11 @@ Options: } import("./daemon").then(daemon => { - daemon.init(port, argv.password); + daemon.init({ + host: argv.host, + port, + password: argv.password + }); }); } else { import("./bridge"); diff --git a/ext/src/lib/nativeMessaging.ts b/ext/src/lib/nativeMessaging.ts index 4882ad2..f9e7171 100644 --- a/ext/src/lib/nativeMessaging.ts +++ b/ext/src/lib/nativeMessaging.ts @@ -15,7 +15,16 @@ async function getBackupServerUrl() { const { bridgeBackupHost, bridgeBackupPort, bridgeBackupPassword } = await options.getAll(); - const url = new URL(`ws://${bridgeBackupHost}:${bridgeBackupPort}`); + const url = new URL( + `ws://${ + // Handle IPv6 address formatting + bridgeBackupHost.includes(":") + ? `[${bridgeBackupHost}]` + : bridgeBackupHost + }` + ); + url.port = bridgeBackupPort.toString(); + if (bridgeBackupPassword) { url.searchParams.append("password", bridgeBackupPassword); }