mirror of
https://github.com/kjanat/livedash-node.git
synced 2026-01-16 12:52:09 +01:00
feat: implement comprehensive CSRF protection
This commit is contained in:
41
lib/trpc.ts
41
lib/trpc.ts
@ -15,6 +15,7 @@ import type { z } from "zod";
|
||||
import { authOptions } from "./auth";
|
||||
import { prisma } from "./prisma";
|
||||
import { validateInput } from "./validation";
|
||||
import { CSRFProtection } from "./csrf";
|
||||
|
||||
/**
|
||||
* Create context for tRPC requests
|
||||
@ -151,6 +152,38 @@ export const companyProcedure = publicProcedure.use(enforceCompanyAccess);
|
||||
export const adminProcedure = publicProcedure.use(enforceAdminAccess);
|
||||
export const validatedProcedure = createValidatedProcedure;
|
||||
|
||||
/**
|
||||
* CSRF protection middleware for state-changing operations
|
||||
*/
|
||||
const enforceCSRFProtection = t.middleware(async ({ ctx, next }) => {
|
||||
// Extract request from context
|
||||
const request = ctx.req as Request;
|
||||
|
||||
// Skip CSRF validation for GET requests
|
||||
if (request.method === "GET") {
|
||||
return next({ ctx });
|
||||
}
|
||||
|
||||
// Convert to NextRequest for validation
|
||||
const nextRequest = new Request(request.url, {
|
||||
method: request.method,
|
||||
headers: request.headers,
|
||||
body: request.body,
|
||||
}) as any;
|
||||
|
||||
// Validate CSRF token
|
||||
const validation = await CSRFProtection.validateRequest(nextRequest);
|
||||
|
||||
if (!validation.valid) {
|
||||
throw new TRPCError({
|
||||
code: "FORBIDDEN",
|
||||
message: validation.error || "CSRF validation failed",
|
||||
});
|
||||
}
|
||||
|
||||
return next({ ctx });
|
||||
});
|
||||
|
||||
/**
|
||||
* Rate limiting middleware for sensitive operations
|
||||
*/
|
||||
@ -161,3 +194,11 @@ export const rateLimitedProcedure = publicProcedure.use(
|
||||
return next({ ctx });
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* CSRF-protected procedures for state-changing operations
|
||||
*/
|
||||
export const csrfProtectedProcedure = publicProcedure.use(enforceCSRFProtection);
|
||||
export const csrfProtectedAuthProcedure = csrfProtectedProcedure.use(enforceUserIsAuthed);
|
||||
export const csrfProtectedCompanyProcedure = csrfProtectedProcedure.use(enforceCompanyAccess);
|
||||
export const csrfProtectedAdminProcedure = csrfProtectedProcedure.use(enforceAdminAccess);
|
||||
|
||||
Reference in New Issue
Block a user