Update launch_progress.js
This commit is contained in:
@@ -123,6 +123,18 @@ function initializeSteps() {
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
stepsContainer.appendChild(healthStep);
|
stepsContainer.appendChild(healthStep);
|
||||||
|
|
||||||
|
// Add Authentication step
|
||||||
|
const authStep = document.createElement('div');
|
||||||
|
authStep.className = 'step-item';
|
||||||
|
authStep.innerHTML = `
|
||||||
|
<div class="step-icon"><i class="fas fa-key"></i></div>
|
||||||
|
<div class="step-content">
|
||||||
|
<h5>Instance Authentication</h5>
|
||||||
|
<p class="step-status">Setting up instance authentication...</p>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
stepsContainer.appendChild(authStep);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function startLaunch(data) {
|
async function startLaunch(data) {
|
||||||
@@ -410,9 +422,65 @@ async function startLaunch(data) {
|
|||||||
healthStep.querySelector('.step-content').appendChild(retryButton);
|
healthStep.querySelector('.step-content').appendChild(retryButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// After health check, add authentication step
|
||||||
|
await updateStep(10, 'Instance Authentication', 'Setting up instance authentication...');
|
||||||
|
const authResult = await authenticateInstance(`https://${data.webAddresses[0]}`, data.instanceId);
|
||||||
|
|
||||||
|
if (!authResult.success) {
|
||||||
|
throw new Error(`Authentication failed: ${authResult.error}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the auth step to show success
|
||||||
|
const authStep = document.querySelectorAll('.step-item')[9];
|
||||||
|
authStep.classList.remove('active');
|
||||||
|
authStep.classList.add('completed');
|
||||||
|
authStep.querySelector('.step-status').textContent = authResult.alreadyAuthenticated ?
|
||||||
|
'Instance is already authenticated' :
|
||||||
|
'Successfully authenticated instance';
|
||||||
|
|
||||||
|
// Add authentication details
|
||||||
|
const authDetails = document.createElement('div');
|
||||||
|
authDetails.className = 'mt-3';
|
||||||
|
authDetails.innerHTML = `
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h6 class="card-title mb-3">Authentication Details</h6>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-sm">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Property</th>
|
||||||
|
<th>Value</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Status</td>
|
||||||
|
<td><span class="badge bg-success">Authenticated</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Default Admin</td>
|
||||||
|
<td>administrator@docupulse.com</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Connection Type</td>
|
||||||
|
<td>Management API Key</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Authentication Type</td>
|
||||||
|
<td>${authResult.alreadyAuthenticated ? 'Existing' : 'New'}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
authStep.querySelector('.step-content').appendChild(authDetails);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Launch failed:', error);
|
console.error('Launch failed:', error);
|
||||||
await updateStep(9, 'Health Check', `Error: ${error.message}`);
|
await updateStep(10, 'Instance Authentication', `Error: ${error.message}`);
|
||||||
showError(error.message);
|
showError(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1018,8 +1086,8 @@ function updateStep(stepNumber, title, description) {
|
|||||||
document.getElementById('currentStep').textContent = title;
|
document.getElementById('currentStep').textContent = title;
|
||||||
document.getElementById('stepDescription').textContent = description;
|
document.getElementById('stepDescription').textContent = description;
|
||||||
|
|
||||||
// Calculate progress based on total number of steps (9 steps total)
|
// Calculate progress based on total number of steps (10 steps total)
|
||||||
const totalSteps = 9;
|
const totalSteps = 10;
|
||||||
const progress = ((stepNumber - 1) / (totalSteps - 1)) * 100;
|
const progress = ((stepNumber - 1) / (totalSteps - 1)) * 100;
|
||||||
const progressBar = document.getElementById('launchProgress');
|
const progressBar = document.getElementById('launchProgress');
|
||||||
progressBar.style.width = `${progress}%`;
|
progressBar.style.width = `${progress}%`;
|
||||||
@@ -1303,3 +1371,124 @@ async function checkInstanceHealth(instanceUrl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function authenticateInstance(instanceUrl, instanceId) {
|
||||||
|
try {
|
||||||
|
// First check if instance is already authenticated
|
||||||
|
const instancesResponse = await fetch('/instances');
|
||||||
|
const text = await instancesResponse.text();
|
||||||
|
const parser = new DOMParser();
|
||||||
|
const doc = parser.parseFromString(text, 'text/html');
|
||||||
|
|
||||||
|
// Find the instance with matching URL
|
||||||
|
const instanceRow = Array.from(doc.querySelectorAll('table tbody tr')).find(row => {
|
||||||
|
const urlCell = row.querySelector('td:nth-child(7) a'); // URL is in the 7th column
|
||||||
|
return urlCell && urlCell.textContent.trim() === instanceUrl;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!instanceRow) {
|
||||||
|
throw new Error('Instance not found in database');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the instance ID from the status badge's data attribute
|
||||||
|
const statusBadge = instanceRow.querySelector('[data-instance-id]');
|
||||||
|
if (!statusBadge) {
|
||||||
|
throw new Error('Could not find instance ID');
|
||||||
|
}
|
||||||
|
|
||||||
|
const dbInstanceId = statusBadge.dataset.instanceId;
|
||||||
|
|
||||||
|
// Check if already authenticated
|
||||||
|
const authStatusResponse = await fetch(`/instances/${dbInstanceId}/auth-status`);
|
||||||
|
if (!authStatusResponse.ok) {
|
||||||
|
throw new Error('Failed to check authentication status');
|
||||||
|
}
|
||||||
|
|
||||||
|
const authStatus = await authStatusResponse.json();
|
||||||
|
if (authStatus.authenticated) {
|
||||||
|
console.log('Instance is already authenticated');
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: 'Instance is already authenticated',
|
||||||
|
alreadyAuthenticated: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Attempting login to:', `${instanceUrl}/api/admin/login`);
|
||||||
|
|
||||||
|
// First login to get token
|
||||||
|
const loginResponse = await fetch(`${instanceUrl}/api/admin/login`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Accept': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
email: 'administrator@docupulse.com',
|
||||||
|
password: 'changeme'
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!loginResponse.ok) {
|
||||||
|
const errorText = await loginResponse.text();
|
||||||
|
throw new Error(`Login failed: ${errorText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const loginData = await loginResponse.json();
|
||||||
|
if (loginData.status !== 'success' || !loginData.token) {
|
||||||
|
throw new Error('Login failed: Invalid response from server');
|
||||||
|
}
|
||||||
|
|
||||||
|
const token = loginData.token;
|
||||||
|
|
||||||
|
// Then create management API key
|
||||||
|
const keyResponse = await fetch(`${instanceUrl}/api/admin/management-api-key`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
name: `Connection from ${window.location.hostname}`
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!keyResponse.ok) {
|
||||||
|
const errorText = await keyResponse.text();
|
||||||
|
throw new Error(`Failed to create API key: ${errorText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const keyData = await keyResponse.json();
|
||||||
|
if (!keyData.api_key) {
|
||||||
|
throw new Error('No API key received from server');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the token to our database
|
||||||
|
const saveResponse = await fetch(`/instances/${dbInstanceId}/save-token`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ token: keyData.api_key })
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!saveResponse.ok) {
|
||||||
|
const errorText = await saveResponse.text();
|
||||||
|
throw new Error(`Failed to save token: ${errorText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: 'Successfully authenticated instance',
|
||||||
|
alreadyAuthenticated: false
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Authentication error:', error);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: error.message
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user