auth: implement /consent auto-approve (Claude sends prompt=consent, forcing it)
build / test (push) Successful in 14s
build / build (push) Successful in 8s

Google login worked; the flow died on the unimplemented consent page. Auto-accept
via auth.api.oauth2Consent with the signed oauth_query + session, then 302 to the
client callback with the code.
This commit is contained in:
2026-07-06 16:53:06 -04:00
parent 5d4cc7a122
commit 462d8c0223
+36
View File
@@ -43,6 +43,38 @@ async function startLogin(req: IncomingMessage, res: ServerResponse, rawSearch:
}
}
// Better Auth redirects here when the client sends prompt=consent (which forces
// the consent screen even with skipConsent). For a personal MCP connector the
// login *is* the authorization, so auto-approve: call the consent endpoint with
// the signed oauth_query + the user's session, then 302 to the client callback.
async function handleConsent(req: IncomingMessage, res: ServerResponse, rawSearch: string) {
const headers = new Headers();
if (req.headers.cookie) headers.set("cookie", req.headers.cookie);
const oauthQuery = rawSearch.startsWith("?") ? rawSearch.slice(1) : rawSearch;
try {
const result = await auth.api.oauth2Consent({
body: { accept: true, oauth_query: oauthQuery },
headers,
returnHeaders: true,
});
const setCookie = result.headers.getSetCookie();
if (setCookie.length) res.setHeader("set-cookie", setCookie);
const target = (result.response as { url?: string } | null)?.url;
if (!target) {
res.writeHead(500, { "content-type": "text/plain" });
res.end("Consent failed.");
return;
}
res.writeHead(302, { location: target });
res.end();
} catch (err) {
// eslint-disable-next-line no-console
console.error("[consent] oauth2Consent failed", err);
res.writeHead(500, { "content-type": "text/plain" });
res.end("Consent error.");
}
}
const server = createServer((req, res) => {
const url = new URL(req.url ?? "/", "http://localhost");
if (url.pathname !== "/healthz") {
@@ -60,6 +92,10 @@ const server = createServer((req, res) => {
void startLogin(req, res, url.search);
return;
}
if (url.pathname === "/consent" && req.method === "GET") {
void handleConsent(req, res, url.search);
return;
}
// Everything else -> Better Auth (async handler).
void handler(req, res);
});