working
This commit is contained in:
@@ -10,6 +10,10 @@
|
||||
<div class="container mt-5">
|
||||
<h1>Fitbit-Garmin Sync - Setup</h1>
|
||||
|
||||
<div class="mb-3">
|
||||
<button type="button" class="btn btn-info" id="load-from-consul-btn">Load Config from Consul</button>
|
||||
</div>
|
||||
|
||||
<!-- Current Status Section -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-12">
|
||||
@@ -32,19 +36,28 @@
|
||||
<form id="garmin-credentials-form">
|
||||
<div class="mb-3">
|
||||
<label for="garmin-username" class="form-label">Username</label>
|
||||
<input type="text" class="form-control" id="garmin-username" name="username" required>
|
||||
<input type="text" class="form-control" id="garmin-username" name="username" required autocomplete="username">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="garmin-password" class="form-label">Password</label>
|
||||
<input type="password" class="form-control" id="garmin-password" name="password" required>
|
||||
<input type="password" class="form-control" id="garmin-password" name="password" required autocomplete="current-password">
|
||||
</div>
|
||||
<div class="mb-3 form-check">
|
||||
<input type="checkbox" class="form-check-input" id="garmin-china" name="is_china">
|
||||
<label class="form-check-label" for="garmin-china">Use China domain (garmin.cn)</label>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Save Garmin Credentials</button>
|
||||
<button type="button" class="btn btn-secondary" id="test-garmin-btn">Test Garmin Credentials</button>
|
||||
<button type="submit" class="btn btn-primary" id="save-garmin-btn" disabled>Save Garmin Credentials</button>
|
||||
<button type="button" class="btn btn-info" id="test-garmin-token-btn">Test Current Garmin Token</button>
|
||||
</form>
|
||||
|
||||
<!-- Garmin Authentication Status -->
|
||||
<div id="garmin-auth-status-text" class="mt-3">
|
||||
<p>Current auth state: <span class="badge bg-secondary">Not Tested</span></p>
|
||||
</div>
|
||||
|
||||
<div id="garmin-token-test-result" class="mt-3"></div>
|
||||
|
||||
<!-- Garmin Authentication Status -->
|
||||
<div id="garmin-auth-status" class="mt-3">
|
||||
<p>Loading Garmin authentication status...</p>
|
||||
@@ -70,13 +83,14 @@
|
||||
<form id="fitbit-credentials-form">
|
||||
<div class="mb-3">
|
||||
<label for="fitbit-client-id" class="form-label">Client ID</label>
|
||||
<input type="text" class="form-control" id="fitbit-client-id" name="client_id" required>
|
||||
<input type="text" class="form-control" id="fitbit-client-id" name="client_id" required autocomplete="username">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="fitbit-client-secret" class="form-label">Client Secret</label>
|
||||
<input type="password" class="form-control" id="fitbit-client-secret" name="client_secret" required>
|
||||
<input type="password" class="form-control" id="fitbit-client-secret" name="client_secret" required autocomplete="new-password">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Save Fitbit Credentials</button>
|
||||
<button type="button" class="btn btn-secondary" id="test-fitbit-btn">Test Fitbit Credentials</button>
|
||||
<button type="submit" class="btn btn-primary" id="save-fitbit-btn" disabled>Save Fitbit Credentials</button>
|
||||
</form>
|
||||
<div class="mt-3">
|
||||
<div id="auth-url-container" style="display: none;">
|
||||
@@ -94,7 +108,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mt-4">
|
||||
<div class="row mt-4" id="fitbit-oauth-flow-section" style="display: none;">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
@@ -112,17 +126,60 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Load initial status information
|
||||
loadStatusInfo();
|
||||
|
||||
// Setup form event listeners
|
||||
document.getElementById('load-from-consul-btn').addEventListener('click', loadFromConsul);
|
||||
document.getElementById('test-garmin-btn').addEventListener('click', testGarminCredentials);
|
||||
document.getElementById('test-garmin-token-btn').addEventListener('click', testGarminToken);
|
||||
document.getElementById('garmin-credentials-form').addEventListener('submit', saveGarminCredentials);
|
||||
document.getElementById('test-fitbit-btn').addEventListener('click', testFitbitCredentials);
|
||||
document.getElementById('fitbit-credentials-form').addEventListener('submit', saveFitbitCredentials);
|
||||
document.getElementById('fitbit-callback-form').addEventListener('submit', completeFitbitAuth);
|
||||
});
|
||||
|
||||
async function testGarminToken() {
|
||||
const resultDiv = document.getElementById('garmin-token-test-result');
|
||||
resultDiv.innerHTML = '<p>Testing token...</p>';
|
||||
try {
|
||||
const response = await fetch('/api/setup/garmin/test-token', { method: 'POST' });
|
||||
const data = await response.json();
|
||||
if (response.ok) {
|
||||
resultDiv.innerHTML = `<div class="alert alert-success"><pre>${JSON.stringify(data, null, 2)}</pre></div>`;
|
||||
} else {
|
||||
resultDiv.innerHTML = `<div class="alert alert-danger">${data.detail || 'Failed to test token'}</div>`;
|
||||
}
|
||||
} catch (error) {
|
||||
resultDiv.innerHTML = `<div class="alert alert-danger">Error: ${error.message}</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
async function loadFromConsul() {
|
||||
alert('Attempting to load config from Consul and save to backend...');
|
||||
console.log('loadFromConsul function called');
|
||||
try {
|
||||
const response = await fetch('/api/setup/load-consul-config', { method: 'POST' });
|
||||
console.log('Response received:', response);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json();
|
||||
throw new Error(errorData.detail || 'Failed to load config from Consul');
|
||||
}
|
||||
const data = await response.json();
|
||||
if (data.status === "mfa_required") {
|
||||
alert(data.message);
|
||||
loadStatusInfo(); // Refresh the status info to potentially show MFA section
|
||||
} else {
|
||||
alert(data.message || 'Configuration loaded from Consul successfully.');
|
||||
loadStatusInfo(); // Refresh the status info
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error loading config from Consul:', error);
|
||||
alert('Error loading config from Consul: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function loadStatusInfo() {
|
||||
try {
|
||||
@@ -156,16 +213,26 @@
|
||||
// Update Garmin auth status
|
||||
const garminStatusContainer = document.getElementById('garmin-auth-status');
|
||||
if (authData.garmin) {
|
||||
garminStatusContainer.innerHTML = `
|
||||
<div class="alert ${authData.garmin.authenticated ? 'alert-success' : 'alert-warning'}">
|
||||
<h6>Garmin Authentication Status</h6>
|
||||
<p><strong>Username:</strong> ${authData.garmin.username || 'Not set'}</p>
|
||||
<p><strong>Authenticated:</strong> ${authData.garmin.authenticated ? 'Yes' : 'No'}</p>
|
||||
${authData.garmin.token_expires_at ? `<p><strong>Token Expires:</strong> ${new Date(authData.garmin.token_expires_at).toLocaleString()}</p>` : ''}
|
||||
${authData.garmin.last_login ? `<p><strong>Last Login:</strong> ${new Date(authData.garmin.last_login).toLocaleString()}</p>` : ''}
|
||||
<p><strong>Domain:</strong> ${authData.garmin.is_china ? 'garmin.cn' : 'garmin.com'}</p>
|
||||
</div>
|
||||
`;
|
||||
let garminStatusHtml = `<h6>Garmin Authentication Status</h6>`;
|
||||
if (authData.garmin.token_stored) {
|
||||
garminStatusHtml += `<p><strong>Tokens Stored:</strong> Yes</p>`;
|
||||
garminStatusHtml += `<p><strong>Authenticated:</strong> ${authData.garmin.authenticated ? 'Yes' : 'No'}</p>`;
|
||||
garminStatusHtml += `<p><strong>OAuth1 Token Exists:</strong> ${authData.garmin.garth_oauth1_token_exists ? 'Yes' : 'No'}</p>`;
|
||||
garminStatusHtml += `<p><strong>OAuth2 Token Exists:</strong> ${authData.garmin.garth_oauth2_token_exists ? 'Yes' : 'No'}</p>`;
|
||||
garminStatusHtml += `<p><strong>MFA State Exists:</strong> ${authData.garmin.mfa_state_exists ? 'Yes' : 'No'}</p>`;
|
||||
if (authData.garmin.mfa_expires_at) {
|
||||
garminStatusHtml += `<p><strong>MFA Expires:</strong> ${new Date(authData.garmin.mfa_expires_at).toLocaleString()}</p>`;
|
||||
}
|
||||
if (authData.garmin.last_used) {
|
||||
garminStatusHtml += `<p><strong>Last Used:</strong> ${new Date(authData.garmin.last_used).toLocaleString()}</p>`;
|
||||
}
|
||||
if (authData.garmin.updated_at) {
|
||||
garminStatusHtml += `<p><strong>Last Updated:</strong> ${new Date(authData.garmin.updated_at).toLocaleString()}</p>`;
|
||||
}
|
||||
} else {
|
||||
garminStatusHtml += `<p><strong>Tokens Stored:</strong> No</p>`;
|
||||
}
|
||||
garminStatusContainer.innerHTML = `<div class="alert ${authData.garmin.authenticated ? 'alert-success' : 'alert-warning'}">${garminStatusHtml}</div>`;
|
||||
}
|
||||
|
||||
// Update Fitbit auth status
|
||||
@@ -187,6 +254,49 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function testGarminCredentials() {
|
||||
const form = document.getElementById('garmin-credentials-form');
|
||||
const formData = new FormData(form);
|
||||
const credentials = {
|
||||
username: formData.get('username'),
|
||||
password: formData.get('password'),
|
||||
is_china: formData.get('is_china') === 'on' || formData.get('is_china') === 'true'
|
||||
};
|
||||
const statusText = document.getElementById('garmin-auth-status-text');
|
||||
const saveBtn = document.getElementById('save-garmin-btn');
|
||||
|
||||
statusText.innerHTML = `<p>Current auth state: <span class="badge bg-info">Testing...</span></p>`;
|
||||
saveBtn.disabled = true;
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/setup/garmin', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(credentials)
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.status === 'mfa_required') {
|
||||
statusText.innerHTML = `<p>Current auth state: <span class="badge bg-warning">MFA Required</span></p>`;
|
||||
document.getElementById('garmin-mfa-section').style.display = 'block';
|
||||
window.garmin_mfa_session_id = data.session_id;
|
||||
alert('Multi-factor authentication required. Please enter the verification code.');
|
||||
} else if (response.ok) {
|
||||
statusText.innerHTML = `<p>Current auth state: <span class="badge bg-success">Authentication Successful</span></p>`;
|
||||
saveBtn.disabled = false;
|
||||
alert('Garmin authentication successful. You can now save the credentials.');
|
||||
} else {
|
||||
statusText.innerHTML = `<p>Current auth state: <span class="badge bg-danger">Authentication Failed</span></p>`;
|
||||
alert(data.message || 'Garmin authentication failed.');
|
||||
}
|
||||
} catch (error) {
|
||||
statusText.innerHTML = `<p>Current auth state: <span class="badge bg-danger">Error</span></p>`;
|
||||
console.error('Error testing Garmin credentials:', error);
|
||||
alert('Error testing Garmin credentials: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function saveGarminCredentials(event) {
|
||||
event.preventDefault();
|
||||
|
||||
@@ -200,28 +310,17 @@
|
||||
try {
|
||||
const response = await fetch('/api/setup/garmin', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(credentials)
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.status === 'mfa_required') {
|
||||
// Show MFA section if MFA is required and store session ID
|
||||
document.getElementById('garmin-mfa-section').style.display = 'block';
|
||||
// Store the session ID for later use when submitting the MFA code
|
||||
window.garmin_mfa_session_id = data.session_id;
|
||||
alert('Multi-factor authentication required. Please enter the verification code sent to your device.');
|
||||
} else {
|
||||
alert(data.message || 'Garmin credentials saved successfully');
|
||||
|
||||
// Refresh status after saving
|
||||
if (response.ok) {
|
||||
alert('Garmin credentials saved successfully');
|
||||
loadStatusInfo();
|
||||
|
||||
// Hide MFA section if showing
|
||||
document.getElementById('garmin-mfa-section').style.display = 'none';
|
||||
} else {
|
||||
alert(data.message || 'Error saving Garmin credentials.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error saving Garmin credentials:', error);
|
||||
@@ -229,6 +328,42 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function testFitbitCredentials() {
|
||||
const form = document.getElementById('fitbit-credentials-form');
|
||||
const formData = new FormData(form);
|
||||
const credentials = {
|
||||
client_id: formData.get('client_id'),
|
||||
client_secret: formData.get('client_secret')
|
||||
};
|
||||
const saveBtn = document.getElementById('save-fitbit-btn');
|
||||
|
||||
saveBtn.disabled = true;
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/setup/fitbit', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(credentials)
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
const authLink = document.getElementById('auth-link');
|
||||
authLink.href = data.auth_url;
|
||||
document.getElementById('auth-url-container').style.display = 'block';
|
||||
document.getElementById('fitbit-oauth-flow-section').style.display = 'block';
|
||||
saveBtn.disabled = false;
|
||||
alert('Fitbit credentials seem valid. You can now save them and proceed with authorization.');
|
||||
} else {
|
||||
alert(data.message || 'Fitbit credentials test failed.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error testing Fitbit credentials:', error);
|
||||
alert('Error testing Fitbit credentials: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function saveFitbitCredentials(event) {
|
||||
event.preventDefault();
|
||||
|
||||
@@ -248,12 +383,12 @@
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
alert(data.message || 'Fitbit credentials saved successfully');
|
||||
|
||||
// Show the authorization link
|
||||
const authLink = document.getElementById('auth-link');
|
||||
authLink.href = data.auth_url;
|
||||
document.getElementById('auth-url-container').style.display = 'block';
|
||||
if(response.ok) {
|
||||
alert('Fitbit credentials saved successfully');
|
||||
loadStatusInfo();
|
||||
} else {
|
||||
alert(data.message || 'Error saving Fitbit credentials.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error saving Fitbit credentials:', error);
|
||||
alert('Error saving Fitbit credentials: ' + error.message);
|
||||
@@ -293,12 +428,16 @@
|
||||
|
||||
async function submitMFA() {
|
||||
const mfaCode = document.getElementById('mfa-code').value.trim();
|
||||
|
||||
const statusText = document.getElementById('garmin-auth-status-text');
|
||||
const saveBtn = document.getElementById('save-garmin-btn');
|
||||
|
||||
if (!mfaCode) {
|
||||
alert('Please enter the verification code');
|
||||
return;
|
||||
}
|
||||
|
||||
statusText.innerHTML = `<p>Current auth state: <span class="badge bg-info">Verifying MFA...</span></p>`;
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/setup/garmin/mfa', {
|
||||
method: 'POST',
|
||||
@@ -314,18 +453,18 @@
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
statusText.innerHTML = `<p>Current auth state: <span class="badge bg-success">MFA Verification Successful</span></p>`;
|
||||
saveBtn.disabled = false;
|
||||
alert(data.message || 'MFA verification successful');
|
||||
document.getElementById('garmin-mfa-section').style.display = 'none';
|
||||
|
||||
// Clear the MFA code field
|
||||
document.getElementById('mfa-code').value = '';
|
||||
|
||||
// Refresh status after MFA
|
||||
loadStatusInfo();
|
||||
} else {
|
||||
statusText.innerHTML = `<p>Current auth state: <span class="badge bg-danger">MFA Verification Failed</span></p>`;
|
||||
alert('MFA verification failed: ' + data.message);
|
||||
}
|
||||
} catch (error) {
|
||||
statusText.innerHTML = `<p>Current auth state: <span class="badge bg-danger">Error</span></p>`;
|
||||
console.error('Error submitting MFA code:', error);
|
||||
alert('Error submitting MFA code: ' + error.message);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user