비밀번호 변경 기능 구현

This commit is contained in:
dohyeons
2025-08-26 13:42:57 +09:00
parent 9ff797ba89
commit 6f68fa5639
5 changed files with 306 additions and 10 deletions

View File

@@ -2592,3 +2592,158 @@ export const deleteCompany = async (
});
}
};
/**
* POST /api/admin/users/reset-password
* 사용자 비밀번호 초기화 API
* 기존 Java AdminController.resetUserPassword() 포팅
*/
export const resetUserPassword = async (
req: AuthenticatedRequest,
res: Response
) => {
try {
const { userId, newPassword } = req.body;
logger.info("비밀번호 초기화 요청", { userId, user: req.user });
// 입력값 검증
if (!userId || !userId.trim()) {
res.status(400).json({
result: false,
msg: "사용자 ID가 필요합니다.",
});
return;
}
if (!newPassword || !newPassword.trim()) {
res.status(400).json({
success: false,
result: false,
message: "새 비밀번호가 필요합니다.",
msg: "새 비밀번호가 필요합니다.",
});
return;
}
// 비밀번호 길이 검증 (최소 4자)
if (newPassword.length < 4) {
res.status(400).json({
success: false,
result: false,
message: "비밀번호는 최소 4자 이상이어야 합니다.",
msg: "비밀번호는 최소 4자 이상이어야 합니다.",
});
return;
}
const client = new Client({ connectionString: config.databaseUrl });
try {
await client.connect();
// 1. 사용자 존재 여부 확인
const userCheckResult = await client.query(
"SELECT user_id, user_name FROM user_info WHERE user_id = $1",
[userId]
);
if (userCheckResult.rows.length === 0) {
res.status(404).json({
success: false,
result: false,
message: "사용자를 찾을 수 없습니다.",
msg: "사용자를 찾을 수 없습니다.",
});
return;
}
const currentUser = userCheckResult.rows[0];
// 2. 비밀번호 암호화 (기존 Java 로직과 동일)
let encryptedPassword: string;
try {
// EncryptUtil과 동일한 암호화 사용
const crypto = require("crypto");
const keyName = "ILJIAESSECRETKEY";
const algorithm = "aes-128-ecb";
// AES-128-ECB 암호화
const cipher = crypto.createCipher(algorithm, keyName);
let encrypted = cipher.update(newPassword, "utf8", "hex");
encrypted += cipher.final("hex");
encryptedPassword = encrypted.toUpperCase();
} catch (encryptError) {
logger.error("비밀번호 암호화 중 오류 발생", {
error: encryptError,
userId,
});
res.status(500).json({
success: false,
result: false,
message: "비밀번호 암호화 중 오류가 발생했습니다.",
msg: "비밀번호 암호화 중 오류가 발생했습니다.",
});
return;
}
// 3. 비밀번호 업데이트 실행
const updateResult = await client.query(
"UPDATE user_info SET user_password = $1 WHERE user_id = $2",
[encryptedPassword, userId]
);
if (updateResult.rowCount && updateResult.rowCount > 0) {
// 4. 이력 저장 (선택적)
try {
const writer = req.user?.userId || "system";
await client.query(
`
INSERT INTO user_info_history
(sabun, user_id, user_name, dept_code, dept_name, user_type_name, history_type, writer, regdate, status)
VALUES ('', $1, $2, '', '', '', '비밀번호 초기화', $3, NOW(), '')
`,
[userId, currentUser.user_name || userId, writer]
);
} catch (historyError) {
logger.warn("비밀번호 초기화 이력 저장 실패", {
error: historyError,
userId,
});
// 이력 저장 실패해도 비밀번호 초기화는 성공으로 처리
}
logger.info("비밀번호 초기화 성공", {
userId,
updatedBy: req.user?.userId,
});
res.json({
success: true,
result: true,
message: "비밀번호가 성공적으로 초기화되었습니다.",
msg: "비밀번호가 성공적으로 초기화되었습니다.",
});
} else {
res.status(400).json({
success: false,
result: false,
message: "사용자 정보를 찾을 수 없거나 비밀번호 변경에 실패했습니다.",
msg: "사용자 정보를 찾을 수 없거나 비밀번호 변경에 실패했습니다.",
});
}
} finally {
await client.end();
}
} catch (error) {
logger.error("비밀번호 초기화 중 오류 발생", {
error,
userId: req.body.userId,
});
res.status(500).json({
success: false,
result: false,
message: "비밀번호 초기화 중 시스템 오류가 발생했습니다.",
msg: "비밀번호 초기화 중 시스템 오류가 발생했습니다.",
});
}
};