mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-07 22:45:46 +01:00
feat: track uid for email/username changes, closes #12454
This commit is contained in:
@@ -103,10 +103,10 @@
|
|||||||
"nodebb-plugin-ntfy": "1.7.4",
|
"nodebb-plugin-ntfy": "1.7.4",
|
||||||
"nodebb-plugin-spam-be-gone": "2.2.2",
|
"nodebb-plugin-spam-be-gone": "2.2.2",
|
||||||
"nodebb-rewards-essentials": "1.0.0",
|
"nodebb-rewards-essentials": "1.0.0",
|
||||||
"nodebb-theme-harmony": "1.2.53",
|
"nodebb-theme-harmony": "1.2.54",
|
||||||
"nodebb-theme-lavender": "7.1.8",
|
"nodebb-theme-lavender": "7.1.8",
|
||||||
"nodebb-theme-peace": "2.2.4",
|
"nodebb-theme-peace": "2.2.4",
|
||||||
"nodebb-theme-persona": "13.3.18",
|
"nodebb-theme-persona": "13.3.19",
|
||||||
"nodebb-widget-essentials": "7.0.16",
|
"nodebb-widget-essentials": "7.0.16",
|
||||||
"nodemailer": "6.9.13",
|
"nodemailer": "6.9.13",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
|
|||||||
@@ -454,7 +454,7 @@ usersAPI.addEmail = async (caller, { email, skipConfirmation, uid }) => {
|
|||||||
throw new Error('[[error:email-taken]]');
|
throw new Error('[[error:email-taken]]');
|
||||||
}
|
}
|
||||||
await user.setUserField(uid, 'email', email);
|
await user.setUserField(uid, 'email', email);
|
||||||
await user.email.confirmByUid(uid);
|
await user.email.confirmByUid(uid, caller.uid);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await usersAPI.update(caller, { uid, email });
|
await usersAPI.update(caller, { uid, email });
|
||||||
@@ -504,7 +504,7 @@ usersAPI.confirmEmail = async (caller, { uid, email, sessionId }) => {
|
|||||||
await user.email.confirmByCode(code, sessionId);
|
await user.email.confirmByCode(code, sessionId);
|
||||||
return true;
|
return true;
|
||||||
} else if (current && current === email) { // i.e. old account w/ unconf. email in user hash
|
} else if (current && current === email) { // i.e. old account w/ unconf. email in user hash
|
||||||
await user.email.confirmByUid(uid);
|
await user.email.confirmByUid(uid, caller.uid);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ User.validateEmail = async function (socket, uids) {
|
|||||||
if (email) {
|
if (email) {
|
||||||
await user.setUserField(uid, 'email', email);
|
await user.setUserField(uid, 'email', email);
|
||||||
}
|
}
|
||||||
await user.email.confirmByUid(uid);
|
await user.email.confirmByUid(uid, socket.uid);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -214,10 +214,11 @@ UserEmail.confirmByCode = async function (code, sessionId) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// confirm uid's email via ACP
|
// confirm uid's email via ACP
|
||||||
UserEmail.confirmByUid = async function (uid) {
|
UserEmail.confirmByUid = async function (uid, callerUid = 0) {
|
||||||
if (!(parseInt(uid, 10) > 0)) {
|
if (!(parseInt(uid, 10) > 0)) {
|
||||||
throw new Error('[[error:invalid-uid]]');
|
throw new Error('[[error:invalid-uid]]');
|
||||||
}
|
}
|
||||||
|
callerUid = callerUid || uid;
|
||||||
const currentEmail = await user.getUserField(uid, 'email');
|
const currentEmail = await user.getUserField(uid, 'email');
|
||||||
if (!currentEmail) {
|
if (!currentEmail) {
|
||||||
throw new Error('[[error:invalid-email]]');
|
throw new Error('[[error:invalid-email]]');
|
||||||
@@ -241,7 +242,7 @@ UserEmail.confirmByUid = async function (uid) {
|
|||||||
db.sortedSetAddBulk([
|
db.sortedSetAddBulk([
|
||||||
['email:uid', uid, currentEmail.toLowerCase()],
|
['email:uid', uid, currentEmail.toLowerCase()],
|
||||||
['email:sorted', 0, `${currentEmail.toLowerCase()}:${uid}`],
|
['email:sorted', 0, `${currentEmail.toLowerCase()}:${uid}`],
|
||||||
[`user:${uid}:emails`, Date.now(), `${currentEmail}:${Date.now()}`],
|
[`user:${uid}:emails`, Date.now(), `${currentEmail}:${Date.now()}:${callerUid}`],
|
||||||
]),
|
]),
|
||||||
user.setUserField(uid, 'email:confirmed', 1),
|
user.setUserField(uid, 'email:confirmed', 1),
|
||||||
groups.join('verified-users', uid),
|
groups.join('verified-users', uid),
|
||||||
|
|||||||
@@ -60,13 +60,24 @@ module.exports = function (User) {
|
|||||||
|
|
||||||
User.getHistory = async function (set) {
|
User.getHistory = async function (set) {
|
||||||
const data = await db.getSortedSetRevRangeWithScores(set, 0, -1);
|
const data = await db.getSortedSetRevRangeWithScores(set, 0, -1);
|
||||||
return data.map((set) => {
|
data.forEach((set) => {
|
||||||
set.timestamp = set.score;
|
set.timestamp = set.score;
|
||||||
set.timestampISO = utils.toISOString(set.score);
|
set.timestampISO = utils.toISOString(set.score);
|
||||||
set.value = validator.escape(String(set.value.split(':')[0]));
|
const parts = set.value.split(':');
|
||||||
|
set.value = validator.escape(String(parts[0]));
|
||||||
|
set.byUid = validator.escape(String(parts[2] || ''));
|
||||||
delete set.score;
|
delete set.score;
|
||||||
return set;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const uids = _.uniq(data.map(d => d && d.byUid).filter(Boolean));
|
||||||
|
const usersData = await User.getUsersFields(uids, ['uid', 'username', 'userslug', 'picture']);
|
||||||
|
const uidToUser = _.zipObject(uids, usersData);
|
||||||
|
data.forEach((d) => {
|
||||||
|
if (d.byUid) {
|
||||||
|
d.byUser = uidToUser[d.byUid];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
async function getFlagMetadata(flags) {
|
async function getFlagMetadata(flags) {
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ module.exports = function (User) {
|
|||||||
if (field === 'email') {
|
if (field === 'email') {
|
||||||
return await updateEmail(updateUid, data.email);
|
return await updateEmail(updateUid, data.email);
|
||||||
} else if (field === 'username') {
|
} else if (field === 'username') {
|
||||||
return await updateUsername(updateUid, data.username);
|
return await updateUsername(updateUid, data.username, uid);
|
||||||
} else if (field === 'fullname') {
|
} else if (field === 'fullname') {
|
||||||
return await updateFullname(updateUid, data.fullname);
|
return await updateFullname(updateUid, data.fullname);
|
||||||
}
|
}
|
||||||
@@ -247,7 +247,7 @@ module.exports = function (User) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateUsername(uid, newUsername) {
|
async function updateUsername(uid, newUsername, callerUid) {
|
||||||
if (!newUsername) {
|
if (!newUsername) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -260,7 +260,7 @@ module.exports = function (User) {
|
|||||||
await Promise.all([
|
await Promise.all([
|
||||||
updateUidMapping('username', uid, newUsername, userData.username),
|
updateUidMapping('username', uid, newUsername, userData.username),
|
||||||
updateUidMapping('userslug', uid, newUserslug, userData.userslug),
|
updateUidMapping('userslug', uid, newUserslug, userData.userslug),
|
||||||
db.sortedSetAdd(`user:${uid}:usernames`, now, `${newUsername}:${now}`),
|
db.sortedSetAdd(`user:${uid}:usernames`, now, `${newUsername}:${now}:${callerUid}`),
|
||||||
]);
|
]);
|
||||||
await db.sortedSetRemove('username:sorted', `${userData.username.toLowerCase()}:${uid}`);
|
await db.sortedSetRemove('username:sorted', `${userData.username.toLowerCase()}:${uid}`);
|
||||||
await db.sortedSetAdd('username:sorted', 0, `${newUsername.toLowerCase()}:${uid}`);
|
await db.sortedSetAdd('username:sorted', 0, `${newUsername.toLowerCase()}:${uid}`);
|
||||||
|
|||||||
Reference in New Issue
Block a user