@botpress/adk-cli
Version:
Command-line interface for the Botpress Agent Development Kit (ADK)
110 lines (108 loc) • 3.67 kB
JavaScript
// @bun
// src/utils/login-callback-server.ts
import http from "http";
async function startCallbackServer(options = {}) {
const { port = 0, timeout = 300000 } = options;
return new Promise((resolve, reject) => {
let tokenResolver = null;
let timeoutId = null;
const server = http.createServer((req, res) => {
if (req.method === "OPTIONS") {
res.writeHead(200, {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type"
});
res.end();
return;
}
if (req.method === "POST" && req.url === "/login-callback") {
let body = "";
req.on("data", (chunk) => {
body += chunk.toString();
});
req.on("end", () => {
try {
const data = JSON.parse(body);
const token = data.token;
if (!token || typeof token !== "string") {
res.writeHead(400, {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
});
res.end(JSON.stringify({ error: "Invalid token format" }));
return;
}
res.writeHead(200, {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
});
res.end(JSON.stringify({ success: true, message: "Login successful! You can close this window." }));
if (timeoutId) {
clearTimeout(timeoutId);
}
if (tokenResolver) {
tokenResolver({ token, success: true });
tokenResolver = null;
}
setTimeout(() => {
server.close();
}, 100);
} catch {
res.writeHead(400, {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
});
res.end(JSON.stringify({ error: "Invalid JSON body" }));
}
});
} else {
res.writeHead(404, { "Content-Type": "text/plain" });
res.end("Not Found");
}
});
server.on("error", (error) => {
reject(error);
});
server.listen(port, "127.0.0.1", () => {
const address = server.address();
const callbackUrl = `http://localhost:${address.port}/login-callback`;
const waitForToken = () => {
return new Promise((resolveToken) => {
tokenResolver = resolveToken;
timeoutId = setTimeout(() => {
if (tokenResolver) {
tokenResolver({ token: "", success: false });
tokenResolver = null;
}
server.close();
}, timeout);
});
};
const cancel = () => {
if (timeoutId) {
clearTimeout(timeoutId);
timeoutId = null;
}
if (tokenResolver) {
tokenResolver({ token: "", success: false });
tokenResolver = null;
}
server.close();
};
resolve({
url: callbackUrl,
waitForToken,
cancel
});
});
});
}
function getLoginUrl(callbackUrl, apiUrl) {
const isDev = apiUrl?.endsWith(".dev") || apiUrl?.includes(".dev/");
const appBase = isDev ? "https://app.botpress.dev" : "https://app.botpress.cloud";
const ssoBase = isDev ? "https://sso.botpress.dev" : "https://sso.botpress.cloud";
const appLoginUrl = `${appBase}/cli-login?callback=${encodeURIComponent(callbackUrl)}`;
return `${ssoBase}/login?return_to=${encodeURIComponent(appLoginUrl)}`;
}
export { startCallbackServer, getLoginUrl };