Initial release: cloud browser with auth and one-click deploy on port 32450
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+163
@@ -0,0 +1,163 @@
|
||||
const loginSection = document.getElementById("login-section");
|
||||
const mainSection = document.getElementById("main-section");
|
||||
const settingsSection = document.getElementById("settings-section");
|
||||
const loginForm = document.getElementById("login-form");
|
||||
const loginError = document.getElementById("login-error");
|
||||
const welcomeUser = document.getElementById("welcome-user");
|
||||
const settingsForm = document.getElementById("settings-form");
|
||||
const settingsError = document.getElementById("settings-error");
|
||||
const settingsSuccess = document.getElementById("settings-success");
|
||||
const form = document.getElementById("start-form");
|
||||
const urlInput = document.getElementById("url-input");
|
||||
const startBtn = document.getElementById("start-btn");
|
||||
const errorMsg = document.getElementById("error-msg");
|
||||
|
||||
function show(el) {
|
||||
el.classList.remove("hidden");
|
||||
}
|
||||
|
||||
function hide(el) {
|
||||
el.classList.add("hidden");
|
||||
}
|
||||
|
||||
function showPanelError(el, message) {
|
||||
el.textContent = message;
|
||||
show(el);
|
||||
}
|
||||
|
||||
function hidePanelError(el) {
|
||||
hide(el);
|
||||
}
|
||||
|
||||
function showMain(username) {
|
||||
hide(loginSection);
|
||||
hide(settingsSection);
|
||||
show(mainSection);
|
||||
welcomeUser.textContent = `当前用户:${username}`;
|
||||
document.getElementById("cur-user").value = username;
|
||||
urlInput.focus();
|
||||
}
|
||||
|
||||
function showLogin() {
|
||||
hide(mainSection);
|
||||
hide(settingsSection);
|
||||
show(loginSection);
|
||||
}
|
||||
|
||||
async function init() {
|
||||
const user = await AUTH.me();
|
||||
if (user) {
|
||||
showMain(user.username);
|
||||
} else {
|
||||
showLogin();
|
||||
}
|
||||
}
|
||||
|
||||
loginForm.addEventListener("submit", async (e) => {
|
||||
e.preventDefault();
|
||||
hidePanelError(loginError);
|
||||
const username = document.getElementById("login-user").value.trim();
|
||||
const password = document.getElementById("login-pass").value;
|
||||
try {
|
||||
const data = await AUTH.login(username, password);
|
||||
showMain(data.username);
|
||||
} catch (err) {
|
||||
showPanelError(loginError, err.message);
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById("btn-logout").addEventListener("click", async () => {
|
||||
await AUTH.logout();
|
||||
showLogin();
|
||||
});
|
||||
|
||||
document.getElementById("btn-settings").addEventListener("click", () => {
|
||||
hide(mainSection);
|
||||
hidePanelError(settingsError);
|
||||
hide(settingsSuccess);
|
||||
show(settingsSection);
|
||||
});
|
||||
|
||||
document.getElementById("btn-settings-cancel").addEventListener("click", () => {
|
||||
const user = welcomeUser.textContent.replace("当前用户:", "");
|
||||
showMain(user);
|
||||
});
|
||||
|
||||
settingsForm.addEventListener("submit", async (e) => {
|
||||
e.preventDefault();
|
||||
hidePanelError(settingsError);
|
||||
hide(settingsSuccess);
|
||||
try {
|
||||
const data = await AUTH.changeCredentials({
|
||||
current_username: document.getElementById("cur-user").value.trim(),
|
||||
current_password: document.getElementById("cur-pass").value,
|
||||
new_username: document.getElementById("new-user").value.trim(),
|
||||
new_password: document.getElementById("new-pass").value,
|
||||
});
|
||||
document.getElementById("cur-pass").value = "";
|
||||
document.getElementById("new-pass").value = "";
|
||||
settingsSuccess.textContent = "账号已更新,请使用新凭据登录";
|
||||
show(settingsSuccess);
|
||||
setTimeout(async () => {
|
||||
await AUTH.logout();
|
||||
showLogin();
|
||||
}, 1500);
|
||||
welcomeUser.textContent = `当前用户:${data.username}`;
|
||||
} catch (err) {
|
||||
showPanelError(settingsError, err.message);
|
||||
}
|
||||
});
|
||||
|
||||
function showError(message) {
|
||||
errorMsg.textContent = message;
|
||||
show(errorMsg);
|
||||
}
|
||||
|
||||
function hideError() {
|
||||
hide(errorMsg);
|
||||
}
|
||||
|
||||
form.addEventListener("submit", async (event) => {
|
||||
event.preventDefault();
|
||||
hideError();
|
||||
|
||||
const url = urlInput.value.trim();
|
||||
if (!url) {
|
||||
showError("请输入网址");
|
||||
return;
|
||||
}
|
||||
|
||||
startBtn.disabled = true;
|
||||
startBtn.textContent = "启动中...";
|
||||
|
||||
try {
|
||||
const response = await fetch("/api/session", {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ url }),
|
||||
});
|
||||
|
||||
const data = await response.json().catch(() => ({}));
|
||||
|
||||
if (response.status === 401) {
|
||||
showLogin();
|
||||
showPanelError(loginError, "登录已过期,请重新登录");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
showError(data.detail || "创建会话失败");
|
||||
return;
|
||||
}
|
||||
|
||||
window.location.href = `/view/${data.session_id}`;
|
||||
} catch (err) {
|
||||
showError("网络错误,请稍后重试");
|
||||
} finally {
|
||||
startBtn.disabled = false;
|
||||
startBtn.textContent = "进入";
|
||||
}
|
||||
});
|
||||
|
||||
init();
|
||||
Reference in New Issue
Block a user