feature: Adds start and stop routes.
This commit is contained in:
parent
5bfbf5cb05
commit
18b13d4aa3
6 changed files with 203 additions and 4 deletions
28
routes/NextNet API/Forward/Start.bru
Normal file
28
routes/NextNet API/Forward/Start.bru
Normal file
|
@ -0,0 +1,28 @@
|
|||
meta {
|
||||
name: Start
|
||||
type: http
|
||||
seq: 4
|
||||
}
|
||||
|
||||
post {
|
||||
url: http://127.0.0.1:3000/api/v1/forward/create
|
||||
body: json
|
||||
auth: none
|
||||
}
|
||||
|
||||
body:json {
|
||||
{
|
||||
"token": "914abf2223f84375eed884671bfaefd7755d378af496b345f322214e75b51ed4465f11e26c944914c9b4fcc35c53250325fbc6530853ddfed8f72976d6fc5",
|
||||
"name": "Test Route",
|
||||
"description": "This is a test route for SSH",
|
||||
|
||||
"protocol": "tcp",
|
||||
|
||||
"sourceIP": "127.0.0.1",
|
||||
"sourcePort": "8000",
|
||||
|
||||
"destinationPort": "9000",
|
||||
|
||||
"providerID": "1"
|
||||
}
|
||||
}
|
18
routes/NextNet API/Forward/Stop.bru
Normal file
18
routes/NextNet API/Forward/Stop.bru
Normal file
|
@ -0,0 +1,18 @@
|
|||
meta {
|
||||
name: Stop
|
||||
type: http
|
||||
seq: 5
|
||||
}
|
||||
|
||||
post {
|
||||
url: http://127.0.0.1:3000/api/v1/forward/start
|
||||
body: json
|
||||
auth: none
|
||||
}
|
||||
|
||||
body:json {
|
||||
{
|
||||
"token": "914abf2223f84375eed884671bfaefd7755d378af496b345f322214e75b51ed4465f11e26c944914c9b4fcc35c53250325fbc6530853ddfed8f72976d6fc5",
|
||||
"id": "1"
|
||||
}
|
||||
}
|
|
@ -3,6 +3,10 @@ import { Socket } from "node:net";
|
|||
|
||||
import type { BackendBaseClass, ForwardRule, ConnectedClient, ParameterReturnedValue } from "./base.js";
|
||||
|
||||
type ForwardRuleExt = ForwardRule & {
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
// Fight me (for better naming)
|
||||
type BackendParsedProviderString = {
|
||||
ip: string,
|
||||
|
@ -40,7 +44,7 @@ export class SSHBackendProvider implements BackendBaseClass {
|
|||
state: "stopped" | "stopping" | "started" | "starting";
|
||||
|
||||
clients: ConnectedClient[];
|
||||
proxies: ForwardRule[];
|
||||
proxies: ForwardRuleExt[];
|
||||
logs: string[];
|
||||
|
||||
sshInstance: NodeSSH;
|
||||
|
@ -118,6 +122,7 @@ export class SSHBackendProvider implements BackendBaseClass {
|
|||
await this.sshInstance.forwardIn("0.0.0.0", destPort, (info, accept, reject) => {
|
||||
const foundProxyEntry = this.proxies.find((i) => i.sourceIP == sourceIP && i.sourcePort == sourcePort && i.destPort == destPort);
|
||||
if (!foundProxyEntry) return reject();
|
||||
if (!foundProxyEntry.enabled) return reject();
|
||||
|
||||
const client: ConnectedClient = {
|
||||
ip: info.srcIP,
|
||||
|
@ -161,7 +166,9 @@ export class SSHBackendProvider implements BackendBaseClass {
|
|||
this.proxies.push({
|
||||
sourceIP,
|
||||
sourcePort,
|
||||
destPort
|
||||
destPort,
|
||||
|
||||
enabled: true
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -172,8 +179,7 @@ export class SSHBackendProvider implements BackendBaseClass {
|
|||
const foundProxyEntry = this.proxies.find((i) => i.sourceIP == sourceIP && i.sourcePort == sourcePort && i.destPort == destPort);
|
||||
if (!foundProxyEntry) return;
|
||||
|
||||
const proxyIndex = this.proxies.indexOf(foundProxyEntry);
|
||||
this.proxies.splice(proxyIndex, 1);
|
||||
foundProxyEntry.enabled = false;
|
||||
};
|
||||
|
||||
getAllConnections(): ConnectedClient[] {
|
||||
|
|
|
@ -15,11 +15,14 @@ import { route as backendLookup } from "./routes/backends/lookup.js";
|
|||
import { route as forwardCreate } from "./routes/forward/create.js";
|
||||
import { route as forwardRemove } from "./routes/forward/remove.js";
|
||||
import { route as forwardLookup } from "./routes/forward/lookup.js";
|
||||
import { route as forwardStart } from "./routes/forward/start.js";
|
||||
import { route as forwardStop } from "./routes/forward/stop.js";
|
||||
|
||||
import { route as userCreate } from "./routes/user/create.js";
|
||||
import { route as userRemove } from "./routes/user/remove.js";
|
||||
import { route as userLookup } from "./routes/user/lookup.js";
|
||||
import { route as userLogin } from "./routes/user/login.js";
|
||||
|
||||
import { backendInit } from "./libs/backendInit.js";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
@ -78,6 +81,8 @@ backendLookup(routeOptions);
|
|||
forwardCreate(routeOptions);
|
||||
forwardRemove(routeOptions);
|
||||
forwardLookup(routeOptions);
|
||||
forwardStart(routeOptions);
|
||||
forwardStop(routeOptions);
|
||||
|
||||
userCreate(routeOptions);
|
||||
userRemove(routeOptions);
|
||||
|
|
72
src/routes/forward/start.ts
Normal file
72
src/routes/forward/start.ts
Normal file
|
@ -0,0 +1,72 @@
|
|||
import { hasPermissionByToken } from "../../libs/permissions.js";
|
||||
import type { RouteOptions } from "../../libs/types.js";
|
||||
|
||||
export function route(routeOptions: RouteOptions) {
|
||||
const {
|
||||
fastify,
|
||||
prisma,
|
||||
tokens,
|
||||
backends
|
||||
} = routeOptions;
|
||||
|
||||
function hasPermission(token: string, permissionList: string[]): Promise<boolean> {
|
||||
return hasPermissionByToken(permissionList, token, tokens, prisma);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new route to use
|
||||
*/
|
||||
fastify.post("/api/v1/forward/start", {
|
||||
schema: {
|
||||
body: {
|
||||
type: "object",
|
||||
required: ["token", "id"],
|
||||
|
||||
properties: {
|
||||
token: { type: "string" },
|
||||
id: { type: "number" }
|
||||
}
|
||||
},
|
||||
}
|
||||
}, async(req, res) => {
|
||||
// @ts-ignore
|
||||
const body: {
|
||||
token: string,
|
||||
id: number
|
||||
} = req.body;
|
||||
|
||||
console.log(body);
|
||||
|
||||
if (!await hasPermission(body.token, [
|
||||
"routes.start"
|
||||
])) {
|
||||
return res.status(403).send({
|
||||
error: "Unauthorized"
|
||||
});
|
||||
};
|
||||
|
||||
const forward = await prisma.forwardRule.findUnique({
|
||||
where: {
|
||||
id: body.id
|
||||
}
|
||||
});
|
||||
|
||||
if (!forward) return res.status(400).send({
|
||||
error: "Could not find forward entry"
|
||||
});
|
||||
|
||||
if (!backends[forward.destProviderID]) return res.status(400).send({
|
||||
error: "Backend not found"
|
||||
});
|
||||
|
||||
// Other restrictions in place make it so that it MUST be either TCP or UDP
|
||||
// @ts-ignore
|
||||
const protocol: "tcp" | "udp" = forward.protocol;
|
||||
|
||||
backends[forward.destProviderID].addConnection(forward.sourceIP, forward.sourcePort, forward.destPort, protocol);
|
||||
|
||||
return {
|
||||
success: true
|
||||
}
|
||||
});
|
||||
}
|
70
src/routes/forward/stop.ts
Normal file
70
src/routes/forward/stop.ts
Normal file
|
@ -0,0 +1,70 @@
|
|||
import { hasPermissionByToken } from "../../libs/permissions.js";
|
||||
import type { RouteOptions } from "../../libs/types.js";
|
||||
|
||||
export function route(routeOptions: RouteOptions) {
|
||||
const {
|
||||
fastify,
|
||||
prisma,
|
||||
tokens,
|
||||
backends
|
||||
} = routeOptions;
|
||||
|
||||
function hasPermission(token: string, permissionList: string[]): Promise<boolean> {
|
||||
return hasPermissionByToken(permissionList, token, tokens, prisma);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new route to use
|
||||
*/
|
||||
fastify.post("/api/v1/forward/stop", {
|
||||
schema: {
|
||||
body: {
|
||||
type: "object",
|
||||
required: ["token", "id"],
|
||||
|
||||
properties: {
|
||||
token: { type: "string" },
|
||||
id: { type: "number" }
|
||||
}
|
||||
},
|
||||
}
|
||||
}, async(req, res) => {
|
||||
// @ts-ignore
|
||||
const body: {
|
||||
token: string,
|
||||
id: number
|
||||
} = req.body;
|
||||
|
||||
if (!await hasPermission(body.token, [
|
||||
"routes.stop"
|
||||
])) {
|
||||
return res.status(403).send({
|
||||
error: "Unauthorized"
|
||||
});
|
||||
};
|
||||
|
||||
const forward = await prisma.forwardRule.findUnique({
|
||||
where: {
|
||||
id: body.id
|
||||
}
|
||||
});
|
||||
|
||||
if (!forward) return res.status(400).send({
|
||||
error: "Could not find forward entry"
|
||||
});
|
||||
|
||||
if (!backends[forward.destProviderID]) return res.status(400).send({
|
||||
error: "Backend not found"
|
||||
});
|
||||
|
||||
// Other restrictions in place make it so that it MUST be either TCP or UDP
|
||||
// @ts-ignore
|
||||
const protocol: "tcp" | "udp" = forward.protocol;
|
||||
|
||||
backends[forward.destProviderID].removeConnection(forward.sourceIP, forward.sourcePort, forward.destPort, protocol);
|
||||
|
||||
return {
|
||||
success: true
|
||||
}
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue