From 5bfbf5cb0595b537457242e3e7cb05b7620e5722 Mon Sep 17 00:00:00 2001 From: greysoh Date: Sat, 27 Apr 2024 16:12:59 -0400 Subject: [PATCH] feature: Changes backend creation to use checks, and to automatically enable. --- src/index.ts | 46 +++--------------------------- src/libs/backendInit.ts | 53 +++++++++++++++++++++++++++++++++++ src/routes/backends/create.ts | 31 +++++++++++++++++++- src/routes/backends/remove.ts | 18 +++++++++++- src/routes/user/login.ts | 2 +- 5 files changed, 105 insertions(+), 45 deletions(-) create mode 100644 src/libs/backendInit.ts diff --git a/src/index.ts b/src/index.ts index 58d6269..26efceb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,9 +4,7 @@ import { PrismaClient } from '@prisma/client'; import Fastify from "fastify"; import type { ServerOptions, SessionToken, RouteOptions } from "./libs/types.js"; -import type { BackendBaseClass } from "./backendimpl/base.js"; - -import { backendProviders } from "./backendimpl/index.js"; +import type { BackendBaseClass } from "./backendimpl/base.js";`` import { route as getPermissions } from "./routes/getPermissions.js"; @@ -22,7 +20,7 @@ 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 { connect } from "node:http2"; +import { backendInit } from "./libs/backendInit.js"; const prisma = new PrismaClient(); @@ -64,45 +62,9 @@ const createdBackends = await prisma.desinationProvider.findMany(); for (const backend of createdBackends) { console.log(`Running init steps for ID '${backend.id}' (${backend.name})`); + const init = await backendInit(backend, backends, prisma); - const ourProvider = backendProviders[backend.backend]; - - if (!ourProvider) { - console.log(" - Error: Invalid backend recieved!"); - continue; - } - - console.log(" - Initializing backend..."); - - backends[backend.id] = new ourProvider(backend.connectionDetails); - const ourBackend = backends[backend.id]; - - if (!await ourBackend.start()) { - console.log(" - Error initializing backend!"); - console.log(" - " + ourBackend.logs.join("\n - ")); - - continue; - } - - console.log(" - Initializing clients..."); - - const clients = await prisma.forwardRule.findMany({ - where: { - destProviderID: backend.id, - enabled: true - } - }); - - for (const client of clients) { - if (client.protocol != "tcp" && client.protocol != "udp") { - console.error(` - Error: Client with ID of '${client.id}' has an invalid protocol! (must be either TCP or UDP)`); - continue; - } - - ourBackend.addConnection(client.sourceIP, client.sourcePort, client.destPort, client.protocol); - } - - console.log("Init successful."); + if (init) console.log("Init successful."); } console.log("Done."); diff --git a/src/libs/backendInit.ts b/src/libs/backendInit.ts new file mode 100644 index 0000000..a9e8a25 --- /dev/null +++ b/src/libs/backendInit.ts @@ -0,0 +1,53 @@ +import type { PrismaClient } from "@prisma/client"; + +import type { BackendBaseClass } from "../backendimpl/base.js"; +import { backendProviders } from "../backendimpl/index.js"; + +type Backend = { + id: number; + name: string; + description: string | null; + backend: string; + connectionDetails: string; +}; + +export async function backendInit(backend: Backend, backends: Record, prisma: PrismaClient): Promise { + const ourProvider = backendProviders[backend.backend]; + + if (!ourProvider) { + console.log(" - Error: Invalid backend recieved!"); + return false; + } + + console.log(" - Initializing backend..."); + + backends[backend.id] = new ourProvider(backend.connectionDetails); + const ourBackend = backends[backend.id]; + + if (!await ourBackend.start()) { + console.log(" - Error initializing backend!"); + console.log(" - " + ourBackend.logs.join("\n - ")); + + return false; + } + + console.log(" - Initializing clients..."); + + const clients = await prisma.forwardRule.findMany({ + where: { + destProviderID: backend.id, + enabled: true + } + }); + + for (const client of clients) { + if (client.protocol != "tcp" && client.protocol != "udp") { + console.error(` - Error: Client with ID of '${client.id}' has an invalid protocol! (must be either TCP or UDP)`); + continue; + } + + ourBackend.addConnection(client.sourceIP, client.sourcePort, client.destPort, client.protocol); + } + + return true; +} \ No newline at end of file diff --git a/src/routes/backends/create.ts b/src/routes/backends/create.ts index fc71527..9412c6f 100644 --- a/src/routes/backends/create.ts +++ b/src/routes/backends/create.ts @@ -1,11 +1,15 @@ import { hasPermissionByToken } from "../../libs/permissions.js"; import type { RouteOptions } from "../../libs/types.js"; +import { backendProviders } from "../../backendimpl/index.js"; +import { backendInit } from "../../libs/backendInit.js"; + export function route(routeOptions: RouteOptions) { const { fastify, prisma, - tokens + tokens, + backends } = routeOptions; function hasPermission(token: string, permissionList: string[]): Promise { @@ -47,6 +51,21 @@ export function route(routeOptions: RouteOptions) { }); }; + if (!backendProviders[body.backend]) { + return res.status(400).send({ + error: "Unknown/unsupported/deprecated backend!" + }); + }; + + const connectionDetails = JSON.stringify(body.connectionDetails); + const connectionDetailsValidityCheck = backendProviders[body.backend].checkParametersBackendInstance(connectionDetails); + + if (!connectionDetailsValidityCheck.success) { + return res.status(400).send({ + error: connectionDetailsValidityCheck.message ?? "Unknown error while attempting to parse connectionDetails (it's on your side)" + }); + }; + const backend = await prisma.desinationProvider.create({ data: { name: body.name, @@ -57,6 +76,16 @@ export function route(routeOptions: RouteOptions) { } }); + const init = await backendInit(backend, backends, prisma); + + if (!init) { + // TODO: better error code + return res.status(504).send({ + error: "Backend is created, but failed to initalize correctly", + id: backend.id + }); + } + return { success: true, id: backend.id diff --git a/src/routes/backends/remove.ts b/src/routes/backends/remove.ts index 13dbb73..8a69c31 100644 --- a/src/routes/backends/remove.ts +++ b/src/routes/backends/remove.ts @@ -5,7 +5,8 @@ export function route(routeOptions: RouteOptions) { const { fastify, prisma, - tokens + tokens, + backends } = routeOptions; function hasPermission(token: string, permissionList: string[]): Promise { @@ -42,6 +43,21 @@ export function route(routeOptions: RouteOptions) { }); }; + if (!backends[body.id]) { + return res.status(400).send({ + error: "Backend not found" + }); + }; + + // Unload the backend + if (!await backends[body.id].stop()) { + return res.status(400).send({ + error: "Failed to stop backend! Please report this issue." + }) + } + + delete backends[body.id]; + await prisma.desinationProvider.delete({ where: { id: body.id diff --git a/src/routes/user/login.ts b/src/routes/user/login.ts index 525b23b..bf9dec6 100644 --- a/src/routes/user/login.ts +++ b/src/routes/user/login.ts @@ -20,7 +20,7 @@ export function route(routeOptions: RouteOptions) { required: ["email", "password"], properties: { - email: { type: "string" }, + email: { type: "string" }, password: { type: "string" } } }