Files
dokploy/apps/dokploy/server/wss/utils.ts
Mauricio Siu f1d0fb95f4 feat(deployment-logs): enhance readValidDirectory function to accept serverId parameter
- Updated the readValidDirectory function to include an optional serverId parameter, improving its flexibility for directory validation.
- Modified the deployment logs WebSocket server setup to utilize the updated readValidDirectory function, ensuring proper log path validation based on server context.
2026-02-07 23:19:33 -06:00

80 lines
2.0 KiB
TypeScript

import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { execAsync, IS_CLOUD, paths } from "@dokploy/server";
/**
* Validates that the container ID matches Docker's expected format.
* Docker container IDs are 64-character hex strings (or 12-char short form).
* Also allows container names: alphanumeric, underscores, hyphens, and dots.
*/
export const isValidContainerId = (id: string): boolean => {
// Match full ID (64 hex chars), short ID (12 hex chars), or container name
const hexPattern = /^[a-f0-9]{12,64}$/i;
const namePattern = /^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/;
return hexPattern.test(id) || (namePattern.test(id) && id.length <= 128);
};
/**
* Validates that the shell is one of the allowed shells.
*/
export const isValidShell = (shell: string): boolean => {
const allowedShells = [
"sh",
"bash",
"zsh",
"ash",
"/bin/sh",
"/bin/bash",
"/bin/zsh",
"/bin/ash",
];
return allowedShells.includes(shell);
};
export const readValidDirectory = (
directory: string,
serverId?: string | null,
) => {
const { BASE_PATH } = paths(!!serverId);
const resolvedBase = path.resolve(BASE_PATH);
const resolvedDir = path.resolve(directory);
return (
resolvedDir === resolvedBase ||
resolvedDir.startsWith(resolvedBase + path.sep)
);
};
export const getShell = () => {
if (IS_CLOUD) {
return "NO_AVAILABLE";
}
switch (os.platform()) {
case "win32":
return "powershell.exe";
case "darwin":
return "zsh";
default:
return "bash";
}
};
/** Returns private SSH key for dokploy local server terminal. Uses already created SSH key or generates a new SSH key.
*/
export const setupLocalServerSSHKey = async () => {
const { SSH_PATH } = paths(true);
const sshKeyPath = path.join(SSH_PATH, "auto_generated-dokploy-local");
if (!fs.existsSync(sshKeyPath)) {
// Generate new SSH key if it hasn't been created yet
await execAsync(
`ssh-keygen -t rsa -b 4096 -f ${sshKeyPath} -N "" -C "dokploy-local-access"`,
);
}
const privateKey = fs.readFileSync(sshKeyPath, "utf8");
return privateKey;
};