grabbit 13ce6ae442 feat: implement complete edge device registration system
- Add hardware fingerprinting with cross-platform support
- Implement secure device registration flow with X.509 certificates
- Add WebSocket real-time communication for device status
- Create comprehensive device management dashboard
- Establish zero-trust security architecture with multi-layer protection
- Add database migrations for device registration entities
- Implement Rust edge client with hardware identification
- Add certificate management and automated provisioning system

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-13 08:46:25 +08:00

189 lines
5.4 KiB
TypeScript

import {
DevicesResponse,
DeviceDto,
InitiateRegistrationRequest,
InitiateRegistrationResponse,
ClaimDeviceRequest,
ClaimDeviceResponse,
DeviceRegistrationSession,
DeviceConfiguration,
DeviceHeartbeat,
DeviceStatus
} from '../types/device'
const BASE_URL = "http://localhost:3001/api/v1"
// Helper function to get auth headers
const getAuthHeaders = (): HeadersInit => {
const token = localStorage.getItem("accessToken")
if (!token) {
throw new Error("No access token found")
}
return {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json",
}
}
// Helper function to handle API responses
const handleResponse = async <T>(response: Response): Promise<T> => {
if (!response.ok) {
if (response.status === 401) {
throw new Error("Unauthorized - please login again")
}
let errorMessage = `Request failed: ${response.statusText}`
try {
const errorData = await response.json()
errorMessage = errorData.message || errorMessage
} catch {
// Ignore JSON parse error, use default message
}
throw new Error(errorMessage)
}
return response.json()
}
export const devicesApi = {
// Device Management
async getDevices(): Promise<DevicesResponse> {
const response = await fetch(`${BASE_URL}/devices`, {
method: "GET",
headers: getAuthHeaders(),
})
return handleResponse<DevicesResponse>(response)
},
async getDevice(deviceId: string): Promise<DeviceDto> {
const response = await fetch(`${BASE_URL}/devices/${deviceId}`, {
method: "GET",
headers: getAuthHeaders(),
})
return handleResponse<DeviceDto>(response)
},
async updateDevice(deviceId: string, updates: Partial<DeviceDto>): Promise<DeviceDto> {
const response = await fetch(`${BASE_URL}/devices/${deviceId}`, {
method: "PATCH",
headers: getAuthHeaders(),
body: JSON.stringify(updates),
})
return handleResponse<DeviceDto>(response)
},
async deleteDevice(deviceId: string): Promise<void> {
const response = await fetch(`${BASE_URL}/devices/${deviceId}`, {
method: "DELETE",
headers: getAuthHeaders(),
})
if (!response.ok) {
throw new Error(`Failed to delete device: ${response.statusText}`)
}
},
async updateDeviceStatus(deviceId: string, status: DeviceStatus): Promise<DeviceDto> {
const response = await fetch(`${BASE_URL}/devices/${deviceId}/status`, {
method: "PATCH",
headers: getAuthHeaders(),
body: JSON.stringify({ status }),
})
return handleResponse<DeviceDto>(response)
},
// Device Registration
async initiateRegistration(request: InitiateRegistrationRequest): Promise<InitiateRegistrationResponse> {
const response = await fetch(`${BASE_URL}/device-registration/test-initiate`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(request),
})
return handleResponse<InitiateRegistrationResponse>(response)
},
async getRegistrationSession(sessionId: string): Promise<DeviceRegistrationSession> {
const response = await fetch(`${BASE_URL}/device-registration/session/${sessionId}`, {
method: "GET",
headers: getAuthHeaders(),
})
return handleResponse<DeviceRegistrationSession>(response)
},
async claimDevice(request: ClaimDeviceRequest): Promise<ClaimDeviceResponse> {
const response = await fetch(`${BASE_URL}/device-registration/claim`, {
method: "POST",
headers: getAuthHeaders(),
body: JSON.stringify(request),
})
return handleResponse<ClaimDeviceResponse>(response)
},
async cancelRegistration(sessionId: string): Promise<void> {
const response = await fetch(`${BASE_URL}/device-registration/${sessionId}`, {
method: "DELETE",
headers: getAuthHeaders(),
})
if (!response.ok && response.status !== 204) {
throw new Error(`Failed to cancel registration: ${response.statusText}`)
}
},
// Device Configuration
async getDeviceConfiguration(deviceId: string): Promise<DeviceConfiguration[]> {
const response = await fetch(`${BASE_URL}/devices/${deviceId}/configuration`, {
method: "GET",
headers: getAuthHeaders(),
})
return handleResponse<DeviceConfiguration[]>(response)
},
async updateDeviceConfiguration(
deviceId: string,
configType: string,
configData: Record<string, any>
): Promise<DeviceConfiguration> {
const response = await fetch(`${BASE_URL}/devices/${deviceId}/configuration`, {
method: "POST",
headers: getAuthHeaders(),
body: JSON.stringify({ configType, configData }),
})
return handleResponse<DeviceConfiguration>(response)
},
// Device Heartbeat
async sendHeartbeat(heartbeat: DeviceHeartbeat): Promise<void> {
const response = await fetch(`${BASE_URL}/devices/heartbeat`, {
method: "POST",
headers: getAuthHeaders(),
body: JSON.stringify(heartbeat),
})
if (!response.ok) {
throw new Error(`Failed to send heartbeat: ${response.statusText}`)
}
},
async getDeviceHeartbeats(deviceId: string, limit: number = 50): Promise<DeviceHeartbeat[]> {
const response = await fetch(`${BASE_URL}/devices/${deviceId}/heartbeats?limit=${limit}`, {
method: "GET",
headers: getAuthHeaders(),
})
return handleResponse<DeviceHeartbeat[]>(response)
},
}