Improve security and reliability of macOS updates
This commit introduces several improvements to the macOS update process, primarily focusing on enhancing security and reliability: - Add data integrity checks to ensure downloaded updates haven't been tampered with. - Optimize update progress logging in `streamWithProgress` by limiting amount of logs during the download process. - Improve resource management by ensuring proper closure of file read/write streams. - Add retry logic with exponential back-off during file access to handle occassionally seen file system preparation delays on macOS. - Improve decision-making based on user responses. - Improve clarity and informativeness of log messages. - Update error dialogs for better user guidance when updates fail to download, unexpected errors occur or the installer can't be opened. - Add handling for unexpected errors during the update process. - Move to asynchronous functions for more efficient operation. - Move to scoped imports for better code clarity. - Update `Readable` stream type to a more modern variant in Node. - Refactor `ManualUpdater` for improved separation of concerns. - Document the secure update process, and log directory locations. - Rename files to more accurately reflect their purpose. - Add `.DS_Store` in `.gitignore` to avoid unintended files in commits.
This commit is contained in:
46
src/presentation/electron/main/Update/UpdateInitializer.ts
Normal file
46
src/presentation/electron/main/Update/UpdateInitializer.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { autoUpdater, UpdateInfo } from 'electron-updater';
|
||||
import { ElectronLogger } from '@/infrastructure/Log/ElectronLogger';
|
||||
import { requiresManualUpdate, startManualUpdateProcess } from './ManualUpdater/ManualUpdateCoordinator';
|
||||
import { handleAutoUpdate } from './AutomaticUpdateCoordinator';
|
||||
|
||||
interface Updater {
|
||||
checkForUpdates(): Promise<void>;
|
||||
}
|
||||
|
||||
export function setupAutoUpdater(): Updater {
|
||||
autoUpdater.logger = ElectronLogger;
|
||||
|
||||
// Auto-downloads are disabled to allow separate handling of 'check' and 'download' actions,
|
||||
// which vary based on the specific platform and user preferences.
|
||||
autoUpdater.autoDownload = false;
|
||||
|
||||
autoUpdater.on('error', (error: Error) => {
|
||||
ElectronLogger.error('@error@\n', error);
|
||||
});
|
||||
|
||||
let isAlreadyHandled = false;
|
||||
autoUpdater.on('update-available', async (info: UpdateInfo) => {
|
||||
ElectronLogger.info('@update-available@\n', info);
|
||||
if (isAlreadyHandled) {
|
||||
ElectronLogger.info('Available updates is already handled');
|
||||
return;
|
||||
}
|
||||
isAlreadyHandled = true;
|
||||
await handleAvailableUpdate(info);
|
||||
});
|
||||
|
||||
return {
|
||||
checkForUpdates: async () => {
|
||||
// autoUpdater.emit('update-available'); // For testing
|
||||
await autoUpdater.checkForUpdates();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async function handleAvailableUpdate(info: UpdateInfo) {
|
||||
if (requiresManualUpdate()) {
|
||||
await startManualUpdateProcess(info);
|
||||
return;
|
||||
}
|
||||
await handleAutoUpdate();
|
||||
}
|
||||
Reference in New Issue
Block a user