mirror of https://github.com/openclaw/openclaw.git
119 lines
3.7 KiB
TypeScript
119 lines
3.7 KiB
TypeScript
import { listChannelPlugins } from "../../channels/plugins/index.js";
|
|
import {
|
|
ErrorCodes,
|
|
errorShape,
|
|
formatValidationErrors,
|
|
validateWebLoginStartParams,
|
|
validateWebLoginWaitParams,
|
|
} from "../protocol/index.js";
|
|
import { formatForLog } from "../ws-log.js";
|
|
import type { GatewayRequestHandlers, RespondFn } from "./types.js";
|
|
|
|
const WEB_LOGIN_METHODS = new Set(["web.login.start", "web.login.wait"]);
|
|
|
|
const resolveWebLoginProvider = () =>
|
|
listChannelPlugins().find((plugin) =>
|
|
(plugin.gatewayMethods ?? []).some((method) => WEB_LOGIN_METHODS.has(method)),
|
|
) ?? null;
|
|
|
|
function resolveAccountId(params: unknown): string | undefined {
|
|
return typeof (params as { accountId?: unknown }).accountId === "string"
|
|
? (params as { accountId?: string }).accountId
|
|
: undefined;
|
|
}
|
|
|
|
function respondProviderUnavailable(respond: RespondFn) {
|
|
respond(
|
|
false,
|
|
undefined,
|
|
errorShape(ErrorCodes.INVALID_REQUEST, "web login provider is not available"),
|
|
);
|
|
}
|
|
|
|
function respondProviderUnsupported(respond: RespondFn, providerId: string) {
|
|
respond(
|
|
false,
|
|
undefined,
|
|
errorShape(ErrorCodes.INVALID_REQUEST, `web login is not supported by provider ${providerId}`),
|
|
);
|
|
}
|
|
|
|
export const webHandlers: GatewayRequestHandlers = {
|
|
"web.login.start": async ({ params, respond, context }) => {
|
|
if (!validateWebLoginStartParams(params)) {
|
|
respond(
|
|
false,
|
|
undefined,
|
|
errorShape(
|
|
ErrorCodes.INVALID_REQUEST,
|
|
`invalid web.login.start params: ${formatValidationErrors(validateWebLoginStartParams.errors)}`,
|
|
),
|
|
);
|
|
return;
|
|
}
|
|
try {
|
|
const accountId = resolveAccountId(params);
|
|
const provider = resolveWebLoginProvider();
|
|
if (!provider) {
|
|
respondProviderUnavailable(respond);
|
|
return;
|
|
}
|
|
await context.stopChannel(provider.id, accountId);
|
|
if (!provider.gateway?.loginWithQrStart) {
|
|
respondProviderUnsupported(respond, provider.id);
|
|
return;
|
|
}
|
|
const result = await provider.gateway.loginWithQrStart({
|
|
force: Boolean((params as { force?: boolean }).force),
|
|
timeoutMs:
|
|
typeof (params as { timeoutMs?: unknown }).timeoutMs === "number"
|
|
? (params as { timeoutMs?: number }).timeoutMs
|
|
: undefined,
|
|
verbose: Boolean((params as { verbose?: boolean }).verbose),
|
|
accountId,
|
|
});
|
|
respond(true, result, undefined);
|
|
} catch (err) {
|
|
respond(false, undefined, errorShape(ErrorCodes.UNAVAILABLE, formatForLog(err)));
|
|
}
|
|
},
|
|
"web.login.wait": async ({ params, respond, context }) => {
|
|
if (!validateWebLoginWaitParams(params)) {
|
|
respond(
|
|
false,
|
|
undefined,
|
|
errorShape(
|
|
ErrorCodes.INVALID_REQUEST,
|
|
`invalid web.login.wait params: ${formatValidationErrors(validateWebLoginWaitParams.errors)}`,
|
|
),
|
|
);
|
|
return;
|
|
}
|
|
try {
|
|
const accountId = resolveAccountId(params);
|
|
const provider = resolveWebLoginProvider();
|
|
if (!provider) {
|
|
respondProviderUnavailable(respond);
|
|
return;
|
|
}
|
|
if (!provider.gateway?.loginWithQrWait) {
|
|
respondProviderUnsupported(respond, provider.id);
|
|
return;
|
|
}
|
|
const result = await provider.gateway.loginWithQrWait({
|
|
timeoutMs:
|
|
typeof (params as { timeoutMs?: unknown }).timeoutMs === "number"
|
|
? (params as { timeoutMs?: number }).timeoutMs
|
|
: undefined,
|
|
accountId,
|
|
});
|
|
if (result.connected) {
|
|
await context.startChannel(provider.id, accountId);
|
|
}
|
|
respond(true, result, undefined);
|
|
} catch (err) {
|
|
respond(false, undefined, errorShape(ErrorCodes.UNAVAILABLE, formatForLog(err)));
|
|
}
|
|
},
|
|
};
|