- 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>
147 lines
5.2 KiB
JavaScript
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";
|
|
}
|