Add session version handling
This commit is contained in:
@@ -21,6 +21,8 @@ const loginUsernameInput = $("loginUsername");
|
||||
const loginPasswordInput = $("loginPassword");
|
||||
const registerUsernameInput = $("registerUsername");
|
||||
const registerPasswordInput = $("registerPassword");
|
||||
const registerInviteField = $("registerInviteField");
|
||||
const registerInviteCodeInput = $("registerInviteCode");
|
||||
const loginSubmit = $("loginSubmit");
|
||||
const registerSubmit = $("registerSubmit");
|
||||
const chatList = $("chatList");
|
||||
@@ -190,6 +192,8 @@ export {
|
||||
popupModal,
|
||||
popupTitle,
|
||||
registerForm,
|
||||
registerInviteCodeInput,
|
||||
registerInviteField,
|
||||
registerPasswordInput,
|
||||
registerSubmit,
|
||||
registerUsernameInput,
|
||||
|
||||
@@ -52,6 +52,10 @@
|
||||
<span>Create password</span>
|
||||
<input id="registerPassword" type="password" placeholder="Create a password" autocomplete="new-password"/>
|
||||
</label>
|
||||
<label id="registerInviteField" class="field hidden">
|
||||
<span>Invite code</span>
|
||||
<input id="registerInviteCode" placeholder="Enter invite code" autocomplete="off"/>
|
||||
</label>
|
||||
<div class="consent-container">
|
||||
<input type="checkbox" id="consentCheckbox" required/>
|
||||
<label for="consentCheckbox">
|
||||
|
||||
+7
-1
@@ -78,6 +78,8 @@ import {
|
||||
popupModal,
|
||||
popupTitle,
|
||||
registerForm,
|
||||
registerInviteCodeInput,
|
||||
registerInviteField,
|
||||
registerPasswordInput,
|
||||
registerSubmit,
|
||||
registerUsernameInput,
|
||||
@@ -1643,6 +1645,7 @@ async function displayModels() {
|
||||
|
||||
async function checkSession() {
|
||||
const res = await get("/session");
|
||||
if (registerInviteField) registerInviteField.classList.toggle("hidden", !res.inviteOnlyRegistration);
|
||||
if (!res.user) return false;
|
||||
currentUsername = res.user; authDiv.style.display = "none"; chatDiv.style.display = "block";
|
||||
await Promise.all([displayModels(), loadSummary(), loadChatSessions(), loadPersonas()]);
|
||||
@@ -1654,7 +1657,10 @@ async function handleAuth(endpoint, credentials) {
|
||||
const {username, password} = credentials, submitBtn = endpoint === "login" ? loginSubmit : registerSubmit;
|
||||
if (!username || !password) return setAuthMessage("Please enter both username and password.", "error");
|
||||
submitBtn.disabled = true; setAuthMessage("Processing...");
|
||||
const res = await post(`/${endpoint}`, {username, password});
|
||||
const payload = endpoint === "register"
|
||||
? {username, password, inviteCode: registerInviteCodeInput?.value.trim() || ""}
|
||||
: {username, password};
|
||||
const res = await post(`/${endpoint}`, payload);
|
||||
submitBtn.disabled = false;
|
||||
if (res.error) return setAuthMessage(res.error, "error");
|
||||
if (endpoint === "login") {
|
||||
|
||||
@@ -81,6 +81,33 @@
|
||||
<button id="savePassword" type="submit">Save password</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="settings-panel">
|
||||
<div class="settings-section-header">
|
||||
<div>
|
||||
<p class="eyebrow">Account data</p>
|
||||
<h2>Export and sessions</h2>
|
||||
<p class="subtitle">Download your account data or sign out every active browser session.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="persona-actions">
|
||||
<button id="exportAccount" type="button" class="secondary-action">Export account</button>
|
||||
<button id="logoutAllSessions" type="button" class="secondary-action">Logout all sessions</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-panel">
|
||||
<div class="settings-section-header">
|
||||
<div>
|
||||
<p class="eyebrow">Danger zone</p>
|
||||
<h2>Delete account</h2>
|
||||
<p class="subtitle">This permanently removes your account, chats, personas, templates, and market activity.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="persona-actions">
|
||||
<button id="deleteAccount" type="button" class="secondary-action danger">Delete account</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="settings-view" role="tabpanel" aria-hidden="true" data-settings-panel="my-roleplay-companions">
|
||||
|
||||
@@ -21,6 +21,9 @@ const usernamePasswordInput = $("usernamePassword");
|
||||
const currentPasswordInput = $("currentPassword");
|
||||
const newPasswordInput = $("newPassword");
|
||||
const repeatPasswordInput = $("repeatPassword");
|
||||
const exportAccountBtn = $("exportAccount");
|
||||
const logoutAllSessionsBtn = $("logoutAllSessions");
|
||||
const deleteAccountBtn = $("deleteAccount");
|
||||
const usernameForm = $("usernameForm");
|
||||
const passwordForm = $("passwordForm");
|
||||
const settingsNavItems = document.querySelectorAll("[data-settings-view]");
|
||||
@@ -458,6 +461,56 @@ async function unpublishPersona(id) {
|
||||
setNotice("Persona unpublished.", "success");
|
||||
}
|
||||
|
||||
function downloadJson(filename, payload) {
|
||||
const blob = new Blob([JSON.stringify(payload, null, 2)], {type: "application/json;charset=utf-8"});
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement("a");
|
||||
link.href = url;
|
||||
link.download = filename;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
link.remove();
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
async function exportAccount() {
|
||||
const res = await get("/settings/export");
|
||||
if (res.error) return setNotice(res.error, "error");
|
||||
const username = currentUsernameInput.value || "account";
|
||||
downloadJson(`account-export-${username}-${new Date().toISOString().slice(0, 10)}.json`, res.account);
|
||||
setNotice("Account export downloaded.", "success");
|
||||
}
|
||||
|
||||
async function logoutAllSessions() {
|
||||
const confirmed = await promptSettingsPopup({
|
||||
eyebrow: "Security",
|
||||
title: "Logout all sessions",
|
||||
description: "Type logout to sign out this browser and every other active session.",
|
||||
label: "Confirmation",
|
||||
placeholder: "logout",
|
||||
confirmLabel: "Logout all"
|
||||
});
|
||||
if (String(confirmed || "").trim().toLowerCase() !== "logout") return;
|
||||
const res = await post("/settings/logout-all-sessions", {});
|
||||
if (res.error) return setNotice(res.error, "error");
|
||||
window.location.href = "/";
|
||||
}
|
||||
|
||||
async function deleteAccount() {
|
||||
const currentPassword = await promptSettingsPopup({
|
||||
eyebrow: "Danger zone",
|
||||
title: "Delete account",
|
||||
description: "Enter your current password to permanently delete your account and all account data.",
|
||||
label: "Current password",
|
||||
placeholder: "Password",
|
||||
confirmLabel: "Delete account"
|
||||
});
|
||||
if (currentPassword === null) return;
|
||||
const res = await request("/settings/account", {currentPassword}, "DELETE");
|
||||
if (res.error) return setNotice(res.error, "error");
|
||||
window.location.href = "/";
|
||||
}
|
||||
|
||||
usernameForm.addEventListener("submit", async (event) => {
|
||||
event.preventDefault();
|
||||
const username = newUsernameInput.value.trim();
|
||||
@@ -514,6 +567,9 @@ workspaceModeSelect.addEventListener("change", (event) => {
|
||||
localStorage.setItem("krishd-workspace-mode", mode);
|
||||
setNotice(`Workspace mode set to ${mode}.`, "success");
|
||||
});
|
||||
exportAccountBtn.addEventListener("click", () => { void exportAccount(); });
|
||||
logoutAllSessionsBtn.addEventListener("click", () => { void logoutAllSessions(); });
|
||||
deleteAccountBtn.addEventListener("click", () => { void deleteAccount(); });
|
||||
refreshDiagnosticsBtn.addEventListener("click", () => { void loadDiagnostics(); });
|
||||
|
||||
settingsNavItems.forEach((item) => item.addEventListener("click", () => setSettingsView(item.dataset.settingsView)));
|
||||
|
||||
Reference in New Issue
Block a user