mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-25 03:45:46 -06:00
56 lines
2.0 KiB
TypeScript
56 lines
2.0 KiB
TypeScript
/** Coordinates provider OAuth flows exposed by plugin-owned auth integrations. */
|
|
import type { RuntimeEnv } from "../runtime.js";
|
|
import type { WizardPrompter } from "../wizard/prompts.js";
|
|
|
|
/** Prompt payload used when OAuth flow code entry needs user input. */
|
|
export type OAuthPrompt = { message: string; placeholder?: string };
|
|
|
|
const validateRequiredInput = (value: string) => (value.trim().length > 0 ? undefined : "Required");
|
|
|
|
/** Creates OAuth callbacks that use local browser auth locally and manual code entry on VPS hosts. */
|
|
export function createVpsAwareOAuthHandlers(params: {
|
|
isRemote: boolean;
|
|
prompter: WizardPrompter;
|
|
runtime: RuntimeEnv;
|
|
spin: ReturnType<WizardPrompter["progress"]>;
|
|
openUrl: (url: string) => Promise<unknown>;
|
|
localBrowserMessage: string;
|
|
manualPromptMessage?: string;
|
|
}): {
|
|
onAuth: (event: { url: string }) => Promise<void>;
|
|
onPrompt: (prompt: OAuthPrompt) => Promise<string>;
|
|
} {
|
|
const manualPromptMessage = params.manualPromptMessage ?? "Paste the redirect URL";
|
|
// Remote hosts cannot open the user's browser, so auth starts in onAuth and finishes in onPrompt.
|
|
let manualCodePromise: Promise<string> | undefined;
|
|
|
|
return {
|
|
onAuth: async ({ url }) => {
|
|
if (params.isRemote) {
|
|
params.spin.stop("OAuth URL ready");
|
|
params.runtime.log(`\nOpen this URL in your LOCAL browser:\n\n${url}\n`);
|
|
manualCodePromise = params.prompter.text({
|
|
message: manualPromptMessage,
|
|
validate: validateRequiredInput,
|
|
});
|
|
return;
|
|
}
|
|
|
|
params.spin.update(params.localBrowserMessage);
|
|
await params.openUrl(url);
|
|
params.runtime.log(`Open: ${url}`);
|
|
},
|
|
onPrompt: async (prompt) => {
|
|
if (manualCodePromise) {
|
|
return manualCodePromise;
|
|
}
|
|
const code = await params.prompter.text({
|
|
message: prompt.message,
|
|
placeholder: prompt.placeholder,
|
|
validate: validateRequiredInput,
|
|
});
|
|
return code;
|
|
},
|
|
};
|
|
}
|