Chungus 2.0

This commit is contained in:
Owen
2025-10-10 11:27:15 -07:00
parent f64a477c3d
commit d92b87b7c8
224 changed files with 1507 additions and 1586 deletions

View File

@@ -1,19 +1,16 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { sites, resources, targets, exitNodes, ExitNode } from "@server/db";
import { sites, exitNodes, ExitNode } from "@server/db";
import { db } from "@server/db";
import { eq, isNotNull, and } from "drizzle-orm";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
import logger from "@server/logger";
import config from "@server/lib/config";
import { getUniqueExitNodeEndpointName } from "../../db/names";
import { findNextAvailableCidr } from "@server/lib/ip";
import { fromError } from "zod-validation-error";
import { getAllowedIps } from "../target/helpers";
import { proxyToRemote } from "@server/lib/remoteProxy";
import { getNextAvailableSubnet } from "@server/lib/exitNodes";
import { createExitNode } from "./privateCreateExitNode";
import { createExitNode } from "#dynamic/routers/gerbil/createExitNode";
// Define Zod schema for request validation
const getConfigSchema = z.object({

View File

@@ -4,9 +4,9 @@ import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
import logger from "@server/logger";
import { fromError } from "zod-validation-error";
import { resolveExitNodes } from "@server/lib/exitNodes";
import config from "@server/lib/config";
import { resolveExitNodes } from "#dynamic/lib/exitNodes";
import { build } from "@server/build";
import config from "@server/lib/config";
// Define Zod schema for request validation
const getResolvedHostnameSchema = z.object({
@@ -36,7 +36,15 @@ export async function getResolvedHostname(
const { hostname, publicKey } = parsedParams.data;
const baseDomain = config.getRawPrivateConfig().app.base_domain;
const dashboardUrl = config.getRawConfig().app.dashboard_url;
// extract the domain removing the http and stuff
const baseDomain = dashboardUrl
? dashboardUrl
.replace("http://", "")
.replace("https://", "")
.split("/")[0]
: null;
// if the hostname ends with the base domain then send back a empty array
if (baseDomain && hostname.endsWith(baseDomain)) {
@@ -50,6 +58,13 @@ export async function getResolvedHostname(
publicKey
);
if (resourceExitNodes.length === 0) {
// no exit nodes found, return empty array to force local routing
return res.status(HttpCode.OK).send({
endpoints: [] // this should force to route locally
});
}
endpoints = resourceExitNodes.map((node) => node.endpoint);
}

View File

@@ -2,7 +2,7 @@ import logger from "@server/logger";
import { db } from "@server/db";
import { exitNodes } from "@server/db";
import { eq } from "drizzle-orm";
import { sendToExitNode } from "@server/lib/exitNodes";
import { sendToExitNode } from "#dynamic/lib/exitNodes";
export async function addPeer(
exitNodeId: number,

View File

@@ -1,67 +0,0 @@
/*
* This file is part of a proprietary work.
*
* Copyright (c) 2025 Fossorial, Inc.
* All rights reserved.
*
* This file is licensed under the Fossorial Commercial License.
* You may not use this file except in compliance with the License.
* Unauthorized use, copying, modification, or distribution is strictly prohibited.
*
* This file is not licensed under the AGPLv3.
*/
import { db, ExitNode, exitNodes } from "@server/db";
import { getUniqueExitNodeEndpointName } from "@server/db/names";
import config from "@server/lib/config";
import { getNextAvailableSubnet } from "@server/lib/exitNodes";
import logger from "@server/logger";
import { eq } from "drizzle-orm";
export async function createExitNode(
publicKey: string,
reachableAt: string | undefined
) {
// Fetch exit node
const [exitNodeQuery] = await db
.select()
.from(exitNodes)
.where(eq(exitNodes.publicKey, publicKey));
let exitNode: ExitNode;
if (!exitNodeQuery) {
const address = await getNextAvailableSubnet();
// TODO: eventually we will want to get the next available port so that we can multiple exit nodes
// const listenPort = await getNextAvailablePort();
const listenPort = config.getRawConfig().gerbil.start_port;
let subEndpoint = "";
if (config.getRawConfig().gerbil.use_subdomain) {
subEndpoint = await getUniqueExitNodeEndpointName();
}
const exitNodeName =
config.getRawConfig().gerbil.exit_node_name ||
`Exit Node ${publicKey.slice(0, 8)}`;
// create a new exit node
[exitNode] = await db
.insert(exitNodes)
.values({
publicKey,
endpoint: `${subEndpoint}${subEndpoint != "" ? "." : ""}${config.getRawConfig().gerbil.base_endpoint}`,
address,
listenPort,
reachableAt,
name: exitNodeName
})
.returning()
.execute();
logger.info(
`Created new exit node ${exitNode.name} with address ${exitNode.address} and port ${exitNode.listenPort}`
);
} else {
exitNode = exitNodeQuery;
}
return exitNode;
}

View File

@@ -1,13 +0,0 @@
/*
* This file is part of a proprietary work.
*
* Copyright (c) 2025 Fossorial, Inc.
* All rights reserved.
*
* This file is licensed under the Fossorial Commercial License.
* You may not use this file except in compliance with the License.
* Unauthorized use, copying, modification, or distribution is strictly prohibited.
*
* This file is not licensed under the AGPLv3.
*/

View File

@@ -6,9 +6,9 @@ import logger from "@server/logger";
import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode";
import response from "@server/lib/response";
import { usageService } from "@server/lib/private/billing/usageService";
import { FeatureId } from "@server/lib/private/billing/features";
import { checkExitNodeOrg } from "@server/lib/exitNodes";
import { usageService } from "@server/lib/billing/usageService";
import { FeatureId } from "@server/lib/billing/features";
import { checkExitNodeOrg } from "#dynamic/lib/exitNodes";
import { build } from "@server/build";
// Track sites that are already offline to avoid unnecessary queries

View File

@@ -18,8 +18,7 @@ import logger from "@server/logger";
import { fromError } from "zod-validation-error";
import { validateNewtSessionToken } from "@server/auth/sessions/newt";
import { validateOlmSessionToken } from "@server/auth/sessions/olm";
import axios from "axios";
import { checkExitNodeOrg } from "@server/lib/exitNodes";
import { checkExitNodeOrg } from "#dynamic/lib/exitNodes";
// Define Zod schema for request validation
const updateHolePunchSchema = z.object({