Merge branch 'canary' into 01-16-2026/fix-readme

This commit is contained in:
Taesu
2026-01-17 02:15:50 +09:00
committed by GitHub
4 changed files with 66 additions and 1 deletions

View File

@@ -543,7 +543,8 @@ export const auth = betterAuth({
})) | false | "serial" | "uuid",
defaultFindManyLimit: 100,
experimentalJoins: false,
}
},
skipTrailingSlashes: true
},
})
```
@@ -557,6 +558,7 @@ export const auth = betterAuth({
- `defaultCookieAttributes`: Default attributes for all cookies
- `cookiePrefix`: Prefix for cookies
- `database`: Database configuration options
- `skipTrailingSlashes`: Skip trailing slash validation in route matching. (default: `false`)
- OAuth state configuration options (`storeStateStrategy`, `skipStateCookieCheck`) are now part of the `account` option
## `logger`

View File

@@ -183,3 +183,59 @@ describe("onRequest chain", () => {
expect(result.error?.status).toBe(403);
});
});
describe("skipTrailingSlashes option", () => {
it("should return 404 for trailing slash requests by default", async () => {
const { auth } = await getTestInstance({});
const response = await auth.handler(
new Request("http://localhost:3000/api/auth/ok/", {
method: "GET",
}),
);
expect(response.status).toBe(404);
});
it("should handle trailing slash requests when skipTrailingSlashes is enabled", async () => {
const { auth } = await getTestInstance({
advanced: {
skipTrailingSlashes: true,
},
});
const response = await auth.handler(
new Request("http://localhost:3000/api/auth/ok/", {
method: "GET",
}),
);
expect(response.status).toBe(200);
const body = await response.json();
expect(body).toEqual({ ok: true });
});
it("should work with POST requests with trailing slash", async () => {
const { auth } = await getTestInstance({
advanced: {
skipTrailingSlashes: true,
},
});
// POST to sign-up endpoint with trailing slash
const response = await auth.handler(
new Request("http://localhost:3000/api/auth/sign-up/email/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
email: "test2@example.com",
password: "password123",
name: "Test User 2",
}),
}),
);
// Should reach the endpoint (probably fail validation, but not 404)
expect(response.status).not.toBe(404);
});
});

View File

@@ -273,6 +273,7 @@ export const router = <Option extends BetterAuthOptions>(
...middlewares,
],
allowedMediaTypes: ["application/json"],
skipTrailingSlashes: options.advanced?.skipTrailingSlashes ?? false,
async onRequest(req) {
//handle disabled paths
const disabledPaths = ctx.options.disabledPaths || [];

View File

@@ -305,6 +305,12 @@ export type BetterAuthAdvancedOptions = {
backgroundTasks?: {
handler: (promise: Promise<void>) => void;
};
/**
* Skip trailing slash validation in route matching
*
* @default false
*/
skipTrailingSlashes?: boolean | undefined;
};
export type BetterAuthOptions = {