Merge branch 'dev' of github.com:jln-brtn/pangolin into jln-brtn-dev

This commit is contained in:
Owen
2025-12-20 15:34:32 -05:00
17 changed files with 477 additions and 281 deletions

View File

@@ -1,19 +1,19 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import {Request, Response, NextFunction} from "express";
import {z} from "zod";
import {
db,
resourceHeaderAuth,
resourceHeaderAuth, resourceHeaderAuthExtendedCompatibility,
resourcePassword,
resourcePincode,
resources
} from "@server/db";
import { eq } from "drizzle-orm";
import {eq} from "drizzle-orm";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
import { fromError } from "zod-validation-error";
import {fromError} from "zod-validation-error";
import logger from "@server/logger";
import { build } from "@server/build";
import {build} from "@server/build";
const getResourceAuthInfoSchema = z.strictObject({
resourceGuid: z.string()
@@ -27,6 +27,7 @@ export type GetResourceAuthInfoResponse = {
password: boolean;
pincode: boolean;
headerAuth: boolean;
headerAuthExtendedCompatibility: boolean;
sso: boolean;
blockAccess: boolean;
url: string;
@@ -51,53 +52,68 @@ export async function getResourceAuthInfo(
);
}
const { resourceGuid } = parsedParams.data;
const {resourceGuid} = parsedParams.data;
const isGuidInteger = /^\d+$/.test(resourceGuid);
const [result] =
isGuidInteger && build === "saas"
? await db
.select()
.from(resources)
.leftJoin(
resourcePincode,
eq(resourcePincode.resourceId, resources.resourceId)
)
.leftJoin(
resourcePassword,
eq(resourcePassword.resourceId, resources.resourceId)
)
.select()
.from(resources)
.leftJoin(
resourcePincode,
eq(resourcePincode.resourceId, resources.resourceId)
)
.leftJoin(
resourcePassword,
eq(resourcePassword.resourceId, resources.resourceId)
)
.leftJoin(
resourceHeaderAuth,
eq(
resourceHeaderAuth.resourceId,
resources.resourceId
)
)
.where(eq(resources.resourceId, Number(resourceGuid)))
.limit(1)
.leftJoin(
resourceHeaderAuth,
eq(
resourceHeaderAuth.resourceId,
resources.resourceId
)
)
.leftJoin(
resourceHeaderAuthExtendedCompatibility,
eq(
resourceHeaderAuthExtendedCompatibility.resourceId,
resources.resourceId
)
)
.where(eq(resources.resourceId, Number(resourceGuid)))
.limit(1)
: await db
.select()
.from(resources)
.leftJoin(
resourcePincode,
eq(resourcePincode.resourceId, resources.resourceId)
)
.leftJoin(
resourcePassword,
eq(resourcePassword.resourceId, resources.resourceId)
)
.leftJoin(
resourceHeaderAuth,
eq(
resourceHeaderAuth.resourceId,
resources.resourceId
)
)
.where(eq(resources.resourceGuid, resourceGuid))
.limit(1);
.select()
.from(resources)
.leftJoin(
resourcePincode,
eq(resourcePincode.resourceId, resources.resourceId)
)
.leftJoin(
resourcePassword,
eq(resourcePassword.resourceId, resources.resourceId)
)
.leftJoin(
resourceHeaderAuth,
eq(
resourceHeaderAuth.resourceId,
resources.resourceId
)
)
.leftJoin(
resourceHeaderAuthExtendedCompatibility,
eq(
resourceHeaderAuthExtendedCompatibility.resourceId,
resources.resourceId
)
)
.where(eq(resources.resourceGuid, resourceGuid))
.limit(1);
const resource = result?.resources;
if (!resource) {
@@ -109,6 +125,7 @@ export async function getResourceAuthInfo(
const pincode = result?.resourcePincode;
const password = result?.resourcePassword;
const headerAuth = result?.resourceHeaderAuth;
const headerAuthExtendedCompatibility = result?.resourceHeaderAuthExtendedCompatibility;
const url = `${resource.ssl ? "https" : "http"}://${resource.fullDomain}`;
@@ -121,6 +138,7 @@ export async function getResourceAuthInfo(
password: password !== null,
pincode: pincode !== null,
headerAuth: headerAuth !== null,
headerAuthExtendedCompatibility: headerAuthExtendedCompatibility !== null,
sso: resource.sso,
blockAccess: resource.blockAccess,
url,

View File

@@ -1,6 +1,6 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db, resourceHeaderAuth } from "@server/db";
import {db, resourceHeaderAuth, resourceHeaderAuthExtendedCompatibility} from "@server/db";
import {
resources,
userResources,
@@ -109,7 +109,7 @@ function queryResources(accessibleResourceIds: number[], orgId: string) {
domainId: resources.domainId,
niceId: resources.niceId,
headerAuthId: resourceHeaderAuth.headerAuthId,
headerAuthExtendedCompatibilityId: resourceHeaderAuthExtendedCompatibility.headerAuthExtendedCompatibilityId,
targetId: targets.targetId,
targetIp: targets.ip,
targetPort: targets.port,
@@ -131,6 +131,10 @@ function queryResources(accessibleResourceIds: number[], orgId: string) {
resourceHeaderAuth,
eq(resourceHeaderAuth.resourceId, resources.resourceId)
)
.leftJoin(
resourceHeaderAuthExtendedCompatibility,
eq(resourceHeaderAuthExtendedCompatibility.resourceId, resources.resourceId)
)
.leftJoin(targets, eq(targets.resourceId, resources.resourceId))
.leftJoin(
targetHealthCheck,

View File

@@ -1,14 +1,14 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db, resourceHeaderAuth } from "@server/db";
import { eq } from "drizzle-orm";
import {Request, Response, NextFunction} from "express";
import {z} from "zod";
import {db, resourceHeaderAuth, resourceHeaderAuthExtendedCompatibility} from "@server/db";
import {eq} from "drizzle-orm";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
import { fromError } from "zod-validation-error";
import { response } from "@server/lib/response";
import {fromError} from "zod-validation-error";
import {response} from "@server/lib/response";
import logger from "@server/logger";
import { hashPassword } from "@server/auth/password";
import { OpenAPITags, registry } from "@server/openApi";
import {hashPassword} from "@server/auth/password";
import {OpenAPITags, registry} from "@server/openApi";
const setResourceAuthMethodsParamsSchema = z.object({
resourceId: z.string().transform(Number).pipe(z.int().positive())
@@ -16,7 +16,8 @@ const setResourceAuthMethodsParamsSchema = z.object({
const setResourceAuthMethodsBodySchema = z.strictObject({
user: z.string().min(4).max(100).nullable(),
password: z.string().min(4).max(100).nullable()
password: z.string().min(4).max(100).nullable(),
extendedCompatibility: z.boolean().nullable()
});
registry.registerPath({
@@ -66,23 +67,29 @@ export async function setResourceHeaderAuth(
);
}
const { resourceId } = parsedParams.data;
const { user, password } = parsedBody.data;
const {resourceId} = parsedParams.data;
const {user, password, extendedCompatibility} = parsedBody.data;
await db.transaction(async (trx) => {
await trx
.delete(resourceHeaderAuth)
.where(eq(resourceHeaderAuth.resourceId, resourceId));
await trx.delete(resourceHeaderAuthExtendedCompatibility).where(eq(resourceHeaderAuthExtendedCompatibility.resourceId, resourceId));
if (user && password) {
const headerAuthHash = await hashPassword(
Buffer.from(`${user}:${password}`).toString("base64")
);
if (user && password && extendedCompatibility !== null) {
const headerAuthHash = await hashPassword(Buffer.from(`${user}:${password}`).toString("base64"));
await trx
.insert(resourceHeaderAuth)
.values({ resourceId, headerAuthHash });
await Promise.all([
trx
.insert(resourceHeaderAuth)
.values({resourceId, headerAuthHash}),
trx
.insert(resourceHeaderAuthExtendedCompatibility)
.values({resourceId, extendedCompatibilityIsActivated: extendedCompatibility})
]);
}
});
return response(res, {