mirror of
https://github.com/fosrl/pangolin.git
synced 2026-07-05 19:59:43 +00:00
Merge branch 'dev' into refactor/show-if-client-needs-update
This commit is contained in:
@@ -84,7 +84,7 @@ registry.registerPath({
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
data: z.unknown().nullable(),
|
||||
data: z.record(z.string(), z.any()).nullable(),
|
||||
success: z.boolean(),
|
||||
error: z.boolean(),
|
||||
message: z.string(),
|
||||
|
||||
@@ -33,7 +33,7 @@ registry.registerPath({
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
data: z.unknown().nullable(),
|
||||
data: z.record(z.string(), z.any()).nullable(),
|
||||
success: z.boolean(),
|
||||
error: z.boolean(),
|
||||
message: z.string(),
|
||||
|
||||
@@ -67,7 +67,7 @@ registry.registerPath({
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
data: z.unknown().nullable(),
|
||||
data: z.record(z.string(), z.any()).nullable(),
|
||||
success: z.boolean(),
|
||||
error: z.boolean(),
|
||||
message: z.string(),
|
||||
@@ -95,7 +95,7 @@ registry.registerPath({
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
data: z.unknown().nullable(),
|
||||
data: z.record(z.string(), z.any()).nullable(),
|
||||
success: z.boolean(),
|
||||
error: z.boolean(),
|
||||
message: z.string(),
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed";
|
||||
import {
|
||||
db,
|
||||
exitNodes,
|
||||
labels,
|
||||
newts,
|
||||
orgs,
|
||||
remoteExitNodes,
|
||||
roleSites,
|
||||
siteLabels,
|
||||
siteNetworks,
|
||||
siteResources,
|
||||
targets,
|
||||
sites,
|
||||
targets,
|
||||
userSites,
|
||||
labels,
|
||||
siteLabels,
|
||||
type Label
|
||||
} from "@server/db";
|
||||
import cache from "#dynamic/lib/cache";
|
||||
import { tierMatrix } from "@server/lib/billing/tierMatrix";
|
||||
import response from "@server/lib/response";
|
||||
import logger from "@server/logger";
|
||||
import { OpenAPITags, registry } from "@server/openApi";
|
||||
@@ -23,11 +24,8 @@ import type { PaginatedResponse } from "@server/types/Pagination";
|
||||
import { and, asc, desc, eq, inArray, like, or, sql } from "drizzle-orm";
|
||||
import { NextFunction, Request, Response } from "express";
|
||||
import createHttpError from "http-errors";
|
||||
import semver from "semver";
|
||||
import { z } from "zod";
|
||||
import { fromError } from "zod-validation-error";
|
||||
import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed";
|
||||
import { tierMatrix } from "@server/lib/billing/tierMatrix";
|
||||
|
||||
const listSitesParamsSchema = z.strictObject({
|
||||
orgId: z.string()
|
||||
@@ -189,7 +187,7 @@ registry.registerPath({
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
data: z.unknown().nullable(),
|
||||
data: z.record(z.string(), z.any()).nullable(),
|
||||
success: z.boolean(),
|
||||
error: z.boolean(),
|
||||
message: z.string(),
|
||||
@@ -236,27 +234,6 @@ export async function listSites(
|
||||
);
|
||||
}
|
||||
|
||||
let accessibleSites;
|
||||
if (req.user) {
|
||||
accessibleSites = await db
|
||||
.select({
|
||||
siteId: sql<number>`COALESCE(${userSites.siteId}, ${roleSites.siteId})`
|
||||
})
|
||||
.from(userSites)
|
||||
.fullJoin(roleSites, eq(userSites.siteId, roleSites.siteId))
|
||||
.where(
|
||||
or(
|
||||
eq(userSites.userId, req.user!.userId),
|
||||
inArray(roleSites.roleId, req.userOrgRoleIds!)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
accessibleSites = await db
|
||||
.select({ siteId: sites.siteId })
|
||||
.from(sites)
|
||||
.where(eq(sites.orgId, orgId));
|
||||
}
|
||||
|
||||
const isLabelFeatureEnabled = await isLicensedOrSubscribed(
|
||||
orgId,
|
||||
tierMatrix.labels
|
||||
@@ -273,14 +250,38 @@ export async function listSites(
|
||||
labels: labelFilter
|
||||
} = parsedQuery.data;
|
||||
|
||||
const accessibleSiteIds = accessibleSites.map((site) => site.siteId);
|
||||
const conditions = [eq(sites.orgId, orgId)];
|
||||
|
||||
const conditions = [
|
||||
and(
|
||||
inArray(sites.siteId, accessibleSiteIds),
|
||||
eq(sites.orgId, orgId)
|
||||
)
|
||||
];
|
||||
if (req.user) {
|
||||
const userAccessConditions = [
|
||||
inArray(
|
||||
sites.siteId,
|
||||
db
|
||||
.select({ siteId: userSites.siteId })
|
||||
.from(userSites)
|
||||
.where(eq(userSites.userId, req.user.userId))
|
||||
)
|
||||
];
|
||||
|
||||
const roleIds = req.userOrgRoleIds ?? [];
|
||||
if (roleIds.length > 0) {
|
||||
userAccessConditions.push(
|
||||
inArray(
|
||||
sites.siteId,
|
||||
db
|
||||
.select({ siteId: roleSites.siteId })
|
||||
.from(roleSites)
|
||||
.where(inArray(roleSites.roleId, roleIds))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
conditions.push(
|
||||
userAccessConditions.length === 1
|
||||
? userAccessConditions[0]
|
||||
: or(...userAccessConditions)!
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof online !== "undefined") {
|
||||
conditions.push(eq(sites.online, online));
|
||||
@@ -327,17 +328,15 @@ export async function listSites(
|
||||
)
|
||||
);
|
||||
}
|
||||
conditions.push(or(...queryList));
|
||||
conditions.push(or(...queryList)!);
|
||||
}
|
||||
|
||||
const baseQuery = querySitesBase().where(and(...conditions));
|
||||
|
||||
// we need to add `as` so that drizzle filters the result as a subquery
|
||||
const countQuery = db.$count(
|
||||
querySitesBase()
|
||||
.where(and(...conditions))
|
||||
.as("filtered_sites")
|
||||
);
|
||||
const countQuery = db
|
||||
.select({ count: sql<number>`count(*)` })
|
||||
.from(sites)
|
||||
.where(and(...conditions));
|
||||
|
||||
const siteListQuery = baseQuery
|
||||
.limit(pageSize)
|
||||
@@ -350,11 +349,13 @@ export async function listSites(
|
||||
: asc(sites.name)
|
||||
);
|
||||
|
||||
const [totalCount, rows] = await Promise.all([
|
||||
const [countRows, rows] = await Promise.all([
|
||||
countQuery,
|
||||
siteListQuery
|
||||
]);
|
||||
|
||||
const totalCount = Number(countRows[0]?.count ?? 0);
|
||||
|
||||
const siteIds = rows.map((site) => site.siteId);
|
||||
|
||||
let labelsForSites: Array<{
|
||||
|
||||
@@ -50,7 +50,7 @@ registry.registerPath({
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
data: z.unknown().nullable(),
|
||||
data: z.record(z.string(), z.any()).nullable(),
|
||||
success: z.boolean(),
|
||||
error: z.boolean(),
|
||||
message: z.string(),
|
||||
|
||||
Reference in New Issue
Block a user