📜
connectionmanager.js
Back
📝 Javascript ⚡ Executable Ctrl+S: Save • Ctrl+R: Run • Ctrl+F: Find
// Simple SFTP Test Connection Component (function() { const TestConnection = { id: "testConnection", label: "🔧 Test SFTP", html: ` <div class="test-container"> <h1>🔐 SFTP Connection Test</h1> <div class="test-info"> <div><strong>Host:</strong> files.devbrewing.com</div> <div><strong>Port:</strong> 22</div> <div><strong>Username:</strong> olinhll</div> <div><strong>Password:</strong> devbrewing123</div> </div> <button id="connectTestBtn" class="test-btn test-btn-connect">🚀 Test Connection</button> <button id="listTestBtn" class="test-btn test-btn-list" disabled>📁 List Root Directory</button> <button id="disconnectTestBtn" class="test-btn test-btn-disconnect" disabled>🔌 Disconnect</button> <div id="testOutput" class="test-output"></div> </div> <style> .test-container { padding: 20px; max-width: 800px; margin: 0 auto; } .test-container h1 { margin: 0 0 20px 0; font-size: 24px; color: #e2e8f0; } .test-info { background: #0f172a; padding: 15px; border-radius: 8px; margin-bottom: 20px; font-size: 14px; line-height: 1.8; } .test-info div { margin-bottom: 5px; } .test-info strong { color: #60a5fa; min-width: 100px; display: inline-block; } .test-btn { background: linear-gradient(135deg, #3b82f6, #9333ea); color: white; border: none; padding: 12px 24px; border-radius: 8px; font-size: 14px; font-weight: 600; cursor: pointer; margin-right: 10px; margin-bottom: 15px; } .test-btn:hover:not(:disabled) { opacity: 0.9; } .test-btn:disabled { opacity: 0.5; cursor: not-allowed; } .test-output { background: #0f172a; border: 1px solid #334155; border-radius: 8px; padding: 15px; font-family: 'Courier New', monospace; font-size: 13px; line-height: 1.6; max-height: 500px; overflow-y: auto; white-space: pre-wrap; word-break: break-all; } .test-output:empty::before { content: 'Click "Test Connection" to begin...'; color: #64748b; font-style: italic; } .log-success { color: #10b981; } .log-error { color: #ef4444; } .log-info { color: #60a5fa; } .log-warn { color: #f59e0b; } </style> `, driver: null, async onRender(el) { this.el = el; // Attach event listeners el.querySelector('#connectTestBtn').addEventListener('click', () => this.testConnection()); el.querySelector('#listTestBtn').addEventListener('click', () => this.testList()); el.querySelector('#disconnectTestBtn').addEventListener('click', () => this.testDisconnect()); this.log('Component ready. Click "Test Connection" to start.', 'info'); }, log(message, type = 'info') { const output = this.el.querySelector('#testOutput'); const time = new Date().toLocaleTimeString(); const className = `log-${type}`; const div = document.createElement('div'); div.className = className; div.textContent = `[${time}] ${message}`; output.appendChild(div); output.scrollTop = output.scrollHeight; }, async testConnection() { const connectBtn = this.el.querySelector('#connectTestBtn'); const listBtn = this.el.querySelector('#listTestBtn'); const disconnectBtn = this.el.querySelector('#disconnectTestBtn'); connectBtn.disabled = true; connectBtn.textContent = '⏳ Connecting...'; this.el.querySelector('#testOutput').innerHTML = ''; this.log('Starting connection test...', 'info'); try { // Load the SFTP driver with cache busting this.log('Loading SFTP driver module...', 'info'); const cacheBuster = '?v=' + Date.now(); this.log('Cache buster: ' + cacheBuster, 'info'); const module = await import('/core/js/drivers_files/sftp.js' + cacheBuster); this.log('Module loaded, checking exports...', 'info'); this.log('Available exports: ' + Object.keys(module).join(', '), 'info'); this.driver = module.SFTPDriver || module.default; if (!this.driver) { throw new Error('SFTPDriver not found in module exports'); } this.log('Checking driver methods...', 'info'); this.log('Has connect: ' + (typeof this.driver.connect === 'function'), 'info'); this.log('Has list: ' + (typeof this.driver.list === 'function'), 'info'); this.log('Has disconnect: ' + (typeof this.driver.disconnect === 'function'), 'info'); this.log('✓ SFTP driver loaded successfully', 'success'); // Test connection this.log('Attempting to connect to files.devbrewing.com:22...', 'info'); this.log('Username: olinhll', 'info'); const result = await this.driver.connect( 'files.devbrewing.com', 22, 'olinhll', 'devbrewing123' ); this.log('✓ Connection successful!', 'success'); this.log('Server response: ' + JSON.stringify(result, null, 2), 'success'); connectBtn.textContent = '✅ Connected'; listBtn.disabled = false; disconnectBtn.disabled = false; } catch (err) { this.log('✗ Connection FAILED!', 'error'); this.log('Error message: ' + err.message, 'error'); this.log('Error stack: ' + err.stack, 'error'); connectBtn.textContent = '🚀 Test Connection'; connectBtn.disabled = false; } }, async testList() { const listBtn = this.el.querySelector('#listTestBtn'); listBtn.disabled = true; listBtn.textContent = '⏳ Loading...'; try { this.log('==================', 'info'); this.log('Listing root directory (/)...', 'info'); const files = await this.driver.list('/'); this.log(`✓ Successfully loaded ${files.length} items:`, 'success'); this.log('==================', 'info'); if (files.length === 0) { this.log(' (Directory is empty)', 'warn'); } else { files.forEach(file => { const icon = file.is_dir ? '📁' : '📄'; const size = file.is_dir ? 'DIR' : this.formatBytes(file.size); const modified = file.modified || 'unknown'; this.log(` ${icon} ${file.name.padEnd(30)} ${size.padEnd(10)} ${modified}`, 'info'); }); } listBtn.textContent = '📁 List Root Directory'; listBtn.disabled = false; } catch (err) { this.log('✗ List operation FAILED!', 'error'); this.log('Error: ' + err.message, 'error'); this.log('Stack: ' + err.stack, 'error'); listBtn.textContent = '📁 List Root Directory'; listBtn.disabled = false; } }, async testDisconnect() { const disconnectBtn = this.el.querySelector('#disconnectTestBtn'); const connectBtn = this.el.querySelector('#connectTestBtn'); const listBtn = this.el.querySelector('#listTestBtn'); disconnectBtn.disabled = true; try { this.log('==================', 'info'); this.log('Disconnecting from server...', 'info'); const result = await this.driver.disconnect(); this.log('✓ Disconnected successfully', 'success'); this.log('Server response: ' + JSON.stringify(result, null, 2), 'success'); connectBtn.textContent = '🚀 Test Connection'; connectBtn.disabled = false; listBtn.disabled = true; disconnectBtn.disabled = true; } catch (err) { this.log('✗ Disconnect FAILED!', 'error'); this.log('Error: ' + err.message, 'error'); disconnectBtn.disabled = false; } }, formatBytes(bytes) { if (!bytes || bytes === 0) return '0 B'; const k = 1024; const sizes = ['B', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]; } }; // Register the component window.AppItems = window.AppItems || []; window.AppItems.push(TestConnection); console.log('[TestConnection] Component registered and ready'); })();