From efabce436d3d4828c9cefbfcb45ccf806dea2b56 Mon Sep 17 00:00:00 2001 From: "LamTrinh.Dev" Date: Sun, 18 Oct 2026 00:51:15 +0700 Subject: [PATCH 1/2] fix: match service domains exactly instead of by substring Added isOwnDomain function to check for exact domain matches in a case-insensitive manner. --- api/internal/transport/api/alias.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/api/internal/transport/api/alias.go b/api/internal/transport/api/alias.go index 89f47756..d83c31e0 100644 --- a/api/internal/transport/api/alias.go +++ b/api/internal/transport/api/alias.go @@ -279,6 +279,19 @@ func (h *Handler) ExportAliases(c *fiber.Ctx) error { return c.SendString(b.String()) } +// isOwnDomain reports whether domain exactly matches one of the comma-separated +// service domains, case-insensitively. Unlike strings.Contains, it doesn't match +// substrings (e.g. "vpn.net" inside "ivpn.net") and ignores casing differences. +func isOwnDomain(domains string, domain string) bool { + for _, d := range strings.Split(domains, ",") { + if strings.EqualFold(strings.TrimSpace(d), domain) { + return true + } + } + + return false +} + // resolveDomain resolves an AliasReq-style domain value - either a plain built-in domain // name or a custom domain's UUID - to its FQDN. ok is false if domainParam doesn't resolve // to a valid domain accessible to userID. @@ -292,7 +305,7 @@ func (h *Handler) resolveDomain(ctx context.Context, userID string, domainParam return fqdn.Name, true, true } - if !strings.Contains(h.Cfg.Domains, domain) { + if !isOwnDomain(h.Cfg.Domains, domain) { return "", false, false } From a6b1b883b2129298b6ce0cb477ffdf516ffab130 Mon Sep 17 00:00:00 2001 From: "LamTrinh.Dev" Date: Sun, 18 Oct 2026 00:55:05 +0700 Subject: [PATCH 2/2] fix: match service domains exactly instead of by substring --- api/internal/transport/api/recipient.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/internal/transport/api/recipient.go b/api/internal/transport/api/recipient.go index e3cb3293..fc7214db 100644 --- a/api/internal/transport/api/recipient.go +++ b/api/internal/transport/api/recipient.go @@ -104,8 +104,8 @@ func (h *Handler) PostRecipient(c *fiber.Ctx) error { }) } - domain := strings.Split(req.Email, "@") - if strings.Contains(h.Cfg.Domains, domain[1]) { + parts := strings.Split(req.Email, "@") + if isOwnDomain(h.Cfg.Domains, parts[len(parts)-1]) { return c.Status(400).JSON(fiber.Map{ "error": ErrInvalidDomain, })