From 36fb988ab05033f25fff6bc6ca4332fd8cc707c4 Mon Sep 17 00:00:00 2001 From: LingandRX Date: Thu, 26 Dec 2024 20:50:51 +0800 Subject: [PATCH] =?UTF-8?q?feat(user):=20=E6=B7=BB=E5=8A=A0=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E7=99=BB=E5=BD=95=E5=8A=9F=E8=83=BD=E5=92=8C=E6=88=90?= =?UTF-8?q?=E5=8A=9F/=E9=94=99=E8=AF=AF=E6=B6=88=E6=81=AF=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/errorMessages.js | 23 +++-------------- config/successMessages.js | 9 +++++++ controllers/userController.js | 47 +++++++++++++++++++++++++++++++++- models/userModel.js | 6 +---- repositories/userRepository.js | 13 ++++------ routes/index.js | 24 +++++++++-------- services/userService.js | 25 ++++++++++++++++++ utils/hashUtils.js | 23 +++++++++++++++++ 8 files changed, 126 insertions(+), 44 deletions(-) create mode 100644 config/successMessages.js create mode 100644 utils/hashUtils.js diff --git a/config/errorMessages.js b/config/errorMessages.js index 26f5664..88187c7 100644 --- a/config/errorMessages.js +++ b/config/errorMessages.js @@ -2,25 +2,8 @@ module.exports = { user: { not_found: 'User not found', already_exists: 'User already exists', - created: 'User created', - updated: 'User updated', - deleted: 'User deleted', - not_deleted: 'User not deleted', - not_updated: 'User not updated', - not_created: 'User not created', - not_found_id: 'User not found', - not_found_account: 'User not found', - not_found_email: 'User not found', - not_found_phone: 'User not found', - not_found_username: 'User not found', - not_found_role: 'User not found', - not_found_status: 'User not found', - not_found_created_at: 'User not found', - not_found_updated_at: 'User not found', - not_found_deleted_at: 'User not found', - not_found_created_by: 'User not found', - not_found_updated_by: 'User not found', - not_found_deleted_by: 'User not found', - not_found_password: 'User not found', + account_not_match: 'Account not match', + password_not_match: 'Password not match', + password_incorrect: 'Password incorrect' } } diff --git a/config/successMessages.js b/config/successMessages.js new file mode 100644 index 0000000..970ac2e --- /dev/null +++ b/config/successMessages.js @@ -0,0 +1,9 @@ +module.exports = { + user: { + created: 'User created', + updated: 'User updated', + deleted: 'User deleted', + login: 'Login successful', + logout: 'Logout successful' + } +} diff --git a/controllers/userController.js b/controllers/userController.js index 329ea08..c74d537 100644 --- a/controllers/userController.js +++ b/controllers/userController.js @@ -1,6 +1,7 @@ const { body, validationResult } = require('express-validator') const userService = require('../services/userService') const errorMessages = require('../config/errorMessages') +const successMessages = require('../config/successMessages') exports.getAllUsers = async (req, res) => { try { @@ -30,7 +31,7 @@ exports.createUser = [ try { const user = req.body await userService.create_user(user) - res.status(201).json({ message: errorMessages.user.created }) + res.status(201).json({ message: successMessages.user.created }) } catch (err) { if (err.message === errorMessages.user.already_exists) { return res.status(400).json({ error: err.message }) @@ -40,3 +41,47 @@ exports.createUser = [ } } ] + +exports.login = [ + async (req, res, next) => { + const errors = validationResult(req) + if (!errors.isEmpty()) { + const formattedErrors = errors.array().map((err) => ({ + field: err.path, // 错误字段名 + message: err.msg // 错误提示消息 + })) + return res.status(400).json({ errors: formattedErrors }) + } + + const { account, password } = req.body + + if (!account) { + return res.status(400).json({ error: errorMessages.user.account_not_match }) + } + if (!password) { + return res.status(400).json({ error: errorMessages.user.password_not_match }) + } + + next() + }, + async (req, res) => { + try { + const { account, password } = req.body + if (account === 'admin' && password === 'admin') { + req.session.user = { account } + return res.status(200).json({ message: successMessages.user.login }) + } + const user = await userService.login(account, password) + + req.session.user = user + res.status(200).json({ message: successMessages.user.login }) + } catch (err) { + if (err.message === errorMessages.user.not_found) { + return res.status(404).json({ error: err.message }) + } + console.log(err) + + return res.status(500).json({ error: 'Internal server error' }) + } + } +] diff --git a/models/userModel.js b/models/userModel.js index 95122dd..d876d3c 100644 --- a/models/userModel.js +++ b/models/userModel.js @@ -1,5 +1,5 @@ const mongoose = require('mongoose') -const bcrypt = require('bcrypt') +const { hashPassword } = require('../utils/hashUtils') const Schema = mongoose.Schema const UserSchema = new Schema({ @@ -16,10 +16,6 @@ const UserSchema = new Schema({ status: { type: String, enum: ['active', 'inactive', 'pending'], default: 'pending' } }) -function hashPassword(password) { - return bcrypt.hash(password, 10) -} - UserSchema.pre('save', async function (next) { const user = this if (!user.isModified('password')) return next() diff --git a/repositories/userRepository.js b/repositories/userRepository.js index e3300db..7a7fb1d 100644 --- a/repositories/userRepository.js +++ b/repositories/userRepository.js @@ -1,4 +1,5 @@ const UserModel = require('../models/userModel') +const { hashPassword } = require('../utils/hashUtils') exports.startTransaction = async () => { const seesion = await UserModel.startSession() @@ -22,14 +23,6 @@ exports.selectUserById = async (id) => { return await UserModel.findById(id) } -exports.selectUserByUsernameAndPassword = async (username, password) => { - return await UserModel.findOne({ username: username, password: password }) -} - -exports.selectUserByAccountAndPassword = async (account, password) => { - return await UserModel.findOne({ account: account, password: password }) -} - exports.selectUserByAccount = async (account) => { return await UserModel.findOne({ account: account }) } @@ -54,6 +47,10 @@ exports.updateUserById = async (id, user) => { return await UserModel.findByIdAndUpdate(id, user) } +exports.updateUserByLoginDate = async (id, loginDate) => { + return await UserModel.findByIdAndUpdate(id, { last_login_date: loginDate }) +} + exports.deleteUserById = async (id) => { return await UserModel.findByIdAndDelete(id) } diff --git a/routes/index.js b/routes/index.js index 1936353..c48ae77 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,19 +1,23 @@ var express = require('express') var router = express.Router() +const userController = require('../controllers/userController') + router.get('/', function (req, res, next) { res.send('respond with a resource') }) -router.post('/login', function (req, res, next) { - const { account, password } = req.body - console.log(account, password) - if (account === 'admin' && password === 'admin') { - req.session.user = { account } - res.json({ account }) - } else { - res.status(401).json({ error: 'Unauthorized' }) - } -}) +// router.post('/login', function (req, res, next) { +// const { account, password } = req.body +// console.log(account, password) +// if (account === 'admin' && password === 'admin') { +// req.session.user = { account } +// res.json({ account }) +// } else { +// res.status(401).json({ error: 'Unauthorized' }) +// } +// }) + +router.post('/login', userController.login) module.exports = router diff --git a/services/userService.js b/services/userService.js index 43b99d0..21f445c 100644 --- a/services/userService.js +++ b/services/userService.js @@ -1,6 +1,31 @@ const userMapper = require('../repositories/userRepository') const logger = require('morgan') const errorMessages = require('../config/errorMessages') +const { comparePassword } = require('../utils/hashUtils') + +exports.login = async (account, password) => { + try { + const user = await userMapper.selectUserByAccount(account) + + if (!user) { + throw new Error(errorMessages.user.not_found) + } + + const isMatch = await comparePassword(password, user.password) + + if (!isMatch) { + throw new Error(errorMessages.user.password_incorrect) + } + + user.last_login_date = new Date() + + await userMapper.updateUserByLoginDate(user.id, user.last_login_date) + + return user + } catch (err) { + throw err + } +} exports.user_list = async () => { try { diff --git a/utils/hashUtils.js b/utils/hashUtils.js new file mode 100644 index 0000000..171811d --- /dev/null +++ b/utils/hashUtils.js @@ -0,0 +1,23 @@ +const bcrypt = require('bcrypt') + +async function hashPassword(password) { + try { + const hashedPassword = await bcrypt.hash(password, 10) + return hashedPassword + } catch (error) { + console.error('Error hashing password:', error) + throw error // 重新抛出错误以便调用方处理 + } +} + +async function comparePassword(password, hashedPassword) { + try { + const isMatch = await bcrypt.compare(password, hashedPassword) + return isMatch + } catch (error) { + console.error('Error comparing password:', error) + throw error // 重新抛出错误以便调用方处理 + } +} + +module.exports = { hashPassword, comparePassword }