From 806e54bf5a0d6a6cefb2f9e0ba57346e77aef8a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 5 Jun 2025 11:42:29 -0400 Subject: [PATCH] fix: closes #13475, don't store escaped username when updating profile --- src/api/users.js | 8 ++++---- test/user.js | 25 ++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/api/users.js b/src/api/users.js index d3f9d8f7a3..4fb8155734 100644 --- a/src/api/users.js +++ b/src/api/users.js @@ -57,7 +57,7 @@ usersAPI.update = async function (caller, data) { throw new Error('[[error:invalid-data]]'); } - const oldUserData = await user.getUserFields(data.uid, ['email', 'username']); + const oldUserData = await db.getObjectFields(`user:${data.uid}`, ['email', 'username']); if (!oldUserData || !oldUserData.username) { throw new Error('[[error:invalid-data]]'); } @@ -86,14 +86,14 @@ usersAPI.update = async function (caller, data) { await user.updateProfile(caller.uid, data); const userData = await user.getUserData(data.uid); - - if (userData.username !== oldUserData.username) { + const oldUsernameEscaped = validator.escape(String(oldUserData.username)); + if (userData.username !== oldUsernameEscaped) { await events.log({ type: 'username-change', uid: caller.uid, targetUid: data.uid, ip: caller.ip, - oldUsername: oldUserData.username, + oldUsername: oldUsernameEscaped, newUsername: userData.username, }); } diff --git a/test/user.js b/test/user.js index 3fb1592af7..16f0919366 100644 --- a/test/user.js +++ b/test/user.js @@ -748,7 +748,9 @@ describe('User', () => { signature: 'nodebb is good', password: '123456', }; - const result = await apiUser.update({ uid: uid }, { ...data, password: '123456', invalid: 'field' }); + const result = await apiUser.update({ uid: uid }, { + ...data, password: '123456', invalid: 'field', + }); assert.equal(result.username, 'updatedUserName'); assert.equal(result.userslug, 'updatedusername'); assert.equal(result.fullname, 'updatedFullname'); @@ -767,6 +769,27 @@ describe('User', () => { assert.strictEqual(userData.invalid, undefined); }); + it('should not change the username to escaped version', async () => { + const uid = await User.create({ + username: 'ex\'ample_user', email: '13475@test.com', password: '123456', + }); + await User.setUserField(uid, 'email', '13475@test.com'); + await User.email.confirmByUid(uid); + + const data = { + uid: uid, + username: 'ex\'ample_user', + password: '123456', + }; + const result = await apiUser.update({ uid: uid }, { + ...data, password: '123456', invalid: 'field', + }); + const storedUsername = await db.getObjectField(`user:${uid}`, 'username'); + assert.equal(result.username, 'ex'ample_user'); + assert.equal(storedUsername, 'ex\'ample_user'); + assert.equal(result.userslug, 'ex-ample_user'); + }); + it('should also generate an email confirmation code for the changed email', async () => { const confirmSent = await User.email.isValidationPending(uid, 'updatedemail@me.com'); assert.strictEqual(confirmSent, true);