zioinfo-mail/workspace/guardia-itsm/static/change-password.js
DESKTOP-TKLFCPR\ython cfe2901a55 refactor(structure): consolidate all projects under workspace/
- itsm/    -> workspace/guardia-itsm/
- manager/ -> workspace/guardia-manager/
- app/     -> workspace/guardia-messenger/
- manual/  -> workspace/guardia-docs/

workspace/zioinfo-web/ unchanged.
git mv preserves full commit history.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 23:50:56 +09:00

147 lines
5.2 KiB
JavaScript

/* ─── 인증 확인 ──────────────────────────────────── */
const token = localStorage.getItem("guardia_token");
const userInfo = JSON.parse(localStorage.getItem("guardia_userinfo") || "{}");
if (!token) {
window.location.replace("/login");
}
/* ─── UI 초기화 ──────────────────────────────────── */
document.getElementById("user-subtitle").textContent =
userInfo.display_name ? `${userInfo.display_name}` : "GUARDiA ITSM";
// must_change_pw가 false면 배너 숨기기
if (!userInfo.must_change_pw) {
document.getElementById("must-change-banner").classList.add("hidden");
document.getElementById("skip-link").style.display = "none";
}
// 건너뛰기 링크 (must_change_pw가 false인 경우에만 허용)
document.getElementById("skip-link").addEventListener("click", e => {
e.preventDefault();
if (!userInfo.must_change_pw) {
window.location.replace("/");
}
});
/* ─── 비밀번호 보기/숨기기 ─────────────────────── */
function togglePw(inputId, btn) {
const input = document.getElementById(inputId);
if (input.type === "password") {
input.type = "text";
btn.textContent = "🙈";
} else {
input.type = "password";
btn.textContent = "👁";
}
}
/* ─── 강도 체크 ──────────────────────────────────── */
function checkStrength(pw) {
const bar = document.getElementById("strength-bar");
const label = document.getElementById("strength-label");
if (!pw) { bar.style.width = "0"; label.textContent = ""; return; }
let score = 0;
if (pw.length >= 4) score++;
if (pw.length >= 8) score++;
if (/[A-Z]/.test(pw) || /[a-z]/.test(pw)) score++;
if (/[0-9]/.test(pw)) score++;
if (/[^A-Za-z0-9]/.test(pw)) score++;
const levels = [
{ w: "20%", bg: "#f85149", txt: "매우 약함" },
{ w: "40%", bg: "#f85149", txt: "약함" },
{ w: "60%", bg: "#e3b341", txt: "보통" },
{ w: "80%", bg: "#2bac76", txt: "강함" },
{ w: "100%", bg: "#1d9bd1", txt: "매우 강함" },
];
const lv = levels[Math.min(score - 1, 4)] || levels[0];
bar.style.width = lv.w;
bar.style.background = lv.bg;
label.textContent = lv.txt;
label.style.color = lv.bg;
}
/* ─── 일치 확인 ──────────────────────────────────── */
function checkMatch() {
const newPw = document.getElementById("new-pw").value;
const confirmPw = document.getElementById("confirm-pw").value;
const msgEl = document.getElementById("match-msg");
if (!confirmPw) { msgEl.textContent = ""; return; }
if (newPw === confirmPw) {
msgEl.textContent = "✓ 비밀번호가 일치합니다";
msgEl.className = "pw-match-msg ok";
} else {
msgEl.textContent = "✗ 비밀번호가 일치하지 않습니다";
msgEl.className = "pw-match-msg fail";
}
}
/* ─── 폼 제출 ────────────────────────────────────── */
document.getElementById("cp-form").addEventListener("submit", async e => {
e.preventDefault();
const curPw = document.getElementById("cur-pw").value;
const newPw = document.getElementById("new-pw").value;
const confirmPw = document.getElementById("confirm-pw").value;
const errEl = document.getElementById("cp-error");
errEl.style.display = "none";
if (newPw !== confirmPw) {
showError("새 비밀번호가 일치하지 않습니다");
return;
}
if (newPw.length < 4) {
showError("새 비밀번호는 4자 이상이어야 합니다");
return;
}
setLoading(true);
try {
const res = await fetch("/api/auth/change-password", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
},
body: JSON.stringify({ current_password: curPw, new_password: newPw }),
});
const data = await res.json();
if (!res.ok) {
showError(data.detail || "변경에 실패했습니다");
setLoading(false);
return;
}
/* 성공 — userinfo 업데이트 후 메인으로 */
const updated = { ...userInfo, must_change_pw: false };
localStorage.setItem("guardia_userinfo", JSON.stringify(updated));
/* 잠깐 성공 메시지 표시 */
const btn = document.getElementById("cp-btn");
btn.style.background = "#2bac76";
document.getElementById("cp-btn-text").textContent = "✓ 변경 완료! 이동 중…";
setTimeout(() => window.location.replace("/"), 1200);
} catch {
showError("서버에 연결할 수 없습니다");
setLoading(false);
}
});
function setLoading(on) {
document.getElementById("cp-btn").disabled = on;
document.getElementById("cp-btn-text").textContent = on ? "변경 중…" : "비밀번호 변경";
document.getElementById("cp-spinner").style.display = on ? "inline-block" : "none";
}
function showError(msg) {
const errEl = document.getElementById("cp-error");
errEl.textContent = msg;
errEl.style.display = "block";
}