refactor: System1 API 인증 체계 SSO 전환 및 마이그레이션 정비

- SSO JWT 인증으로 전환 (auth.service.js)
- worker_id → user_id 마이그레이션 완료
- departments 연동, CORS 미들웨어 정리
- 불필요 파일 삭제 (tk_database.db, visitRequestController.js)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-03-06 23:18:00 +09:00
parent 2f7e083db0
commit ec755ed52f
47 changed files with 181 additions and 716 deletions

View File

@@ -9,20 +9,12 @@
const express = require('express');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const mysql = require('mysql2/promise');
const { getDb } = require('../dbPool');
const { verifyToken } = require('../middlewares/auth');
const { validatePassword, getPasswordError } = require('../utils/passwordValidator');
const router = express.Router();
const authController = require('../controllers/authController');
// DB 연결 설정
const dbConfig = {
host: process.env.DB_HOST || 'db_hyungi_net',
user: process.env.DB_USER || 'hyungi',
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME || 'hyungi'
};
// 로그인 시도 추적 (메모리 기반 - 실제로는 Redis 권장)
const loginAttempts = new Map();
@@ -143,7 +135,7 @@ router.post('/refresh-token', async (req, res) => {
return res.status(401).json({ error: '유효하지 않은 토큰입니다.' });
}
const connection = await mysql.createConnection(dbConfig);
const connection = await getDb();
// 사용자 정보 조회
const [users] = await connection.execute(
@@ -151,8 +143,6 @@ router.post('/refresh-token', async (req, res) => {
[decoded.user_id]
);
await connection.end();
if (users.length === 0) {
return res.status(404).json({ error: '사용자를 찾을 수 없습니다.' });
}
@@ -167,7 +157,7 @@ router.post('/refresh-token', async (req, res) => {
access_level: user.access_level,
name: user.name || user.username
},
process.env.JWT_SECRET || 'your-secret-key',
process.env.JWT_SECRET,
{ expiresIn: process.env.JWT_EXPIRES_IN || '24h' }
);
@@ -224,7 +214,7 @@ router.post('/change-password', verifyToken, async (req, res) => {
});
}
connection = await mysql.createConnection(dbConfig);
connection = await getDb();
// 현재 사용자의 비밀번호 조회
const [users] = await connection.execute(
@@ -290,10 +280,6 @@ router.post('/change-password', verifyToken, async (req, res) => {
success: false,
error: '서버 오류가 발생했습니다.'
});
} finally {
if (connection) {
await connection.end();
}
}
});
@@ -334,7 +320,7 @@ router.post('/admin/change-password', verifyToken, async (req, res) => {
});
}
connection = await mysql.createConnection(dbConfig);
connection = await getDb();
// 대상 사용자 확인
const [users] = await connection.execute(
@@ -391,10 +377,6 @@ router.post('/admin/change-password', verifyToken, async (req, res) => {
success: false,
error: '서버 오류가 발생했습니다.'
});
} finally {
if (connection) {
await connection.end();
}
}
});
@@ -453,7 +435,7 @@ router.get('/me', verifyToken, async (req, res) => {
try {
const userId = req.user.user_id;
connection = await mysql.createConnection(dbConfig);
connection = await getDb();
const [rows] = await connection.execute(
'SELECT user_id, username, name, email, access_level, last_login_at, created_at FROM users WHERE user_id = ?',
[userId]
@@ -477,10 +459,6 @@ router.get('/me', verifyToken, async (req, res) => {
} catch (error) {
console.error('Get current user error:', error);
res.status(500).json({ error: '서버 오류가 발생했습니다.' });
} finally {
if (connection) {
await connection.end();
}
}
});
@@ -516,7 +494,7 @@ router.post('/register', verifyToken, async (req, res) => {
});
}
connection = await mysql.createConnection(dbConfig);
connection = await getDb();
// 사용자명 중복 체크
const [existing] = await connection.execute(
@@ -586,10 +564,6 @@ router.post('/register', verifyToken, async (req, res) => {
success: false,
error: '서버 오류가 발생했습니다.'
});
} finally {
if (connection) {
await connection.end();
}
}
});
@@ -600,7 +574,7 @@ router.get('/users', verifyToken, async (req, res) => {
let connection;
try {
connection = await mysql.createConnection(dbConfig);
connection = await getDb();
// 기본 쿼리 (role 테이블과 JOIN)
let query = `
@@ -656,10 +630,6 @@ router.get('/users', verifyToken, async (req, res) => {
} catch (error) {
console.error('Get users error:', error);
res.status(500).json({ error: '서버 오류가 발생했습니다.' });
} finally {
if (connection) {
await connection.end();
}
}
});
@@ -691,7 +661,7 @@ router.put('/users/:id', verifyToken, async (req, res) => {
}
}
connection = await mysql.createConnection(dbConfig);
connection = await getDb();
// 사용자 존재 확인
const [existing] = await connection.execute(
@@ -802,10 +772,6 @@ router.put('/users/:id', verifyToken, async (req, res) => {
success: false,
error: '서버 오류가 발생했습니다.'
});
} finally {
if (connection) {
await connection.end();
}
}
});
@@ -834,7 +800,7 @@ router.delete('/users/:id', verifyToken, async (req, res) => {
});
}
connection = await mysql.createConnection(dbConfig);
connection = await getDb();
// 사용자 존재 확인
const [existing] = await connection.execute(
@@ -871,10 +837,6 @@ router.delete('/users/:id', verifyToken, async (req, res) => {
success: false,
error: '서버 오류가 발생했습니다.'
});
} finally {
if (connection) {
await connection.end();
}
}
});
@@ -887,17 +849,13 @@ router.post('/logout', verifyToken, async (req, res) => {
// 로그아웃 시간 기록 (선택사항)
let connection;
try {
connection = await mysql.createConnection(dbConfig);
connection = await getDb();
await connection.execute(
'UPDATE login_logs SET logout_time = NOW() WHERE user_id = ? AND logout_time IS NULL ORDER BY login_time DESC LIMIT 1',
[req.user.user_id]
);
} catch (error) {
console.error('로그아웃 기록 실패:', error);
} finally {
if (connection) {
await connection.end();
}
}
res.json({
@@ -916,7 +874,7 @@ router.get('/login-history', verifyToken, async (req, res) => {
const { limit = 50, offset = 0 } = req.query;
const userId = req.user.user_id;
connection = await mysql.createConnection(dbConfig);
connection = await getDb();
// 본인의 로그인 이력만 조회 (관리자는 전체 조회 가능)
let query = `
@@ -958,10 +916,6 @@ router.get('/login-history', verifyToken, async (req, res) => {
} catch (error) {
console.error('Get login history error:', error);
res.status(500).json({ error: '서버 오류가 발생했습니다.' });
} finally {
if (connection) {
await connection.end();
}
}
});