feat: GET /pair-qr endpoint — QR code in terminal, fix double-port bug
This commit is contained in:
parent
1f36636e06
commit
571cf8c9ec
|
|
@ -28,7 +28,12 @@ import type {
|
|||
ExtensionAPI,
|
||||
ExtensionContext,
|
||||
} from "@earendil-works/pi-coding-agent";
|
||||
import { consumePairingToken } from "../auth/pairing.js";
|
||||
import {
|
||||
buildPairingUrl,
|
||||
consumePairingToken,
|
||||
generatePairingToken,
|
||||
printPairingQr,
|
||||
} from "../auth/pairing.js";
|
||||
import { createToken, validateBearer } from "../auth/tokens.js";
|
||||
import {
|
||||
generateSessionId,
|
||||
|
|
@ -226,6 +231,46 @@ export async function startServer(
|
|||
|
||||
// New API routes (IC-2) — bearer token auth
|
||||
const asyncHandler = async (): Promise<boolean> => {
|
||||
// GET /pair-qr — generates pairing token + prints QR to response
|
||||
if (pathname === "/pair-qr" && req.method === "GET") {
|
||||
if (!isAuthenticated(req)) {
|
||||
sendJson(res, 403, { error: "forbidden" });
|
||||
return true;
|
||||
}
|
||||
const addr = httpServer.address() as {
|
||||
address: string;
|
||||
port: number;
|
||||
} | null;
|
||||
const port = addr?.port ?? 7777;
|
||||
const rawHost =
|
||||
(config.publicBaseUrl ?? config.advertisedBaseUrl)
|
||||
?.replace(/^https?:\/\//, "")
|
||||
.replace(/\/$/, "") ??
|
||||
addr?.address ??
|
||||
"localhost";
|
||||
// Strip :port suffix if publicBaseUrl already contains it
|
||||
const host = rawHost.includes(":")
|
||||
? rawHost.slice(0, rawHost.lastIndexOf(":"))
|
||||
: rawHost;
|
||||
const pairingEntry = generatePairingToken();
|
||||
const url = buildPairingUrl({
|
||||
host,
|
||||
port,
|
||||
pairingToken: pairingEntry.token,
|
||||
fingerprint: "",
|
||||
sidecarName: "pi-remote",
|
||||
});
|
||||
res.writeHead(200, { "Content-Type": "text/plain; charset=utf-8" });
|
||||
// Render QR inline
|
||||
const qrcode = await import("qrcode");
|
||||
const qr = await qrcode.toString(url, {
|
||||
type: "terminal",
|
||||
small: true,
|
||||
});
|
||||
res.end(`${qr}\n${url}\n\nExpires in 10 minutes.`);
|
||||
return true;
|
||||
}
|
||||
|
||||
// POST /pair — unauthenticated, uses one-time pairingToken
|
||||
if (pathname === "/pair" && req.method === "POST") {
|
||||
let body: Record<string, unknown> = {};
|
||||
|
|
|
|||
Loading…
Reference in New Issue