Something went wrong. Try again.
Monorepo for Aesthetic.Computer aesthetic.computer
Something went wrong. Try again.
JavaScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203// device-pair, 2026.03.18// Device pairing flow for AC Native OS identity switching.// POST {action:"create"} → generates a 6-char code (no auth required)// GET ?code=XXXXXX → polls for claimed status (no auth required)// POST {action:"claim", code:"XXXXXX"} → authenticated user claims the code
import { authorize } from "../../backend/authorization.mjs";import { connect } from "../../backend/database.mjs";import { respond } from "../../backend/http.mjs";import { getDeviceCreds } from "../../backend/device-creds.mjs";import crypto from "node:crypto";
function generateCode() { const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"; // no I/O/0/1 for clarity let code = ""; for (let i = 0; i < 6; i++) { code += chars[Math.floor(Math.random() * chars.length)]; } return code;}
function generatePollSecret() { return crypto.randomBytes(32).toString("base64url");}
function secretDigest(secret) { return crypto.createHash("sha256").update(String(secret)).digest("hex");}
export async function handler(event) { // CORS preflight if (event.httpMethod === "OPTIONS") { return respond(200, ""); }
// GET: Poll for claimed code if (event.httpMethod === "GET") { const code = event.queryStringParameters?.code; if (!code) return respond(400, { message: "Missing code parameter" });
const database = await connect(); try { const doc = await database.db .collection("device-pairs") .findOne({ _id: code.toUpperCase() });
if (!doc) return respond(404, { message: "Code not found or expired" });
// Browser/TV pairings are bearer flows: the short public code shown in // the QR is not sufficient to retrieve a session. Only the creating TV // possesses this 256-bit secret, and only its digest is stored. if (doc.kind === "browser") { const supplied = secretDigest(event.queryStringParameters?.secret || ""); const expected = String(doc.pollSecretDigest || ""); if (!expected || supplied.length !== expected.length || !crypto.timingSafeEqual(Buffer.from(supplied), Buffer.from(expected))) { return respond(403, { message: "Invalid polling credential" }); } if (doc.claimed) { const result = { status: "claimed", handle: doc.handle, session: { accessToken: doc.token, account: { label: `@${doc.handle}`, id: doc.sub } }, }; // A browser session can be collected once. Never place native // Claude/GitHub credentials in this document or response. const delivery = await database.db.collection("device-pairs").updateOne( { _id: doc._id, deliveredAt: { $exists: false } }, { $set: { deliveredAt: new Date() }, $unset: { token: "" } }, ); if (doc.deliveredAt || !doc.token || delivery.modifiedCount !== 1) return respond(410, { message: "Session already collected" }); return respond(200, result); } return respond(200, { status: "pending" }); }
if (doc.claimed) { // Return the full config for the device return respond(200, { status: "claimed", handle: doc.handle, sub: doc.sub, email: doc.email, token: doc.token, claudeToken: doc.claudeToken || null, githubPat: doc.githubPat || null, }); }
return respond(200, { status: "pending" }); } finally { await database.disconnect(); } }
// POST: Create or claim if (event.httpMethod === "POST") { let body; try { body = JSON.parse(event.body); } catch { return respond(400, { message: "Invalid JSON" }); }
const database = await connect(); try { const pairs = database.db.collection("device-pairs");
// Ensure TTL index exists (codes expire after 10 minutes) await pairs .createIndex({ createdAt: 1 }, { expireAfterSeconds: 600 }) .catch(() => {});
if (body.action === "create") { // Generate unique code let code; let attempts = 0; do { code = generateCode(); const existing = await pairs.findOne({ _id: code }); if (!existing) break; attempts++; } while (attempts < 10);
const kind = body.kind === "browser" ? "browser" : "native"; const pollSecret = kind === "browser" ? generatePollSecret() : null; await pairs.insertOne({ _id: code, kind, claimed: false, createdAt: new Date(), ...(pollSecret ? { pollSecretDigest: secretDigest(pollSecret) } : {}), });
return respond(200, { code, ...(pollSecret ? { pollSecret } : {}) }); }
if (body.action === "claim") { const code = body.code?.toUpperCase(); if (!code) return respond(400, { message: "Missing code" });
// Require authentication const user = await authorize(event.headers); if (!user) return respond(401, { message: "unauthorized" });
// Look up handle (for display) + device creds (from the dedicated store) const handleDoc = await database.db .collection("@handles") .findOne({ _id: user.sub }, { projection: { handle: 1 } }); if (!handleDoc) return respond(404, { message: "No handle found for this account" });
const pair = await pairs.findOne({ _id: code }); if (!pair) return respond(404, { message: "Code not found or expired" }); const creds = pair.kind === "browser" ? null : await getDeviceCreds(database.db, user.sub);
// Get the auth token from the request (pass it through to the device) const authHeader = event.headers.authorization || ""; const authToken = authHeader.startsWith("Bearer ") ? authHeader.slice(7).trim() : "";
const result = await pairs.updateOne( { _id: code, claimed: false }, { $set: { claimed: true, claimedAt: new Date(), handle: handleDoc.handle, sub: user.sub, email: user.email || "", token: authToken, ...(pair.kind === "browser" ? {} : { claudeToken: creds?.claudeToken || "", githubPat: creds?.githubPat || "", }), }, }, );
if (result.matchedCount === 0) { return respond(404, { message: "Code not found, expired, or already claimed", }); }
return respond(200, { message: `Device paired as @${handleDoc.handle}`, handle: handleDoc.handle, kind: pair.kind, }); }
return respond(400, { message: "Invalid action" }); } finally { await database.disconnect(); } }
return respond(405, { message: "Method Not Allowed" });}