docs(electron): added warning about invalidating bundle signature

This commit is contained in:
2025-08-10 07:00:21 -04:00
parent 55ef3490ae
commit 54b4378fff
3 changed files with 199 additions and 22 deletions

View File

@@ -116,6 +116,15 @@
<button class="modal-close" onclick="hideSaveOptionsModal()">&times;</button>
</div>
<div class="modal-body">
<div id="signature-warning-section" class="signature-warning-section hidden">
<div class="warning-banner">
<span class="warning-icon">⚠️</span>
<div class="warning-text">
<strong>Signature Warning:</strong> This operation will invalidate the bundle's digital signature.
You will need to re-sign the bundle using the <strong>Sign</strong> button and a <strong>PEM private key</strong> file.
</div>
</div>
</div>
<p>How would you like to save your metadata changes?</p>
<div class="save-options">
<button id="overwrite-bundle-btn" class="save-option-btn primary">
@@ -131,18 +140,37 @@
</div>
</div>
<!-- Fill Modal -->
<!-- Signature Invalidation Warning Modal -->
<div id="signature-warning-modal" class="modal-container hidden">
<div class="modal-content">
<h2>⚠️ Signature Warning</h2>
<div class="warning-content">
<p><strong>This operation will invalidate the bundle's digital signature.</strong></p>
<p>After making changes, you will need to re-sign the bundle using:</p>
<ul>
<li>The <strong>Sign</strong> button in the action bar</li>
<li>A valid <strong>PEM private key</strong> file</li>
</ul>
<p>Do you want to continue?</p>
</div>
<div class="modal-actions">
<button id="signature-warning-cancel" class="action-button secondary">Cancel</button>
<button id="signature-warning-continue" class="action-button primary">Continue</button>
</div>
</div>
</div>
<!-- Fill Modal (Legacy - can be removed later) -->
<div id="fill-modal" class="modal-container hidden">
<div class="modal-content">
<span class="close-fill-modal-button">&times;</span>
<h2 id="fill-modal-title">Fill Bundle</h2>
<div id="fill-modal-body">
<p>Select targets to build and add to the bundle:</p>
<p>Select the targets you want to build:</p>
<div id="fill-targets-list"></div>
<button id="start-fill-button" class="action-button">Start Fill</button>
<button id="start-fill-button">Start Fill</button>
</div>
<div id="fill-progress-view" style="display: none;">
<h3>Fill Progress:</h3>
<div id="fill-progress-list"></div>
</div>
</div>

View File

@@ -26,6 +26,12 @@ const saveOptionsModal = document.getElementById('save-options-modal');
const overwriteBundleBtn = document.getElementById('overwrite-bundle-btn');
const saveAsNewBtn = document.getElementById('save-as-new-btn');
// Signature warning modal elements
const signatureWarningModal = document.getElementById('signature-warning-modal');
const signatureWarningCancel = document.getElementById('signature-warning-cancel');
const signatureWarningContinue = document.getElementById('signature-warning-continue');
let pendingOperation = null; // Store the operation to execute after warning confirmation
// Fill tab elements
const fillTabLink = document.getElementById('fill-tab-link');
const loadFillableTargetsBtn = document.getElementById('load-fillable-targets-btn');
@@ -117,6 +123,20 @@ function setupEventListeners() {
overwriteBundleBtn.addEventListener('click', () => handleSaveMetadata(false));
saveAsNewBtn.addEventListener('click', () => handleSaveMetadata(true));
// Signature warning modal event listeners
signatureWarningCancel.addEventListener('click', () => {
signatureWarningModal.classList.add('hidden');
pendingOperation = null;
});
signatureWarningContinue.addEventListener('click', () => {
signatureWarningModal.classList.add('hidden');
if (pendingOperation) {
pendingOperation();
pendingOperation = null;
}
});
// Load fillable targets button
loadFillableTargetsBtn.addEventListener('click', async () => {
await loadFillableTargets();
@@ -185,6 +205,35 @@ function setupEventListeners() {
fillTargetsContent.classList.add('hidden');
}
// Check if bundle is signed and show warning before bundle-modifying operations
function checkSignatureAndWarn(operation, operationName = 'operation') {
console.log('checkSignatureAndWarn called for:', operationName);
console.log('currentBundle:', currentBundle);
// Check if current bundle has a valid signature
const isSigned = currentBundle &&
currentBundle.report &&
currentBundle.report.signature &&
currentBundle.report.signature.status &&
['TRUSTED', 'UNTRUSTED'].includes(currentBundle.report.signature.status);
console.log('Bundle signature status:', currentBundle?.report?.signature?.status);
console.log('isSigned:', isSigned);
if (isSigned) {
// Bundle is signed, show warning modal
console.log('Bundle is signed, showing warning modal');
pendingOperation = operation;
signatureWarningModal.classList.remove('hidden');
return false; // Don't execute operation immediately
} else {
// Bundle is not signed, execute operation directly
console.log('Bundle is not signed, executing operation directly');
operation();
return true; // Operation executed
}
}
// Old modal code removed - now using tab-based interface
// Create modern table-based interface for fillable targets
@@ -290,25 +339,28 @@ function setupEventListeners() {
selectedTargets[pluginName].push(target);
});
// Hide target selection and show progress
fillTargetsContent.classList.add('hidden');
fillProgressContainer.classList.remove('hidden');
populateFillProgress(selectedTargets);
// Check for signature and warn before starting fill process
checkSignatureAndWarn(async () => {
// Hide target selection and show progress
fillTargetsContent.classList.add('hidden');
fillProgressContainer.classList.remove('hidden');
populateFillProgress(selectedTargets);
const result = await ipcRenderer.invoke('fill-bundle', {
bundlePath: currentBundlePath,
targetsToBuild: selectedTargets
});
const result = await ipcRenderer.invoke('fill-bundle', {
bundlePath: currentBundlePath,
targetsToBuild: selectedTargets
});
if (!result.success) {
const errorItem = document.createElement('div');
errorItem.className = 'progress-item';
errorItem.innerHTML = `
<span class="progress-status failure">Error</span>
<span>Fill process failed: ${result.error}</span>
`;
fillProgressContent.appendChild(errorItem);
}
if (!result.success) {
const errorItem = document.createElement('div');
errorItem.className = 'progress-item';
errorItem.innerHTML = `
<span class="progress-status failure">Error</span>
<span>Fill process failed: ${result.error}</span>
`;
fillProgressContent.appendChild(errorItem);
}
}, 'fill bundle');
});
}
@@ -723,7 +775,24 @@ function updateSaveButtonVisibility() {
// Show save options modal
function showSaveOptionsModal() {
if (!currentBundlePath || !hasUnsavedChanges) return;
if (!hasUnsavedChanges) {
return;
}
// Check if bundle is signed and show warning banner
const signatureWarningSection = document.getElementById('signature-warning-section');
const isSigned = currentBundle &&
currentBundle.report &&
currentBundle.report.signature &&
currentBundle.report.signature.status &&
['TRUSTED', 'UNTRUSTED'].includes(currentBundle.report.signature.status);
if (isSigned) {
signatureWarningSection.classList.remove('hidden');
} else {
signatureWarningSection.classList.add('hidden');
}
saveOptionsModal.classList.remove('hidden');
}

View File

@@ -499,6 +499,7 @@ body {
.fill-target-checkbox {
margin-right: 8px;
border-color: var(--primary-hover);
}
.fill-actions {
@@ -578,6 +579,85 @@ body {
color: #991b1b;
}
/* Signature Warning Modal */
#signature-warning-modal .modal-content {
max-width: 500px;
}
#signature-warning-modal h2 {
color: #f59e0b;
margin-bottom: 16px;
display: flex;
align-items: center;
gap: 8px;
}
.warning-content {
margin-bottom: 24px;
}
.warning-content p {
margin-bottom: 12px;
line-height: 1.5;
}
.warning-content ul {
margin: 12px 0;
padding-left: 24px;
}
.warning-content li {
margin-bottom: 6px;
line-height: 1.4;
}
.modal-actions {
display: flex;
gap: 12px;
justify-content: flex-end;
}
.modal-actions button {
padding: 10px 20px;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
font-weight: 600;
transition: background-color 0.2s;
}
/* Signature Warning Banner in Save Modal */
.signature-warning-section {
margin-bottom: 20px;
}
.warning-banner {
display: flex;
align-items: flex-start;
gap: 12px;
padding: 16px;
background-color: #fef3c7;
border: 1px solid #f59e0b;
border-radius: 8px;
margin-bottom: 16px;
}
.warning-icon {
font-size: 20px;
flex-shrink: 0;
margin-top: 2px;
}
.warning-text {
line-height: 1.5;
color: #92400e;
}
.warning-text strong {
color: #78350f;
}
/* Save Options Modal */
.save-options {
display: flex;