Код UserService
const UserModel = require('../models/User')
const bcrypt = require('bcrypt')
const MailService = require('./MailService')
const TokenService = require('./TokenService')
const uuid = require('uuid');
const UserDto = require('../dtos/UserDto')
class UserService {
async register(name, email, password) {
const candidate = await UserModel.findOne({email})
if (candidate) {
throw new Error("Пользователь с такой почтой уже зарегистрирован")
}
const activationLink = uuid.v4(); // v34fa-asfasf-142saf-sa-asf
const link = `https://localhost:8080/api/activate/${activationLink}`;
const hash = await bcrypt.hash(password, 10)
const user = await UserModel.create({
name: name,
email: email,
password: hash,
activationLink
})
await MailService.sendActivationCode(email, link)
const userDto = new UserDto(user)
const tokens = TokenService.generateTokens({...userDto});
console.log(tokens)
await TokenService.saveToken(userDto.id, tokens.refreshToken);
return {...tokens, user: userDto}
}
async activate(activationLink) {
const user = await UserModel.findOne(activationLink)
if(!user) {
throw new Error("Некорректная ссылка активации")
}
user.isActivated = true;
await user.save()
}
async refresh(refreshToken) {
if (!refreshToken) {
throw new Error("Не авторизован")
}
const userData = TokenService.validateRefreshToken(refreshToken);
const tokenFromDb = await TokenService.findToken(refreshToken);
if (!userData || !tokenFromDb) {
throw new Error("Не авторизован")
}
const user = await UserModel.findById(userData.id);
const userDto = new UserDto(user);
const tokens = TokenService.generateTokens({...userDto});
await TokenService.saveToken(userDto.id, tokens.refreshToken);
return {...tokens, user: userDto}
}
}
module.exports = new UserService()
Код TokenService:
const jwt = require('jsonwebtoken');
const TokenModel = require('../models/Token');
const config = require('../config.json')
class TokenService {
async generateTokens(payload) {
const accessToken = jwt.sign(payload, config.SECRET_KEY_ACCESS_TOKEN, {expiresIn: '15m'})
const refreshToken = jwt.sign(payload, config.SECRET_KEY_REFRESH_TOKEN, {expiresIn: '30d'})
return {
accessToken,
refreshToken
}
}
validateAccessToken(token) {
try {
return jwt.verify(token, config.SECRET_KEY_ACCESS_TOKEN);
} catch (e) {
return null;
}
}
validateRefreshToken(token) {
try {
return jwt.verify(token, process.env.JWT_REFRESH_SECRET);
} catch (e) {
return null;
}
}
async saveToken(userId, refreshToken) {
const tokenData = await TokenModel.findOne({user: userId})
if (tokenData) {
tokenData.refreshToken = refreshToken;
return tokenData.save();
}
const token = await TokenModel.create({user: userId, token: refreshToken})
return token;
}
async removeToken(refreshToken) {
return TokenModel.deleteOne({refreshToken});
}
async findToken(refreshToken) {
return TokenModel.findOne({refreshToken});
}
}
module.exports = new TokenService();
Код контроллера:
const UserService = require('../services/UserService')
class UserController {
async register(req, res, next) {
const { name, email, password } = req.body
const userData = await UserService.register(name, email, password)
res.cookie('refreshToken', userData.refreshToken, {MaxAge: 30 * 24 * 60 * 60 * 1000, httpOnly: true})
console.log("User Controller" + userData)
return res.json(userData)
}
async login(req, res, next) {
}
async logout(req, res, next) {
}
async refresh(req, res, next) {
try {
const {refreshToken} = req.cookies;
const userData = await UserService.refresh(refreshToken);
res.cookie('refreshToken', userData.refreshToken, {maxAge: 30 * 24 * 60 * 60 * 1000, httpOnly: true})
return res.json(userData);
} catch (e) {
next(e);
}
}
async activate(req, res, next) {
try {
const activationLink = req.params.link;
await UserService.activate(activationLink);
return res.redirect("/home");
} catch (e) {
next(e);
}
}
}
module.exports = new UserController()