Newt registration?

This commit is contained in:
Owen Schwartz 2024-11-15 21:53:58 -05:00
parent e141263b7e
commit 40734184af
No known key found for this signature in database
GPG key ID: 8271FDFFD9E0CCBD
11 changed files with 89 additions and 53 deletions

View file

@ -12,7 +12,7 @@ post {
body:json { body:json {
{ {
"email": "milo@fossorial.io", "email": "owen@fossorial.io",
"password": "Password123!" "password": "Password123!"
} }
} }

View file

@ -12,7 +12,7 @@ put {
body:json { body:json {
{ {
"email": "milo@fossorial.io", "email": "numbat@fossorial.io",
"password": "Password123!" "password": "Password123!"
} }
} }

View file

@ -5,7 +5,7 @@ meta {
} }
get { get {
url: http://localhost:3000/api/v1/org/theorg/sites/mexican-mole-lizard-windy url: http://localhost:3000/api/v1/org/test/sites/mexican-mole-lizard-windy
body: none body: none
auth: none auth: none
} }

View file

@ -17,7 +17,7 @@ export const sites = sqliteTable("sites", {
onDelete: "set null", onDelete: "set null",
}), }),
name: text("name").notNull(), name: text("name").notNull(),
pubKey: text("pubKey").notNull(), pubKey: text("pubKey"),
subnet: text("subnet").notNull(), subnet: text("subnet").notNull(),
megabytesIn: integer("bytesIn"), megabytesIn: integer("bytesIn"),
megabytesOut: integer("bytesOut"), megabytesOut: integer("bytesOut"),
@ -77,6 +77,9 @@ export const newts = sqliteTable("newt", {
newtId: text("id").primaryKey(), newtId: text("id").primaryKey(),
secretHash: text("secretHash").notNull(), secretHash: text("secretHash").notNull(),
dateCreated: text("dateCreated").notNull(), dateCreated: text("dateCreated").notNull(),
siteId: integer("siteId").references(() => sites.siteId, {
onDelete: "cascade",
}),
}); });
export const twoFactorBackupCodes = sqliteTable("twoFactorBackupCodes", { export const twoFactorBackupCodes = sqliteTable("twoFactorBackupCodes", {

View file

@ -1,6 +1,6 @@
import { handleNewtMessage } from "./newt"; import { handleRegisterMessage } from "./newt";
import { MessageHandler } from "./ws"; import { MessageHandler } from "./ws";
export const messageHandlers: Record<string, MessageHandler> = { export const messageHandlers: Record<string, MessageHandler> = {
"newt": handleNewtMessage, "newt/wg/register": handleRegisterMessage,
}; };

View file

@ -1,22 +0,0 @@
// messageHandlers/chat.ts
import { MessageHandler } from "../ws";
export const handleNewtMessage: MessageHandler = async (context) => {
const { message, senderNewtId, sendToClient } = context;
// Process chat message
// ... your chat logic here ...
// Example response
return {
message: {
type: 'newt_response',
data: {
originalMessage: message.data,
timestamp: new Date().toISOString()
}
},
broadcast: false, // Send to all clients
excludeSender: false // Include sender in broadcast
};
};

View file

@ -0,0 +1,42 @@
import db from "@server/db";
import { MessageHandler } from "../ws";
import { sites } from "@server/db/schema";
import { eq } from "drizzle-orm";
export const handleRegisterMessage: MessageHandler = async (context) => {
const { message, newt, sendToClient } = context;
if (!newt) {
console.log("Newt not found");
return;
}
if (!newt.siteId) {
console.log("Newt has no site!"); // TODO: Maybe we create the site here?
return;
}
const siteId = newt.siteId;
// get the site
const site = await db
.select()
.from(sites)
.where(eq(sites.siteId, siteId))
.limit(1);
const { publicKey } = message.data;
return {
message: {
type: 'newt/wg/connect',
data: {
publicKey: 'publicKey',
}
},
broadcast: false, // Send to all clients
excludeSender: false // Include sender in broadcast
};
};

View file

@ -1,3 +1,3 @@
export * from "./createNewt"; export * from "./createNewt";
export * from "./getToken"; export * from "./getToken";
export * from "./handleNewtMessage"; export * from "./handleRegisterMessage";

View file

@ -19,7 +19,7 @@ const createSiteSchema = z.object({
name: z.string().min(1).max(255), name: z.string().min(1).max(255),
exitNodeId: z.number().int().positive(), exitNodeId: z.number().int().positive(),
subdomain: z.string().min(1).max(255).optional(), subdomain: z.string().min(1).max(255).optional(),
pubKey: z.string(), pubKey: z.string().optional(),
subnet: z.string(), subnet: z.string(),
}); });
@ -68,16 +68,24 @@ export async function createSite(
const niceId = await getUniqueSiteName(orgId); const niceId = await getUniqueSiteName(orgId);
let payload: any = {
orgId,
exitNodeId,
name,
niceId,
subnet,
};
if (pubKey) {
payload = {
...payload,
pubKey,
};
}
const [newSite] = await db const [newSite] = await db
.insert(sites) .insert(sites)
.values({ .values(payload)
orgId,
exitNodeId,
name,
niceId,
pubKey,
subnet,
})
.returning(); .returning();
const adminRole = await db const adminRole = await db
@ -105,11 +113,13 @@ export async function createSite(
}); });
} }
// add the peer to the exit node if (pubKey) {
await addPeer(exitNodeId, { // add the peer to the exit node
publicKey: pubKey, await addPeer(exitNodeId, {
allowedIps: [], publicKey: pubKey,
}); allowedIps: [],
});
}
return response(res, { return response(res, {
data: { data: {

View file

@ -48,7 +48,9 @@ export async function deleteSite(
); );
} }
await deletePeer(deletedSite.exitNodeId!, deletedSite.pubKey); if (deletedSite.pubKey) {
await deletePeer(deletedSite.exitNodeId!, deletedSite.pubKey);
}
return response(res, { return response(res, {
data: null, data: null,
@ -79,7 +81,7 @@ async function removePeer(publicKey: string) {
} }
const data = await response.json(); const data = await response.json();
console.log("Peer removed successfully:", data.status); logger.info("Peer removed successfully:", data.status);
return data; return data;
} catch (error: any) { } catch (error: any) {
console.error("Error removing peer:", error.message); console.error("Error removing peer:", error.message);

View file

@ -8,6 +8,7 @@ import { eq } from "drizzle-orm";
import db from "@server/db"; import db from "@server/db";
import { validateNewtSessionToken } from "@server/auth/newt"; import { validateNewtSessionToken } from "@server/auth/newt";
import { messageHandlers } from "./messageHandlers"; import { messageHandlers } from "./messageHandlers";
import logger from "@server/logger";
// Custom interfaces // Custom interfaces
interface WebSocketRequest extends IncomingMessage { interface WebSocketRequest extends IncomingMessage {
@ -39,7 +40,7 @@ interface HandlerResponse {
interface HandlerContext { interface HandlerContext {
message: WSMessage; message: WSMessage;
senderWs: WebSocket; senderWs: WebSocket;
senderNewtId: string; newt: Newt | undefined;
sendToClient: (newtId: string, message: WSMessage) => boolean; sendToClient: (newtId: string, message: WSMessage) => boolean;
broadcastToAllExcept: (message: WSMessage, excludeNewtId?: string) => void; broadcastToAllExcept: (message: WSMessage, excludeNewtId?: string) => void;
connectedClients: Map<string, WebSocket[]>; connectedClients: Map<string, WebSocket[]>;
@ -58,7 +59,7 @@ const addClient = (newtId: string, ws: AuthenticatedWebSocket): void => {
const existingClients = connectedClients.get(newtId) || []; const existingClients = connectedClients.get(newtId) || [];
existingClients.push(ws); existingClients.push(ws);
connectedClients.set(newtId, existingClients); connectedClients.set(newtId, existingClients);
console.log(`Client added to tracking - Newt ID: ${newtId}, Total connections: ${existingClients.length}`); logger.info(`Client added to tracking - Newt ID: ${newtId}, Total connections: ${existingClients.length}`);
}; };
const removeClient = (newtId: string, ws: AuthenticatedWebSocket): void => { const removeClient = (newtId: string, ws: AuthenticatedWebSocket): void => {
@ -67,10 +68,10 @@ const removeClient = (newtId: string, ws: AuthenticatedWebSocket): void => {
if (updatedClients.length === 0) { if (updatedClients.length === 0) {
connectedClients.delete(newtId); connectedClients.delete(newtId);
console.log(`All connections removed for Newt ID: ${newtId}`); logger.info(`All connections removed for Newt ID: ${newtId}`);
} else { } else {
connectedClients.set(newtId, updatedClients); connectedClients.set(newtId, updatedClients);
console.log(`Connection removed - Newt ID: ${newtId}, Remaining connections: ${updatedClients.length}`); logger.info(`Connection removed - Newt ID: ${newtId}, Remaining connections: ${updatedClients.length}`);
} }
}; };
@ -78,7 +79,7 @@ const removeClient = (newtId: string, ws: AuthenticatedWebSocket): void => {
const sendToClient = (newtId: string, message: WSMessage): boolean => { const sendToClient = (newtId: string, message: WSMessage): boolean => {
const clients = connectedClients.get(newtId); const clients = connectedClients.get(newtId);
if (!clients || clients.length === 0) { if (!clients || clients.length === 0) {
console.log(`No active connections found for Newt ID: ${newtId}`); logger.info(`No active connections found for Newt ID: ${newtId}`);
return false; return false;
} }
@ -198,7 +199,7 @@ wss.on("connection", (ws: AuthenticatedWebSocket, request: WebSocketRequest) =>
ws.on("message", async (data) => { ws.on("message", async (data) => {
try { try {
const message: WSMessage = JSON.parse(data.toString()); const message: WSMessage = JSON.parse(data.toString());
// console.log(`Message received from Newt ID ${newtId}:`, message); // logger.info(`Message received from Newt ID ${newtId}:`, message);
// Validate message format // Validate message format
if (!message.type || typeof message.type !== "string") { if (!message.type || typeof message.type !== "string") {
@ -215,7 +216,7 @@ wss.on("connection", (ws: AuthenticatedWebSocket, request: WebSocketRequest) =>
const response = await handler({ const response = await handler({
message, message,
senderWs: ws, senderWs: ws,
senderNewtId: newtId, newt: ws.newt,
sendToClient, sendToClient,
broadcastToAllExcept, broadcastToAllExcept,
connectedClients connectedClients
@ -250,7 +251,7 @@ wss.on("connection", (ws: AuthenticatedWebSocket, request: WebSocketRequest) =>
ws.on("close", () => { ws.on("close", () => {
clearInterval(pingInterval); clearInterval(pingInterval);
removeClient(newtId, ws); removeClient(newtId, ws);
console.log(`Client disconnected - Newt ID: ${newtId}`); logger.info(`Client disconnected - Newt ID: ${newtId}`);
}); });
ws.on("error", (error: Error) => { ws.on("error", (error: Error) => {