mirror of
https://github.com/fosrl/pangolin.git
synced 2025-07-24 04:34:55 +02:00
Newt registration?
This commit is contained in:
parent
e141263b7e
commit
40734184af
11 changed files with 89 additions and 53 deletions
|
@ -12,7 +12,7 @@ post {
|
||||||
|
|
||||||
body:json {
|
body:json {
|
||||||
{
|
{
|
||||||
"email": "milo@fossorial.io",
|
"email": "owen@fossorial.io",
|
||||||
"password": "Password123!"
|
"password": "Password123!"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ put {
|
||||||
|
|
||||||
body:json {
|
body:json {
|
||||||
{
|
{
|
||||||
"email": "milo@fossorial.io",
|
"email": "numbat@fossorial.io",
|
||||||
"password": "Password123!"
|
"password": "Password123!"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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", {
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
|
@ -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
|
|
||||||
};
|
|
||||||
};
|
|
42
server/routers/newt/handleRegisterMessage.ts
Normal file
42
server/routers/newt/handleRegisterMessage.ts
Normal 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
|
||||||
|
};
|
||||||
|
};
|
|
@ -1,3 +1,3 @@
|
||||||
export * from "./createNewt";
|
export * from "./createNewt";
|
||||||
export * from "./getToken";
|
export * from "./getToken";
|
||||||
export * from "./handleNewtMessage";
|
export * from "./handleRegisterMessage";
|
|
@ -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: {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue