(email, password)
| 277 | } |
| 278 | |
| 279 | async login(email, password) { |
| 280 | try { |
| 281 | const foundUser = await db.User.findOne({ where: { email: { [Op.like]: email } } }); |
| 282 | |
| 283 | if (!foundUser) { |
| 284 | throw new Error(401); |
| 285 | } |
| 286 | |
| 287 | let isAuthenticated = false; |
| 288 | |
| 289 | if (foundUser.password.startsWith("$2a$") || foundUser.password.startsWith("$2b$") || foundUser.password.startsWith("$2y$")) { |
| 290 | isAuthenticated = await bcrypt.compare(password, foundUser.password); |
| 291 | } else { |
| 292 | isAuthenticated = (foundUser.password === sc.encrypt(password)); |
| 293 | |
| 294 | if (isAuthenticated) { |
| 295 | const bcryptHash = await bcrypt.hash(password, 10); |
| 296 | await db.User.update({ password: bcryptHash }, { where: { email } }); |
| 297 | } |
| 298 | } |
| 299 | |
| 300 | if (!isAuthenticated) { |
| 301 | throw new Error(401); |
| 302 | } |
| 303 | |
| 304 | const user2FA = await db.User2fa.findOne({ |
| 305 | where: { user_id: foundUser.id, isEnabled: true } |
| 306 | }); |
| 307 | |
| 308 | if (user2FA?.id) { |
| 309 | return new Promise((resolve) => resolve({ |
| 310 | user_id: foundUser.id, method_id: user2FA.id, method: user2FA.method, |
| 311 | })); |
| 312 | } |
| 313 | |
| 314 | return foundUser; |
| 315 | } catch (error) { |
| 316 | throw new Error(error.message); |
| 317 | } |
| 318 | } |
| 319 | |
| 320 | async validate2FaLogin(userId, methodId, token) { |
| 321 | const user2FA = await db.User2fa.findByPk(methodId); |
no test coverage detected