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:
@@ -0,0 +1,38 @@
|
||||
import { createHash } from 'crypto';
|
||||
import { createReadStream } from 'fs';
|
||||
import { ElectronLogger } from '@/infrastructure/Log/ElectronLogger';
|
||||
import { retryFileSystemAccess } from './RetryFileSystemAccess';
|
||||
|
||||
export async function checkIntegrity(
|
||||
filePath: string,
|
||||
base64Sha512: string,
|
||||
): Promise<boolean> {
|
||||
return retryFileSystemAccess(
|
||||
async () => {
|
||||
const hash = await computeSha512(filePath);
|
||||
if (hash === base64Sha512) {
|
||||
ElectronLogger.info(`Integrity check passed for file: ${filePath}.`);
|
||||
return true;
|
||||
}
|
||||
ElectronLogger.warn([
|
||||
`Integrity check failed for file: ${filePath}`,
|
||||
`Expected hash: ${base64Sha512}, but found: ${hash}`,
|
||||
].join('\n'));
|
||||
return false;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
async function computeSha512(filePath: string): Promise<string> {
|
||||
try {
|
||||
const hash = createHash('sha512');
|
||||
const stream = createReadStream(filePath);
|
||||
for await (const chunk of stream) {
|
||||
hash.update(chunk);
|
||||
}
|
||||
return hash.digest('base64');
|
||||
} catch (error) {
|
||||
ElectronLogger.error(`Failed to compute SHA512 hash for file: ${filePath}`, error);
|
||||
throw error; // Rethrow to handle it in the calling context if necessary
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user