fix(storefront-chat): normalize shop domain matching

Handle shop domain variants (protocol/trailing slash/case) when resolving storefront chat stores so enabled widgets do not return false 403 Widget disabled responses.

Made-with: Cursor
This commit is contained in:
talatops 2026-04-02 22:17:49 +05:00
parent 8e25dd88e8
commit 53c2ed7a4e

View File

@ -9,6 +9,24 @@ type StorefrontMessagePayload = {
customerEmail?: string | null customerEmail?: string | null
} }
function normalizeShopDomain(input: string) {
return input
.trim()
.toLowerCase()
.replace(/^https?:\/\//i, "")
.replace(/\/$/, "")
}
function shopVariants(cleanDomain: string) {
if (!cleanDomain) return []
const v = new Set<string>()
v.add(cleanDomain)
v.add(`${cleanDomain}/`)
v.add(`https://${cleanDomain}`)
v.add(`http://${cleanDomain}`)
return Array.from(v)
}
export async function POST(req: Request) { export async function POST(req: Request) {
try { try {
const p = prisma as any const p = prisma as any
@ -27,7 +45,7 @@ export async function POST(req: Request) {
const trimmedContent = content.trim() const trimmedContent = content.trim()
const trimmedVisitorId = visitorId.trim() const trimmedVisitorId = visitorId.trim()
const trimmedShop = shop.trim() const normalizedShop = normalizeShopDomain(shop)
// Guardrails (v1): keep it small, avoid empty spam. // Guardrails (v1): keep it small, avoid empty spam.
if (trimmedContent.length < 1) { if (trimmedContent.length < 1) {
@ -40,11 +58,13 @@ export async function POST(req: Request) {
return NextResponse.json({ message: "Invalid visitorId" }, { status: 400 }) return NextResponse.json({ message: "Invalid visitorId" }, { status: 400 })
} }
const store = await p.store.findFirst({ const variants = shopVariants(normalizedShop)
where: { shopifyDomain: trimmedShop }, const stores = await p.store.findMany({
where: { shopifyDomain: { in: variants } },
select: { id: true, storefrontChatEnabled: true } select: { id: true, storefrontChatEnabled: true }
}) })
const store = stores.find((s: any) => Boolean(s.storefrontChatEnabled)) || stores[0]
if (!store) { if (!store) {
return NextResponse.json({ message: "Store not found" }, { status: 404 }) return NextResponse.json({ message: "Store not found" }, { status: 404 })
} }
@ -142,11 +162,15 @@ export async function GET(req: Request) {
return NextResponse.json({ message: "Missing visitorId" }, { status: 400 }) return NextResponse.json({ message: "Missing visitorId" }, { status: 400 })
} }
const store = await p.store.findFirst({ const normalizedShop = normalizeShopDomain(shop)
where: { shopifyDomain: shop }, const variants = shopVariants(normalizedShop)
const stores = await p.store.findMany({
where: { shopifyDomain: { in: variants } },
select: { id: true, storefrontChatEnabled: true } select: { id: true, storefrontChatEnabled: true }
}) })
const store = stores.find((s: any) => Boolean(s.storefrontChatEnabled)) || stores[0]
if (!store) { if (!store) {
return NextResponse.json({ message: "Store not found" }, { status: 404 }) return NextResponse.json({ message: "Store not found" }, { status: 404 })
} }