feature: Adds start and stop routes.

This commit is contained in:
greysoh 2024-04-27 16:34:14 -04:00
parent 5bfbf5cb05
commit 18b13d4aa3
No known key found for this signature in database
GPG key ID: FE0F173B8FC01571
6 changed files with 203 additions and 4 deletions

View 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"
}
}

View 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"
}
}

View file

@ -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[] {

View file

@ -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);

View 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
}
});
}

View 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
}
});
}