UNPKG

@eternaljs/captcha

Version:

This npm package generates secure and customizable CAPTCHA images for web applications, preventing automated abuse with ease.

67 lines (51 loc) 2.32 kB
import { createCanvas } from 'canvas'; import { CaptchaInterface, OptionsInterface } from './interface'; function generateCaptcha(options: OptionsInterface): CaptchaInterface { const canvas = createCanvas(options['width'], options['height']); const ctx = canvas.getContext('2d'); const captchaText = generateCaptchaText(options['length'] ?? 6); ctx.font = `${options['font_size']}px Arial`; ctx.textBaseline = 'middle'; ctx.textAlign = 'center'; const textX = options['width'] / 2; const textY = options['height'] / 2; ctx.fillText(captchaText, textX, textY); ctx.beginPath(); ctx.moveTo(textX - ctx.measureText(captchaText).width / 2, textY); ctx.lineTo(textX + ctx.measureText(captchaText).width / 2, textY); ctx.strokeStyle = 'rgba(0,0,0)'; ctx.stroke(); const lines: number = options['lines'] ?? 6 for (let i = 0; i < lines; i++) { ctx.beginPath(); ctx.moveTo(0, Math.random() * options['height']); ctx.lineTo(options['width'], Math.random() * options['height']); ctx.strokeStyle = 'rgba(0,0,0,0.8)'; ctx.stroke(); } return { text: captchaText, image: canvas, }; } function generateCaptchaText(length: number): string { const charSet: Record<string, string> = { digit: '0123456789', lowercase: 'abcdefghijklmnopqrstuvwxyz', uppercase: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', } let captchaText = ''; for (const type in charSet) { captchaText += charSet[type].charAt(Math.floor(Math.random() * charSet[type].length)); } const remaining: number = length - captchaText.length; if (!remaining) return captchaText; for (let i = 0; i < remaining; i++) { if (i === 0) { captchaText += charSet["uppercase"].charAt(Math.floor(Math.random() * charSet["uppercase"].length)); } else if (i === 1) { captchaText += charSet["lowercase"].charAt(Math.floor(Math.random() * charSet["lowercase"].length)); } else { captchaText += charSet["digit"].charAt(Math.floor(Math.random() * charSet["digit"].length)); } } return captchaText.split('').sort(() => Math.random() - 0.5).join(''); } export default generateCaptcha;