Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 7 additions & 39 deletions apps/dokploy/__test__/backup/restore-security.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import * as schema from "@dokploy/server/db/schema";
import { TRPCError } from "@trpc/server";
import { drizzle } from "drizzle-orm/postgres-js";
import { parse } from "shell-quote";
import { beforeEach, describe, expect, it, vi } from "vitest";
import {
maxJsonBuildArrayArgs,
POSTGRES_MAX_FUNCTION_ARGS,
relationalQueryDb,
} from "../helpers/postgres-function-args";

const mocks = vi.hoisted(() => ({
checkPermission: vi.fn(),
Expand Down Expand Up @@ -326,40 +329,6 @@ const emit = (log: string) => emittedLogs.push(log);
const parseShellArgs = (command: string) =>
parse(command).filter((part): part is string => typeof part === "string");

const POSTGRES_MAX_FUNCTION_ARGS = 100;

const maxJsonBuildArrayArgs = (sqlText: string) => {
let max = 0;
for (const match of sqlText.matchAll(/json_build_array\(/g)) {
let depth = 1;
let args = 1;
let inIdentifier = false;
for (
let index = match.index + match[0].length;
index < sqlText.length && depth > 0;
index++
) {
const char = sqlText[index];
if (char === '"') {
inIdentifier = !inIdentifier;
continue;
}
if (inIdentifier) {
continue;
}
if (char === "(") {
depth++;
} else if (char === ")") {
depth--;
} else if (char === "," && depth === 1) {
args++;
}
}
max = Math.max(max, args);
}
return max;
};

describe("backup destination ownership boundary", () => {
beforeEach(() => {
vi.clearAllMocks();
Expand Down Expand Up @@ -821,11 +790,10 @@ describe("backup restore route boundary", () => {
});

it("keeps backup file listing queries within the Postgres function argument limit", async () => {
const relationalDb = drizzle.mock({ schema });
const compiledQueries: string[] = [];
mocks.findRestoreBackups.mockImplementation(async (config) => {
compiledQueries.push(
relationalDb.query.backups.findMany(config).toSQL().sql,
relationalQueryDb.query.backups.findMany(config).toSQL().sql,
);
return [
{
Expand All @@ -841,7 +809,7 @@ describe("backup restore route boundary", () => {
});
mocks.findVolumeBackupSchedules.mockImplementation(async (config) => {
compiledQueries.push(
relationalDb.query.volumeBackups.findMany(config).toSQL().sql,
relationalQueryDb.query.volumeBackups.findMany(config).toSQL().sql,
);
return [
{
Expand Down
Loading