65 lines
2.3 KiB
Plaintext
65 lines
2.3 KiB
Plaintext
|
|
---
|
||
|
|
// Time Trap Component //
|
||
|
|
// This component is used to prevent bots from submitting the form.
|
||
|
|
// It encrypts the current timestamp and stores it in a hidden input field.
|
||
|
|
// The server then decrypts the timestamp and checks if it's valid and
|
||
|
|
// if the time difference is within the allowed range.
|
||
|
|
// If the timestamp is invalid, the form is not submitted.
|
||
|
|
|
||
|
|
import crypto from 'crypto'
|
||
|
|
|
||
|
|
import { timeTrapSecretKey } from '../lib/timeTrapSecret'
|
||
|
|
|
||
|
|
const algorithm = 'aes-256-cbc'
|
||
|
|
const iv = crypto.randomBytes(16) // Generate a random IV for each encryption
|
||
|
|
const timestamp = Date.now().toString()
|
||
|
|
|
||
|
|
const cipher = crypto.createCipheriv(algorithm, timeTrapSecretKey, iv)
|
||
|
|
let encrypted = cipher.update(timestamp, 'utf8', 'hex')
|
||
|
|
encrypted += cipher.final('hex')
|
||
|
|
|
||
|
|
// Combine IV and encrypted timestamp, then encode as base64 for the input value
|
||
|
|
const encryptedValue = Buffer.from(`${iv.toString('hex')}:${encrypted}`).toString('base64')
|
||
|
|
|
||
|
|
// --- Time Trap Validation Start ---
|
||
|
|
// try {
|
||
|
|
|
||
|
|
// const algorithm = 'aes-256-cbc'
|
||
|
|
// const decodedValue = Buffer.from(input.encTimestamp, 'base64').toString('utf8')
|
||
|
|
// const [ivHex, encryptedHex] = decodedValue.split(':')
|
||
|
|
|
||
|
|
// if (!ivHex || !encryptedHex) {
|
||
|
|
// throw new Error('Invalid time trap format.')
|
||
|
|
// }
|
||
|
|
|
||
|
|
// const iv = Buffer.from(ivHex, 'hex')
|
||
|
|
// const decipher = crypto.createDecipheriv(algorithm, timeTrapSecretKey, iv)
|
||
|
|
// let decrypted = decipher.update(encryptedHex, 'hex', 'utf8')
|
||
|
|
// decrypted += decipher.final('utf8')
|
||
|
|
|
||
|
|
// const originalTimestamp = parseInt(decrypted, 10)
|
||
|
|
// if (isNaN(originalTimestamp)) {
|
||
|
|
// throw new Error('Invalid timestamp data.')
|
||
|
|
// }
|
||
|
|
|
||
|
|
// const now = Date.now()
|
||
|
|
// const timeDiff = now - originalTimestamp
|
||
|
|
// const minTimeSeconds = 2 // 2 seconds
|
||
|
|
// const maxTimeMinutes = 60 // 1 hour
|
||
|
|
|
||
|
|
// if (timeDiff < minTimeSeconds * 1000 || timeDiff > maxTimeMinutes * 60 * 1000) {
|
||
|
|
// console.warn(`Time trap triggered: ${timeDiff / 1000}s`)
|
||
|
|
// throw new Error('Invalid submission timing.')
|
||
|
|
// }
|
||
|
|
// } catch (err: any) {
|
||
|
|
// console.error('Time trap validation failed:', err.message)
|
||
|
|
// throw new ActionError({
|
||
|
|
// code: 'BAD_REQUEST',
|
||
|
|
// message: 'Invalid request',
|
||
|
|
// })
|
||
|
|
// }
|
||
|
|
// --- Time Trap Validation End ---
|
||
|
|
---
|
||
|
|
|
||
|
|
<input type="hidden" name="encTimestamp" value={encryptedValue} data-time-trap class="hidden" />
|