From b5525fda797e4fc1971ff333da08095c669cac59 Mon Sep 17 00:00:00 2001 From: Latifa Al-Hitmi Date: Thu, 12 Sep 2024 18:58:07 +0300 Subject: [PATCH] editing the show error to give the idea of suffix --- public/src/client/register.js | 2 +- src/user/create.js | 362 +++++++++++++++++----------------- 2 files changed, 182 insertions(+), 182 deletions(-) diff --git a/public/src/client/register.js b/public/src/client/register.js index d8144d26d5..13d5f4688a 100644 --- a/public/src/client/register.js +++ b/public/src/client/register.js @@ -135,7 +135,7 @@ define('forum/register', [ if (results.every(obj => obj.status === 'rejected')) { showSuccess(usernameInput, username_notify, successIcon); } else { - showError(usernameInput, username_notify, '[[error:username-taken]]'); + showError(usernameInput, username_notify, `[[error:username-taken]] Maybe try ${usernameInput.val()}suffix`); } callback(); diff --git a/src/user/create.js b/src/user/create.js index 610d614e81..e423a2aa46 100644 --- a/src/user/create.js +++ b/src/user/create.js @@ -12,184 +12,184 @@ const meta = require('../meta'); const analytics = require('../analytics'); module.exports = function (User) { - User.create = async function (data) { - data.username = data.username.trim(); - data.userslug = slugify(data.username); - if (data.email !== undefined) { - data.email = String(data.email).trim(); - } - - await User.isDataValid(data); - - await lock(data.username, '[[error:username-taken]]'); - if (data.email && data.email !== data.username) { - await lock(data.email, '[[error:email-taken]]'); - } - - try { - return await create(data); - } finally { - await db.deleteObjectFields('locks', [data.username, data.email]); - } - }; - - async function lock(value, error) { - const count = await db.incrObjectField('locks', value); - if (count > 1) { - throw new Error(error); - } - } - - async function create(data) { - const timestamp = data.timestamp || Date.now(); - - let userData = { - username: data.username, - userslug: data.userslug, - joindate: timestamp, - lastonline: timestamp, - status: 'online', - }; - ['picture', 'fullname', 'location', 'birthday'].forEach((field) => { - if (data[field]) { - userData[field] = data[field]; - } - }); - if (data.gdpr_consent === true) { - userData.gdpr_consent = 1; - } - if (data.acceptTos === true) { - userData.acceptTos = 1; - } - - const renamedUsername = await User.uniqueUsername(userData); - const userNameChanged = !!renamedUsername; - if (userNameChanged) { - userData.username = renamedUsername; - userData.userslug = slugify(renamedUsername); - } - - const results = await plugins.hooks.fire('filter:user.create', { user: userData, data: data }); - userData = results.user; - - const uid = await db.incrObjectField('global', 'nextUid'); - const isFirstUser = uid === 1; - userData.uid = uid; - - await db.setObject(`user:${uid}`, userData); - - const bulkAdd = [ - ['username:uid', userData.uid, userData.username], - [`user:${userData.uid}:usernames`, timestamp, `${userData.username}:${timestamp}`], - ['username:sorted', 0, `${userData.username.toLowerCase()}:${userData.uid}`], - ['userslug:uid', userData.uid, userData.userslug], - ['users:joindate', timestamp, userData.uid], - ['users:online', timestamp, userData.uid], - ['users:postcount', 0, userData.uid], - ['users:reputation', 0, userData.uid], - ]; - - if (userData.fullname) { - bulkAdd.push(['fullname:sorted', 0, `${userData.fullname.toLowerCase()}:${userData.uid}`]); - } - - await Promise.all([ - db.incrObjectField('global', 'userCount'), - analytics.increment('registrations'), - db.sortedSetAddBulk(bulkAdd), - groups.join(['registered-users', 'unverified-users'], userData.uid), - User.notifications.sendWelcomeNotification(userData.uid), - storePassword(userData.uid, data.password), - User.updateDigestSetting(userData.uid, meta.config.dailyDigestFreq), - ]); - - if (data.email && isFirstUser) { - await User.setUserField(uid, 'email', data.email); - await User.email.confirmByUid(userData.uid); - } - - if (data.email && userData.uid > 1) { - await User.email.sendValidationEmail(userData.uid, { - email: data.email, - template: 'welcome', - subject: `[[email:welcome-to, ${meta.config.title || meta.config.browserTitle || 'NodeBB'}]]`, - }).catch(err => winston.error(`[user.create] Validation email failed to send\n[emailer.send] ${err.stack}`)); - } - if (userNameChanged) { - await User.notifications.sendNameChangeNotification(userData.uid, userData.username); - } - plugins.hooks.fire('action:user.create', { user: userData, data: data }); - return userData.uid; - } - - async function storePassword(uid, password) { - if (!password) { - return; - } - const hash = await User.hashPassword(password); - await Promise.all([ - User.setUserFields(uid, { - password: hash, - 'password:shaWrapped': 1, - }), - User.reset.updateExpiry(uid), - ]); - } - - User.isDataValid = async function (userData) { - if (userData.email && !utils.isEmailValid(userData.email)) { - throw new Error('[[error:invalid-email]]'); - } - - if (!utils.isUserNameValid(userData.username) || !userData.userslug) { - throw new Error(`[[error:invalid-username, ${userData.username}]]`); - } - - if (userData.password) { - User.isPasswordValid(userData.password); - } - - if (userData.email) { - const available = await User.email.available(userData.email); - if (!available) { - throw new Error('[[error:email-taken]]'); - } - } - }; - - User.isPasswordValid = function (password, minStrength) { - minStrength = (minStrength || minStrength === 0) ? minStrength : meta.config.minimumPasswordStrength; - - // Sanity checks: Checks if defined and is string - if (!password || !utils.isPasswordValid(password)) { - throw new Error('[[error:invalid-password]]'); - } - - if (password.length < meta.config.minimumPasswordLength) { - throw new Error('[[reset_password:password-too-short]]'); - } - - if (password.length > 512) { - throw new Error('[[error:password-too-long]]'); - } - - const strength = zxcvbn(password); - if (strength.score < minStrength) { - throw new Error('[[user:weak-password]]'); - } - }; - - User.uniqueUsername = async function (userData) { - let numTries = 0; - let { username } = userData; - while (true) { - /* eslint-disable no-await-in-loop */ - const exists = await meta.userOrGroupExists(username); - if (!exists) { - return numTries ? username : null; - } - username = `${userData.username} ${numTries.toString(32)}`; - numTries += 1; - } - }; -}; + User.create = async function (data) { + data.username = data.username.trim(); + data.userslug = slugify(data.username); + if (data.email !== undefined) { + data.email = String(data.email).trim(); + } + + await User.isDataValid(data); + + await lock(data.username, '[[error:username-taken]] suffix'); + if (data.email && data.email !== data.username) { + await lock(data.email, '[[error:email-taken]] suffix'); + } + + try { + return await create(data); + } finally { + await db.deleteObjectFields('locks', [data.username, data.email]); + } + }; + + async function lock(value, error) { + const count = await db.incrObjectField('locks', value); + if (count > 1) { + throw new Error(error); + } + } + + async function create(data) { + const timestamp = data.timestamp || Date.now(); + + let userData = { + username: data.username, + userslug: data.userslug, + joindate: timestamp, + lastonline: timestamp, + status: 'online', + }; + ['picture', 'fullname', 'location', 'birthday'].forEach((field) => { + if (data[field]) { + userData[field] = data[field]; + } + }); + if (data.gdpr_consent === true) { + userData.gdpr_consent = 1; + } + if (data.acceptTos === true) { + userData.acceptTos = 1; + } + + const renamedUsername = await User.uniqueUsername(userData); + const userNameChanged = !!renamedUsername; + if (userNameChanged) { + userData.username = renamedUsername; + userData.userslug = slugify(renamedUsername); + } + + const results = await plugins.hooks.fire('filter:user.create', { user: userData, data: data }); + userData = results.user; + + const uid = await db.incrObjectField('global', 'nextUid'); + const isFirstUser = uid === 1; + userData.uid = uid; + + await db.setObject(`user:${uid}`, userData); + + const bulkAdd = [ + ['username:uid', userData.uid, userData.username], + [`user:${userData.uid}:usernames`, timestamp, `${userData.username}:${timestamp}`], + ['username:sorted', 0, `${userData.username.toLowerCase()}:${userData.uid}`], + ['userslug:uid', userData.uid, userData.userslug], + ['users:joindate', timestamp, userData.uid], + ['users:online', timestamp, userData.uid], + ['users:postcount', 0, userData.uid], + ['users:reputation', 0, userData.uid], + ]; + + if (userData.fullname) { + bulkAdd.push(['fullname:sorted', 0, `${userData.fullname.toLowerCase()}:${userData.uid}`]); + } + + await Promise.all([ + db.incrObjectField('global', 'userCount'), + analytics.increment('registrations'), + db.sortedSetAddBulk(bulkAdd), + groups.join(['registered-users', 'unverified-users'], userData.uid), + User.notifications.sendWelcomeNotification(userData.uid), + storePassword(userData.uid, data.password), + User.updateDigestSetting(userData.uid, meta.config.dailyDigestFreq), + ]); + + if (data.email && isFirstUser) { + await User.setUserField(uid, 'email', data.email); + await User.email.confirmByUid(userData.uid); + } + + if (data.email && userData.uid > 1) { + await User.email.sendValidationEmail(userData.uid, { + email: data.email, + template: 'welcome', + subject: `[[email:welcome-to, ${meta.config.title || meta.config.browserTitle || 'NodeBB'}]]`, + }).catch(err => winston.error(`[user.create] Validation email failed to send\n[emailer.send] ${err.stack}`)); + } + if (userNameChanged) { + await User.notifications.sendNameChangeNotification(userData.uid, userData.username); + } + plugins.hooks.fire('action:user.create', { user: userData, data: data }); + return userData.uid; + } + + async function storePassword(uid, password) { + if (!password) { + return; + } + const hash = await User.hashPassword(password); + await Promise.all([ + User.setUserFields(uid, { + password: hash, + 'password:shaWrapped': 1, + }), + User.reset.updateExpiry(uid), + ]); + } + + User.isDataValid = async function (userData) { + if (userData.email && !utils.isEmailValid(userData.email)) { + throw new Error('[[error:invalid-email]]'); + } + + if (!utils.isUserNameValid(userData.username) || !userData.userslug) { + throw new Error(`[[error:invalid-username, ${userData.username}]]`); + } + + if (userData.password) { + User.isPasswordValid(userData.password); + } + + if (userData.email) { + const available = await User.email.available(userData.email); + if (!available) { + throw new Error('[[error:email-taken]]'); + } + } + }; + + User.isPasswordValid = function (password, minStrength) { + minStrength = (minStrength || minStrength === 0) ? minStrength : meta.config.minimumPasswordStrength; + + // Sanity checks: Checks if defined and is string + if (!password || !utils.isPasswordValid(password)) { + throw new Error('[[error:invalid-password]]'); + } + + if (password.length < meta.config.minimumPasswordLength) { + throw new Error('[[reset_password:password-too-short]]'); + } + + if (password.length > 512) { + throw new Error('[[error:password-too-long]]'); + } + + const strength = zxcvbn(password); + if (strength.score < minStrength) { + throw new Error('[[user:weak-password]]'); + } + }; + + User.uniqueUsername = async function (userData) { + let numTries = 0; + let { username } = userData; + while (true) { + /* eslint-disable no-await-in-loop */ + const exists = await meta.userOrGroupExists(username); + if (!exists) { + return numTries ? username : null; + } + username = `${userData.username} ${numTries.toString(32)}`; + numTries += 1; + } + }; +}; \ No newline at end of file