import bcrypt from 'bcrypt'; import crypto from 'crypto'; import { v4 as uuidv4 } from 'uuid'; import User from '../models/community/user.js'; import UserParam from '../models/community/user_param.js'; import UserParamType from '../models/type/user_param.js'; import { sendAccountActivationEmail, sendPasswordResetEmail } from './emailService.js'; import { sequelize } from '../utils/sequelize.js'; const saltRounds = 10; export const registerUser = async ({ email, username, password, language }) => { const encryptionKey = process.env.SECRET_KEY; const results = await sequelize.query( `SELECT * FROM community.user WHERE pgp_sym_decrypt(email::bytea, :key) = :email`, { replacements: { key: encryptionKey, email }, type: sequelize.QueryTypes.SELECT } ); if (results.length > 0) { throw new Error('emailinuse'); } const hashedPassword = await bcrypt.hash(password, saltRounds); const resetToken = uuidv4(); const user = await User.create({ email: email, username, password: hashedPassword, resetToken: resetToken, active: false, registration_date: new Date() }); const languageType = await UserParamType.findOne({ where: { description: 'language' } }); if (!languageType) { throw new Error('languagenotfound'); } const languageParam = await UserParam.create({ userId: user.id, paramTypeId: languageType.id, value: language }); const activationLink = `${process.env.FRONTEND_URL}/activate?token=${resetToken}`; await sendAccountActivationEmail(email, activationLink, username, resetToken, language); const authCode = crypto.randomBytes(20).toString('hex'); return { id: user.hashedId, username: user.username, active: user.active, param: [languageParam], authCode }; }; export const loginUser = async ({ username, password }) => { const user = await User.findOne({ where: { username } }); if (!user) { throw new Error('credentialsinvalid'); } const match = await bcrypt.compare(password, user.password); if (!match) { throw new Error('credentialsinvalid'); } const authCode = crypto.randomBytes(20).toString('hex'); user.authCode = authCode; await user.save(); const params = await UserParam.findAll({ where: { userId: user.id }, include: { model: UserParamType, as: 'paramType', where: { description: ['birthdate', 'gender', 'language'] } } }); const mappedParams = params.map(param => { return { 'name': param.paramType.description, 'value': param.value }; }); return { id: user.hashedId, username: user.username, active: user.active, param: mappedParams, authCode }; }; export const handleForgotPassword = async ({ email }) => { const user = await User.findOne({ where: { email } }); if (!user) { throw new Error('Email not found'); } const resetToken = uuidv4(); const resetLink = `${process.env.FRONTEND_URL}/reset-password?token=${resetToken}`; await user.update({ reset_token: resetToken }); const languageParam = await UserParam.findOne({ where: { user_id: user.id, param_type_id: languageType.id } }); const userLanguage = languageParam ? languageParam.value : 'en'; await sendPasswordResetEmail(email, resetLink, userLanguage); return { message: 'Password reset email sent' }; }; export const activateUserAccount = async ({ token }) => { const user = await User.findOne({ where: { reset_token: token } }); if (!user) { throw new Error('Invalid token'); } await user.update({ active: true, reset_token: null }); return { message: 'Account activated' }; };