Compare commits

...

1 Commits

Author SHA1 Message Date
97b14edbaa fix(api): skip CSRF for Bearer-authenticated requests
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
2026-03-01 13:01:06 -06:00
2 changed files with 16 additions and 0 deletions

View File

@@ -87,6 +87,17 @@ describe("CsrfGuard", () => {
}); });
describe("State-changing methods requiring CSRF", () => { describe("State-changing methods requiring CSRF", () => {
it("should allow POST with Bearer auth without CSRF token", () => {
const context = createContext(
"POST",
{},
{ authorization: "Bearer api-token" },
false,
"user-123"
);
expect(guard.canActivate(context)).toBe(true);
});
it("should reject POST without CSRF token", () => { it("should reject POST without CSRF token", () => {
const context = createContext("POST", {}, {}, false, "user-123"); const context = createContext("POST", {}, {}, false, "user-123");
expect(() => guard.canActivate(context)).toThrow(ForbiddenException); expect(() => guard.canActivate(context)).toThrow(ForbiddenException);

View File

@@ -57,6 +57,11 @@ export class CsrfGuard implements CanActivate {
return true; return true;
} }
const authHeader = request.headers.authorization;
if (typeof authHeader === "string" && authHeader.startsWith("Bearer ")) {
return true;
}
// Get CSRF token from cookie and header // Get CSRF token from cookie and header
const cookies = request.cookies as Record<string, string> | undefined; const cookies = request.cookies as Record<string, string> | undefined;
const cookieToken = cookies?.["csrf-token"]; const cookieToken = cookies?.["csrf-token"];