Ver Fonte

fix: edge case during email change

Previous logic was:
- on email change, update temporary value
- send email to confirm new email
- temporary value is moved to real email

This doesn't work when an account has not yet confirmed their email
after signup (i.e. user's email_confirmed is still 0). Well, it actually
does work, but the user is only able to confirm the change to their
email and not set their account as having a confirmed email.

New logic has a branch for this case; IFF email_confirmed=0:
- change account confirm code
- send new account confirm email
KernelDeimos há 1 mês atrás
pai
commit
fb01bb474a
1 ficheiros alterados com 20 adições e 0 exclusões
  1. 20 0
      src/backend/src/routers/user-protected/change-email.js

+ 20 - 0
src/backend/src/routers/user-protected/change-email.js

@@ -22,6 +22,9 @@ const jwt = require('jsonwebtoken');
 const validator = require('validator');
 const crypto = require('crypto');
 const config = require("../../config");
+const { send_email_verification_token } = require("../../helpers");
+const { Context } = require("../../util/context");
+const { v4: uuidv4 } = require('uuid');
 
 module.exports = {
     route: '/change-email',
@@ -66,6 +69,23 @@ module.exports = {
         if ( rows[0].count > 0 ) {
             throw APIError.create('email_already_in_use', null, { email: new_email });
         }
+        
+        // If user does not have a confirmed email, then update `email` directly
+        // and send a new confirmation email for their account instead.
+        if ( ! user.email_confirmed ) {
+            const email_confirm_token = uuidv4();
+            await db.write(
+                'UPDATE `user` SET `email` = ?, `email_confirm_token` = ? WHERE `id` = ?',
+                [new_email, email_confirm_token, user.id],
+            );
+
+            const svc_email = Context.get('services').get('email');
+            const link = `${config.origin}/confirm-email-by-token?user_uuid=${user.uuid}&token=${email_confirm_token}`;
+            svc_email.send_email({ email: new_email }, 'email_verification_link', { link });
+            
+            res.send({ success: true });
+            return;
+        }
 
         // generate confirmation token
         const token = crypto.randomBytes(4).toString('hex');