From 0008b2f0229e7f6c3d0a57b1fd07c9b9644e3212 Mon Sep 17 00:00:00 2001 From: Eugene Pankov Date: Sat, 10 Jul 2021 20:39:45 +0200 Subject: [PATCH] preserve file modes for up- and downloads - fixes #4141 --- tabby-core/src/api/platform.ts | 7 ++++++- .../src/services/platform.service.ts | 20 +++++++++++++++---- .../src/components/sftpPanel.component.ts | 8 ++++---- tabby-terminal/src/features/debug.ts | 2 +- tabby-terminal/src/features/zmodem.ts | 2 +- tabby-web/src/platform.ts | 9 +++++++-- 6 files changed, 35 insertions(+), 13 deletions(-) diff --git a/tabby-core/src/api/platform.ts b/tabby-core/src/api/platform.ts index 74b0204a..d87b6fef 100644 --- a/tabby-core/src/api/platform.ts +++ b/tabby-core/src/api/platform.ts @@ -21,6 +21,7 @@ export interface MessageBoxResult { export abstract class FileTransfer { abstract getName (): string + abstract getMode (): number abstract getSize (): number abstract close (): void @@ -95,7 +96,7 @@ export abstract class PlatformService { abstract loadConfig (): Promise abstract saveConfig (content: string): Promise - abstract startDownload (name: string, size: number): Promise + abstract startDownload (name: string, mode: number, size: number): Promise abstract startUpload (options?: FileUploadOptions): Promise startUploadFromDragEvent (event: DragEvent, multiple = false): FileUpload[] { @@ -188,6 +189,10 @@ export class HTMLFileUpload extends FileUpload { return this.file.name } + getMode (): number { + return 0o644 + } + getSize (): number { return this.file.size } diff --git a/tabby-electron/src/services/platform.service.ts b/tabby-electron/src/services/platform.service.ts index ad076c83..ea78b668 100644 --- a/tabby-electron/src/services/platform.service.ts +++ b/tabby-electron/src/services/platform.service.ts @@ -205,7 +205,7 @@ export class ElectronPlatformService extends PlatformService { })) } - async startDownload (name: string, size: number): Promise { + async startDownload (name: string, mode: number, size: number): Promise { const result = await this.electron.dialog.showSaveDialog( this.hostWindow.getWindow(), { @@ -215,7 +215,7 @@ export class ElectronPlatformService extends PlatformService { if (!result.filePath) { return null } - const transfer = new ElectronFileDownload(result.filePath, size) + const transfer = new ElectronFileDownload(result.filePath, mode, size) await wrapPromise(this.zone, transfer.open()) this.fileTransferStarted.next(transfer) return transfer @@ -230,6 +230,7 @@ export class ElectronPlatformService extends PlatformService { class ElectronFileUpload extends FileUpload { private size: number + private mode: number private file: fs.FileHandle private buffer: Buffer @@ -239,7 +240,9 @@ class ElectronFileUpload extends FileUpload { } async open (): Promise { - this.size = (await fs.stat(this.filePath)).size + const stat = await fs.stat(this.filePath) + this.size = stat.size + this.mode = stat.mode this.file = await fs.open(this.filePath, 'r') } @@ -247,6 +250,10 @@ class ElectronFileUpload extends FileUpload { return path.basename(this.filePath) } + getMode (): number { + return this.mode + } + getSize (): number { return this.size } @@ -267,19 +274,24 @@ class ElectronFileDownload extends FileDownload { constructor ( private filePath: string, + private mode: number, private size: number, ) { super() } async open (): Promise { - this.file = await fs.open(this.filePath, 'w') + this.file = await fs.open(this.filePath, 'w', this.mode) } getName (): string { return path.basename(this.filePath) } + getMode (): number { + return this.mode + } + getSize (): number { return this.size } diff --git a/tabby-ssh/src/components/sftpPanel.component.ts b/tabby-ssh/src/components/sftpPanel.component.ts index a0f3f59a..6207b7b3 100644 --- a/tabby-ssh/src/components/sftpPanel.component.ts +++ b/tabby-ssh/src/components/sftpPanel.component.ts @@ -82,10 +82,10 @@ export class SFTPPanelComponent { if (stat.isDirectory) { await this.navigate(item.fullPath) } else { - await this.download(item.fullPath, stat.size) + await this.download(item.fullPath, stat.mode, stat.size) } } else { - await this.download(item.fullPath, item.size) + await this.download(item.fullPath, item.mode, item.size) } } @@ -117,8 +117,8 @@ export class SFTPPanelComponent { } } - async download (itemPath: string, size: number): Promise { - const transfer = await this.platform.startDownload(path.basename(itemPath), size) + async download (itemPath: string, mode: number, size: number): Promise { + const transfer = await this.platform.startDownload(path.basename(itemPath), mode, size) if (!transfer) { return } diff --git a/tabby-terminal/src/features/debug.ts b/tabby-terminal/src/features/debug.ts index e06b665c..0653db9e 100644 --- a/tabby-terminal/src/features/debug.ts +++ b/tabby-terminal/src/features/debug.ts @@ -71,7 +71,7 @@ export class DebugDecorator extends TerminalDecorator { private async saveFile (content: string, name: string) { const data = Buffer.from(content) - const transfer = await this.platform.startDownload(name, data.length) + const transfer = await this.platform.startDownload(name, 0o644, data.length) if (transfer) { transfer.write(data) transfer.close() diff --git a/tabby-terminal/src/features/zmodem.ts b/tabby-terminal/src/features/zmodem.ts index 445071be..7f82a20b 100644 --- a/tabby-terminal/src/features/zmodem.ts +++ b/tabby-terminal/src/features/zmodem.ts @@ -113,7 +113,7 @@ export class ZModemDecorator extends TerminalDecorator { this.showMessage(terminal, colors.bgYellow.black(' Offered ') + ' ' + details.name, true) this.logger.info('offered', xfer) - const transfer = await this.platform.startDownload(details.name, details.size) + const transfer = await this.platform.startDownload(details.name, 0o644, details.size) if (!transfer) { this.showMessage(terminal, colors.bgRed.black(' Rejected ') + ' ' + details.name) xfer.skip() diff --git a/tabby-web/src/platform.ts b/tabby-web/src/platform.ts index 29ccd938..91aac26f 100644 --- a/tabby-web/src/platform.ts +++ b/tabby-web/src/platform.ts @@ -108,8 +108,8 @@ export class WebPlatformService extends PlatformService { window.close() } - async startDownload (name: string, size: number): Promise { - const transfer = new HTMLFileDownload(name, size) + async startDownload (name: string, mode: number, size: number): Promise { + const transfer = new HTMLFileDownload(name, mode, size) this.fileTransferStarted.next(transfer) return transfer } @@ -145,6 +145,7 @@ class HTMLFileDownload extends FileDownload { constructor ( private name: string, + private mode: number, private size: number, ) { super() @@ -154,6 +155,10 @@ class HTMLFileDownload extends FileDownload { return this.name } + getMode (): number { + return this.mode + } + getSize (): number { return this.size } -- GitLab