#!/usr/bin/env node // Tiny admin CLI for dsh-remote that talks to the LOCAL DSH over loopback, authenticating // with DSH's own browser-session secret from $DSH_HOME/.credentials.yaml (owner-only file). // // node dshr-cli.mjs GET state // node dshr-cli.mjs POST pairing '{}' // node dshr-cli.mjs POST pair '{"masterUrl":"http://192.168.0.111:3080","code":"ABCD-..."}' // node dshr-cli.mjs GET /r// (raw path, prints status + first bytes) // // Env: DSH_PORT (default 3081), DSH_HOME (default ~/.dsh) import fs from 'node:fs' import os from 'node:os' import path from 'node:path' import { mintCookie } from '../lib/auth-cookie.mjs' const [method = 'GET', target = 'state', body] = process.argv.slice(2) const port = process.env.DSH_PORT || '3081' const home = process.env.DSH_HOME || path.join(os.homedir(), '.dsh') const creds = fs.readFileSync(path.join(home, '.credentials.yaml'), 'utf8') const m = creds.match(/client-connection\/browser-session:[\s\S]*?secret:\s*([A-Za-z0-9_-]{43})/) if (!m) { console.error('browser-session secret not found'); process.exit(2) } const authority = `127.0.0.1:${port}` const cookie = mintCookie(authority, m[1], 1) const url = target.startsWith('/') ? `http://${authority}${target}` : `http://${authority}/dsh-remote/${target}` const res = await fetch(url, { method, headers: { cookie, ...(body ? { 'content-type': 'application/json' } : {}) }, body: body || undefined, redirect: 'manual', }) const text = await res.text() if (target.startsWith('/')) { console.log(res.status, res.headers.get('content-type') || '', res.headers.get('location') || '') console.log(text.slice(0, Number(process.env.BYTES || 400))) } else { console.log(res.status) try { console.log(JSON.stringify(JSON.parse(text), null, 2)) } catch { console.log(text) } }