/* ─── 인증 확인 ──────────────────────────────────── */ 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"; }