diff --git a/server/db/schema.ts b/server/db/schema.ts index ad71eaea..081fad7c 100644 --- a/server/db/schema.ts +++ b/server/db/schema.ts @@ -3,61 +3,63 @@ import { InferSelectModel } from "drizzle-orm"; // Orgs table export const orgs = sqliteTable("orgs", { - orgId: integer("orgId").primaryKey({ autoIncrement: true }), - name: text("name").notNull(), - domain: text("domain").notNull(), + orgId: integer("orgId").primaryKey({ autoIncrement: true }), + name: text("name").notNull(), + domain: text("domain").notNull(), }); // Users table export const users = sqliteTable("users", { - userId: integer("userId").primaryKey({ autoIncrement: true }), - orgId: integer("orgId").references(() => orgs.orgId), - name: text("name").notNull(), - email: text("email").notNull(), - groups: text("groups"), + userId: integer("userId").primaryKey({ autoIncrement: true }), + orgId: integer("orgId").references(() => orgs.orgId), + name: text("name").notNull(), + email: text("email").notNull(), + groups: text("groups"), }); // Sites table export const sites = sqliteTable("sites", { - siteId: integer("siteId").primaryKey({ autoIncrement: true }), - orgId: integer("orgId").references(() => orgs.orgId), - exitNode: integer("exitNode").references(() => exitNodes.exitNodeId), - name: text("name").notNull(), - subdomain: text("subdomain"), - pubKey: text("pubKey"), - subnet: text("subnet"), + siteId: integer("siteId").primaryKey({ autoIncrement: true }), + orgId: integer("orgId").references(() => orgs.orgId), + exitNode: integer("exitNode").references(() => exitNodes.exitNodeId), + name: text("name").notNull(), + subdomain: text("subdomain"), + pubKey: text("pubKey"), + subnet: text("subnet"), }); // Resources table export const resources = sqliteTable("resources", { - resourceId: integer("resourceId").primaryKey({ autoIncrement: true }), - siteId: integer("siteId").references(() => sites.siteId), - name: text("name").notNull(), - subdomain: text("subdomain"), + resourceId: integer("resourceId").primaryKey({ autoIncrement: true }), + siteId: integer("siteId").references(() => sites.siteId), + name: text("name").notNull(), + subdomain: text("subdomain"), }); // Exit Nodes table export const exitNodes = sqliteTable("exitNodes", { - exitNodeId: integer("exitNodeId").primaryKey({ autoIncrement: true }), - name: text("name").notNull(), - address: text("address").notNull(), + exitNodeId: integer("exitNodeId").primaryKey({ autoIncrement: true }), + name: text("name").notNull(), + address: text("address").notNull(), + privateKey: text("privateKey"), + listenPort: integer("listenPort"), }); // Routes table export const routes = sqliteTable("routes", { - routeId: integer("routeId").primaryKey({ autoIncrement: true }), - exitNodeId: integer("exitNodeId").references(() => exitNodes.exitNodeId), - subnet: text("subnet").notNull(), + routeId: integer("routeId").primaryKey({ autoIncrement: true }), + exitNodeId: integer("exitNodeId").references(() => exitNodes.exitNodeId), + subnet: text("subnet").notNull(), }); // Targets table export const targets = sqliteTable("targets", { - targetId: integer("targetId").primaryKey({ autoIncrement: true }), - resourceId: integer("resourceId").references(() => resources.resourceId), - ip: text("ip").notNull(), - method: text("method"), - port: integer("port"), - protocol: text("protocol"), + targetId: integer("targetId").primaryKey({ autoIncrement: true }), + resourceId: integer("resourceId").references(() => resources.resourceId), + ip: text("ip").notNull(), + method: text("method"), + port: integer("port"), + protocol: text("protocol"), }); // Define the model types for type inference diff --git a/server/migrations/0000_short_ulik.sql b/server/migrations/0000_unique_killraven.sql similarity index 96% rename from server/migrations/0000_short_ulik.sql rename to server/migrations/0000_unique_killraven.sql index 84c95510..229c589d 100644 --- a/server/migrations/0000_short_ulik.sql +++ b/server/migrations/0000_unique_killraven.sql @@ -1,7 +1,9 @@ CREATE TABLE `exitNodes` ( `exitNodeId` integer PRIMARY KEY AUTOINCREMENT NOT NULL, `name` text NOT NULL, - `address` text NOT NULL + `address` text NOT NULL, + `privateKey` text, + `listenPort` integer ); --> statement-breakpoint CREATE TABLE `orgs` ( diff --git a/server/migrations/meta/0000_snapshot.json b/server/migrations/meta/0000_snapshot.json index 5a16c25d..75117eb4 100644 --- a/server/migrations/meta/0000_snapshot.json +++ b/server/migrations/meta/0000_snapshot.json @@ -1,7 +1,7 @@ { "version": "6", "dialect": "sqlite", - "id": "9b039f4c-6867-4b08-8aa9-bc184c37b910", + "id": "369f669c-f220-4706-9a5c-8a66ab5653b2", "prevId": "00000000-0000-0000-0000-000000000000", "tables": { "exitNodes": { @@ -27,6 +27,20 @@ "primaryKey": false, "notNull": true, "autoincrement": false + }, + "privateKey": { + "name": "privateKey", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "listenPort": { + "name": "listenPort", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false } }, "indexes": {}, diff --git a/server/migrations/meta/_journal.json b/server/migrations/meta/_journal.json index abe1f447..55506fe3 100644 --- a/server/migrations/meta/_journal.json +++ b/server/migrations/meta/_journal.json @@ -5,8 +5,8 @@ { "idx": 0, "version": "6", - "when": 1727544220529, - "tag": "0000_short_ulik", + "when": 1727551266674, + "tag": "0000_unique_killraven", "breakpoints": true } ] diff --git a/server/routers/badger/getConfig.ts b/server/routers/badger/getConfig.ts index ce614b22..a7b47d53 100644 --- a/server/routers/badger/getConfig.ts +++ b/server/routers/badger/getConfig.ts @@ -1,20 +1,53 @@ import { Request, Response, NextFunction } from 'express'; -import { DrizzleError } from 'drizzle-orm'; +import { DrizzleError, eq } from 'drizzle-orm'; import { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3'; import { sites, Site } from '../../db/schema'; import db from '../../db'; export const getConfig = async (req: Request, res: Response, next: NextFunction): Promise => { try { - const exitNodeId = req.query.exitNodeId as string; + const exitNodeId = parseInt(req.query.exitNodeId as string); if (!db) { throw new Error('Database is not attached to the request'); } - const results: Site[] = db.select().from(sites).all(); - res.json(results); + const exitNode = await db.query.exitNodes.findFirst({ + where: { + exitNodeId: eq(exitNodeId) + }, + with: { + routes: true, + sites: { + with: { + resources: { + with: { + targets: true + } + } + } + } + } + }); + + if (!exitNode) { + throw new Error('Exit node not found'); + } + + const config = { + privateKey, + listenPort, + ipAddress: exitNode.address, + peers: exitNode.sites.map((site, index) => ({ + publicKey: site.pubKey, + allowedIps: site.resources.flatMap(resource => + resource.targets.map(target => target.ip) + ) + })) + }; + + res.json(config); } catch (error) { console.error('Error querying database:', error); if (error instanceof DrizzleError) { @@ -23,4 +56,11 @@ export const getConfig = async (req: Request, res: Response, next: NextFunction) next(error); } } -}; \ No newline at end of file +}; + +function calculateSubnet(index: number): string { + const baseIp = 10 << 24; + const subnetSize = 16; + return `${(baseIp | (index * subnetSize)).toString()}/28`; + } + \ No newline at end of file