</option>
<option name="register_username_force_ascii">
<categoryname>user.register</categoryname>
- <optiontype>boolean</optiontype>
- <defaultvalue>1</defaultvalue>
+ <optiontype>radioButton</optiontype>
+ <defaultvalue>2</defaultvalue>
+ <selectoptions>0:wcf.acp.option.register_username_force_ascii.disabled
+1:wcf.acp.option.register_username_force_ascii.ascii
+2:wcf.acp.option.register_username_force_ascii.suspicious</selectoptions>
</option>
<option name="register_min_user_age">
<categoryname>user.register</categoryname>
\define('REGISTER_ACTIVATION_METHOD', '1');
\define('REGISTER_USERNAME_MIN_LENGTH', 3);
\define('REGISTER_USERNAME_MAX_LENGTH', 25);
-\define('REGISTER_USERNAME_FORCE_ASCII', 1);
+\define('REGISTER_USERNAME_FORCE_ASCII', 2);
\define('REGISTER_MIN_USER_AGE', 0);
\define('GITHUB_PUBLIC_KEY', '');
\define('GITHUB_PRIVATE_KEY', '');
namespace wcf\util;
+use Spoofchecker;
+
/**
* Contains user registration related functions.
*
return false;
}
- if (REGISTER_USERNAME_FORCE_ASCII) {
- if (!\preg_match('/^[\x20-\x7E]+$/', $name)) {
- return false;
- }
+ switch (REGISTER_USERNAME_FORCE_ASCII) {
+ case 0:
+ break;
+ case 1:
+ if (!\preg_match('/^[\x20-\x7E]+$/', $name)) {
+ return false;
+ }
+ break;
+ case 2:
+ $spoofchecker = new \Spoofchecker();
+ $checks = Spoofchecker::INVISIBLE;
+ if (\defined(Spoofchecker::class . '::HIDDEN_OVERLAY')) {
+ // The constant will exist with PHP 8.3.
+ $checks |= Spoofchecker::HIDDEN_OVERLAY;
+ } else {
+ // HIDDEN_OVERLAY == 256
+ $checks |= 256;
+ }
+
+ // ->setRestrictionLevel() requires ICU 58.
+ if (\method_exists($spoofchecker, 'setRestrictionLevel')) {
+ // This method needs to be called first. ->setRestrictionLevel() will
+ // implicitly enable the check for the restriction level for which no
+ // constant exists. When calling ->setChecks() after ->setRestrictionLevel()
+ // the check will be implicitly disabled again.
+ $spoofchecker->setChecks($checks);
+
+ // https://unicode.org/reports/tr39/#Restriction_Level_Detection
+ $spoofchecker->setRestrictionLevel(Spoofchecker::HIGHLY_RESTRICTIVE);
+ } else {
+ $spoofchecker->setChecks($checks | Spoofchecker::SINGLE_SCRIPT);
+ }
+
+ \assert(
+ $spoofchecker->isSuspicious("GREEK CAPITAL LETTER SIGMA: \u{03A3}"),
+ "The restriction level check was not correctly enabled."
+ );
+
+ if ($spoofchecker->isSuspicious($name)) {
+ return false;
+ }
+ break;
}
return true;
<item name="wcf.acp.option.register_allowed_emails.description"><![CDATA[E-Mail-Adressen, die ausschließlich bei der Registrierung verwendet werden dürfen.]]></item>
<item name="wcf.acp.option.register_username_min_length"><![CDATA[Minimale Benutzernamenlänge]]></item>
<item name="wcf.acp.option.register_username_max_length"><![CDATA[Maximale Benutzernamenlänge]]></item>
- <item name="wcf.acp.option.register_username_force_ascii"><![CDATA[Benutzernamen auf ASCII-Zeichen beschränken]]></item>
+ <item name="wcf.acp.option.register_username_force_ascii"><![CDATA[Zeichenbeschränkung in Benutzernamen]]></item>
+ <item name="wcf.acp.option.register_username_force_ascii.description"><![CDATA[Die Zeichenbeschränkung in Benutzernamen schränkt die zulässigen Zeichen in Benutzernamen ein, die vom Benutzer selbst gewählt werden. Die Prüfung greift nicht bei Änderungen durch einen Administrator. Das Komma ist in Benutzernamen aus technischen Gründen generell unzulässig.
+Die Beschränkung auf ASCII-Zeichen erlaubt in Benutzernamen lediglich lateinische Buchstaben, Ziffern und einfache Sonderzeichen. Umlaute, erweiterte Sonderzeichen und Emoji sind nicht zulässig. Die Beschränkung irreführender Kombinationen von Schriftsystemen verbietet Benutzernamen, die aus Zeichen mehrerer und optisch ähnlicher Schriftsysteme bestehen. Beispielsweise ist es nicht zulässig, Zeichen aus dem lateinischen Alphabet mit Zeichen aus dem kyrillischen Alphabet in einem Benutzernamen zu kombinieren.]]></item>
+ <item name="wcf.acp.option.register_username_force_ascii.disabled"><![CDATA[Keine Beschränkung]]></item>
+ <item name="wcf.acp.option.register_username_force_ascii.ascii"><![CDATA[Beschränkung auf ASCII-Zeichen]]></item>
+ <item name="wcf.acp.option.register_username_force_ascii.suspicious"><![CDATA[Irreführende Kombinationen von Schriftsystemen beschränken]]></item>
<item name="wcf.acp.option.register_min_user_age"><![CDATA[Mindestalter]]></item>
<item name="wcf.acp.option.register_min_user_age.description"><![CDATA[Eine Angabe hier führt dazu, dass das Geburtsdatum während der Registrierung abgefragt und zum Pflichtfeld wird.]]></item>
<item name="wcf.acp.option.register_disabled"><![CDATA[Registrierung deaktivieren]]></item>
<item name="wcf.acp.option.register_allowed_emails.description"><![CDATA[You can specify which email addresses are allowed for registration.]]></item>
<item name="wcf.acp.option.register_username_min_length"><![CDATA[Minimum Username Length]]></item>
<item name="wcf.acp.option.register_username_max_length"><![CDATA[Maximum Username Length]]></item>
- <item name="wcf.acp.option.register_username_force_ascii"><![CDATA[Require ASCII characters for usernames]]></item>
+ <item name="wcf.acp.option.register_username_force_ascii"><![CDATA[Restricted Characters in Usernames]]></item>
+ <item name="wcf.acp.option.register_username_force_ascii.description"><![CDATA[Restricting characters in usernames restricts the use of specific characters or character sequences within usernames that are selected by the user themselves. Usernames that are changed by the administrator are not restricted. The comma is always considered an invalid character for technical reasons.
+Restricting usernames to ASCII characters restricts usernames to latin letters, digits, and simple special characters. Extended special characters, diacritics and umlauts, as well as emoji are not allowed. Restricting suspicious mixing of writing systems disallows usernames that combine characters from different, but visually similar, writing systems. As an example it will not be allowed to combine letters from the latin script with letters from the cyrillic script.]]></item>
+ <item name="wcf.acp.option.register_username_force_ascii.disabled"><![CDATA[No restriction]]></item>
+ <item name="wcf.acp.option.register_username_force_ascii.ascii"><![CDATA[Restrict to ASCII characters]]></item>
+ <item name="wcf.acp.option.register_username_force_ascii.suspicious"><![CDATA[Restrict suspicious mixing of writing systems]]></item>
<item name="wcf.acp.option.register_min_user_age"><![CDATA[Minimum Age]]></item>
<item name="wcf.acp.option.register_min_user_age.description"><![CDATA[Specifying a value requires the user to provide a birthday during registration.]]></item>
<item name="wcf.acp.option.register_disabled"><![CDATA[Disable registration]]></item>