mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-15 10:06:03 +00:00
* feat(onboarding): add provider sign-in flows * fix(oauth): keep callback compatibility * fix(onboarding): reconcile lost auth outcomes * fix(onboarding): lock auth cancellation at commit * fix(onboarding): close provider auth lifecycle gaps * fix(onboarding): make terminal auth failures dismissable * fix(onboarding): satisfy native app checks * fix(onboarding): reconcile absent auth sessions * fix(onboarding): bound provider auth sessions * fix(onboarding): open provider auth links safely * test(onboarding): use scanner-safe auth fixtures * revert: keep established onboarding auth fixtures * fix(onboarding): close provider auth cancellation gaps * fix(gateway): retain uncollected wizard results * fix(onboarding): bind provider reconciliation attempt * fix(i18n): avoid guessing moved string identities * style(onboarding): normalize remote auth choices efficiently * fix(protocol): refresh optional provider auth choices * test(gateway): cover provider auth dispatch order * refactor(macos): split onboarding setup support * fix(macos): refresh merged native checks
65 lines
2.1 KiB
TypeScript
65 lines
2.1 KiB
TypeScript
// Google plugin module implements oauth.flow behavior.
|
|
import { generateHexPkceVerifierChallenge } from "openclaw/plugin-sdk/provider-auth";
|
|
import {
|
|
generateOAuthState,
|
|
parseOAuthCallbackInput,
|
|
waitForLocalOAuthCallback,
|
|
} from "openclaw/plugin-sdk/provider-auth-runtime";
|
|
import { isWSL2Sync } from "openclaw/plugin-sdk/runtime-env";
|
|
import { resolveOAuthClientConfig } from "./oauth.credentials.js";
|
|
import { AUTH_URL, REDIRECT_URI, SCOPES } from "./oauth.shared.js";
|
|
|
|
export { generateOAuthState };
|
|
|
|
export function shouldUseManualOAuthFlow(isRemote: boolean): boolean {
|
|
return isRemote || isWSL2Sync();
|
|
}
|
|
|
|
export function generatePkce(): { verifier: string; challenge: string } {
|
|
return generateHexPkceVerifierChallenge();
|
|
}
|
|
|
|
export function buildAuthUrl(challenge: string, state: string): string {
|
|
const { clientId } = resolveOAuthClientConfig();
|
|
const params = new URLSearchParams({
|
|
client_id: clientId,
|
|
response_type: "code",
|
|
redirect_uri: REDIRECT_URI,
|
|
scope: SCOPES.join(" "),
|
|
code_challenge: challenge,
|
|
code_challenge_method: "S256",
|
|
state,
|
|
access_type: "offline",
|
|
prompt: "consent",
|
|
});
|
|
return `${AUTH_URL}?${params.toString()}`;
|
|
}
|
|
|
|
export function parseCallbackInput(
|
|
input: string,
|
|
): { code: string; state: string } | { error: string } {
|
|
return parseOAuthCallbackInput(input, {
|
|
missingState: "Missing 'state' parameter. Paste the full URL.",
|
|
invalidInput: "Paste the full redirect URL, not just the code.",
|
|
});
|
|
}
|
|
|
|
export async function waitForLocalCallback(params: {
|
|
expectedState: string;
|
|
timeoutMs: number;
|
|
onProgress?: (message: string) => void;
|
|
signal?: AbortSignal;
|
|
}): Promise<{ code: string; state: string }> {
|
|
return await waitForLocalOAuthCallback({
|
|
expectedState: params.expectedState,
|
|
timeoutMs: params.timeoutMs,
|
|
port: 8085,
|
|
callbackPath: "/oauth2callback",
|
|
redirectUri: REDIRECT_URI,
|
|
successTitle: "Gemini CLI OAuth complete",
|
|
progressMessage: `Waiting for OAuth callback on ${REDIRECT_URI}…`,
|
|
onProgress: params.onProgress,
|
|
...(params.signal ? { signal: params.signal } : {}),
|
|
});
|
|
}
|