fix(vpn): восстановление VPN-модуля после затирания chat/push fix'ом
- Добавлена ветка bot.type === 'vpn' в messenger.messages.routes.ts - Добавлен полный модуль server/vpn/ (routes, service, db, bot, config) - Подключены VPN-маршруты в server/routes/index.ts - Добавлена раздача /apps статики и COPY в Dockerfile - apps/ пока содержит .gitkeep и README; APK/IPA нужно добавить отдельно
This commit is contained in:
87
server/vpn/vpn.routes.ts
Normal file
87
server/vpn/vpn.routes.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import { Router } from "express";
|
||||
import type { Request, Response } from "express";
|
||||
import {
|
||||
fetchSubscription,
|
||||
authorizeSession,
|
||||
closeSession,
|
||||
recordTraffic,
|
||||
VpnError,
|
||||
} from "./vpn.service";
|
||||
import { SUBSCRIPTION_UPDATE_INTERVAL_HOURS } from "./vpn.config";
|
||||
|
||||
function handleVpnError(res: Response, err: unknown): void {
|
||||
if (err instanceof VpnError) {
|
||||
res.status(403).type("text/plain").send(err.message);
|
||||
return;
|
||||
}
|
||||
console.error("[VPN API] error:", err);
|
||||
res.status(500).type("text/plain").send("Internal error");
|
||||
}
|
||||
|
||||
export function registerVpnRoutes(router: Router): void {
|
||||
// Subscription endpoint used by olcbox clients
|
||||
router.get("/api/vpn/sub/:token", async (req: Request, res: Response) => {
|
||||
try {
|
||||
const token = req.params.token;
|
||||
const hwid = req.headers["x-hwid"] as string | undefined;
|
||||
const uri = await fetchSubscription(token, hwid);
|
||||
res.setHeader("profile-update-interval", String(SUBSCRIPTION_UPDATE_INTERVAL_HOURS));
|
||||
res.setHeader("Content-Type", "text/plain; charset=utf-8");
|
||||
res.send(uri);
|
||||
} catch (err) {
|
||||
handleVpnError(res, err);
|
||||
}
|
||||
});
|
||||
|
||||
// olrtc srv AuthHook
|
||||
router.post("/api/vpn/olrtc/auth", async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { device_id, room_url } = req.body || {};
|
||||
if (!device_id || !room_url) {
|
||||
res.status(400).json({ success: false, error: "missing device_id or room_url" });
|
||||
return;
|
||||
}
|
||||
const result = await authorizeSession(room_url, device_id);
|
||||
res.json({ success: true, session_id: result.sessionId });
|
||||
} catch (err) {
|
||||
if (err instanceof VpnError) {
|
||||
res.status(403).json({ success: false, error: err.message });
|
||||
return;
|
||||
}
|
||||
console.error("[VPN Auth] error:", err);
|
||||
res.status(500).json({ success: false, error: "internal error" });
|
||||
}
|
||||
});
|
||||
|
||||
// olrtc srv OnSessionClose
|
||||
router.post("/api/vpn/olrtc/close", async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { session_id, room_url } = req.body || {};
|
||||
if (!session_id || !room_url) {
|
||||
res.status(400).json({ success: false, error: "missing fields" });
|
||||
return;
|
||||
}
|
||||
await closeSession(room_url, session_id);
|
||||
res.json({ success: true });
|
||||
} catch (err) {
|
||||
console.error("[VPN Close] error:", err);
|
||||
res.status(500).json({ success: false, error: "internal error" });
|
||||
}
|
||||
});
|
||||
|
||||
// olrtc srv OnTraffic
|
||||
router.post("/api/vpn/olrtc/traffic", async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { session_id, room_url, bytes_in, bytes_out } = req.body || {};
|
||||
if (!session_id || !room_url || typeof bytes_in !== "number" || typeof bytes_out !== "number") {
|
||||
res.status(400).json({ success: false, error: "missing fields" });
|
||||
return;
|
||||
}
|
||||
await recordTraffic(room_url, session_id, bytes_in, bytes_out);
|
||||
res.json({ success: true });
|
||||
} catch (err) {
|
||||
console.error("[VPN Traffic] error:", err);
|
||||
res.status(500).json({ success: false, error: "internal error" });
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user