Feat: Adding SFTP Client & Automatic Connections via button!

This commit is contained in:
MCHost
2025-06-23 22:54:03 -04:00
parent 560b3f1659
commit ee0707a9c1
2 changed files with 85 additions and 11 deletions

View File

@ -144,6 +144,7 @@
<div class="flex space-x-4">
<button id="refresh" class="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded">Refresh</button>
<button id="backupBtn" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded">Backup</button>
<button id="sftpBtn" class="bg-green-600 hover:bg-green-700 px-4 py-2 rounded">SFTP</button>
<div id="authControls">
<input id="apiKey" type="text" placeholder="Enter API Key" class="bg-gray-700 px-4 py-2 rounded text-white">
</div>
@ -211,6 +212,12 @@
<pre id="consoleOutput" class="bg-gray-900 p-4 rounded mt-4 h-48 overflow-y-auto"></pre>
</div>
<div class="bg-gray-800 p-6 rounded-lg shadow-lg mb-6" id="sftpBrowserSection" style="display: none;">
<h2 class="text-xl font-semibold mb-4">SFTP Browser</h2>
<!-- Iframe height set explicitly to 650px to ensure visibility and prevent shrinking -->
<iframe id="sftpIframe" class="w-full rounded" style="height: 650px; min-height: 650px;" sandbox="allow-same-origin allow-scripts"></iframe>
</div>
<div class="bg-gray-800 p-6 rounded-lg shadow-lg mb-6">
<h2 class="text-xl font-semibold mb-4">Mod Management</h2>
<form id="modSearchForm" onsubmit="event.preventDefault(); searchMods(1);">
@ -277,7 +284,7 @@
</footer>
</div>
<script src="app.js"></script>
<script src="js/app.js"></script>
</body>
</html>

View File

@ -13,6 +13,8 @@ document.addEventListener('DOMContentLoaded', () => {
let modListCurrentPage = 1;
let modListSearchQuery = '';
let allProperties = {};
let sftpCredentials = null;
let isSftpOnline = false;
const filteredSettings = [
'bug-report-link',
'query.port',
@ -92,7 +94,10 @@ document.addEventListener('DOMContentLoaded', () => {
effectModal: document.getElementById('effectModal'),
effectPlayerName: document.getElementById('effectPlayerName'),
effectSelect: document.getElementById('effectSelect'),
effectForm: document.getElementById('effectForm')
effectForm: document.getElementById('effectForm'),
sftpBtn: document.getElementById('sftpBtn'),
sftpBrowserSection: document.getElementById('sftpBrowserSection'),
sftpIframe: document.getElementById('sftpIframe')
};
const loadouts = {
@ -358,7 +363,8 @@ document.addEventListener('DOMContentLoaded', () => {
'my-link-cache',
'my-geyser-cache',
'my-sftp-cache',
'backup'
'backup',
'sftp-status'
]
}));
responseTimeout = setTimeout(() => {
@ -438,6 +444,8 @@ document.addEventListener('DOMContentLoaded', () => {
updateGeyserStatusUI(message);
} else if (message.type === 'sftp-status') {
updateSftpStatusUI(message);
} else if (message.type === 'my-sftp-cache') {
updateSftpCacheUI(message);
} else if (message.type === 'update-mods') {
updateModsUI(message);
} else if (message.type === 'backup') {
@ -485,6 +493,7 @@ document.addEventListener('DOMContentLoaded', () => {
const editPropertiesBtn = elements.editPropertiesBtn;
const updateModsBtn = elements.updateModsBtn;
const backupBtn = elements.backupBtn;
const sftpBtn = elements.sftpBtn;
const startBtn = document.getElementById('startBtn');
const stopBtn = elements.stopBtn;
const restartBtn = elements.restartBtn;
@ -514,6 +523,9 @@ document.addEventListener('DOMContentLoaded', () => {
if (backupBtn) {
backupBtn.classList.add('hidden');
}
if (sftpBtn) {
sftpBtn.classList.add('hidden');
}
if (stopBtn) {
stopBtn.disabled = true;
stopBtn.classList.add('disabled-btn');
@ -539,6 +551,9 @@ document.addEventListener('DOMContentLoaded', () => {
if (backupBtn) {
backupBtn.classList.remove('hidden');
}
if (sftpBtn) {
sftpBtn.classList.remove('hidden');
}
if (stopBtn) {
stopBtn.disabled = false;
stopBtn.classList.remove('disabled-btn');
@ -598,6 +613,7 @@ document.addEventListener('DOMContentLoaded', () => {
function updateSftpStatusUI(message) {
if (message.data?.isOnline !== undefined && elements.sftpStatus) {
const statusIcon = message.data.isOnline ? '✅' : '❌';
isSftpOnline = message.data.isOnline;
if (state.sftpStatus !== statusIcon) {
elements.sftpStatus.textContent = statusIcon;
state.sftpStatus = statusIcon;
@ -605,6 +621,22 @@ document.addEventListener('DOMContentLoaded', () => {
}
}
function updateSftpCacheUI(message) {
if (message.data?.hostname && message.data?.port && message.data?.user && message.data?.password) {
sftpCredentials = {
hostname: message.data.hostname,
port: message.data.port,
user: message.data.user,
password: message.data.password
};
const sftpLinkText = `${message.data.hostname}:${message.data.port} (Auth: User: ${message.data.user} | Pass: ${message.data.password})`;
if (state.sftpLink !== sftpLinkText && elements.sftpLink) {
elements.sftpLink.textContent = sftpLinkText;
state.sftpLink = sftpLinkText;
}
}
}
function updateModsUI(message) {
if (message.error) {
elements.updateModsOutput.textContent = `Error: ${message.error}`;
@ -912,14 +944,6 @@ document.addEventListener('DOMContentLoaded', () => {
}
}
if (message.type === 'my-sftp-cache' && message.data?.hostname && message.data?.port && message.data?.user && message.data?.password) {
const sftpLinkText = `${message.data.hostname}:${message.data.port} (Auth: User: ${message.data.user} | Pass: ${message.data.password})`;
if (state.sftpLink !== sftpLinkText && elements.sftpLink) {
elements.sftpLink.textContent = sftpLinkText;
state.sftpLink = sftpLinkText;
}
}
if (message.type === 'my-link' && message.data?.hostname && message.data?.port) {
const myLinkText = `${message.data.hostname}:${message.data.port}`;
if (state.myLink !== myLinkText && elements.myLink) {
@ -1537,6 +1561,47 @@ document.addEventListener('DOMContentLoaded', () => {
}
}
async function connectSftp() {
if (!isSftpOnline) {
showNotification('SFTP is offline. Please try again later.', 'error', 'sftp-offline');
return;
}
if (!sftpCredentials) {
showNotification('SFTP credentials not available.', 'error', 'sftp-credentials');
return;
}
try {
const key = `action-sftp-connect`;
const notification = showNotification('Connecting to SFTP...', 'loading', key);
const response = await fetch('https://sftp.my-mc.link/auto-connection', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
host: sftpCredentials.hostname.replace('sftp://', ''),
port: sftpCredentials.port,
username: sftpCredentials.user,
password: sftpCredentials.password,
}),
});
const result = await response.json();
if (result.success && result.connectionUrl) {
elements.sftpIframe.src = result.connectionUrl;
elements.sftpBrowserSection.style.display = 'block';
updateNotification(notification, 'SFTP connected successfully', 'success', key);
} else {
updateNotification(notification, 'Failed to establish SFTP connection.', 'error', key);
}
} catch (error) {
console.error('SFTP connection error:', error);
showNotification(`Failed to connect to SFTP: ${error.message}`, 'error', 'sftp-connect-error');
}
}
elements.loginBtn.addEventListener('click', () => {
apiKey = elements.loginApiKey.value.trim();
if (apiKey) {
@ -1584,6 +1649,8 @@ document.addEventListener('DOMContentLoaded', () => {
}
});
elements.sftpBtn.addEventListener('click', connectSftp);
document.getElementById('refresh').addEventListener('click', async () => {
if (ws && ws.readyState === WebSocket.OPEN) {
const key = `action-refresh`;