fix(388-1 · 388-3 보안): 로그아웃 · 계정 바뀜 지움 · 세션 넘침 · 탭 프로젝트 고정

- 로그아웃 = 떠남 확인 먼저 → 서버 로그아웃 → 세션 전부 · 현재 프로젝트 · 3D 지형 지움 → 홈 새로고침
- 계정 바뀜(저장한 주인 ≠ 지금 사용자) = 같은 지움 뒤 새로고침 · 열쇠에 계정 안 섞음
- 세션 한도 넘침 = 결과 칸 비우고 한 번 다시 · 그래도 넘치면 「저장 공간 부족」 안내
- B05 · B06 이 연 프로젝트 고정 — 다른 탭이 바꿔도 이 탭 초안 칸 그대로
- 새 test_384_s_logout_wipe

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VmC34fsxxbweEG3RUjs3Mn
This commit is contained in:
2026-10-17 17:21:38 +09:00
co-authored by Claude Opus 5.5
parent 23c6645839
commit 3e312b68d7
8 changed files with 281 additions and 5 deletions
+10 -3
View File
@@ -10,7 +10,7 @@
import { ui_locales, currentLanguageIndex, setLanguage } from "@ui/ui_template_locale";
import { createButton } from "@ui/ui_template_elements";
import { THEME_STORAGE_KEY, LANG_STORAGE_KEY, ROUTES } from "@config/config_frontend";
import { navigateTo, isAuthenticated } from "./router";
import { navigateTo, isAuthenticated, setLeaveGuard, takeLeaveGuard } from "./router";
import { readTouchMode, setTouchMode, type TouchMode } from "./device_context";
const BRAND_ICON_URL = new URL("../resources/app_branding/prog_icon.jpg", import.meta.url).href;
@@ -49,14 +49,21 @@ function onApp_Lang_Toggle_Click(): void {
window.dispatchEvent(new HashChangeEvent("hashchange"));
}
/** 로그아웃(388-1) — 떠남 확인 먼저 → 서버 로그아웃 → 이 브라우저 자료 지움 → 홈으로 새로고침. */
async function onApp_Logout_Click(): Promise<void> {
const guard = takeLeaveGuard();
if (guard && !(await guard())) return; // [취소] — 머묾
setLeaveGuard(null);
const { logout } = await import("../A06_Login/A06_Login_Api_Fetch");
try {
await logout();
} catch {
// 세션이 이미 만료된 경우 등은 무시하고 홈으로 이동
// 세션이 이미 만료된 경우 등은 무시하고 지움 · 홈으로 이동
}
navigateTo(ROUTES.A01_HOME);
const { wipeAccountCache } = await import("./b_project_switch");
await wipeAccountCache();
history.replaceState(null, "", `#/${ROUTES.A01_HOME}`); // hashchange 없이 — 바로 새로고침
window.location.reload();
}
/* -----------------------------------------------------------------------------