chore: bump version to 2.23.2 and enhance team account creation (#440)

* chore: bump version to 2.23.2 and enhance team account creation

- Updated application version from 2.23.1 to 2.23.2 in package.json.
- Enhanced team account creation to support slugs for non-Latin names, including validation and UI updates.
- Updated localization files to reflect new slug requirements and error messages.
- Refactored related schemas and server actions to accommodate slug handling in team account creation and updates.

* refactor: remove old trigger and function for adding current user to new account

- Dropped the trigger "add_current_user_to_new_account" and the associated function from the database schema.
- Updated permissions for the function public.create_team_account to ensure proper access control.
This commit is contained in:
Giancarlo Buomprisco
2026-01-08 14:18:13 +01:00
committed by GitHub
parent e1bfbc8106
commit 0636f8cf11
21 changed files with 2042 additions and 1619 deletions

View File

@@ -15,12 +15,51 @@ const RESERVED_NAMES_ARRAY = [
const SPECIAL_CHARACTERS_REGEX = /[!@#$%^&*()+=[\]{};':"\\|,.<>/?]/;
/**
* Regex that matches only Latin characters (a-z, A-Z), numbers, spaces, and hyphens
* Regex that detects non-Latin scripts (Korean, Japanese, Chinese, Cyrillic, Arabic, Hebrew, Thai)
* Does NOT match extended Latin characters like café, naïve, Zürich
*/
const LATIN_ONLY_REGEX = /^[a-zA-Z0-9\s-]+$/;
export const NON_LATIN_REGEX =
/[\u0400-\u04FF\u0590-\u05FF\u0600-\u06FF\u0E00-\u0E7F\u1100-\u11FF\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FFF\uAC00-\uD7AF]/;
/**
* Regex for valid slugs: lowercase letters, numbers, and hyphens
* Must start and end with alphanumeric, hyphens only in middle
*/
const SLUG_REGEX = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
/**
* @name containsNonLatinCharacters
* @description Checks if a string contains non-Latin characters
*/
export function containsNonLatinCharacters(value: string): boolean {
return NON_LATIN_REGEX.test(value);
}
/**
* @name SlugSchema
* @description Schema for validating URL-friendly slugs
*/
export const SlugSchema = z
.string({
description: 'URL-friendly identifier for the team',
})
.min(2)
.max(50)
.regex(SLUG_REGEX, {
message: 'teams:invalidSlugError',
})
.refine(
(slug) => {
return !RESERVED_NAMES_ARRAY.includes(slug.toLowerCase());
},
{
message: 'teams:reservedNameError',
},
);
/**
* @name TeamNameSchema
* @description Schema for team name - allows non-Latin characters
*/
export const TeamNameSchema = z
.string({
@@ -36,14 +75,6 @@ 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());
@@ -56,7 +87,27 @@ export const TeamNameSchema = z
/**
* @name CreateTeamSchema
* @description Schema for creating a team account
* When the name contains non-Latin characters, a slug is required
*/
export const CreateTeamSchema = z.object({
name: TeamNameSchema,
});
export const CreateTeamSchema = z
.object({
name: TeamNameSchema,
// Transform empty strings to undefined before validation
slug: z.preprocess(
(val) => (val === '' ? undefined : val),
SlugSchema.optional(),
),
})
.refine(
(data) => {
if (containsNonLatinCharacters(data.name)) {
return !!data.slug;
}
return true;
},
{
message: 'teams:slugRequiredForNonLatinName',
path: ['slug'],
},
);

View File

@@ -1,12 +1,34 @@
import { z } from 'zod';
import { TeamNameSchema } from './create-team.schema';
import {
SlugSchema,
TeamNameSchema,
containsNonLatinCharacters,
} from './create-team.schema';
export const TeamNameFormSchema = z.object({
name: TeamNameSchema,
});
export const TeamNameFormSchema = z
.object({
name: TeamNameSchema,
// Transform empty strings to undefined before validation
newSlug: z.preprocess(
(val) => (val === '' ? undefined : val),
SlugSchema.optional(),
),
})
.refine(
(data) => {
if (containsNonLatinCharacters(data.name)) {
return !!data.newSlug;
}
return true;
},
{
message: 'teams:slugRequiredForNonLatinName',
path: ['newSlug'],
},
);
export const UpdateTeamNameSchema = TeamNameFormSchema.merge(
export const UpdateTeamNameSchema = TeamNameFormSchema.and(
z.object({
slug: z.string().min(1).max(255),
path: z.string().min(1).max(255),