소스 검색

Fix 8688ha84v

KernelDeimos 1 년 전
부모
커밋
8cca067991
3개의 변경된 파일40개의 추가작업 그리고 1개의 파일을 삭제
  1. 8 1
      packages/backend/src/routers/_default.js
  2. 15 0
      packages/backend/src/routers/change_email.js
  3. 17 0
      packages/backend/src/routers/confirm-email.js

+ 8 - 1
packages/backend/src/routers/_default.js

@@ -209,7 +209,7 @@ router.all('*', async function(req, res, next) {
                 const {get_user} = require('../helpers')
 
                 // get user
-                const user = await get_user({uuid: req.query.user_uuid})
+                const user = await get_user({uuid: req.query.user_uuid, force: true})
 
                 // more validation
                 if(user === undefined || user === null || user === false)
@@ -220,6 +220,13 @@ router.all('*', async function(req, res, next) {
                     h += '<p style="text-align:center; color:red;">invalid token.</p>';
                 // mark user as confirmed
                 else{
+                    // If other users have the same unconfirmed email, revoke it
+                    await db.write(
+                        'UPDATE `user` SET `unconfirmed_change_email` = NULL, `change_email_confirm_token` = NULL WHERE `unconfirmed_change_email` = ?',
+                        [user.email],
+                    );
+
+                    // update user
                     await db.write(
                         "UPDATE `user` SET `email_confirmed` = 1, `requires_email_confirmation` = 0 WHERE id = ?",
                         [user.id]

+ 15 - 0
packages/backend/src/routers/change_email.js

@@ -53,6 +53,21 @@ const CHANGE_EMAIL_CONFIRM = eggspress('/change_email/confirm', {
         throw APIError.create('token_invalid');
     }
 
+    // Scenario: email was confirmed on another account already
+    const rows2 = await db.read(
+        'SELECT `id` FROM `user` WHERE `email` = ?',
+        [rows[0].unconfirmed_change_email]
+    );
+    if ( rows2.length > 0 ) {
+        throw APIError.create('email_already_in_use');
+    }
+
+    // If other users have the same unconfirmed email, revoke it
+    await db.write(
+        'UPDATE `user` SET `unconfirmed_change_email` = NULL, `change_email_confirm_token` = NULL WHERE `unconfirmed_change_email` = ?',
+        [rows[0].unconfirmed_change_email]
+    );
+
     const new_email = rows[0].unconfirmed_change_email;
 
     await db.write(

+ 17 - 0
packages/backend/src/routers/confirm-email.js

@@ -22,6 +22,7 @@ const { invalidate_cached_user } = require('../helpers');
 const router = new express.Router();
 const auth = require('../middleware/auth.js');
 const { DB_WRITE } = require('../services/database/consts');
+const APIError = require('../api/APIError.js');
 
 // -----------------------------------------------------------------------//
 // POST /confirm-email
@@ -48,6 +49,22 @@ router.post('/confirm-email', auth, express.json(), async (req, res, next)=>{
     // Set expiry for rate limit
     kv.expire(`confirm-email|${req.ip}|${req.body.email ?? req.body.username}`, 60 * 10, 'NX')
 
+    // Scenario: email was confirmed on another account already
+    const rows = await db.read(
+        'SELECT `id` FROM `user` WHERE `email` = ? AND `email_confirmed` = 1',
+        [req.body.email],
+    );
+    if ( rows.length > 0 ) {
+        APIError.create('email_already_in_use').write(res);
+        return;
+    }
+
+    // If other users have the same unconfirmed email, revoke it
+    await db.write(
+        'UPDATE `user` SET `unconfirmed_change_email` = NULL, `change_email_confirm_token` = NULL WHERE `unconfirmed_change_email` = ?',
+        [req.user.email],
+    );
+
     if(req.body.code === req.user.email_confirm_code) {
         await db.write(
             "UPDATE `user` SET `email_confirmed` = 1, `requires_email_confirmation` = 0 WHERE id = ? LIMIT 1",