From 43038034fd207d8d1353a333bf07d2cde46fb21c Mon Sep 17 00:00:00 2001 From: Giancarlo Buomprisco Date: Tue, 23 Dec 2025 16:49:58 +0100 Subject: [PATCH] Disallow non latin characters team name (#433) * feat: add validation for team names to restrict non-Latin characters - Implemented a new test case to ensure team accounts cannot be created using non-Latin characters, including Cyrillic, Chinese, Japanese, Arabic, and emoji. - Updated the team name schema to include a regex validation for Latin characters only. - Added corresponding error message in the localization file for non-Latin character restrictions. * chore: bump version to 2.21.18 in package.json --- .../tests/team-accounts/team-accounts.spec.ts | 50 +++++++++++++++++++ apps/web/public/locales/en/teams.json | 1 + package.json | 2 +- .../src/schema/create-team.schema.ts | 13 +++++ 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/apps/e2e/tests/team-accounts/team-accounts.spec.ts b/apps/e2e/tests/team-accounts/team-accounts.spec.ts index a6cdf8252..2db63044f 100644 --- a/apps/e2e/tests/team-accounts/team-accounts.spec.ts +++ b/apps/e2e/tests/team-accounts/team-accounts.spec.ts @@ -175,6 +175,56 @@ test.describe('Team Accounts', () => { await teamAccounts.tryCreateTeam('Test Name]'); await expectError(); }); + + test('cannot create a Team account using non-latin characters', async ({ + page, + }) => { + const teamAccounts = new TeamAccountsPageObject(page); + await teamAccounts.createTeam(); + + await teamAccounts.openAccountsSelector(); + await page.click('[data-test="create-team-account-trigger"]'); + + function expectNonLatinError() { + return expect( + page.getByText( + 'This name can only contain Latin characters (a-z), numbers, spaces, and hyphens.', + ), + ).toBeVisible(); + } + + // Test Cyrillic characters + await teamAccounts.tryCreateTeam('Тест Команда'); + await expectNonLatinError(); + + // Test Chinese characters + await teamAccounts.tryCreateTeam('测试团队'); + await expectNonLatinError(); + + // Test Japanese characters + await teamAccounts.tryCreateTeam('テストチーム'); + await expectNonLatinError(); + + // Test Arabic characters + await teamAccounts.tryCreateTeam('فريق اختبار'); + await expectNonLatinError(); + + // Test mixed Latin and non-Latin + await teamAccounts.tryCreateTeam('Test Команда'); + await expectNonLatinError(); + + // Test emoji + await teamAccounts.tryCreateTeam('Test Team 🚀'); + await expectNonLatinError(); + + // Ensure valid Latin names still work (should NOT show error) + await teamAccounts.tryCreateTeam('Valid Team Name 123'); + await expect( + page.getByText( + 'This name can only contain Latin characters (a-z), numbers, spaces, and hyphens.', + ), + ).not.toBeVisible(); + }); }); test.describe('Team Account Deletion', () => { diff --git a/apps/web/public/locales/en/teams.json b/apps/web/public/locales/en/teams.json index ef405e48d..4faa8fe0f 100644 --- a/apps/web/public/locales/en/teams.json +++ b/apps/web/public/locales/en/teams.json @@ -160,6 +160,7 @@ "leaveTeamInputDescription": "By leaving the team, you will no longer have access to it.", "reservedNameError": "This name is reserved. Please choose a different one.", "specialCharactersError": "This name cannot contain special characters. Please choose a different one.", + "nonLatinCharactersError": "This name can only contain Latin characters (a-z), numbers, spaces, and hyphens.", "checkingPolicies": "Loading. Please wait...", "policyCheckError": "We are unable to verify invitations restrictions. Please try again.", "invitationsBlockedMultiple": "Invitations are currently not allowed for the following reasons:", diff --git a/package.json b/package.json index e0299b6bc..1c7c22e2a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "next-supabase-saas-kit-turbo", - "version": "2.21.17", + "version": "2.21.18", "private": true, "sideEffects": false, "engines": { diff --git a/packages/features/team-accounts/src/schema/create-team.schema.ts b/packages/features/team-accounts/src/schema/create-team.schema.ts index 44da2e136..442940689 100644 --- a/packages/features/team-accounts/src/schema/create-team.schema.ts +++ b/packages/features/team-accounts/src/schema/create-team.schema.ts @@ -14,6 +14,11 @@ const RESERVED_NAMES_ARRAY = [ const SPECIAL_CHARACTERS_REGEX = /[!@#$%^&*()+=[\]{};':"\\|,.<>/?]/; +/** + * Regex that matches only Latin characters (a-z, A-Z), numbers, spaces, and hyphens + */ +const LATIN_ONLY_REGEX = /^[a-zA-Z0-9\s-]+$/; + /** * @name TeamNameSchema */ @@ -31,6 +36,14 @@ export const TeamNameSchema = z message: 'teams:specialCharactersError', }, ) + .refine( + (name) => { + return LATIN_ONLY_REGEX.test(name); + }, + { + message: 'teams:nonLatinCharactersError', + }, + ) .refine( (name) => { return !RESERVED_NAMES_ARRAY.includes(name.toLowerCase());