| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- const mongoose = require('mongoose');
- const { Schema } = mongoose;
- const bcrypt = require('bcryptjs');
- const jwt = require('jsonwebtoken');
- const userSchema = new Schema({
- username: { type: String, required: true, unique: true },
- password: { type: String, required: true },
- roles: { type: [String], default: ['user'] },
- }, { timestamps: true });
- const User = mongoose.model('User', userSchema);
- const add = async ({ username, password } = {}) => {
- return User.findOne({ username })
- .then(existing => {
- if (existing) {
- return Promise.reject(new Error('USER_EXISTS'));
- }
- return bcrypt.hash(password, 10);
- })
- .then(hashedPassword => {
- const user = new User({ username, password: hashedPassword });
- return user.save();
- });
- }
- const login = async ({ username, password } = {}) => {
- return User.findOne({ username })
- .then(user => {
- if (!user) {
- return Promise.reject(new Error('USER_NOT_FOUND'));
- }
- return Promise.all([
- bcrypt.compare(password, user.password),
- Promise.resolve(user),
- ]);
- })
- .then(([isMatch, user]) => {
- if (!isMatch) {
- return Promise.reject(new Error('PASSWORD_ERROR'));
- }
- return user;
- })
- .then(user => {
- // 签发 Access Token 和 Refresh Token
- const accessToken = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { expiresIn: '30m' });
- const refreshToken = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { expiresIn: '7d' });
- const userInfo = {
- uid: user._id.toString(),
- username: user.username,
- roles: user.roles ?? ['user'],
- }
- return { info: userInfo, accessToken, refreshToken };
- });
- }
- const refresh = async (refreshToken) => {
- const decoded = jwt.verify(refreshToken, process.env.JWT_SECRET);
- return User.findById(decoded.userId)
- .then(user => {
- if (!user) {
- return Promise.reject(new Error('USER_NOT_FOUND'));
- }
- // 签发新的 Access Token
- const newAccessToken = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { expiresIn: '30m' });
- return newAccessToken;
- });
- }
- const info = async (userId) => {
- return User.findById(userId).select('-password')
- .then(user => {
- if (!user) {
- return Promise.reject(new Error('USER_NOT_FOUND'));
- }
- return {
- uid: user._id.toString(),
- username: user.username,
- roles: user.roles ?? ['user'],
- };
- });
- }
- const init = async ({ username, password } = {}) => {
- return User.find()
- .then(users => {
- if (users.length) {
- return Promise.reject('USER_EXISTS');
- }
- return bcrypt.hash(password, 10);
- })
- .then(hashedPassword => {
- const user = new User({
- username,
- password: hashedPassword,
- roles: ['admin'],
- });
- return user.save();
- });
- }
- module.exports = { add, login, refresh, info, init };
|