// Form validation (function () { 'use strict' var forms = document.querySelectorAll('.needs-validation') Array.prototype.slice.call(forms).forEach(function (form) { form.addEventListener('submit', function (event) { if (!form.checkValidity()) { event.preventDefault() event.stopPropagation() } form.classList.add('was-validated') }, false) }) })() // Show success modal function showSuccess(message) { const successModal = document.getElementById('successModal'); if (successModal) { document.getElementById('successMessage').textContent = message; new bootstrap.Modal(successModal).show(); } else { alert(message); // Fallback if modal doesn't exist } } // Show error modal function showError(message) { const errorModal = document.getElementById('errorModal'); if (errorModal) { document.getElementById('errorMessage').textContent = message; new bootstrap.Modal(errorModal).show(); } else { alert(message); // Fallback if modal doesn't exist } } // Get CSRF token from meta tag function getCsrfToken() { const metaTag = document.querySelector('meta[name="csrf-token"]'); return metaTag ? metaTag.getAttribute('content') : ''; } // Get JWT token using management API key async function getJwtToken() { try { const response = await fetch('/api/admin/management-token', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Key': document.querySelector('meta[name="management-api-key"]').getAttribute('content') } }); if (!response.ok) { throw new Error('Failed to get JWT token'); } const data = await response.json(); return data.token; } catch (error) { console.error('Error getting JWT token:', error); throw error; } } // Load Gitea Repositories async function loadGiteaRepos() { const url = document.getElementById('giteaUrl').value; const token = document.getElementById('giteaToken').value; const repoSelect = document.getElementById('giteaRepo'); const currentRepo = repoSelect.value; // Store current selection if (!url || !token) { showError('Please fill in the server URL and access token'); return; } try { const response = await fetch('/api/admin/list-gitea-repos', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': getCsrfToken() }, body: JSON.stringify({ url, token }) }); const data = await response.json(); if (response.ok) { repoSelect.innerHTML = ''; data.repositories.forEach(repo => { const option = document.createElement('option'); option.value = repo.full_name; option.textContent = repo.full_name; if (repo.full_name === currentRepo) { // Restore selection option.selected = true; } repoSelect.appendChild(option); }); } else { throw new Error(data.message || 'Failed to load repositories'); } } catch (error) { showError(error.message); } } // Test Git Connection async function testGitConnection(provider) { const saveModal = new bootstrap.Modal(document.getElementById('saveConnectionModal')); const messageElement = document.getElementById('saveConnectionMessage'); messageElement.textContent = 'Testing connection...'; messageElement.className = ''; saveModal.show(); try { const url = document.getElementById('giteaUrl').value; const username = document.getElementById('giteaUsername').value; const token = document.getElementById('giteaToken').value; if (!url || !username || !token) { throw new Error('Please fill in all required fields'); } const data = { provider: 'gitea', url: url, username: username, token: token }; const response = await fetch('/settings/test-git-connection', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': getCsrfToken() }, body: JSON.stringify(data) }); if (!response.ok) { const error = await response.json(); throw new Error(error.error || 'Connection test failed'); } messageElement.textContent = 'Connection test successful!'; messageElement.className = 'text-success'; } catch (error) { messageElement.textContent = error.message || 'Connection test failed'; messageElement.className = 'text-danger'; } } // Test Portainer Connection async function testPortainerConnection() { const url = document.getElementById('portainerUrl').value; const apiKey = document.getElementById('portainerApiKey').value; if (!url || !apiKey) { showError('Please fill in all fields'); return; } try { const response = await fetch('/api/admin/test-portainer-connection', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').content }, body: JSON.stringify({ url: url, api_key: apiKey }) }); const data = await response.json(); if (response.ok) { showSuccess('Connection successful'); } else { showError(data.error || 'Failed to connect to Portainer'); } } catch (error) { console.error('Error:', error); showError('Failed to connect to Portainer'); } } // Test NGINX Connection async function testNginxConnection() { const saveModal = new bootstrap.Modal(document.getElementById('saveConnectionModal')); const messageElement = document.getElementById('saveConnectionMessage'); messageElement.textContent = 'Testing connection...'; messageElement.className = ''; saveModal.show(); try { const url = document.getElementById('nginxUrl').value; const username = document.getElementById('nginxUsername').value; const password = document.getElementById('nginxPassword').value; if (!url || !username || !password) { throw new Error('Please fill in all required fields'); } // First, get the token const tokenResponse = await fetch(`${url}/api/tokens`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ identity: username, secret: password }) }); if (!tokenResponse.ok) { throw new Error('Failed to authenticate with NGINX Proxy Manager'); } const tokenData = await tokenResponse.json(); const token = tokenData.token; // Now test the connection using the token const response = await fetch(`${url}/api/nginx/proxy-hosts`, { method: 'GET', headers: { 'Authorization': `Bearer ${token}`, 'Accept': 'application/json' } }); if (!response.ok) { throw new Error('Failed to connect to NGINX Proxy Manager'); } messageElement.textContent = 'Connection test successful!'; messageElement.className = 'text-success'; } catch (error) { messageElement.textContent = error.message || 'Connection test failed'; messageElement.className = 'text-danger'; } } // Save Portainer Connection async function savePortainerConnection(event) { event.preventDefault(); const saveModal = new bootstrap.Modal(document.getElementById('saveConnectionModal')); const messageElement = document.getElementById('saveConnectionMessage'); messageElement.textContent = ''; messageElement.className = ''; try { const url = document.getElementById('portainerUrl').value; const apiKey = document.getElementById('portainerApiKey').value; if (!url || !apiKey) { throw new Error('Please fill in all required fields'); } const response = await fetch('/settings/save-portainer-connection', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': getCsrfToken() }, body: JSON.stringify({ url: url, api_key: apiKey }) }); if (!response.ok) { const error = await response.json(); throw new Error(error.error || 'Failed to save settings'); } messageElement.textContent = 'Settings saved successfully!'; messageElement.className = 'text-success'; } catch (error) { messageElement.textContent = error.message || 'Failed to save settings'; messageElement.className = 'text-danger'; } saveModal.show(); } // Save NGINX Connection async function saveNginxConnection(event) { event.preventDefault(); const saveModal = new bootstrap.Modal(document.getElementById('saveConnectionModal')); const messageElement = document.getElementById('saveConnectionMessage'); messageElement.textContent = ''; messageElement.className = ''; try { const url = document.getElementById('nginxUrl').value; const username = document.getElementById('nginxUsername').value; const password = document.getElementById('nginxPassword').value; if (!url || !username || !password) { throw new Error('Please fill in all required fields'); } const response = await fetch('/settings/save-nginx-connection', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': getCsrfToken() }, body: JSON.stringify({ url: url, username: username, password: password }) }); if (!response.ok) { const error = await response.json(); throw new Error(error.error || 'Failed to save settings'); } messageElement.textContent = 'Settings saved successfully!'; messageElement.className = 'text-success'; } catch (error) { messageElement.textContent = error.message || 'Failed to save settings'; messageElement.className = 'text-danger'; } saveModal.show(); } // Save Git Connection async function saveGitConnection(event, provider) { event.preventDefault(); const saveModal = new bootstrap.Modal(document.getElementById('saveConnectionModal')); const messageElement = document.getElementById('saveConnectionMessage'); messageElement.textContent = ''; messageElement.className = ''; try { const url = document.getElementById('giteaUrl').value; const username = document.getElementById('giteaUsername').value; const token = document.getElementById('giteaToken').value; const repo = document.getElementById('giteaRepo').value; const password = document.getElementById('giteaPassword').value; const otp = document.getElementById('giteaOtp').value; if (!url || !username || !token || !repo) { throw new Error('Please fill in all required fields'); } const data = { provider: 'gitea', url: url, username: username, token: token, repo: repo, password: password, otp: otp }; const response = await fetch('/settings/save-git-connection', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': getCsrfToken() }, body: JSON.stringify(data) }); if (!response.ok) { const error = await response.json(); throw new Error(error.error || 'Failed to save settings'); } messageElement.textContent = 'Settings saved successfully!'; messageElement.className = 'text-success'; } catch (error) { messageElement.textContent = error.message || 'Failed to save settings'; messageElement.className = 'text-danger'; } saveModal.show(); } // Initialize on page load document.addEventListener('DOMContentLoaded', function() { const gitSettings = JSON.parse(document.querySelector('meta[name="git-settings"]').getAttribute('content')); if (gitSettings && gitSettings.provider === 'gitea' && gitSettings.url && gitSettings.token) { loadGiteaRepos(); } });