diff --git a/backend/database/__pycache__/schemas.cpython-311.pyc b/backend/database/__pycache__/schemas.cpython-311.pyc index 451dc04..807a84f 100644 Binary files a/backend/database/__pycache__/schemas.cpython-311.pyc and b/backend/database/__pycache__/schemas.cpython-311.pyc differ diff --git a/backend/database/schemas.py b/backend/database/schemas.py index 9e6d908..34e5893 100644 --- a/backend/database/schemas.py +++ b/backend/database/schemas.py @@ -32,6 +32,10 @@ class UserUpdate(BaseModel): role: Optional[UserRole] = None is_active: Optional[bool] = None +class PasswordChange(BaseModel): + current_password: str + new_password: str + class User(UserBase): id: int is_active: bool diff --git a/backend/routers/__pycache__/auth.cpython-311.pyc b/backend/routers/__pycache__/auth.cpython-311.pyc index 18d8b7f..e209c51 100644 Binary files a/backend/routers/__pycache__/auth.cpython-311.pyc and b/backend/routers/__pycache__/auth.cpython-311.pyc differ diff --git a/backend/routers/auth.py b/backend/routers/auth.py index a45294e..1080ee7 100644 --- a/backend/routers/auth.py +++ b/backend/routers/auth.py @@ -112,20 +112,39 @@ async def update_user( db.refresh(db_user) return db_user -@router.delete("/users/{user_id}") +@router.delete("/users/{username}") async def delete_user( - user_id: int, + username: str, current_admin: User = Depends(get_current_admin), db: Session = Depends(get_db) ): - db_user = db.query(User).filter(User.id == user_id).first() + db_user = db.query(User).filter(User.username == username).first() if not db_user: raise HTTPException(status_code=404, detail="User not found") - # 관리자는 삭제 불가 - if db_user.role == UserRole.ADMIN: - raise HTTPException(status_code=400, detail="Cannot delete admin user") + # hyungi 계정은 삭제 불가 + if db_user.username == "hyungi": + raise HTTPException(status_code=400, detail="Cannot delete primary admin user") db.delete(db_user) db.commit() return {"detail": "User deleted successfully"} + +@router.post("/change-password") +async def change_password( + password_change: schemas.PasswordChange, + current_user: User = Depends(get_current_user), + db: Session = Depends(get_db) +): + # 현재 비밀번호 확인 + if not verify_password(password_change.current_password, current_user.hashed_password): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="Incorrect current password" + ) + + # 새 비밀번호 설정 + current_user.hashed_password = get_password_hash(password_change.new_password) + db.commit() + + return {"detail": "Password changed successfully"} diff --git a/frontend/admin.html b/frontend/admin.html new file mode 100644 index 0000000..5a63a56 --- /dev/null +++ b/frontend/admin.html @@ -0,0 +1,369 @@ + + + + + + 관리자 페이지 - 작업보고서 + + + + + + + + + + + + +
+
+
+

+ 작업보고서 시스템 - 관리자 +

+ +
+
+
+ + + + + +
+
+ +
+

+ 사용자 추가 +

+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+
+ + +
+

+ 사용자 목록 +

+ +
+ +
+ +

로딩 중...

+
+
+
+
+ + + +
+ + + + + + diff --git a/frontend/daily-work.html b/frontend/daily-work.html index e79ae4f..e348aa8 100644 --- a/frontend/daily-work.html +++ b/frontend/daily-work.html @@ -110,7 +110,7 @@ @@ -253,6 +256,9 @@ } currentUser = user; + // 네비게이션 권한 체크 + updateNavigation(); + // 오늘 날짜로 초기화 document.getElementById('workDate').valueAsDate = new Date(); @@ -260,6 +266,27 @@ await loadRecentEntries(); }); + // 네비게이션 권한 업데이트 + function updateNavigation() { + const listBtn = document.getElementById('listBtn'); + const summaryBtn = document.getElementById('summaryBtn'); + const adminBtn = document.getElementById('adminBtn'); + + if (currentUser.role === 'admin') { + // 관리자는 모든 메뉴 표시 + listBtn.style.display = ''; + summaryBtn.style.display = ''; + adminBtn.style.display = ''; + adminBtn.innerHTML = '사용자 관리'; + } else { + // 일반 사용자는 제한된 메뉴만 표시 + listBtn.style.display = 'none'; + summaryBtn.style.display = 'none'; + adminBtn.style.display = ''; + adminBtn.innerHTML = '비밀번호 변경'; + } + } + // 잔업 토글 function toggleOvertime() { const section = document.getElementById('overtimeSection'); diff --git a/frontend/index.html b/frontend/index.html index c5542d7..728dc0f 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -153,7 +153,7 @@ @@ -276,11 +279,8 @@ document.getElementById('loginScreen').classList.add('hidden'); document.getElementById('mainScreen').classList.remove('hidden'); - // 일반 사용자는 보고서 메뉴 숨김 - if (user.role === 'user') { - const reportBtn = document.querySelector('button[onclick="showSection(\'summary\')"]'); - if (reportBtn) reportBtn.style.display = 'none'; - } + // 권한에 따른 메뉴 표시/숨김 + updateNavigation(); loadIssues(); } @@ -299,11 +299,8 @@ document.getElementById('loginScreen').classList.add('hidden'); document.getElementById('mainScreen').classList.remove('hidden'); - // 일반 사용자는 보고서 메뉴 숨김 - if (currentUser.role === 'user') { - const reportBtn = document.querySelector('button[onclick="showSection(\'summary\')"]'); - if (reportBtn) reportBtn.style.display = 'none'; - } + // 권한에 따른 메뉴 표시/숨김 + updateNavigation(); loadIssues(); } catch (error) { @@ -316,6 +313,27 @@ AuthAPI.logout(); } + // 네비게이션 권한 업데이트 + function updateNavigation() { + const listBtn = document.getElementById('listBtn'); + const summaryBtn = document.getElementById('summaryBtn'); + const adminBtn = document.getElementById('adminBtn'); + + if (currentUser.role === 'admin') { + // 관리자는 모든 메뉴 표시 + listBtn.style.display = ''; + summaryBtn.style.display = ''; + adminBtn.style.display = ''; + adminBtn.innerHTML = '사용자 관리'; + } else { + // 일반 사용자는 제한된 메뉴만 표시 + listBtn.style.display = 'none'; + summaryBtn.style.display = 'none'; + adminBtn.style.display = ''; + adminBtn.innerHTML = '비밀번호 변경'; + } + } + // 섹션 전환 function showSection(section) { // 모든 섹션 숨기기 diff --git a/frontend/issue-view.html b/frontend/issue-view.html index 2bd316b..c027363 100644 --- a/frontend/issue-view.html +++ b/frontend/issue-view.html @@ -55,7 +55,7 @@

작업보고서 시스템

-
+