sitepaige-mcp-server
Version:
MCP server for generating web applications using SitePaige AI. Generate frontend (FREE/12 credits) then optionally add backend (50 credits)
112 lines (97 loc) • 2.84 kB
text/typescript
/*
Sitepaige v1.0.0
CSRF Protection Utility
WARNING: This file is automatically generated and should not be modified.
*/
import { cookies, headers } from 'next/headers';
import { NextRequest } from 'next/server';
export class CsrfError extends Error {
constructor(message: string) {
super(message);
this.name = 'CsrfError';
}
}
/**
* Generates a new CSRF token
*/
export function generateCsrfToken(): string {
return crypto.randomUUID();
}
/**
* Gets the CSRF token from cookies
*/
export async function getCsrfToken(): Promise<string | undefined> {
const cookieStore = await cookies();
return cookieStore.get('csrf-token')?.value;
}
/**
* Validates CSRF token from request
* Checks both header and form data for the token
*/
export async function validateCsrfToken(request: NextRequest | Request): Promise<boolean> {
// Skip CSRF validation for GET and HEAD requests
if (request.method === 'GET' || request.method === 'HEAD') {
return true;
}
const cookieStore = await cookies();
const headerStore = await headers();
const cookieToken = cookieStore.get('csrf-token')?.value;
if (!cookieToken) {
return false;
}
// Check X-CSRF-Token header first
const headerToken = headerStore.get('x-csrf-token');
if (headerToken === cookieToken) {
return true;
}
// For form submissions, check the request body
if (request.headers.get('content-type')?.includes('application/x-www-form-urlencoded')) {
try {
const formData = await request.formData();
const formToken = formData.get('csrf_token');
if (formToken === cookieToken) {
return true;
}
} catch {
// If form parsing fails, continue to check JSON body
}
}
// For JSON requests, check the body
if (request.headers.get('content-type')?.includes('application/json')) {
try {
const body = await request.json();
if (body.csrf_token === cookieToken) {
return true;
}
} catch {
// If JSON parsing fails, token is invalid
}
}
return false;
}
/**
* Middleware helper to validate CSRF token
* Throws CsrfError if token is invalid
*/
export async function requireCsrfToken(request: NextRequest | Request): Promise<void> {
const isValid = await validateCsrfToken(request);
if (!isValid) {
throw new CsrfError('Invalid or missing CSRF token');
}
}
/**
* React hook helper to get CSRF token for client-side forms
*/
export function useCsrfToken(): { token: string | undefined; header: Record<string, string> } {
// This will be used client-side
const token = typeof document !== 'undefined'
? document.cookie
.split('; ')
.find(row => row.startsWith('csrf-token='))
?.split('=')[1]
: undefined;
return {
token,
header: token ? { 'X-CSRF-Token': token } : {}
};
}