Refactor VPN proxy client implementation
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
import type { IncomingMessage, ServerResponse } from 'node:http';
|
||||
|
||||
import { HarborError } from '../../../shared/errors.js';
|
||||
import { sendJson } from '../response.js';
|
||||
|
||||
interface DeviceInventoryPort {
|
||||
snapshot(): unknown;
|
||||
refresh(): Promise<unknown>;
|
||||
update(deviceId: string, patch: Record<string, unknown>, expectedRevision: unknown): unknown;
|
||||
setPolicy(deviceId: string, mode: unknown, expectedRevision: unknown): Promise<unknown>;
|
||||
}
|
||||
|
||||
interface DeviceInventoryRouteDependencies {
|
||||
deviceInventory: DeviceInventoryPort | null;
|
||||
readBody(req: IncomingMessage): Promise<Record<string, unknown>>;
|
||||
}
|
||||
|
||||
const DEVICE_PATH = /^\/api\/devices\/(dev_[a-f0-9]{16})$/;
|
||||
const DEVICE_POLICY_PATH = /^\/api\/devices\/(dev_[a-f0-9]{16})\/policy$/;
|
||||
|
||||
export function createDeviceInventoryRoute(dependencies: DeviceInventoryRouteDependencies) {
|
||||
return {
|
||||
async handle(req: IncomingMessage, res: ServerResponse) {
|
||||
const pathname = new URL(req.url || '/', 'http://localhost').pathname;
|
||||
|
||||
if (pathname === '/api/devices') {
|
||||
if (!dependencies.deviceInventory || req.method !== 'GET') {
|
||||
throw new HarborError('ENDPOINT_NOT_FOUND');
|
||||
}
|
||||
sendJson(res, 200, dependencies.deviceInventory.snapshot());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pathname === '/api/devices/refresh') {
|
||||
if (!dependencies.deviceInventory || req.method !== 'POST') {
|
||||
throw new HarborError('ENDPOINT_NOT_FOUND');
|
||||
}
|
||||
sendJson(res, 200, await dependencies.deviceInventory.refresh());
|
||||
return true;
|
||||
}
|
||||
|
||||
const deviceMatch = pathname.match(DEVICE_PATH);
|
||||
if (deviceMatch) {
|
||||
if (!dependencies.deviceInventory || req.method !== 'PUT') {
|
||||
throw new HarborError('ENDPOINT_NOT_FOUND');
|
||||
}
|
||||
const { expectedRevision, ...patch } = await dependencies.readBody(req);
|
||||
sendJson(
|
||||
res,
|
||||
200,
|
||||
dependencies.deviceInventory.update(deviceMatch[1], patch, expectedRevision),
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
const policyMatch = pathname.match(DEVICE_POLICY_PATH);
|
||||
if (policyMatch) {
|
||||
if (!dependencies.deviceInventory || req.method !== 'PUT') {
|
||||
throw new HarborError('ENDPOINT_NOT_FOUND');
|
||||
}
|
||||
const body = await dependencies.readBody(req);
|
||||
sendJson(
|
||||
res,
|
||||
200,
|
||||
await dependencies.deviceInventory.setPolicy(
|
||||
policyMatch[1],
|
||||
body.mode,
|
||||
body.expectedRevision,
|
||||
),
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user