// /core/js/drivers_files/sftp.js
// Complete SFTP driver with connection handling
import { createFile } from "./sftpnewfile.js";
console.log("[SFTPDriver] Module loaded");
// ======================================================
// SFTP Driver Object
// ======================================================
export const SFTPDriver = {
// Helper to get current connection credentials
getConnectionData() {
if (!window._currentSFTPConnection) {
throw new Error("No active SFTP connection. Please connect via Connection Manager first.");
}
return window._currentSFTPConnection;
},
// --- Connect to SFTP server ---
async connect(host, port, username, password) {
console.log(`[SFTPDriver] connect() -> ${host}:${port}`);
try {
const res = await fetch("/core/php/sftp/connector.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify({
action: "connect",
host,
port,
username,
password
})
});
console.log("[SFTPDriver] Response status:", res.status);
const contentType = res.headers.get('content-type');
if (!contentType || !contentType.includes('application/json')) {
const text = await res.text();
console.error("[SFTPDriver] Non-JSON response:", text);
throw new Error("Server returned invalid response (not JSON)");
}
const data = await res.json();
console.log("[SFTPDriver] Connection response:", data);
if (data.success) {
console.log("[SFTPDriver] Connected successfully");
// Store connection info
window._currentSFTPConnection = { host, port, username, password };
return data;
} else {
throw new Error(data.message || "Connection failed");
}
} catch (err) {
console.error("[SFTPDriver] connect() failed:", err);
throw err;
}
},
// --- Create a new file on the remote SFTP server ---
async create(path, content = "") {
console.log(`[SFTPDriver] create() -> ${path}`);
try {
// Ensure we're connected
this.getConnectionData();
const result = await createFile(path, content);
if (result.success) {
console.log("[SFTPDriver] File created successfully:", path);
return result;
} else {
throw new Error(result.message || "Unknown error");
}
} catch (err) {
console.error("[SFTPDriver] create() failed:", err);
return { success: false, message: err.message };
}
},
// --- List directory contents ---
async list(path = "/") {
console.log(`[SFTPDriver] list() → ${path}`);
console.log(`[SFTPDriver] Connection data:`, window._currentSFTPConnection);
try {
// Ensure we're connected
this.getConnectionData();
const requestBody = { action: "list", path };
console.log("[SFTPDriver] Sending request:", requestBody);
const res = await fetch("/core/php/sftp/connector.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(requestBody),
credentials: "include" // ensure PHP session cookies are sent
});
console.log("[SFTPDriver] Response status:", res.status);
// Get the raw text for better debugging of backend errors
const text = await res.text();
console.log("[SFTPDriver] Raw response (first 500 chars):", text.substring(0, 500));
let data;
try {
data = JSON.parse(text);
} catch (e) {
console.error("[SFTPDriver] JSON parse error:", e);
console.error("[SFTPDriver] Full response text:", text);
throw new Error("[SFTPDriver] Invalid JSON from connector.php:\n" + text.substring(0, 200));
}
console.log("[SFTPDriver] Parsed data:", data);
if (!data.success) {
console.error("[SFTPDriver] Server returned error:", data.message);
throw new Error(data.message || "Unknown SFTP error");
}
console.log(`[SFTPDriver] Directory loaded successfully: ${data.data?.length || 0} items`);
console.log("[SFTPDriver] Files:", data.data);
return data.data || [];
} catch (err) {
console.error("[SFTPDriver] list() failed with error:", err);
console.error("[SFTPDriver] Error stack:", err.stack);
throw err;
}
},
// --- Delete a file on the server ---
async delete(path) {
console.log(`[SFTPDriver] delete() -> ${path}`);
try {
// Ensure we're connected
this.getConnectionData();
const res = await fetch("/core/php/sftp/connector.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify({ action: "delete", path })
});
const data = await res.json();
if (data.success) {
console.log("[SFTPDriver] File deleted:", path);
return data;
} else {
throw new Error(data.message);
}
} catch (err) {
console.error("[SFTPDriver] delete() failed:", err);
return { success: false, message: err.message };
}
},
// --- Create a folder on the server ---
async mkdir(path) {
console.log(`[SFTPDriver] mkdir() -> ${path}`);
try {
// Ensure we're connected
this.getConnectionData();
const res = await fetch("/core/php/sftp/connector.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify({ action: "create_folder", path })
});
const data = await res.json();
if (data.success) {
console.log("[SFTPDriver] Folder created:", path);
return data;
} else {
throw new Error(data.message);
}
} catch (err) {
console.error("[SFTPDriver] mkdir() failed:", err);
return { success: false, message: err.message };
}
},
// --- Check connection status ---
async status() {
console.log("[SFTPDriver] status()");
try {
const res = await fetch("/core/php/sftp/connector.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify({ action: "status" })
});
const data = await res.json();
console.log("[SFTPDriver] Status:", data);
return data;
} catch (err) {
console.error("[SFTPDriver] status() failed:", err);
return { success: false, connected: false, message: err.message };
}
},
// --- Disconnect cleanly ---
async disconnect() {
console.log("[SFTPDriver] disconnect()");
try {
const res = await fetch("/core/php/sftp/connector.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify({ action: "disconnect" })
});
const data = await res.json();
console.log("[SFTPDriver] Disconnected:", data);
// Clear stored connection
delete window._currentSFTPConnection;
return data;
} catch (err) {
console.error("[SFTPDriver] disconnect() failed:", err);
return { success: false, message: err.message };
}
}
};