Files
edubox/server/app/api/resolve/route.ts
EduBox Dev a414f03a59 feat(agent): v0.3.5 Windows inbound forwarding, UI actions, lifecycle
- Configure tailscale serve automatically for each instance on Windows userspace networking.
- Add local UI buttons: start/stop/reset/delete instances (stop/start preserve volumes).
- Clean shutdown: stop tailscaled and instances, notify server with instance_stopped.
- Restart tailscaled on agent boot using persisted state when pre-auth key is absent.
- Sync instance stopped/deleted status to dashboard (server/lib/websocket.ts).
- Security: include prior authz/scoping changes across API routes, ephemeral pre-auth keys, ACL policy, internal API key.
- Update SUIVI_VPN_ONDEMAND.md and docs/ONBOARDING_CLIENT.md.
- Bump agent version to 0.3.5.
2026-06-25 22:59:09 +00:00

44 lines
1.3 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
function getBearerToken(req: NextRequest): string | null {
const auth = req.headers.get("authorization") || "";
const match = auth.match(/^Bearer\s+(\S+)$/i);
return match ? match[1] : null;
}
export async function GET(req: NextRequest) {
const apiKey = process.env.INTERNAL_API_KEY;
if (!apiKey) {
return NextResponse.json({ error: "Internal API key not configured" }, { status: 500 });
}
const token = getBearerToken(req);
if (!token || token !== apiKey) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
const { searchParams } = new URL(req.url);
const subdomain = searchParams.get("subdomain");
if (!subdomain) {
return NextResponse.json({ error: "subdomain required" }, { status: 400 });
}
const instance = await prisma.instance.findUnique({
where: { id: subdomain },
include: { node: true },
});
if (!instance || !instance.node) {
return NextResponse.json({ error: "instance not found" }, { status: 404 });
}
if (instance.node.status !== "online" || !instance.node.tailscaleIp) {
return NextResponse.json({ error: "node offline" }, { status: 503 });
}
return NextResponse.json({
upstream: `${instance.node.tailscaleIp}:${instance.port}`,
});
}