50 lines
1.4 KiB
TypeScript
50 lines
1.4 KiB
TypeScript
import { verify } from '~/helpers/signature'
|
|
import { DeviceQueryParams } from '../schema'
|
|
import { queryDeviceStatus } from './query'
|
|
|
|
export default abstract class QueryService {
|
|
static async getDeviceStatus(query: DeviceQueryParams, headers: Record<string, string | undefined>): Promise<{
|
|
status: 'success'
|
|
message: 'command accepted'
|
|
data: {
|
|
floor: string
|
|
unit: string
|
|
device: string
|
|
room: string
|
|
devType: string
|
|
code: string
|
|
tower: string
|
|
payload: string
|
|
}
|
|
} | null> {
|
|
const apiKey = headers['x-api-key']
|
|
|
|
// For now, use apiKey as secretKey since DB validation is skipped
|
|
const secretKey = apiKey
|
|
|
|
// Remove signature from query for verification
|
|
const { signature, ...queryWithoutSignature } = query
|
|
|
|
const isValid = verify(queryWithoutSignature, signature, secretKey)
|
|
if (!isValid) {
|
|
throw new Error('invalid_signature')
|
|
}
|
|
|
|
// TODO: Check nonce for replay attack when DB is implemented
|
|
|
|
const topic = `${query.merchantName}/${query.floorName}_${query.unitNumber}-${query.deviceName}-${query.roomName}-${query.deviceType}-${query.commandType}-${query.towerNumber}`
|
|
|
|
const deviceData = await queryDeviceStatus(topic)
|
|
|
|
if (deviceData) {
|
|
return {
|
|
status: 'success',
|
|
message: 'command accepted',
|
|
data: deviceData,
|
|
}
|
|
}
|
|
|
|
return null
|
|
}
|
|
}
|