(userId, { token, password })
| 637 | } |
| 638 | |
| 639 | async verify2faApp(userId, { token, password }) { |
| 640 | const user = await this.findById(userId); |
| 641 | if (!user) { |
| 642 | return new Promise((resolve, reject) => reject(new Error(404))); |
| 643 | } |
| 644 | |
| 645 | // check if the password is correct |
| 646 | const isCorrect = await bcrypt.compare(password, user.password); |
| 647 | if (!isCorrect) { |
| 648 | return new Promise((resolve, reject) => reject(new Error(401))); |
| 649 | } |
| 650 | |
| 651 | const user2FA = await db.User2fa.findOne({ where: { user_id: userId } }); |
| 652 | if (!user2FA) { |
| 653 | return new Promise((resolve, reject) => reject({ error: "2FA not setup." })); |
| 654 | } |
| 655 | |
| 656 | const totp = new TOTP({ |
| 657 | secret: user2FA.secret |
| 658 | }); |
| 659 | |
| 660 | const delta = totp.validate({ token, window: 1 }); |
| 661 | if (delta !== null) { |
| 662 | const backupCodes = []; |
| 663 | for (let i = 0; i < 10; i++) { |
| 664 | backupCodes.push(nanoid(8)); |
| 665 | } |
| 666 | // Mark 2FA as enabled and add backup codes |
| 667 | await user2FA.update({ isEnabled: true, backup: JSON.stringify(backupCodes) }); |
| 668 | return new Promise((resolve) => resolve(backupCodes)); |
| 669 | } else { |
| 670 | return new Promise((resolve, reject) => reject({ error: "Invalid token." })); |
| 671 | } |
| 672 | } |
| 673 | |
| 674 | get2faMethods(userId) { |
| 675 | return db.User2fa.findAll({ |
no test coverage detected