diff --git a/public/src/client/register.js b/public/src/client/register.js index f989901e7b..39c77cd8ab 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]]'); + showErrorWithSuggestions(usernameInput, username_notify, username); } callback(); @@ -205,6 +205,96 @@ define('forum/register', [ }); } + async function generateUsernameSuggestions(baseUsername, count = 3) { + const suggestions = []; + const baseName = baseUsername.replace(/\d+$/, ''); // Remove trailing numbers + + // Generate simple suggestions by appending numbers + for (let i = 1; i <= count + 10; i++) { + const suggestion = baseName + i; + if (await isUsernameAvailable(suggestion)) { + suggestions.push(suggestion); + if (suggestions.length === count) { + break; + } + } + } + + // If not enough suggestions, try with underscores + if (suggestions.length < count) { + for (let i = 1; i <= count + 10; i++) { + const suggestion = baseName + '_' + i; + if (await isUsernameAvailable(suggestion)) { + suggestions.push(suggestion); + if (suggestions.length === count) { + break; + } + } + } + } + + return suggestions; + } + + async function isUsernameAvailable(username) { + const userslug = slugify(username); + + // Check username length requirements + if (username.length < ajaxify.data.minimumUsernameLength || + userslug.length < ajaxify.data.minimumUsernameLength || + username.length > ajaxify.data.maximumUsernameLength) { + return false; + } + + // Check if valid username + if (!utils.isUserNameValid(username) || !userslug) { + return false; + } + + try { + const results = await Promise.allSettled([ + api.head(`/users/bySlug/${userslug}`, {}), + api.head(`/groups/${username}`, {}), + ]); + return results.every(obj => obj.status === 'rejected'); + } catch (err) { + return false; + } + } + + function showErrorWithSuggestions(input, element, username) { + translator.translate('[[error:username-taken]]', function (msg) { + input.attr('aria-invalid', 'true'); + element.html('