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
This commit is contained in:
Giancarlo Buomprisco
2025-12-23 16:49:58 +01:00
committed by GitHub
parent c4a961e93d
commit 43038034fd
4 changed files with 65 additions and 1 deletions

View File

@@ -175,6 +175,56 @@ test.describe('Team Accounts', () => {
await teamAccounts.tryCreateTeam('Test Name]'); await teamAccounts.tryCreateTeam('Test Name]');
await expectError(); 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', () => { test.describe('Team Account Deletion', () => {

View File

@@ -160,6 +160,7 @@
"leaveTeamInputDescription": "By leaving the team, you will no longer have access to it.", "leaveTeamInputDescription": "By leaving the team, you will no longer have access to it.",
"reservedNameError": "This name is reserved. Please choose a different one.", "reservedNameError": "This name is reserved. Please choose a different one.",
"specialCharactersError": "This name cannot contain special characters. 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...", "checkingPolicies": "Loading. Please wait...",
"policyCheckError": "We are unable to verify invitations restrictions. Please try again.", "policyCheckError": "We are unable to verify invitations restrictions. Please try again.",
"invitationsBlockedMultiple": "Invitations are currently not allowed for the following reasons:", "invitationsBlockedMultiple": "Invitations are currently not allowed for the following reasons:",

View File

@@ -1,6 +1,6 @@
{ {
"name": "next-supabase-saas-kit-turbo", "name": "next-supabase-saas-kit-turbo",
"version": "2.21.17", "version": "2.21.18",
"private": true, "private": true,
"sideEffects": false, "sideEffects": false,
"engines": { "engines": {

View File

@@ -14,6 +14,11 @@ const RESERVED_NAMES_ARRAY = [
const SPECIAL_CHARACTERS_REGEX = /[!@#$%^&*()+=[\]{};':"\\|,.<>/?]/; 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 * @name TeamNameSchema
*/ */
@@ -31,6 +36,14 @@ export const TeamNameSchema = z
message: 'teams:specialCharactersError', message: 'teams:specialCharactersError',
}, },
) )
.refine(
(name) => {
return LATIN_ONLY_REGEX.test(name);
},
{
message: 'teams:nonLatinCharactersError',
},
)
.refine( .refine(
(name) => { (name) => {
return !RESERVED_NAMES_ARRAY.includes(name.toLowerCase()); return !RESERVED_NAMES_ARRAY.includes(name.toLowerCase());