✨ 주요 변경사항: - 단일 docker-compose.yml로 통합 (로컬/시놀로지 환경 지원) - 시놀로지 볼륨 매핑 설정 (volume1: 이미지, volume3: 데이터) - 통합 배포 가이드 및 자동 배포 스크립트 추가 - 완전한 Memos 스타일 워크플로우 구현 🎯 새로운 기능: - 📝 메모 작성 (upload.html) - 이미지 업로드 지원 - 📥 수신함 (inbox.html) - 메모 편집 및 Todo/보드 변환 - ✅ Todo 목록 (todo-list.html) - 오늘 할 일 관리 - 📋 보드 (board.html) - 프로젝트 관리, 접기/펼치기, 이미지 지원 - 📚 아카이브 (archive.html) - 완료된 보드 보관 - 🔐 초기 설정 화면 - 관리자 계정 생성 🔧 기술적 개선: - 이미지 업로드/편집 완전 지원 - 반응형 디자인 및 모바일 최적화 - 보드 완료 후 자동 숨김 처리 - 메모 편집 시 제목 필드 제거 - 테스트 로그인 버튼 제거 (프로덕션 준비) - 과거 코드 정리 (TodoService, CalendarSyncService 등) 📦 배포 관련: - env.synology.example - 시놀로지 환경 설정 템플릿 - SYNOLOGY_DEPLOYMENT_GUIDE.md - 상세한 배포 가이드 - deploy-synology.sh - 원클릭 자동 배포 스크립트 - Nginx 정적 파일 서빙 및 이미지 프록시 설정 🗑️ 정리된 파일: - 사용하지 않는 HTML 페이지들 (dashboard, calendar, checklist 등) - 복잡한 통합 서비스들 (integrations 폴더) - 중복된 시놀로지 설정 파일들
214 lines
6.1 KiB
JavaScript
214 lines
6.1 KiB
JavaScript
/**
|
|
* 인증 관리
|
|
*/
|
|
|
|
// 전역 변수로 설정 (중복 선언 방지)
|
|
if (typeof window.currentUser === 'undefined') {
|
|
window.currentUser = null;
|
|
}
|
|
|
|
// 페이지 로드 시 인증 상태 확인 (중복 실행 방지)
|
|
if (!window.authInitialized) {
|
|
window.authInitialized = true;
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
// dashboard.html에서는 자체적으로 인증 처리하므로 건너뜀
|
|
const isDashboardPage = window.location.pathname.endsWith('dashboard.html');
|
|
|
|
if (!isDashboardPage) {
|
|
checkAuthStatus();
|
|
setupLoginForm();
|
|
}
|
|
});
|
|
}
|
|
|
|
// 인증 상태 확인
|
|
function checkAuthStatus() {
|
|
const token = localStorage.getItem('authToken');
|
|
const userData = localStorage.getItem('currentUser');
|
|
|
|
// index.html에서는 토큰이 있으면 대시보드로 리다이렉트 (이미 위에서 처리됨)
|
|
const isIndexPage = window.location.pathname.endsWith('index.html') || window.location.pathname === '/';
|
|
|
|
if (token && isIndexPage) {
|
|
// 이미 index.html에서 리다이렉트 처리했으므로 여기서는 showAlreadyLoggedIn만 호출
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', showAlreadyLoggedIn);
|
|
} else {
|
|
showAlreadyLoggedIn();
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (token && !isIndexPage) {
|
|
try {
|
|
if (userData) {
|
|
window.currentUser = JSON.parse(userData);
|
|
} else {
|
|
// 사용자 데이터가 없으면 기본값 사용
|
|
window.currentUser = { username: 'hyungi', full_name: 'Administrator' };
|
|
localStorage.setItem('currentUser', JSON.stringify(window.currentUser));
|
|
}
|
|
showMainApp();
|
|
} catch (error) {
|
|
console.error('사용자 데이터 파싱 실패:', error);
|
|
// 파싱 실패 시 기본값으로 재시도
|
|
window.currentUser = { username: 'hyungi', full_name: 'Administrator' };
|
|
localStorage.setItem('currentUser', JSON.stringify(window.currentUser));
|
|
showMainApp();
|
|
}
|
|
} else {
|
|
showLoginScreen();
|
|
}
|
|
}
|
|
|
|
// 로그인 폼 설정
|
|
function setupLoginForm() {
|
|
const loginForm = document.getElementById('loginForm');
|
|
if (loginForm) {
|
|
loginForm.addEventListener('submit', handleLogin);
|
|
}
|
|
}
|
|
|
|
// 로그인 처리
|
|
async function handleLogin(event) {
|
|
event.preventDefault();
|
|
|
|
const username = document.getElementById('username').value;
|
|
const password = document.getElementById('password').value;
|
|
|
|
if (!username || !password) {
|
|
alert('사용자명과 비밀번호를 입력해주세요.');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
showLoading(true);
|
|
|
|
// 실제 API 호출
|
|
const response = await AuthAPI.login(username, password);
|
|
window.currentUser = response.user;
|
|
|
|
// 대시보드로 리다이렉트
|
|
window.location.href = 'inbox.html';
|
|
|
|
} catch (error) {
|
|
console.error('로그인 실패:', error);
|
|
alert(error.message || '로그인에 실패했습니다.');
|
|
} finally {
|
|
showLoading(false);
|
|
}
|
|
}
|
|
|
|
// 로그아웃
|
|
function logout() {
|
|
currentUser = null;
|
|
localStorage.removeItem('authToken');
|
|
localStorage.removeItem('currentUser');
|
|
showLoginScreen();
|
|
}
|
|
|
|
// 로그인 화면 표시
|
|
function showLoginScreen() {
|
|
const loginScreen = document.getElementById('loginScreen');
|
|
const mainApp = document.getElementById('mainApp');
|
|
const alreadyLoggedIn = document.getElementById('alreadyLoggedIn');
|
|
|
|
if (loginScreen) {
|
|
loginScreen.classList.remove('hidden');
|
|
} else {
|
|
// dashboard.html에서는 로그인 페이지로 리다이렉트
|
|
window.location.href = 'index.html';
|
|
return;
|
|
}
|
|
|
|
if (mainApp) {
|
|
mainApp.classList.add('hidden');
|
|
}
|
|
|
|
if (alreadyLoggedIn) {
|
|
alreadyLoggedIn.classList.add('hidden');
|
|
}
|
|
|
|
// 폼 초기화
|
|
const loginForm = document.getElementById('loginForm');
|
|
if (loginForm) {
|
|
loginForm.reset();
|
|
}
|
|
}
|
|
|
|
// 이미 로그인됨 표시
|
|
function showAlreadyLoggedIn() {
|
|
const loginScreen = document.getElementById('loginScreen');
|
|
const alreadyLoggedIn = document.getElementById('alreadyLoggedIn');
|
|
|
|
if (loginScreen) {
|
|
loginScreen.classList.remove('hidden');
|
|
}
|
|
|
|
if (alreadyLoggedIn) {
|
|
alreadyLoggedIn.classList.remove('hidden');
|
|
}
|
|
|
|
// 로그인 폼 숨기기
|
|
const loginForm = document.getElementById('loginForm');
|
|
const testLoginSection = loginForm?.parentElement?.querySelector('.mt-4');
|
|
|
|
if (loginForm) {
|
|
loginForm.style.display = 'none';
|
|
}
|
|
if (testLoginSection) {
|
|
testLoginSection.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
// 메인 앱 표시
|
|
function showMainApp() {
|
|
const loginScreen = document.getElementById('loginScreen');
|
|
const mainApp = document.getElementById('mainApp');
|
|
|
|
// index.html에서는 대시보드로 리다이렉트
|
|
if (!mainApp && loginScreen) {
|
|
window.location.href = 'inbox.html';
|
|
return;
|
|
}
|
|
|
|
if (loginScreen) {
|
|
loginScreen.classList.add('hidden');
|
|
}
|
|
|
|
if (mainApp) {
|
|
mainApp.classList.remove('hidden');
|
|
}
|
|
|
|
// 사용자 정보 표시
|
|
const currentUserElement = document.getElementById('currentUser');
|
|
if (currentUserElement && window.currentUser) {
|
|
currentUserElement.textContent = window.currentUser.full_name || window.currentUser.username;
|
|
}
|
|
|
|
// Todo 목록 로드
|
|
if (typeof loadTodos === 'function') {
|
|
loadTodos();
|
|
}
|
|
}
|
|
|
|
// 로딩 상태 표시
|
|
function showLoading(show) {
|
|
const loadingOverlay = document.getElementById('loadingOverlay');
|
|
if (loadingOverlay) {
|
|
if (show) {
|
|
loadingOverlay.classList.remove('hidden');
|
|
} else {
|
|
loadingOverlay.classList.add('hidden');
|
|
}
|
|
}
|
|
}
|
|
|
|
// 전역으로 사용 가능하도록 export
|
|
window.currentUser = currentUser;
|
|
window.logout = logout;
|
|
window.showLoading = showLoading;
|
|
|
|
|