fix: base64 decoding
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
||||
recentActivity,
|
||||
hostAccess,
|
||||
userRoles,
|
||||
sessionRecordings,
|
||||
} from "../db/schema.js";
|
||||
import {
|
||||
eq,
|
||||
@@ -1069,60 +1070,40 @@ router.delete(
|
||||
|
||||
const numericHostId = Number(hostId);
|
||||
|
||||
// Delete all related data in correct order (child tables first)
|
||||
await db
|
||||
.delete(fileManagerRecent)
|
||||
.where(
|
||||
and(
|
||||
eq(fileManagerRecent.hostId, numericHostId),
|
||||
eq(fileManagerRecent.userId, userId),
|
||||
),
|
||||
);
|
||||
.where(eq(fileManagerRecent.hostId, numericHostId));
|
||||
|
||||
await db
|
||||
.delete(fileManagerPinned)
|
||||
.where(
|
||||
and(
|
||||
eq(fileManagerPinned.hostId, numericHostId),
|
||||
eq(fileManagerPinned.userId, userId),
|
||||
),
|
||||
);
|
||||
.where(eq(fileManagerPinned.hostId, numericHostId));
|
||||
|
||||
await db
|
||||
.delete(fileManagerShortcuts)
|
||||
.where(
|
||||
and(
|
||||
eq(fileManagerShortcuts.hostId, numericHostId),
|
||||
eq(fileManagerShortcuts.userId, userId),
|
||||
),
|
||||
);
|
||||
.where(eq(fileManagerShortcuts.hostId, numericHostId));
|
||||
|
||||
await db
|
||||
.delete(commandHistory)
|
||||
.where(
|
||||
and(
|
||||
eq(commandHistory.hostId, numericHostId),
|
||||
eq(commandHistory.userId, userId),
|
||||
),
|
||||
);
|
||||
.where(eq(commandHistory.hostId, numericHostId));
|
||||
|
||||
await db
|
||||
.delete(sshCredentialUsage)
|
||||
.where(
|
||||
and(
|
||||
eq(sshCredentialUsage.hostId, numericHostId),
|
||||
eq(sshCredentialUsage.userId, userId),
|
||||
),
|
||||
);
|
||||
.where(eq(sshCredentialUsage.hostId, numericHostId));
|
||||
|
||||
await db
|
||||
.delete(recentActivity)
|
||||
.where(
|
||||
and(
|
||||
eq(recentActivity.hostId, numericHostId),
|
||||
eq(recentActivity.userId, userId),
|
||||
),
|
||||
);
|
||||
.where(eq(recentActivity.hostId, numericHostId));
|
||||
|
||||
// Delete RBAC host access entries
|
||||
await db.delete(hostAccess).where(eq(hostAccess.hostId, numericHostId));
|
||||
|
||||
// Delete session recordings
|
||||
await db
|
||||
.delete(sessionRecordings)
|
||||
.where(eq(sessionRecordings.hostId, numericHostId));
|
||||
|
||||
// Finally delete the host itself
|
||||
await db
|
||||
.delete(sshData)
|
||||
.where(and(eq(sshData.id, numericHostId), eq(sshData.userId, userId)));
|
||||
@@ -1887,10 +1868,49 @@ router.delete(
|
||||
});
|
||||
}
|
||||
|
||||
const hostIds = hostsToDelete.map((host) => host.id);
|
||||
|
||||
// Delete all related data for all hosts in the folder (child tables first)
|
||||
if (hostIds.length > 0) {
|
||||
await db
|
||||
.delete(fileManagerRecent)
|
||||
.where(inArray(fileManagerRecent.hostId, hostIds));
|
||||
|
||||
await db
|
||||
.delete(fileManagerPinned)
|
||||
.where(inArray(fileManagerPinned.hostId, hostIds));
|
||||
|
||||
await db
|
||||
.delete(fileManagerShortcuts)
|
||||
.where(inArray(fileManagerShortcuts.hostId, hostIds));
|
||||
|
||||
await db
|
||||
.delete(commandHistory)
|
||||
.where(inArray(commandHistory.hostId, hostIds));
|
||||
|
||||
await db
|
||||
.delete(sshCredentialUsage)
|
||||
.where(inArray(sshCredentialUsage.hostId, hostIds));
|
||||
|
||||
await db
|
||||
.delete(recentActivity)
|
||||
.where(inArray(recentActivity.hostId, hostIds));
|
||||
|
||||
// Delete RBAC host access entries
|
||||
await db.delete(hostAccess).where(inArray(hostAccess.hostId, hostIds));
|
||||
|
||||
// Delete session recordings
|
||||
await db
|
||||
.delete(sessionRecordings)
|
||||
.where(inArray(sessionRecordings.hostId, hostIds));
|
||||
}
|
||||
|
||||
// Now delete the hosts themselves
|
||||
await db
|
||||
.delete(sshData)
|
||||
.where(and(eq(sshData.userId, userId), eq(sshData.folder, folderName)));
|
||||
|
||||
// Finally delete the folder metadata
|
||||
await db
|
||||
.delete(sshFolders)
|
||||
.where(
|
||||
|
||||
@@ -824,12 +824,17 @@ app.post("/ssh/file_manager/ssh/connect", async (req, res) => {
|
||||
useSocks5,
|
||||
socks5Host,
|
||||
socks5Port,
|
||||
hasSocks5ProxyChain: !!(socks5ProxyChain && (socks5ProxyChain as any).length > 0),
|
||||
hasSocks5ProxyChain: !!(
|
||||
socks5ProxyChain && (socks5ProxyChain as any).length > 0
|
||||
),
|
||||
proxyChainLength: socks5ProxyChain ? (socks5ProxyChain as any).length : 0,
|
||||
});
|
||||
|
||||
// Check if SOCKS5 proxy is enabled (either single proxy or chain)
|
||||
if (useSocks5 && (socks5Host || (socks5ProxyChain && (socks5ProxyChain as any).length > 0))) {
|
||||
if (
|
||||
useSocks5 &&
|
||||
(socks5Host || (socks5ProxyChain && (socks5ProxyChain as any).length > 0))
|
||||
) {
|
||||
fileLogger.info("SOCKS5 enabled for SFTP, creating connection", {
|
||||
operation: "sftp_socks5_enabled",
|
||||
sessionId,
|
||||
@@ -839,18 +844,14 @@ app.post("/ssh/file_manager/ssh/connect", async (req, res) => {
|
||||
});
|
||||
|
||||
try {
|
||||
const socks5Socket = await createSocks5Connection(
|
||||
ip,
|
||||
port,
|
||||
{
|
||||
const socks5Socket = await createSocks5Connection(ip, port, {
|
||||
useSocks5,
|
||||
socks5Host,
|
||||
socks5Port,
|
||||
socks5Username,
|
||||
socks5Password,
|
||||
socks5ProxyChain: socks5ProxyChain as any,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
if (socks5Socket) {
|
||||
fileLogger.info("SOCKS5 socket created for SFTP", {
|
||||
@@ -1545,7 +1546,22 @@ app.post("/ssh/file_manager/ssh/writeFile", async (req, res) => {
|
||||
|
||||
const tryFallbackMethod = () => {
|
||||
try {
|
||||
const base64Content = Buffer.from(content, "utf8").toString("base64");
|
||||
let contentBuffer: Buffer;
|
||||
if (typeof content === "string") {
|
||||
try {
|
||||
contentBuffer = Buffer.from(content, "base64");
|
||||
if (contentBuffer.toString("base64") !== content) {
|
||||
contentBuffer = Buffer.from(content, "utf8");
|
||||
}
|
||||
} catch {
|
||||
contentBuffer = Buffer.from(content, "utf8");
|
||||
}
|
||||
} else if (Buffer.isBuffer(content)) {
|
||||
contentBuffer = content;
|
||||
} else {
|
||||
contentBuffer = Buffer.from(content);
|
||||
}
|
||||
const base64Content = contentBuffer.toString("base64");
|
||||
const escapedPath = filePath.replace(/'/g, "'\"'\"'");
|
||||
|
||||
const writeCommand = `echo '${base64Content}' | base64 -d > '${escapedPath}' && echo "SUCCESS"`;
|
||||
@@ -1746,7 +1762,22 @@ app.post("/ssh/file_manager/ssh/uploadFile", async (req, res) => {
|
||||
|
||||
const tryFallbackMethod = () => {
|
||||
try {
|
||||
const base64Content = Buffer.from(content, "utf8").toString("base64");
|
||||
let contentBuffer: Buffer;
|
||||
if (typeof content === "string") {
|
||||
try {
|
||||
contentBuffer = Buffer.from(content, "base64");
|
||||
if (contentBuffer.toString("base64") !== content) {
|
||||
contentBuffer = Buffer.from(content, "utf8");
|
||||
}
|
||||
} catch {
|
||||
contentBuffer = Buffer.from(content, "utf8");
|
||||
}
|
||||
} else if (Buffer.isBuffer(content)) {
|
||||
contentBuffer = content;
|
||||
} else {
|
||||
contentBuffer = Buffer.from(content);
|
||||
}
|
||||
const base64Content = contentBuffer.toString("base64");
|
||||
const chunkSize = 1000000;
|
||||
const chunks = [];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user