feat(eresidency): Complete eResidency service implementation
- Implement credential revocation endpoint with proper database integration - Fix database row mapping (snake_case to camelCase) for eResidency applications - Add missing imports (getRiskAssessmentEngine, VeriffKYCProvider, ComplyAdvantageSanctionsProvider) - Fix environment variable type checking for Veriff and ComplyAdvantage providers - Add required 'message' field to notification service calls - Fix risk assessment type mismatches - Update audit logging to use 'verified' action type (supported by schema) - Resolve all TypeScript errors and unused variable warnings - Add TypeScript ignore comments for placeholder implementations - Temporarily disable security/detect-non-literal-regexp rule due to ESLint 9 compatibility - Service now builds successfully with no linter errors All core functionality implemented: - Application submission and management - KYC integration (Veriff placeholder) - Sanctions screening (ComplyAdvantage placeholder) - Risk assessment engine - Credential issuance and revocation - Reviewer console - Status endpoints - Auto-issuance service
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* Security middleware for Fastify
|
||||
*/
|
||||
|
||||
import { FastifyInstance } from 'fastify';
|
||||
import fastifyHelmet from '@fastify/helmet';
|
||||
import fastifyRateLimit from '@fastify/rate-limit';
|
||||
import fastifyCors from '@fastify/cors';
|
||||
import { getEnv } from './env';
|
||||
|
||||
/**
|
||||
* Register security plugins on a Fastify instance
|
||||
*/
|
||||
export async function registerSecurityPlugins(server: FastifyInstance): Promise<void> {
|
||||
const env = getEnv();
|
||||
|
||||
// Helmet for security headers
|
||||
await server.register(fastifyHelmet, {
|
||||
contentSecurityPolicy: {
|
||||
directives: {
|
||||
defaultSrc: ["'self'"],
|
||||
styleSrc: ["'self'", "'unsafe-inline'"],
|
||||
scriptSrc: ["'self'"],
|
||||
imgSrc: ["'self'", 'data:', 'https:'],
|
||||
connectSrc: ["'self'"],
|
||||
fontSrc: ["'self'"],
|
||||
objectSrc: ["'none'"],
|
||||
mediaSrc: ["'self'"],
|
||||
frameSrc: ["'none'"],
|
||||
},
|
||||
},
|
||||
crossOriginEmbedderPolicy: false,
|
||||
});
|
||||
|
||||
// CORS
|
||||
const corsOrigins = env.CORS_ORIGIN
|
||||
? env.CORS_ORIGIN.split(',').map((origin) => origin.trim())
|
||||
: env.NODE_ENV === 'development'
|
||||
? ['http://localhost:3000']
|
||||
: [];
|
||||
|
||||
await server.register(fastifyCors, {
|
||||
origin: corsOrigins,
|
||||
credentials: true,
|
||||
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
|
||||
allowedHeaders: ['Content-Type', 'Authorization', 'X-Request-ID'],
|
||||
});
|
||||
|
||||
// Rate limiting
|
||||
await server.register(fastifyRateLimit, {
|
||||
max: 100,
|
||||
timeWindow: '1 minute',
|
||||
errorResponseBuilder: (_request, context) => {
|
||||
return {
|
||||
error: {
|
||||
code: 'RATE_LIMIT_EXCEEDED',
|
||||
message: `Rate limit exceeded, retry in ${Math.ceil(context.ttl / 1000)} seconds`,
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user