chore: team url slugify and profanity filter

Signed-off-by: Adithya Krishna <adi@documenso.com>
This commit is contained in:
Adithya Krishna
2023-12-27 18:57:38 +05:30
parent d546907c53
commit 39869c46a3
4 changed files with 73 additions and 4 deletions

View File

@ -0,0 +1,25 @@
const diacriticRegex = /\p{Diacritic}/gu;
const nonAlphanumericRegex = /[^.\p{L}\p{N}\p{Zs}\p{Emoji}]+/gu;
const whitespaceUnderscoreRegex = /[\s_#]+/g;
const dashStartRegex = /^-+/;
const multipleDotsRegex = /\.{2,}/g;
export const generateURLSlug = (str: string, forDisplayingInput?: boolean) => {
if (!str) {
return '';
}
const slug = str
.toLowerCase()
.trim()
.normalize('NFD')
.replace(diacriticRegex, '')
.replace(nonAlphanumericRegex, '-')
.replace(whitespaceUnderscoreRegex, '-')
.replace(dashStartRegex, '') // Remove dashes from start
.replace(multipleDotsRegex, '.'); // Replace consecutive periods with a single period
return forDisplayingInput ? slug : slug.replace(/-*$/g, ''); // Remove dashes from end
};
export default generateURLSlug;

View File

@ -17,10 +17,13 @@
"@trpc/next": "^10.36.0",
"@trpc/react-query": "^10.36.0",
"@trpc/server": "^10.36.0",
"bad-words": "^3.0.4",
"luxon": "^3.4.0",
"superjson": "^1.13.1",
"ts-pattern": "^5.0.5",
"zod": "^3.22.4"
},
"devDependencies": {}
"devDependencies": {
"@types/bad-words": "^3.0.3"
}
}

View File

@ -2,6 +2,12 @@ import { z } from 'zod';
import { TeamMemberRole } from '@documenso/prisma/client';
import { generateURLSlug } from '@documenso/lib/utils/generate-url-slug';
import badWords from 'bad-words';
const filter = new badWords();
const GenericFindQuerySchema = z.object({
term: z.string().optional(),
page: z.number().optional(),
@ -20,7 +26,12 @@ export const ZAddTeamEmailVerificationMutationSchema = z.object({
export const ZCreateTeamMutationSchema = z.object({
name: z.string().min(1),
url: z.string().min(1), // Todo: Teams - Apply lowercase, disallow certain symbols, disallow profanity.
url: z.string().min(1).refine((value) => {
const generatedSlug = generateURLSlug(value);
return !filter.isProfane(value.toLowerCase()) && generatedSlug === value.toLowerCase();
}, {
message: 'URL contains inappropriate language or unsupported characters',
}),
});
export const ZCreateTeamMemberInvitesMutationSchema = z.object({
@ -100,7 +111,12 @@ export const ZUpdateTeamMutationSchema = z.object({
data: z.object({
// Todo: Teams
name: z.string().min(1),
url: z.string().min(1), // Todo: Apply regex. Todo: lowercase, etc
url: z.string().min(1).refine((value) => {
const generatedSlug = generateURLSlug(value);
return !filter.isProfane(value.toLowerCase()) && generatedSlug === value.toLowerCase();
}, {
message: 'URL contains inappropriate language or unsupported characters',
}),
}),
});