From cd9ea51039506098b75862d574420baaa34fdc8d Mon Sep 17 00:00:00 2001 From: Yvan Wang <131545713+BootstrapperSBL@users.noreply.github.com> Date: Sun, 19 Apr 2026 00:23:14 +0800 Subject: [PATCH] fix(hub): use rfcEmail validator to allow IDN/Punycode email addresses (#1935) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit valibot's email() action uses a domain-label regex that disallows the -- sequence, so Punycode ACE labels like xn--mnchen-3ya.de (the ASCII form of münchen.de) are incorrectly rejected. Switching to rfcEmail() applies the RFC 5321 domain-label pattern, which allows hyphens within labels and therefore accepts both standard and internationalized domain names. --- internal/site/src/components/login/auth-form.tsx | 2 +- internal/site/src/components/routes/settings/notifications.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/site/src/components/login/auth-form.tsx b/internal/site/src/components/login/auth-form.tsx index c15ff61d..eab87576 100644 --- a/internal/site/src/components/login/auth-form.tsx +++ b/internal/site/src/components/login/auth-form.tsx @@ -17,7 +17,7 @@ import { toast } from "../ui/use-toast" import { OtpInputForm } from "./otp-forms" const honeypot = v.literal("") -const emailSchema = v.pipe(v.string(), v.email(t`Invalid email address.`)) +const emailSchema = v.pipe(v.string(), v.rfcEmail(t`Invalid email address.`)) const passwordSchema = v.pipe( v.string(), v.minLength(8, t`Password must be at least 8 characters.`), diff --git a/internal/site/src/components/routes/settings/notifications.tsx b/internal/site/src/components/routes/settings/notifications.tsx index 3650d24b..07af5c35 100644 --- a/internal/site/src/components/routes/settings/notifications.tsx +++ b/internal/site/src/components/routes/settings/notifications.tsx @@ -24,7 +24,7 @@ interface ShoutrrrUrlCardProps { } const NotificationSchema = v.object({ - emails: v.array(v.pipe(v.string(), v.email())), + emails: v.array(v.pipe(v.string(), v.rfcEmail())), webhooks: v.array(v.pipe(v.string(), v.url())), })