Stage 17: cap display-name special characters at 5 (ui + backend)
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Successful in 35s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m3s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Successful in 35s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m3s
display_name validation gains a rule: at most 5 special characters — the '.' / '_' punctuation (spaces, which separate words, don't count) — so a still-well-formed name can't be mostly punctuation. Mirrored in the Go ValidateDisplayName and the UI validDisplayName; both unit-tested (5 ok, 6 rejected, 'J. R. R. Tolkien' ok). Docs: FUNCTIONAL (+ _ru).
This commit is contained in:
@@ -19,6 +19,9 @@ describe('validDisplayName', () => {
|
||||
['Name2', false],
|
||||
['', false],
|
||||
['a'.repeat(33), false],
|
||||
['a.a.a.a.a.a', true], // 5 dots — at the special-char limit
|
||||
['a.a.a.a.a.a.a', false], // 6 dots — over the limit
|
||||
['J. R. R. Tolkien', true], // 3 dots; spaces are not special
|
||||
])('%s -> %s', (name, ok) => {
|
||||
expect(validDisplayName(name)).toBe(ok);
|
||||
});
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
/** maxDisplayName caps the editable display name in runes. */
|
||||
export const maxDisplayName = 32;
|
||||
|
||||
/** maxDisplayNameSpecials caps the total special characters (the "." / "_" separators — every
|
||||
* rune that is neither a letter nor a space) a display name may carry. Mirrors the Go rule. */
|
||||
export const maxDisplayNameSpecials = 5;
|
||||
|
||||
/** maxAwayMinutes bounds the daily away window's length (12 h). */
|
||||
export const maxAwayMinutes = 12 * 60;
|
||||
|
||||
@@ -17,7 +21,10 @@ const displayNameRe = /^\p{L}+(?:(?:[._] ?| )\p{L}+)*\.?$/u;
|
||||
/** displayNameError returns true when the trimmed name is a valid display name. */
|
||||
export function validDisplayName(raw: string): boolean {
|
||||
const name = raw.trim();
|
||||
return name.length > 0 && [...name].length <= maxDisplayName && displayNameRe.test(name);
|
||||
const chars = [...name];
|
||||
if (name.length === 0 || chars.length > maxDisplayName || !displayNameRe.test(name)) return false;
|
||||
const specials = chars.filter((c) => c !== ' ' && !/\p{L}/u.test(c)).length;
|
||||
return specials <= maxDisplayNameSpecials;
|
||||
}
|
||||
|
||||
// A pragmatic email check (the backend re-validates with net/mail). Rejects spaces
|
||||
|
||||
Reference in New Issue
Block a user