* fix: only show connection lost when the server check fails too

* fix: load the macOS tray icon from the right unpacked folder (#1728)

* fix: hide update and review buttons on disabled plugins (#1745)

* fix: save the database without blocking the server, bump to 26.11.0

* fix: try the key before the password for hosts with both (Plugin-SSH-Terminal#50)

* fix: add macOS Window menu item to reopen main window

* feat: upload Mac App Store screenshots on submit

* chore: drop internal note from changelog

* chore: update translations and plugin pins

* chore: lint, format, and bump version to 26.11.0
This commit is contained in:
Luke Gustafson authored and GitHub committed 2026-11-01 17:16:04 -06:00
1 parent c759a147c6
commit 1d4eac3e20
24 files changed
+337 -56

No files matched your search

+20 -4
View File
@@ -16,6 +16,8 @@ interface EncryptedFileMetadata {
dataSize?: number;
}
const ENCRYPT_CHUNK_BYTES = 4 * 1024 * 1024;
class DatabaseFileEncryption {
private static readonly VERSION = "v2";
private static readonly ALGORITHM = "aes-256-gcm";
@@ -27,7 +29,7 @@ class DatabaseFileEncryption {
buffer: Buffer,
targetPath: string,
): Promise<string> {
const tmpPath = `${targetPath}.tmp-${Date.now()}-${process.pid}`;
const tmpPath = `${targetPath}.tmp-${Date.now()}-${process.pid}-${crypto.randomBytes(4).toString("hex")}`;
const metadataPath = `${targetPath}${this.METADATA_FILE_SUFFIX}`;
try {
@@ -38,7 +40,21 @@ class DatabaseFileEncryption {
key,
iv,
) as crypto.CipherGCM;
const encrypted = Buffer.concat([cipher.update(buffer), cipher.final()]);
// This runs on every save, so a big database must not hold up the event
// loop for the whole encryption.
const parts: Buffer[] = [];
for (
let offset = 0;
offset < buffer.length;
offset += ENCRYPT_CHUNK_BYTES
) {
parts.push(
cipher.update(buffer.subarray(offset, offset + ENCRYPT_CHUNK_BYTES)),
);
await new Promise<void>((resolve) => setImmediate(resolve));
}
parts.push(cipher.final());
const encrypted = Buffer.concat(parts);
const tag = cipher.getAuthTag();
const metadata: EncryptedFileMetadata = {
@@ -62,8 +78,8 @@ class DatabaseFileEncryption {
encrypted,
]);
fs.writeFileSync(tmpPath, finalBuffer);
fs.renameSync(tmpPath, targetPath);
await fs.promises.writeFile(tmpPath, finalBuffer);
await fs.promises.rename(tmpPath, targetPath);
try {
if (fs.existsSync(metadataPath)) {