mirror of
https://github.com/fosrl/pangolin.git
synced 2026-03-03 17:26:38 +00:00
add openapi registers
This commit is contained in:
@@ -13,29 +13,30 @@ import { fromError } from "zod-validation-error";
|
||||
import { hash } from "@node-rs/argon2";
|
||||
import { newts } from "@server/db/schemas";
|
||||
import moment from "moment";
|
||||
import { bearerAuth, OpenAPITags, registry } from "@server/openApi";
|
||||
import { OpenAPITags, registry } from "@server/openApi";
|
||||
import { hashPassword } from "@server/auth/password";
|
||||
|
||||
const createSiteParamsSchema = z
|
||||
.object({
|
||||
orgId: z.string().openapi({})
|
||||
orgId: z.string()
|
||||
})
|
||||
.strict();
|
||||
|
||||
const createSiteSchema = z
|
||||
.object({
|
||||
name: z.string().min(1).max(255).openapi({}),
|
||||
exitNodeId: z.number().int().positive().optional().openapi({}),
|
||||
name: z.string().min(1).max(255),
|
||||
exitNodeId: z.number().int().positive().optional(),
|
||||
// subdomain: z
|
||||
// .string()
|
||||
// .min(1)
|
||||
// .max(255)
|
||||
// .transform((val) => val.toLowerCase())
|
||||
// .optional(),
|
||||
pubKey: z.string().optional().openapi({}),
|
||||
subnet: z.string().optional().openapi({}),
|
||||
newtId: z.string().optional().openapi({}),
|
||||
secret: z.string().optional().openapi({}),
|
||||
type: z.enum(["newt", "wireguard", "local"]).openapi({})
|
||||
pubKey: z.string().optional(),
|
||||
subnet: z.string().optional(),
|
||||
newtId: z.string().optional(),
|
||||
secret: z.string().optional(),
|
||||
type: z.enum(["newt", "wireguard", "local"])
|
||||
})
|
||||
.strict();
|
||||
|
||||
@@ -46,8 +47,7 @@ export type CreateSiteResponse = Site;
|
||||
registry.registerPath({
|
||||
method: "put",
|
||||
path: "/org/{orgId}/site",
|
||||
description: "Create a new site",
|
||||
security: [{ [bearerAuth.name]: [] }],
|
||||
description: "Create a new site.",
|
||||
tags: [OpenAPITags.Site, OpenAPITags.Org],
|
||||
request: {
|
||||
params: createSiteParamsSchema,
|
||||
|
||||
@@ -10,6 +10,7 @@ import logger from "@server/logger";
|
||||
import { deletePeer } from "../gerbil/peers";
|
||||
import { fromError } from "zod-validation-error";
|
||||
import { sendToClient } from "../ws";
|
||||
import { OpenAPITags, registry } from "@server/openApi";
|
||||
|
||||
const deleteSiteSchema = z
|
||||
.object({
|
||||
@@ -17,6 +18,17 @@ const deleteSiteSchema = z
|
||||
})
|
||||
.strict();
|
||||
|
||||
registry.registerPath({
|
||||
method: "delete",
|
||||
path: "/site/{siteId}",
|
||||
description: "Delete a site and all its associated data.",
|
||||
tags: [OpenAPITags.Site],
|
||||
request: {
|
||||
params: deleteSiteSchema
|
||||
},
|
||||
responses: {}
|
||||
});
|
||||
|
||||
export async function deleteSite(
|
||||
req: Request,
|
||||
res: Response,
|
||||
|
||||
@@ -9,6 +9,7 @@ import createHttpError from "http-errors";
|
||||
import logger from "@server/logger";
|
||||
import stoi from "@server/lib/stoi";
|
||||
import { fromError } from "zod-validation-error";
|
||||
import { OpenAPITags, registry } from "@server/openApi";
|
||||
|
||||
const getSiteSchema = z
|
||||
.object({
|
||||
@@ -43,6 +44,34 @@ async function query(siteId?: number, niceId?: string, orgId?: string) {
|
||||
|
||||
export type GetSiteResponse = NonNullable<Awaited<ReturnType<typeof query>>>;
|
||||
|
||||
registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/site/{niceId}",
|
||||
description:
|
||||
"Get a site by orgId and niceId. NiceId is a readable ID for the site and unique on a per org basis.",
|
||||
tags: [OpenAPITags.Org, OpenAPITags.Site],
|
||||
request: {
|
||||
params: z.object({
|
||||
orgId: z.string(),
|
||||
niceId: z.string()
|
||||
})
|
||||
},
|
||||
responses: {}
|
||||
});
|
||||
|
||||
registry.registerPath({
|
||||
method: "get",
|
||||
path: "/site/{siteId}",
|
||||
description: "Get a site by siteId.",
|
||||
tags: [OpenAPITags.Site],
|
||||
request: {
|
||||
params: z.object({
|
||||
siteId: z.number()
|
||||
})
|
||||
},
|
||||
responses: {}
|
||||
});
|
||||
|
||||
export async function getSite(
|
||||
req: Request,
|
||||
res: Response,
|
||||
|
||||
@@ -8,6 +8,7 @@ import { NextFunction, Request, Response } from "express";
|
||||
import createHttpError from "http-errors";
|
||||
import { z } from "zod";
|
||||
import { fromError } from "zod-validation-error";
|
||||
import { OpenAPITags, registry } from "@server/openApi";
|
||||
|
||||
const listSitesParamsSchema = z
|
||||
.object({
|
||||
@@ -59,6 +60,18 @@ export type ListSitesResponse = {
|
||||
pagination: { total: number; limit: number; offset: number };
|
||||
};
|
||||
|
||||
registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/sites",
|
||||
description: "List all sites in an organization",
|
||||
tags: [OpenAPITags.Org, OpenAPITags.Site],
|
||||
request: {
|
||||
params: listSitesParamsSchema,
|
||||
query: listSitesSchema
|
||||
},
|
||||
responses: {}
|
||||
});
|
||||
|
||||
export async function listSites(
|
||||
req: Request,
|
||||
res: Response,
|
||||
|
||||
@@ -9,6 +9,8 @@ import logger from "@server/logger";
|
||||
import { findNextAvailableCidr } from "@server/lib/ip";
|
||||
import { generateId } from "@server/auth/sessions/app";
|
||||
import config from "@server/lib/config";
|
||||
import { OpenAPITags, registry } from "@server/openApi";
|
||||
import { z } from "zod";
|
||||
|
||||
export type PickSiteDefaultsResponse = {
|
||||
exitNodeId: number;
|
||||
@@ -22,6 +24,20 @@ export type PickSiteDefaultsResponse = {
|
||||
newtSecret: string;
|
||||
};
|
||||
|
||||
registry.registerPath({
|
||||
method: "get",
|
||||
path: "/org/{orgId}/pick-site-defaults",
|
||||
description:
|
||||
"Return pre-requisite data for creating a site, such as the exit node, subnet, Newt credentials, etc.",
|
||||
tags: [OpenAPITags.Org, OpenAPITags.Site],
|
||||
request: {
|
||||
params: z.object({
|
||||
orgId: z.string()
|
||||
})
|
||||
},
|
||||
responses: {}
|
||||
});
|
||||
|
||||
export async function pickSiteDefaults(
|
||||
req: Request,
|
||||
res: Response,
|
||||
@@ -45,7 +61,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 +69,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 +102,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);
|
||||
|
||||
@@ -8,6 +8,7 @@ import HttpCode from "@server/types/HttpCode";
|
||||
import createHttpError from "http-errors";
|
||||
import logger from "@server/logger";
|
||||
import { fromError } from "zod-validation-error";
|
||||
import { OpenAPITags, registry } from "@server/openApi";
|
||||
|
||||
const updateSiteParamsSchema = z
|
||||
.object({
|
||||
@@ -35,6 +36,25 @@ const updateSiteBodySchema = z
|
||||
message: "At least one field must be provided for update"
|
||||
});
|
||||
|
||||
registry.registerPath({
|
||||
method: "post",
|
||||
path: "/site/{siteId}",
|
||||
description:
|
||||
"Update a site.",
|
||||
tags: [OpenAPITags.Site],
|
||||
request: {
|
||||
params: updateSiteParamsSchema,
|
||||
body: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: updateSiteBodySchema
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
responses: {}
|
||||
});
|
||||
|
||||
export async function updateSite(
|
||||
req: Request,
|
||||
res: Response,
|
||||
|
||||
Reference in New Issue
Block a user