mockup API device
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
// Clock skew window: ±5 minutes
|
||||
const CLOCK_SKEW_MS = 5 * 60 * 1000
|
||||
|
||||
export const deviceGuard = () => ({
|
||||
beforeHandle(context: unknown) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const { headers, set } = context as any
|
||||
// Validate Content-Type
|
||||
if (headers['content-type'] !== 'application/json') {
|
||||
set.status = 400
|
||||
throw new Error('invalid_request')
|
||||
}
|
||||
|
||||
// Validate X-API-Key
|
||||
const apiKey = headers['x-api-key']
|
||||
if (!apiKey || typeof apiKey !== 'string' || apiKey.trim() === '') {
|
||||
set.status = 401
|
||||
throw new Error('invalid_api_key')
|
||||
}
|
||||
|
||||
// Validate X-Timestamp
|
||||
const timestampStr = headers['x-timestamp']
|
||||
if (!timestampStr) {
|
||||
set.status = 403
|
||||
throw new Error('replay_attack_detected')
|
||||
}
|
||||
const timestamp = new Date(timestampStr)
|
||||
if (isNaN(timestamp.getTime()) || timestampStr !== timestamp.toISOString()) {
|
||||
set.status = 403
|
||||
throw new Error('replay_attack_detected')
|
||||
}
|
||||
const now = new Date()
|
||||
const diff = Math.abs(now.getTime() - timestamp.getTime())
|
||||
if (diff > CLOCK_SKEW_MS) {
|
||||
set.status = 403
|
||||
throw new Error('replay_attack_detected')
|
||||
}
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user