fix(context): use fallback URL as initial baseURL for dynamic config (#8447)

When using dynamic baseURL with allowedHosts, the initial AuthContext.baseURL
was set to empty string. This caused endpoints accessed outside request context
(e.g. .well-known/openid-configuration) to produce broken URLs.
This commit is contained in:
Alex Yang
2026-03-06 10:39:48 -08:00
parent 98cd201a17
commit 43357aaab7
2 changed files with 25 additions and 7 deletions
@@ -192,6 +192,20 @@ describe("auth with dynamic baseURL (allowedHosts)", () => {
).rejects.toThrow('Host "evil.com" is not in the allowed hosts list');
});
/**
* @see https://github.com/better-auth/better-auth/issues/8447
*/
test("should use fallback as initial baseURL for non-request contexts", async () => {
const { auth } = await getTestInstance({
baseURL: {
allowedHosts: ["localhost:*"],
fallback: "http://localhost:5173",
},
});
const ctx = await auth.$context;
expect(ctx.baseURL).toBe("http://localhost:5173/api/auth");
});
test("should use fallback for disallowed host", async () => {
let baseURL: string | undefined;
const { customFetchImpl } = await getTestInstance({
@@ -126,12 +126,16 @@ export async function createAuthContext<Options extends BetterAuthOptions>(
}
}
const baseURL = isDynamicConfig
? undefined
: getBaseURL(
typeof options.baseURL === "string" ? options.baseURL : undefined,
options.basePath,
);
const basePath = options.basePath || "/api/auth";
const baseURL =
isDynamicConfig && isDynamicBaseURLConfig(options.baseURL)
? options.baseURL.fallback
? getBaseURL(options.baseURL.fallback, basePath)
: getBaseURL(undefined, basePath, undefined, true)
: getBaseURL(
typeof options.baseURL === "string" ? options.baseURL : undefined,
basePath,
);
if (!baseURL && !isDynamicConfig) {
logger.warn(
@@ -178,7 +182,7 @@ Most of the features of Better Auth will not work correctly.`,
: baseURL
? new URL(baseURL).origin
: "",
basePath: options.basePath || "/api/auth",
basePath,
plugins: plugins.concat(internalPlugins),
};