auth: implement /consent auto-approve (Claude sends prompt=consent, forcing it)
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:
@@ -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 server = createServer((req, res) => {
|
||||||
const url = new URL(req.url ?? "/", "http://localhost");
|
const url = new URL(req.url ?? "/", "http://localhost");
|
||||||
if (url.pathname !== "/healthz") {
|
if (url.pathname !== "/healthz") {
|
||||||
@@ -60,6 +92,10 @@ const server = createServer((req, res) => {
|
|||||||
void startLogin(req, res, url.search);
|
void startLogin(req, res, url.search);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (url.pathname === "/consent" && req.method === "GET") {
|
||||||
|
void handleConsent(req, res, url.search);
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Everything else -> Better Auth (async handler).
|
// Everything else -> Better Auth (async handler).
|
||||||
void handler(req, res);
|
void handler(req, res);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user