feat: 다수 기능 개선 - 순찰, 출근, 작업분석, 모바일 UI 등
- 순찰/점검 기능 개선 (zone-detail 페이지 추가) - 출근/근태 시스템 개선 (연차 조회, 근무현황) - 작업분석 대분류 그룹화 및 마이그레이션 스크립트 - 모바일 네비게이션 UI 추가 - NAS 배포 도구 및 문서 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
161
deploy/tkfb-package/api.hyungi.net/controllers/authController.js
Normal file
161
deploy/tkfb-package/api.hyungi.net/controllers/authController.js
Normal file
@@ -0,0 +1,161 @@
|
||||
const { getDb } = require('../dbPool');
|
||||
const bcrypt = require('bcryptjs');
|
||||
const jwt = require('jsonwebtoken');
|
||||
const authService = require('../services/auth.service');
|
||||
const { asyncHandler } = require('../utils/errorHandler');
|
||||
const { AuthenticationError, ValidationError } = require('../utils/errors');
|
||||
const { validateSchema, schemas } = require('../utils/validator');
|
||||
|
||||
const login = asyncHandler(async (req, res) => {
|
||||
const { username, password } = req.body;
|
||||
const ipAddress = req.ip || req.connection.remoteAddress;
|
||||
const userAgent = req.headers['user-agent'];
|
||||
|
||||
// 유효성 검사
|
||||
if (!username || !password) {
|
||||
throw new ValidationError('사용자명과 비밀번호를 입력해주세요.');
|
||||
}
|
||||
|
||||
const result = await authService.loginService(username, password, ipAddress, userAgent);
|
||||
|
||||
if (!result.success) {
|
||||
throw new AuthenticationError(result.error);
|
||||
}
|
||||
|
||||
// 로그인 성공 후, 메인 대시보드로 리다이렉트
|
||||
const user = result.data.user;
|
||||
const redirectUrl = '/pages/dashboard.html'; // 메인 대시보드로 리다이렉트
|
||||
|
||||
// 새로운 응답 포맷터 사용
|
||||
res.auth(user, result.data.token, redirectUrl, '로그인 성공');
|
||||
});
|
||||
|
||||
// ✅ 사용자 등록 기능 추가
|
||||
const register = async (req, res) => {
|
||||
try {
|
||||
const { username, password, name, access_level, worker_id } = req.body;
|
||||
const db = await getDb();
|
||||
|
||||
// 필수 필드 검증
|
||||
if (!username || !password || !name || !access_level) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: '필수 정보가 누락되었습니다.'
|
||||
});
|
||||
}
|
||||
|
||||
// 중복 아이디 확인
|
||||
const [existing] = await db.query(
|
||||
'SELECT user_id FROM users WHERE username = ?',
|
||||
[username]
|
||||
);
|
||||
|
||||
if (existing.length > 0) {
|
||||
return res.status(409).json({
|
||||
success: false,
|
||||
error: '이미 존재하는 아이디입니다.'
|
||||
});
|
||||
}
|
||||
|
||||
// 비밀번호 해시화
|
||||
const hashedPassword = await bcrypt.hash(password, 10);
|
||||
|
||||
// role 설정 (access_level에 따라)
|
||||
const roleMap = {
|
||||
'admin': 'admin',
|
||||
'system': 'system', // 시스템 계정은 system role로 설정
|
||||
'group_leader': 'leader',
|
||||
'support_team': 'support',
|
||||
'worker': 'user'
|
||||
};
|
||||
const role = roleMap[access_level] || 'user';
|
||||
|
||||
// 사용자 등록
|
||||
const [result] = await db.query(
|
||||
`INSERT INTO users (username, password, name, role, access_level, worker_id)
|
||||
VALUES (?, ?, ?, ?, ?, ?)`,
|
||||
[username, hashedPassword, name, role, access_level, worker_id]
|
||||
);
|
||||
|
||||
console.log('[사용자 등록 성공]', username);
|
||||
|
||||
return res.status(201).json({
|
||||
success: true,
|
||||
message: '사용자 등록이 완료되었습니다.',
|
||||
user_id: result.insertId
|
||||
});
|
||||
|
||||
} catch (err) {
|
||||
console.error('[사용자 등록 오류]', err);
|
||||
return res.status(500).json({
|
||||
success: false,
|
||||
error: '서버 오류가 발생했습니다.',
|
||||
detail: err.message
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// ✅ 사용자 삭제 기능 추가
|
||||
const deleteUser = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const db = await getDb();
|
||||
|
||||
// 사용자 존재 확인
|
||||
const [user] = await db.query(
|
||||
'SELECT user_id FROM users WHERE user_id = ?',
|
||||
[id]
|
||||
);
|
||||
|
||||
if (user.length === 0) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: '해당 사용자를 찾을 수 없습니다.'
|
||||
});
|
||||
}
|
||||
|
||||
// 사용자 삭제
|
||||
await db.query('DELETE FROM users WHERE user_id = ?', [id]);
|
||||
|
||||
console.log('[사용자 삭제 성공] ID:', id);
|
||||
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
message: '사용자가 삭제되었습니다.'
|
||||
});
|
||||
|
||||
} catch (err) {
|
||||
console.error('[사용자 삭제 오류]', err);
|
||||
return res.status(500).json({
|
||||
success: false,
|
||||
error: '서버 오류가 발생했습니다.',
|
||||
detail: err.message
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 모든 사용자 목록 조회
|
||||
const getAllUsers = async (req, res) => {
|
||||
try {
|
||||
const db = await getDb();
|
||||
|
||||
// 비밀번호 제외하고 조회
|
||||
const [rows] = await db.query(
|
||||
`SELECT user_id, username, name, role, access_level, worker_id, created_at
|
||||
FROM users
|
||||
ORDER BY created_at DESC`
|
||||
);
|
||||
|
||||
res.status(200).json(rows);
|
||||
} catch (err) {
|
||||
console.error('[사용자 목록 조회 실패]', err);
|
||||
res.status(500).json({ error: '서버 오류' });
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
login,
|
||||
register,
|
||||
deleteUser,
|
||||
getAllUsers
|
||||
};
|
||||
Reference in New Issue
Block a user