const bcrypt = require("bcryptjs") const usersRepo = require("../repositories/usersRepo") const tokensService = require("./tokensService") const identitiesRepo = require("../repositories/identitiesRepo") const credentialsRepo = require("../repositories/credentialsRepo") const { DefaultError } = require("../errors/errors") async function registerLocal({ identifier, password, profile = { displayName, avatarURL } }) { try { const user = await usersRepo.create(identifier, process.env.SERVER_UUID, null, profile.displayName, profile.avatarURL) const hashedPassword = await bcrypt.hash(password, Number(process.env.BCRYPT_SALT)) const credentials = await credentialsRepo.create(user.id, hashedPassword) if (Array.isArray(credentials)) { throw new DefaultError(500, "Internal Server Error", "UserRegistration") } return user } catch (error) { throw error } } async function validatePassword({ password, passwordHash }) { try { await bcrypt.compare(password, passwordHash) } catch (error) { throw new DefaultError(401, "Bad credentials", "Wrong password") } } async function loginLocal({ identifier, password }) { try { const user = await usersRepo.findByIdentifier(identifier) const credentials = await credentialsRepo.findByUserId(user.id) await validatePassword({ password: password, passwordHash: credentials.passwordHash }) const accessToken = await tokensService.signToken(user) const refreshToken = await tokensService.signRefreshToken(user.id) return { user, tokens: { accessToken, refreshToken } } } catch (error) { console.log(error) throw new DefaultError(500, "Internal Server Error", error.toString()) } } async function refreshAccessToken({ userId, refreshToken }) { try { await tokensService.verifyRefreshToken(refreshToken) await tokensService.revokeRefreshToken(refreshToken) const user = await usersRepo.findById(userId) const newAccessToken = await tokensService.signToken(user) const newRefreshToken = await tokensService.signRefreshToken(userId) return { accessToken: newAccessToken, refreshToken: newRefreshToken } } catch (error) { throw error } } async function changePassword({ userId, password, newPassword }) { try { const credentials = await credentialsRepo.findByUserId(userId) await validatePassword({ password, passwordHash: credentials.passwordHash }) await credentialsRepo.updatePassword(userId, newPassword) return true } catch (error) { throw error } } async function resetPassword({ userId, newPassword }) { try { await credentialsRepo.updatePassword(userId, newPassword) return true } catch (error) { throw error } } module.exports = { loginLocal, resetPassword, registerLocal, changePassword, refreshAccessToken }