Skip to content

Commit 83a65a8

Browse files
authored
Merge pull request #158 from oasisprotocol/mz/validationFix-2
Mimic Go's net/mail.ParseAddress email validation
2 parents 2bd6c4d + 842a8e3 commit 83a65a8

File tree

1 file changed

+42
-4
lines changed

1 file changed

+42
-4
lines changed

src/pages/CreateApp/types.ts

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,48 @@ export const metadataFormSchema = z.object({
66
message: 'Name is required.',
77
}),
88
author: z.literal('').or(
9-
z.string().regex(/^(.+)\s+<([^@\s]+@[^@\s.]+(?:\.[^@\s.]+)*\.[a-zA-Z]{2,})>$/, {
10-
message:
11-
'Author must follow the format "Name <valid_email>". The email address must be in square brackets.',
12-
}),
9+
z.string().refine(
10+
value => {
11+
// This code is auto generated based on Go's net/mail.ParseAddress
12+
// Accept formats: email@domain.com, Name <email@domain.com>, "Name" <email@domain.com>, <email@domain.com>
13+
14+
// Rejects consecutive dots, leading/trailing dots, and other invalid patterns
15+
const emailRegex =
16+
/^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?@[a-zA-Z0-9]([a-zA-Z0-9.-]*[a-zA-Z0-9])?\.[a-zA-Z]{2,}$/
17+
18+
// Trim whitespace
19+
const trimmed = value.trim()
20+
21+
// Case 1: Simple email address (user@domain.com)
22+
if (emailRegex.test(trimmed)) {
23+
return true
24+
}
25+
26+
// Case 2: Email in angle brackets only (<user@domain.com>)
27+
const angleBracketsOnly = /^<([^<>]+)>$/.exec(trimmed)
28+
if (angleBracketsOnly) {
29+
return emailRegex.test(angleBracketsOnly[1].trim())
30+
}
31+
32+
// Case 3: Display name with email in angle brackets
33+
// Matches: Name <email>, "Name" <email>, "Name with spaces" <email>
34+
const displayNameWithEmail = /^(.+?)\s*<([^<>]+)>$/.exec(trimmed)
35+
if (displayNameWithEmail) {
36+
const displayName = displayNameWithEmail[1].trim()
37+
const email = displayNameWithEmail[2].trim()
38+
39+
// Display name should not be empty and email should be valid
40+
if (displayName.length > 0 && emailRegex.test(email)) {
41+
return true
42+
}
43+
}
44+
45+
return false
46+
},
47+
{
48+
message: 'Author must be a valid email address or in the format "Name <email@domain.com>".',
49+
},
50+
),
1351
),
1452
description: z.string().min(1, {
1553
message: 'Description is required.',

0 commit comments

Comments
 (0)