Unfortunately, we had to end up creating our entire migration script by ourselves. The script that was available at the time (end of 2022) was definitely not even in a “finished” state. Pieces of referenced code were missing and others made no sense at all.
Between the parts we had to deal with, was the renaming of usernames that were not respecting the discourse standard. We had over 10k users so we simply assigned the username to the “user name” field which doesn’t have such restrictions and when a username was infringing any of the rules, we changed it to the md5 string of the username. Then we left the users 1 month to change their username freely so they could change it back to something that resembled their originale one.
Here is an excerpt of the code:
public static string ParseName(string text)
{
var reservedName = new string[] { "user", "system", "moderators" };
var result = NormalizeText(text);
// If reserved change it
if (reservedName.Contains(result, StringComparer.OrdinalIgnoreCase))
result = text.ToLower().ToMD5();
// Invalid alphanumeric
else if (!Regex.IsMatch(result, @"^[a-zA-Z0-9_.-]*$"))
result = text.ToLower().ToMD5();
// Invalid repeated
else if (Regex.IsMatch(result, @"[-_.]{2,}"))
result = text.ToLower().ToMD5();
// Invalid trailing char
else if (Regex.IsMatch(result, @"/[\p{L}\p{N}]+$/"))
result = text.ToLower().ToMD5();
// Confusing extensions
else if (Regex.IsMatch(result, @"/\.(js|json|css|htm|html|xml|jpg|jpeg|png|gif|bmp|ico|tif|tiff|woff)$/i"))
result = text.ToLower().ToMD5();
// Starting and ending dots
else if (result.StartsWith(".") || result.EndsWith("."))
result = text.ToLower().ToMD5();
// No more than 60 character
result = result.Truncate(60);
return result;
}
We used this file as reference to determine what was to be considered a restriction. Might have been changed in the meanwhile so, keep an eye out.