fix: passtrough into pak vegacloud internal routing

This commit is contained in:
2025-12-08 19:32:32 +07:00
parent e81c6bdddc
commit 3dee9b7a4d
5 changed files with 63 additions and 38 deletions
-1
View File
@@ -94,7 +94,6 @@ export const apiKeyAuthMacro = new Elysia().macro({
if (!enabled) {
return
}
const apiKey = headers['x-api-key']
const nonce = headers['x-nonce']
const signature = headers['x-signature']
+30
View File
@@ -31,3 +31,33 @@ export async function sendCommandToThirdParty(topicData: string, payload: string
throw error
}
}
export async function sendQueryToThirdParty(topicData: string) {
try {
const response = await fetch(`${httpConfig.baseUrl}/state-reply`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
topic: topicData,
}),
})
logger.info({ msg: 'Third-party query sent successfully', topic: topicData, status: response.status })
if (response.status != 200) {
return {
status: response.status,
message: response.statusText,
data: null,
}
}
return {
status: response.status,
message: response.statusText,
data: await response.json(),
}
} catch (error) {
logger.error({ msg: 'Failed to send query to third-party service', topic: topicData, error: (error as Error).message })
throw error
}
}
+25 -28
View File
@@ -1,9 +1,10 @@
import { sendQueryToThirdParty } from '../commands/command'
import { DeviceQueryParams } from '../schema'
export default abstract class QueryService {
static async getDeviceStatus(query: DeviceQueryParams): Promise<{
status: 'success'
message: 'command accepted'
status: string
message: string
data: {
floorName: string
unitNumber: string
@@ -13,7 +14,7 @@ export default abstract class QueryService {
code: string
towerNumber: string
payload: string
}
} | null
}> {
// TODO: Check nonce for replay attack when DB is implemented
@@ -23,36 +24,32 @@ export default abstract class QueryService {
throw new Error('Unsupported device topic')
}
if (topic === 'SAVY/L2_01-BL-LV-S-S-T1') {
const request = await sendQueryToThirdParty(topic)
if (request.status !== 200) {
throw new Error('Failed to get device status')
}
if (request.data.data == null) {
return {
status: 'error',
message: 'Device not found',
data: null,
}
}
return {
status: 'success',
message: 'command accepted',
data: {
floorName: 'L2',
unitNumber: '01',
deviceName: 'BL',
roomName: 'LV',
deviceType: 'S',
code: 'S',
towerNumber: 'T1',
payload: 'Open',
floorName: request.data.floor,
unitNumber: request.data.unit,
deviceName: request.data.device,
roomName: request.data.room,
deviceType: request.data.devType,
code: request.data.code,
towerNumber: request.data.tower,
payload: request.data.payload,
},
}
} else {
return {
status: 'success',
message: 'command accepted',
data: {
floorName: 'L2',
unitNumber: '01',
deviceName: 'L',
roomName: 'LV',
deviceType: 'S',
code: 'C',
towerNumber: 'T1',
payload: 'On',
},
}
}
}
}
+3 -4
View File
@@ -33,12 +33,11 @@ export const router = new Elysia({
.get('/status', async ({ query, set }) => {
try {
const result = await QueryService.getDeviceStatus(query)
if (result) {
return result
} else {
if (result.status == 'error' && result.message === 'Device not found') {
set.status = 404
return { status: 'not_found', message: 'Device status not found' }
return { status: 'not_found', message: 'Device not found', data: null }
}
return result
} catch (error) {
if (error instanceof Error && error.message in deviceErrorResponseMap) {
const { status, response } = deviceErrorResponseMap[error.message]
+2 -2
View File
@@ -67,8 +67,8 @@ export const deviceCommandResponseSchema = {
// Query response schema
export const deviceQueryResponseSchema = {
200: z.object({
status: z.literal('success'),
message: z.literal('command accepted'),
status: z.string(),
message: z.string(),
data: z.object({
floorName: z.string(),
unitNumber: z.string(),