mirror of
https://github.com/fosrl/pangolin.git
synced 2025-07-28 22:55:07 +02:00
Get new api endpoints working
This commit is contained in:
parent
6e1bfdac58
commit
b1f4971f25
13 changed files with 79 additions and 51 deletions
|
@ -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:
|
||||
|
|
|
@ -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()
|
||||
});
|
||||
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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!");
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export * from "./createNewt";
|
||||
export * from "./getToken";
|
||||
export * from "./getNewtToken";
|
||||
export * from "./handleNewtRegisterMessage";
|
||||
export* from "./handleReceiveBandwidthMessage";
|
|
@ -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"
|
||||
)
|
||||
);
|
||||
}
|
|
@ -1 +1,3 @@
|
|||
export * from "./handleOlmRegisterMessage";
|
||||
export * from "./getOlmToken";
|
||||
export * from "./createOlm";
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue