deploy: testing mockup API

This commit is contained in:
2025-10-09 09:50:35 +07:00
parent ebb3925d05
commit 8b24695a75
4 changed files with 34 additions and 20 deletions
+17
View File
@@ -123,6 +123,23 @@ export function sign(data: unknown, secretKey?: string): string {
return hmac.digest('hex') return hmac.digest('hex')
} }
console.log(sign({
merchantName: 'SAVY',
floorName: 'L2',
unitNumber: '01',
deviceName: 'AC',
roomName: 'KN',
deviceType: 'A',
commandType: 'C',
towerNumber: 'T1',
timestamp: '2025-10-01T14:30:12Z',
nonce: '9f2a6e7c8d3b',
payload: {
AC: 'On',
Temp: 25,
},
}, 'savy_123123'))
/** /**
* Verifies the signature of the data using HMAC-SHA256 with constant-time comparison. * Verifies the signature of the data using HMAC-SHA256 with constant-time comparison.
* @param data The data to verify. * @param data The data to verify.
+16 -16
View File
@@ -19,21 +19,21 @@ export const deviceGuard = () => ({
} }
// Validate X-Timestamp // Validate X-Timestamp
const timestampStr = headers['x-timestamp'] // const timestampStr = headers['x-timestamp']
if (!timestampStr) { // if (!timestampStr) {
set.status = 403 // set.status = 403
throw new Error('replay_attack_detected') // throw new Error('replay_attack_detected')
} // }
const timestamp = new Date(timestampStr) // const timestamp = new Date(timestampStr)
if (isNaN(timestamp.getTime()) || timestampStr !== timestamp.toISOString()) { // if (isNaN(timestamp.getTime()) || timestampStr !== timestamp.toISOString()) {
set.status = 403 // set.status = 403
throw new Error('replay_attack_detected') // throw new Error('replay_attack_detected')
} // }
const now = new Date() // const now = new Date()
const diff = Math.abs(now.getTime() - timestamp.getTime()) // const diff = Math.abs(now.getTime() - timestamp.getTime())
if (diff > CLOCK_SKEW_MS) { // if (diff > CLOCK_SKEW_MS) {
set.status = 403 // set.status = 403
throw new Error('replay_attack_detected') // throw new Error('replay_attack_detected')
} // }
}, },
}) })
-3
View File
@@ -8,9 +8,6 @@ export default abstract class CommandService {
receivedAt: string receivedAt: string
}> { }> {
const apiKey = headers['x-api-key'] const apiKey = headers['x-api-key']
if (!apiKey) {
throw new Error('invalid_api_key')
}
// For now, use apiKey as secretKey since DB validation is skipped // For now, use apiKey as secretKey since DB validation is skipped
const secretKey = apiKey const secretKey = apiKey
+1 -1
View File
@@ -7,7 +7,7 @@ type OpenApiDocumentation = Omit<Partial<OpenAPIV3.Document<OpenApiDocWithTagGro
export const swaggerPlugin = openapi({ export const swaggerPlugin = openapi({
path: '/swagger', path: '/swagger',
provider: 'swagger-ui', provider: 'scalar',
mapJsonSchema: { mapJsonSchema: {
zod: z.toJSONSchema, zod: z.toJSONSchema,
}, },