Skip to content

Commit c1d4b3e

Browse files
Profiles/i18n: Fix unsupported user names (#8956)
1 parent f51998d commit c1d4b3e

4 files changed

Lines changed: 41 additions & 14 deletions

File tree

app/backend/src/couchers/constants.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
# Must match the frontend values in app/web/utils/validation.ts
1616
VALID_NAME_MIN_LENGTH = 2
1717
VALID_NAME_MAX_LENGTH = 100
18-
VALID_NAME_REGEX = r"^[\p{L}'-]+(\s+[\p{L}'-]+)*$"
18+
19+
# Letters, diacritics, internal spaces, quotes, dashes, commas, dots, and's for two names. See tests!
20+
VALID_NAME_REGEX = r"""^(?!\p{Zs})[\p{L}\p{M}\p{Zs}\p{Pi}\p{Pf}\p{Pd},.'"·・&/|]+(?<!\p{Zs})$"""
1921

2022
BANNED_USERNAME_PHRASES = [
2123
"admin",

app/backend/src/couchers/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
)
3636
from couchers.proto.internal import internal_pb2
3737

38-
_VALID_NAME_PATTERN = regex.compile(VALID_NAME_REGEX)
38+
_VALID_NAME_PATTERN = regex.compile(VALID_NAME_REGEX, regex.UNICODE)
3939

4040
if TYPE_CHECKING:
4141
from couchers.models import Geom

app/backend/src/tests/test_db.py

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from sqlalchemy.sql import func
1212

1313
from couchers.config import config
14+
from couchers.constants import VALID_NAME_MAX_LENGTH
1415
from couchers.db import _get_base_engine, apply_migrations, get_parent_node_at_location, session_scope
1516
from couchers.jobs.handlers import DatabaseInconsistencyError, check_database_consistency
1617
from couchers.models import User
@@ -66,28 +67,51 @@ def test_is_valid_username() -> None:
6667

6768

6869
def test_is_valid_name() -> None:
69-
# valid names
70+
# Basics
7071
assert is_valid_name("ab")
7172
assert is_valid_name("a b")
72-
assert is_valid_name("O'Connor")
7373
assert is_valid_name("Jean-Luc")
74-
assert is_valid_name("老子")
7574

76-
# invalid: too short
75+
# OK punctuation
76+
assert is_valid_name("King K. Rool")
77+
assert is_valid_name("Doe, John")
78+
assert is_valid_name("Alice & Bob")
79+
assert is_valid_name("Alice / Bob")
80+
assert is_valid_name("Alice | Bob")
81+
82+
# Apostrophes and Quotes
83+
assert is_valid_name("O'Connor")
84+
assert is_valid_name("William “Bill” Clinton")
85+
assert is_valid_name("Sha’Nia Jenkins")
86+
87+
# Other scripts
88+
assert is_valid_name("孙悟空")
89+
assert is_valid_name("Combining Diặcritics")
90+
assert is_valid_name("काव्य") # Hindi combining diacritics
91+
assert is_valid_name("Meritxell Col·lell") # Catalan middle dot
92+
assert is_valid_name("レオナルド・ディカプリオ") # Japanese middle dot
93+
assert is_valid_name("Lanaʻi") # Hawaiian ʻokina glottal stop
94+
95+
# invalid: too short / too long
7796
assert not is_valid_name("a")
97+
assert not is_valid_name("a" * (VALID_NAME_MAX_LENGTH + 1))
7898
# invalid: only whitespace
7999
assert not is_valid_name(" ")
80100
assert not is_valid_name("")
81101
assert not is_valid_name(" ")
82102
assert not is_valid_name(" ")
83103
# invalid: leading/trailing whitespace
84-
assert not is_valid_name(" ab")
85-
assert not is_valid_name("ab ")
86-
assert not is_valid_name(" ab ")
87-
# invalid: contains characters outside of letters/whitespace/'/-
88-
assert not is_valid_name("1")
89-
# invalid: too long
90-
assert not is_valid_name("a" * 101)
104+
assert not is_valid_name(" leading whitespace")
105+
assert not is_valid_name("trailing whitespace ")
106+
assert not is_valid_name(" surrounding whitespace ")
107+
# invalid: disallowed characters
108+
assert not is_valid_name("digits123")
109+
assert not is_valid_name("email@domain.com")
110+
assert not is_valid_name("Frosty the ☃️")
111+
assert not is_valid_name("exclamative!")
112+
assert not is_valid_name("interrogative?")
113+
assert not is_valid_name("under_score")
114+
assert not is_valid_name("(╯‵□′)╯︵┻━┻")
91115

92116

93117
def test_parse_date() -> None:

app/web/utils/validation.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// taken from backend
2-
export const nameValidationPattern = /^[\p{L}'-]+(\s+[\p{L}'-]+)*$/u;
2+
export const nameValidationPattern =
3+
/^(?!\p{Zs})[\p{L}\p{M}\p{Zs}\p{Pi}\p{Pf}\p{Pd},.'"·&/|]+(?<!\p{Zs})$/u;
34
export const nameMinLength = 2;
45
export const nameMaxLength = 100;
56
export const usernameValidationPattern = /^[a-z][0-9a-z_]*[a-z0-9]$/i;

0 commit comments

Comments
 (0)