UNPKG

@centinel/nextjs

Version:

Package designed to add Centinel Analytica functionality to Next.js applications

95 lines 3.41 kB
class CentinelApiValidator { config; constructor(config) { this.config = config; } async isBot(request) { try { const clientInfo = this.extractClientInfo(request); const payload = this.buildValidationPayload(request, clientInfo); const validationResult = await this.validateRequest(payload); return (!validationResult.success || ['block', 'redirect'].includes(validationResult.decision)); } catch (error) { console.error('Validation error:', error); return false; } } extractClientInfo(request) { const forwardedFor = request.headers.get('x-forwarded-for'); const realIp = request.headers.get('x-real-ip'); const cfConnectingIp = request.headers.get('cf-connecting-ip'); return { ip: cfConnectingIp ?? forwardedFor?.split(',')[0]?.trim() ?? realIp ?? 'unknown', referer: request.headers.get('referer') ?? request.headers.get('referrer') ?? '', }; } buildValidationPayload(request, clientInfo) { const headers = {}; request.headers.forEach((value, key) => { headers[key] = value; }); let realHost = request.headers.get('x-forwarded-host') ?? request.headers.get('host') ?? request.nextUrl.hostname; if (realHost === 'localhost' && !realHost.includes(':')) { realHost = `localhost:${process.env.PORT ?? '3000'}`; } const requestUrl = `${request.nextUrl.protocol}//${realHost}${request.nextUrl.pathname}${request.nextUrl.search}`; return { cookie: request.cookies.get('_centinel')?.value, url: requestUrl, ip: clientInfo.ip, referrer: clientInfo.referer, method: request.method, headers: headers, }; } async validateRequest(payload) { try { const response = await fetch('https://validator.centinelanalytica.com/validate', { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': this.config.secretKey, }, body: JSON.stringify(payload), }); if (!response.ok) { throw new Error(`Validator service responded with ${response.status}`); } const result = await response.json(); return { success: result.success !== false, decision: result.decision ?? 'block', response_html: result.response_html, cookies: result.cookies ?? [], }; } catch { return { success: false, decision: 'block', }; } } } export function createRequestValidator(config) { const validator = new CentinelApiValidator(config); return { isBot: (request) => validator.isBot(request), }; } export function createRequestValidatorFromEnv() { const config = { siteKey: process.env.CENTINEL_SITE_KEY, secretKey: process.env.CENTINEL_SECRET_KEY, }; return createRequestValidator(config); } export { CentinelApiValidator }; //# sourceMappingURL=api.js.map