mirror of
https://github.com/fosrl/pangolin.git
synced 2026-02-08 05:56:38 +00:00
Chungus 2.0
This commit is contained in:
@@ -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({
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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({
|
||||
|
||||
Reference in New Issue
Block a user