auth: strip prompt=consent from initial authorize (auto-approve for connector)
Claude forces the consent screen with prompt=consent; the consent endpoint's signed-query round-trip is brittle. Simpler: drop prompt=consent from the initial unsigned authorize so skipConsent applies and no consent page is shown. Also pass raw query bytes to the login/consent handlers.
This commit is contained in:
+19
-2
@@ -77,6 +77,11 @@ async function handleConsent(req: IncomingMessage, res: ServerResponse, rawSearc
|
||||
|
||||
const server = createServer((req, res) => {
|
||||
const url = new URL(req.url ?? "/", "http://localhost");
|
||||
// Raw query bytes (the URL API re-encodes .search, which breaks Better Auth's
|
||||
// signed oauth_query check on /consent). Take the query straight from req.url.
|
||||
const rawUrl = req.url ?? "/";
|
||||
const qIndex = rawUrl.indexOf("?");
|
||||
const rawSearch = qIndex >= 0 ? rawUrl.slice(qIndex) : "";
|
||||
if (url.pathname !== "/healthz") {
|
||||
// Request-level trace (path only, no query — avoids logging codes/tokens).
|
||||
// eslint-disable-next-line no-console
|
||||
@@ -89,13 +94,25 @@ const server = createServer((req, res) => {
|
||||
return;
|
||||
}
|
||||
if (url.pathname === "/login" && req.method === "GET") {
|
||||
void startLogin(req, res, url.search);
|
||||
void startLogin(req, res, rawSearch);
|
||||
return;
|
||||
}
|
||||
if (url.pathname === "/consent" && req.method === "GET") {
|
||||
void handleConsent(req, res, url.search);
|
||||
void handleConsent(req, res, rawSearch);
|
||||
return;
|
||||
}
|
||||
// Claude sends prompt=consent on the initial authorize, which forces the
|
||||
// consent screen even with skipConsent. For a personal connector the login is
|
||||
// the authorization, so strip it from the initial (unsigned) request — the
|
||||
// signed resume after login has a `sig` and is left untouched.
|
||||
if (
|
||||
url.pathname === "/api/auth/oauth2/authorize" &&
|
||||
!url.searchParams.has("sig") &&
|
||||
url.searchParams.get("prompt") === "consent"
|
||||
) {
|
||||
url.searchParams.delete("prompt");
|
||||
req.url = url.pathname + (url.searchParams.toString() ? `?${url.searchParams}` : "");
|
||||
}
|
||||
// Everything else -> Better Auth (async handler).
|
||||
void handler(req, res);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user