diff --git a/gateway/html/dashboard.html b/gateway/html/dashboard.html
index 1ca90d6..056f828 100644
--- a/gateway/html/dashboard.html
+++ b/gateway/html/dashboard.html
@@ -787,7 +787,7 @@
}
} catch (err) {
errEl.textContent = err.message;
- errEl.style.display = '';
+ errEl.style.display = 'block';
} finally {
btn.disabled = false;
btn.textContent = '\uB85C\uADF8\uC778';
diff --git a/system1-factory/web/js/change-password.js b/system1-factory/web/js/change-password.js
index 806fe71..f6b207d 100644
--- a/system1-factory/web/js/change-password.js
+++ b/system1-factory/web/js/change-password.js
@@ -1,208 +1,128 @@
-// js/change-password.js
-// 개인 비밀번호 변경 페이지 JavaScript
+// js/change-password.js — 비밀번호 변경 (일반 스크립트, tkfb-core.js 전역 함수 사용)
+(function() {
+ var form = document.getElementById('changePasswordForm');
+ var messageArea = document.getElementById('message-area');
+ var submitBtn = document.getElementById('submitBtn');
+ var resetBtn = document.getElementById('resetBtn');
-import { API, getAuthHeaders, ensureAuthenticated } from '/js/api-config.js';
+ if (!form) return;
-// 인증 확인
-const token = ensureAuthenticated();
-
-// DOM 요소
-const form = document.getElementById('changePasswordForm');
-const messageArea = document.getElementById('message-area');
-const submitBtn = document.getElementById('submitBtn');
-const resetBtn = document.getElementById('resetBtn');
-
-// 비밀번호 토글 기능
-document.querySelectorAll('.password-toggle').forEach(button => {
- button.addEventListener('click', function() {
- const targetId = this.getAttribute('data-target');
- const input = document.getElementById(targetId);
-
- if (input) {
- const isPassword = input.type === 'password';
- input.type = isPassword ? 'text' : 'password';
- this.textContent = isPassword ? '👁️🗨️' : '👁️';
- }
+ // 비밀번호 토글
+ document.querySelectorAll('.password-toggle').forEach(function(button) {
+ button.addEventListener('click', function() {
+ var input = document.getElementById(this.getAttribute('data-target'));
+ if (input) {
+ var isPassword = input.type === 'password';
+ input.type = isPassword ? 'text' : 'password';
+ this.textContent = isPassword ? '숨기기' : '보기';
+ }
+ });
});
-});
-// 초기화 버튼
-resetBtn?.addEventListener('click', () => {
- form.reset();
- clearMessages();
- document.getElementById('passwordStrength').innerHTML = '';
-});
+ // 초기화
+ if (resetBtn) resetBtn.addEventListener('click', function() {
+ form.reset();
+ messageArea.innerHTML = '';
+ var s = document.getElementById('passwordStrength');
+ if (s) s.innerHTML = '';
+ });
-// 메시지 표시 함수
-function showMessage(type, message) {
- messageArea.innerHTML = `
-
- ${type === 'error' ? '❌' : '✅'} ${message}
-
- `;
-
- // 에러 메시지는 5초 후 자동 제거
- if (type === 'error') {
- setTimeout(clearMessages, 5000);
- }
-}
-
-function clearMessages() {
- messageArea.innerHTML = '';
-}
-
-// 비밀번호 강도 체크
-async function checkPasswordStrength(password) {
- if (!password) {
- document.getElementById('passwordStrength').innerHTML = '';
- return;
+ function showMessage(type, msg) {
+ messageArea.innerHTML = '' +
+ (type === 'error' ? '❌ ' : '✅ ') + msg + '
';
+ if (type === 'error') setTimeout(function() { messageArea.innerHTML = ''; }, 5000);
}
- try {
- const res = await fetch(`${API}/auth/check-password-strength`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify({ password })
- });
-
- const result = await res.json();
- updatePasswordStrengthUI(result);
- } catch (error) {
- console.error('Password strength check error:', error);
- }
-}
+ // 비밀번호 강도 체크
+ var strengthTimer;
+ var newPwInput = document.getElementById('newPassword');
+ if (newPwInput) newPwInput.addEventListener('input', function() {
+ clearTimeout(strengthTimer);
+ var pw = this.value;
+ strengthTimer = setTimeout(function() {
+ if (!pw) { document.getElementById('passwordStrength').innerHTML = ''; return; }
+ var token = (window.getSSOToken && window.getSSOToken()) || localStorage.getItem('sso_token') || '';
+ fetch('/api/auth/check-password-strength', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token },
+ body: JSON.stringify({ password: pw })
+ }).then(function(r) { return r.json(); }).then(function(result) {
+ if (!result.success) return;
+ var d = result.data;
+ var colors = { weak: '#f44336', medium: '#ffc107', strong: '#4caf50' };
+ var labels = { weak: '약함', medium: '보통', strong: '강함' };
+ var pct = (d.score / 5) * 100;
+ document.getElementById('passwordStrength').innerHTML =
+ '' +
+ '' + (labels[d.level]||'') + '' +
+ '' + d.score + '/5
' +
+ '
';
+ }).catch(function() {});
+ }, 300);
+ });
-// 비밀번호 강도 UI 업데이트
-function updatePasswordStrengthUI(strength) {
- const container = document.getElementById('passwordStrength');
- if (!container) return;
-
- const colors = {
- 0: '#f44336',
- 1: '#ff9800',
- 2: '#ffc107',
- 3: '#4caf50',
- 4: '#2196f3'
- };
-
- const strengthText = strength.strengthText || '비밀번호를 입력하세요';
- const color = colors[strength.strength] || '#ccc';
- const percentage = (strength.score / strength.maxScore) * 100;
-
- container.innerHTML = `
-
-
-
- ${strengthText}
-
-
- ${strength.score}/${strength.maxScore}
-
-
-
- ${strength.feedback && strength.feedback.length > 0 ? `
-
- ${strength.feedback.map(f => `- ${f}
`).join('')}
-
- ` : ''}
-
- `;
-}
+ // 폼 제출
+ form.addEventListener('submit', function(e) {
+ e.preventDefault();
+ messageArea.innerHTML = '';
-// 비밀번호 입력 이벤트
-let strengthCheckTimer;
-document.getElementById('newPassword')?.addEventListener('input', (e) => {
- clearTimeout(strengthCheckTimer);
- strengthCheckTimer = setTimeout(() => {
- checkPasswordStrength(e.target.value);
- }, 300);
-});
+ var currentPassword = document.getElementById('currentPassword').value;
+ var newPassword = document.getElementById('newPassword').value;
+ var confirmPassword = document.getElementById('confirmPassword').value;
-// 폼 제출
-form?.addEventListener('submit', async (e) => {
- e.preventDefault();
- clearMessages();
-
- const currentPassword = document.getElementById('currentPassword').value;
- const newPassword = document.getElementById('newPassword').value;
- const confirmPassword = document.getElementById('confirmPassword').value;
-
- // 유효성 검사
- if (!currentPassword || !newPassword || !confirmPassword) {
- showMessage('error', '모든 필드를 입력해주세요.');
- return;
- }
-
- if (newPassword !== confirmPassword) {
- showMessage('error', '새 비밀번호가 일치하지 않습니다.');
- return;
- }
-
- if (newPassword.length < 6) {
- showMessage('error', '비밀번호는 최소 6자 이상이어야 합니다.');
- return;
- }
-
- if (currentPassword === newPassword) {
- showMessage('error', '새 비밀번호는 현재 비밀번호와 달라야 합니다.');
- return;
- }
-
- // 버튼 상태 변경
- const originalText = submitBtn.innerHTML;
- submitBtn.disabled = true;
- submitBtn.innerHTML = '⏳처리 중...';
-
- try {
- const res = await fetch(`${API}/auth/change-password`, {
- method: 'POST',
- headers: getAuthHeaders(),
- body: JSON.stringify({
- currentPassword,
- newPassword
- })
- });
-
- const result = await res.json();
-
- if (res.ok && result.success) {
- showMessage('success', '비밀번호가 성공적으로 변경되었습니다.');
- form.reset();
- document.getElementById('passwordStrength').innerHTML = '';
-
- // 카운트다운 시작
- let countdown = 3;
- const countdownInterval = setInterval(() => {
- showMessage('success',
- `비밀번호가 변경되었습니다. ${countdown}초 후 로그인 페이지로 이동합니다.`
- );
- countdown--;
-
- if (countdown < 0) {
- clearInterval(countdownInterval);
- if (window.clearSSOAuth) window.clearSSOAuth();
- window.location.href = window.getLoginUrl ? window.getLoginUrl() : '/login';
- }
- }, 1000);
-
- } else {
- const errorMessage = result.message || result.error || '비밀번호 변경에 실패했습니다.';
- showMessage('error', errorMessage);
+ if (!currentPassword || !newPassword || !confirmPassword) {
+ showMessage('error', '모든 필드를 입력해주세요.');
+ return;
+ }
+ if (newPassword !== confirmPassword) {
+ showMessage('error', '새 비밀번호가 일치하지 않습니다.');
+ return;
+ }
+ if (newPassword.length < 6) {
+ showMessage('error', '비밀번호는 최소 6자 이상이어야 합니다.');
+ return;
+ }
+ if (currentPassword === newPassword) {
+ showMessage('error', '새 비밀번호는 현재 비밀번호와 달라야 합니다.');
+ return;
}
- } catch (error) {
- console.error('Password change error:', error);
- showMessage('error', '서버와의 연결에 실패했습니다. 잠시 후 다시 시도해주세요.');
- } finally {
- submitBtn.disabled = false;
- submitBtn.innerHTML = originalText;
- }
-});
-// 페이지 로드 시 현재 사용자 정보 표시
-document.addEventListener('DOMContentLoaded', () => {
- const user = JSON.parse(localStorage.getItem('sso_user') || '{}');
-});
\ No newline at end of file
+ var originalText = submitBtn.innerHTML;
+ submitBtn.disabled = true;
+ submitBtn.innerHTML = '처리 중...';
+
+ var token = (window.getSSOToken && window.getSSOToken()) || localStorage.getItem('sso_token') || '';
+ fetch('/api/auth/change-password', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token },
+ body: JSON.stringify({ currentPassword: currentPassword, newPassword: newPassword })
+ }).then(function(res) {
+ return res.json().then(function(data) { return { ok: res.ok, data: data }; });
+ }).then(function(result) {
+ if (result.ok && result.data.success) {
+ showMessage('success', '비밀번호가 변경되었습니다.');
+ form.reset();
+ var s = document.getElementById('passwordStrength');
+ if (s) s.innerHTML = '';
+ var countdown = 3;
+ var interval = setInterval(function() {
+ showMessage('success', '비밀번호가 변경되었습니다. ' + countdown + '초 후 로그인 페이지로 이동합니다.');
+ countdown--;
+ if (countdown < 0) {
+ clearInterval(interval);
+ if (window.clearSSOAuth) window.clearSSOAuth();
+ window.location.href = window.getLoginUrl ? window.getLoginUrl() : '/login';
+ }
+ }, 1000);
+ } else {
+ showMessage('error', result.data.message || result.data.error || '비밀번호 변경에 실패했습니다.');
+ }
+ }).catch(function() {
+ showMessage('error', '서버와의 연결에 실패했습니다. 잠시 후 다시 시도해주세요.');
+ }).finally(function() {
+ submitBtn.disabled = false;
+ submitBtn.innerHTML = originalText;
+ });
+ });
+})();
diff --git a/system1-factory/web/pages/profile/password.html b/system1-factory/web/pages/profile/password.html
index e7bd5d5..ce20e76 100644
--- a/system1-factory/web/pages/profile/password.html
+++ b/system1-factory/web/pages/profile/password.html
@@ -391,8 +391,7 @@
-
-
+