From 4e883a007fa06256161ba28e3fd23107192afc9c Mon Sep 17 00:00:00 2001 From: surafel <72102647+surafel58@users.noreply.github.com> Date: Mon, 6 Oct 2025 19:37:00 +0300 Subject: [PATCH] fix(url): handle empty and root path in withPath, prevent double slashes, add tests (#5091) --- packages/better-auth/src/init.test.ts | 26 ++++++++++++++++++++++++++ packages/better-auth/src/utils/url.ts | 12 ++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/packages/better-auth/src/init.test.ts b/packages/better-auth/src/init.test.ts index 7f3eeb354a..bf419a6fa0 100644 --- a/packages/better-auth/src/init.test.ts +++ b/packages/better-auth/src/init.test.ts @@ -219,4 +219,30 @@ describe("init", async () => { }); expect(initFn).toHaveBeenCalled(); }); + + it("handles empty basePath", async () => { + const res = await init({ + database, + baseURL: "http://localhost:5147/", + basePath: "", + }); + expect(res.baseURL).toBe("http://localhost:5147"); + }); + + it("handles root basePath", async () => { + const res = await init({ + database, + baseURL: "http://localhost:5147/", + basePath: "/", + }); + expect(res.baseURL).toBe("http://localhost:5147"); + }); + + it("normalizes trailing slashes with default path", async () => { + const res = await init({ + database, + baseURL: "http://localhost:5147////", + }); + expect(res.baseURL).toBe("http://localhost:5147/api/auth"); + }); }); diff --git a/packages/better-auth/src/utils/url.ts b/packages/better-auth/src/utils/url.ts index 82214cf36f..367454bede 100644 --- a/packages/better-auth/src/utils/url.ts +++ b/packages/better-auth/src/utils/url.ts @@ -4,7 +4,8 @@ import { BetterAuthError } from "../error"; function checkHasPath(url: string): boolean { try { const parsedUrl = new URL(url); - return parsedUrl.pathname !== "/"; + const pathname = parsedUrl.pathname.replace(/\/+$/, "") || "/"; + return pathname !== "/"; } catch (error) { throw new BetterAuthError( `Invalid base URL: ${url}. Please provide a valid base URL.`, @@ -17,8 +18,15 @@ function withPath(url: string, path = "/api/auth") { if (hasPath) { return url; } + + const trimmedUrl = url.replace(/\/+$/, ""); + + if (!path || path === "/") { + return trimmedUrl; + } + path = path.startsWith("/") ? path : `/${path}`; - return `${url.replace(/\/+$/, "")}${path}`; + return `${trimmedUrl}${path}`; } export function getBaseURL(