Get new api endpoints working

This commit is contained in:
Owen 2025-02-21 16:12:21 -05:00
parent 6e1bfdac58
commit b1f4971f25
No known key found for this signature in database
GPG key ID: 8271FDFFD9E0CCBD
13 changed files with 79 additions and 51 deletions

View file

@ -35,7 +35,8 @@ gerbil:
wg_site:
start_port: 51820
block_size: 24
subnet_group: 100.89.137.0/20
subnet_group: 100.89.138.0/20
site_block_size: 30
rate_limits:
global:

View file

@ -173,7 +173,7 @@ export const olmSessions = sqliteTable("clientSession", {
sessionId: text("id").primaryKey(),
olmId: text("olmId")
.notNull()
.references(() => newts.newtId, { onDelete: "cascade" }),
.references(() => olms.olmId, { onDelete: "cascade" }),
expiresAt: integer("expiresAt").notNull()
});

View file

@ -113,7 +113,8 @@ const configSchema = z.object({
wg_site: z.object({
block_size: z.number().positive().gt(0),
subnet_group: z.string(),
start_port: portSchema
start_port: portSchema,
site_block_size: z.number().positive().gt(0)
}),
rate_limits: z.object({
global: z.object({

View file

@ -37,10 +37,10 @@ const createClientSchema = z
.object({
name: z.string().min(1).max(255),
siteId: z.number().int().positive(),
pubKey: z.string(),
subnet: z.string(),
olmId: z.string(),
secret: z.string(),
pubKey: z.string().optional(),
subnet: z.string().optional(),
olmId: z.string().optional(),
secret: z.string().optional(),
type: z.enum(["olm"])
})
.strict();

View file

@ -14,7 +14,7 @@ import { fromError } from "zod-validation-error";
const getSiteSchema = z
.object({
siteId: z.number().int().positive()
siteId: z.string().transform(Number).pipe(z.number())
})
.strict();
@ -92,12 +92,16 @@ export async function pickClientDefaults(
subnets.push(
address.replace(
/\/\d+$/,
`/${config.getRawConfig().wg_site.block_size}`
`/${config.getRawConfig().wg_site.site_block_size}`
)
);
logger.debug(`Subnets: ${subnets}`);
logger.debug(`Address: ${address}`);
logger.debug(`Block size: ${config.getRawConfig().wg_site.block_size}`);
logger.debug(`Site block size: ${config.getRawConfig().wg_site.site_block_size}`);
const newSubnet = findNextAvailableCidr(
subnets,
config.getRawConfig().wg_site.block_size,
config.getRawConfig().wg_site.site_block_size,
address
);
if (!newSubnet) {

View file

@ -28,7 +28,8 @@ import {
import { verifyUserHasAction } from "../middlewares/verifyUserHasAction";
import { ActionsEnum } from "@server/auth/actions";
import { verifyUserIsOrgOwner } from "../middlewares/verifyUserIsOrgOwner";
import { createNewt, getToken } from "./newt";
import { createNewt, getNewtToken } from "./newt";
import { getOlmToken } from "./olm";
import rateLimit from "express-rate-limit";
import createHttpError from "http-errors";
@ -501,7 +502,8 @@ authRouter.use(
authRouter.put("/signup", auth.signup);
authRouter.post("/login", auth.login);
authRouter.post("/logout", auth.logout);
authRouter.post("/newt/get-token", getToken);
authRouter.post("/newt/get-token", getNewtToken);
authRouter.post("/olm/get-token", getOlmToken);
authRouter.post("/2fa/enable", verifySessionUserMiddleware, auth.verifyTotp);
authRouter.post(

View file

@ -24,7 +24,7 @@ export const newtGetTokenBodySchema = z.object({
export type NewtGetTokenBody = z.infer<typeof newtGetTokenBodySchema>;
export async function getToken(
export async function getNewtToken(
req: Request,
res: Response,
next: NextFunction

View file

@ -10,8 +10,7 @@ import config from "@server/lib/config";
const inputSchema = z.object({
publicKey: z.string(),
endpoint: z.string(),
listenPort: z.number()
endpoint: z.string()
});
type Input = z.infer<typeof inputSchema>;
@ -20,6 +19,9 @@ export const handleGetConfigMessage: MessageHandler = async (context) => {
const { message, client, sendToClient } = context;
const newt = client as Newt;
logger.debug(JSON.stringify(message.data));
logger.debug("Handling Newt get config message!");
if (!newt) {
@ -99,8 +101,8 @@ export const handleGetConfigMessage: MessageHandler = async (context) => {
);
const configResponse = {
listenPort: site.listenPort, // ?????
// ipAddress: exitNode[0].address,
listenPort: site.listenPort,
ipAddress: site.address,
peers
};

View file

@ -12,9 +12,12 @@ interface PeerBandwidth {
export const handleReceiveBandwidthMessage: MessageHandler = async (context) => {
const { message, client, sendToClient } = context;
const newt = client as Newt;
const bandwidthData: PeerBandwidth[] = message.data;
if (!message.data.bandwidthData) {
logger.warn("No bandwidth data provided");
}
const bandwidthData: PeerBandwidth[] = message.data.bandwidthData;
if (!Array.isArray(bandwidthData)) {
throw new Error("Invalid bandwidth data");
@ -63,6 +66,4 @@ export const handleReceiveBandwidthMessage: MessageHandler = async (context) =>
.where(eq(clients.clientId, client.clientId));
}
});
logger.info("Handling register olm message!");
};

View file

@ -1,4 +1,4 @@
export * from "./createNewt";
export * from "./getToken";
export * from "./getNewtToken";
export * from "./handleNewtRegisterMessage";
export* from "./handleReceiveBandwidthMessage";

View file

@ -1,6 +1,6 @@
import { generateSessionToken } from "@server/auth/sessions/app";
import db from "@server/db";
import { newts } from "@server/db/schema";
import { olms } from "@server/db/schema";
import HttpCode from "@server/types/HttpCode";
import response from "@server/lib/response";
import { eq } from "drizzle-orm";
@ -9,27 +9,27 @@ import createHttpError from "http-errors";
import { z } from "zod";
import { fromError } from "zod-validation-error";
import {
createNewtSession,
validateNewtSessionToken
} from "@server/auth/sessions/newt";
createOlmSession,
validateOlmSessionToken
} from "@server/auth/sessions/olm";
import { verifyPassword } from "@server/auth/password";
import logger from "@server/logger";
import config from "@server/lib/config";
export const newtGetTokenBodySchema = z.object({
newtId: z.string(),
export const olmGetTokenBodySchema = z.object({
olmId: z.string(),
secret: z.string(),
token: z.string().optional()
});
export type NewtGetTokenBody = z.infer<typeof newtGetTokenBodySchema>;
export type OlmGetTokenBody = z.infer<typeof olmGetTokenBodySchema>;
export async function getToken(
export async function getOlmToken(
req: Request,
res: Response,
next: NextFunction
): Promise<any> {
const parsedBody = newtGetTokenBodySchema.safeParse(req.body);
const parsedBody = olmGetTokenBodySchema.safeParse(req.body);
if (!parsedBody.success) {
return next(
@ -40,15 +40,15 @@ export async function getToken(
);
}
const { newtId, secret, token } = parsedBody.data;
const { olmId, secret, token } = parsedBody.data;
try {
if (token) {
const { session, newt } = await validateNewtSessionToken(token);
const { session, olm } = await validateOlmSessionToken(token);
if (session) {
if (config.getRawConfig().app.log_failed_attempts) {
logger.info(
`Newt session already valid. Newt ID: ${newtId}. IP: ${req.ip}.`
`Olm session already valid. Olm ID: ${olmId}. IP: ${req.ip}.`
);
}
return response<null>(res, {
@ -61,29 +61,31 @@ export async function getToken(
}
}
const existingNewtRes = await db
const existingOlmRes = await db
.select()
.from(newts)
.where(eq(newts.newtId, newtId));
if (!existingNewtRes || !existingNewtRes.length) {
.from(olms)
.where(eq(olms.olmId, olmId));
if (!existingOlmRes || !existingOlmRes.length) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
"No newt found with that newtId"
"No olm found with that olmId"
)
);
}
const existingNewt = existingNewtRes[0];
logger.debug("Existing olm: ", existingOlmRes);
const existingOlm = existingOlmRes[0];
const validSecret = await verifyPassword(
secret,
existingNewt.secretHash
existingOlm.secretHash
);
if (!validSecret) {
if (config.getRawConfig().app.log_failed_attempts) {
logger.info(
`Newt id or secret is incorrect. Newt: ID ${newtId}. IP: ${req.ip}.`
`Olm id or secret is incorrect. Olm: ID ${olmId}. IP: ${req.ip}.`
);
}
return next(
@ -91,8 +93,12 @@ export async function getToken(
);
}
logger.debug("Creating new olm session token");
const resToken = generateSessionToken();
await createNewtSession(resToken, existingNewt.newtId);
await createOlmSession(resToken, existingOlm.olmId);
logger.debug("Token created successfully");
return response<{ token: string }>(res, {
data: {
@ -103,12 +109,12 @@ export async function getToken(
message: "Token created successfully",
status: HttpCode.OK
});
} catch (e) {
console.error(e);
} catch (error) {
logger.error(error);
return next(
createHttpError(
HttpCode.INTERNAL_SERVER_ERROR,
"Failed to authenticate newt"
"Failed to authenticate olm"
)
);
}

View file

@ -1 +1,3 @@
export * from "./handleOlmRegisterMessage";
export * from "./getOlmToken";
export * from "./createOlm";

View file

@ -45,7 +45,7 @@ export async function pickSiteDefaults(
// list all of the sites on that exit node
const sitesQuery = await db
.select({
subnet: sites.subnet,
subnet: sites.subnet
})
.from(sites)
.where(eq(sites.exitNodeId, exitNode.exitNodeId));
@ -53,8 +53,17 @@ export async function pickSiteDefaults(
// TODO: we need to lock this subnet for some time so someone else does not take it
let subnets = sitesQuery.map((site) => site.subnet);
// exclude the exit node address by replacing after the / with a site block size
subnets.push(exitNode.address.replace(/\/\d+$/, `/${config.getRawConfig().gerbil.site_block_size}`));
const newSubnet = findNextAvailableCidr(subnets, config.getRawConfig().gerbil.site_block_size, exitNode.address);
subnets.push(
exitNode.address.replace(
/\/\d+$/,
`/${config.getRawConfig().gerbil.site_block_size}`
)
);
const newSubnet = findNextAvailableCidr(
subnets,
config.getRawConfig().gerbil.site_block_size,
exitNode.address
);
if (!newSubnet) {
return next(
createHttpError(
@ -77,12 +86,12 @@ export async function pickSiteDefaults(
endpoint: exitNode.endpoint,
subnet: newSubnet,
newtId,
newtSecret: secret,
newtSecret: secret
},
success: true,
error: false,
message: "Organization retrieved successfully",
status: HttpCode.OK,
status: HttpCode.OK
});
} catch (error) {
logger.error(error);