From fcd0c529cac2d743abcef05d177a15e37466d8c9 Mon Sep 17 00:00:00 2001 From: Matt Gibson Date: Tue, 2 Mar 2021 10:05:20 -0600 Subject: [PATCH] Direct download for send (#243) * Remove Get file capability This needs to be removed because the SendFileResponse no longer contains a url to download the file from. Instead, a GetDownloadLink method must be used. That method increments access count, which is not desirable for the owner of the Send. The cleanest approach is to remove the capability, which also matches Web client's behavior * jslib updates * Use GetDownloadData method to receive download Url * Update jslib --- jslib | 2 +- src/bw.ts | 4 ++-- src/commands/send/get.command.ts | 7 +------ src/commands/send/receive.command.ts | 18 ++++++++++-------- src/models/response/sendFileResponse.ts | 3 --- src/program.ts | 2 +- src/send.program.ts | 1 - 7 files changed, 15 insertions(+), 22 deletions(-) diff --git a/jslib b/jslib index 09c444ddd4..3942868cf4 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit 09c444ddd4498b5417769e8a795671a6a8ef6ade +Subproject commit 3942868cf488ed8c1983ffadab2c8900b8c78410 diff --git a/src/bw.ts b/src/bw.ts index b0b8f483f0..2bc22b3f5f 100644 --- a/src/bw.ts +++ b/src/bw.ts @@ -143,7 +143,7 @@ export class Main { this.policyService); this.totpService = new TotpService(this.storageService, this.cryptoFunctionService); this.importService = new ImportService(this.cipherService, this.folderService, this.apiService, - this.i18nService, this.collectionService); + this.i18nService, this.collectionService, this.platformUtilsService); this.exportService = new ExportService(this.folderService, this.cipherService, this.apiService); this.authService = new AuthService(this.cryptoService, this.apiService, this.userService, this.tokenService, this.appIdService, this.i18nService, this.platformUtilsService, this.messagingService, @@ -188,7 +188,7 @@ export class Main { } private async init() { - this.storageService.init(); + await this.storageService.init(); this.containerService.attachToWindow(global); await this.environmentService.setUrlsFromStorage(); // Dev Server URLs. Comment out the line above. diff --git a/src/commands/send/get.command.ts b/src/commands/send/get.command.ts index bad4409e1c..2a5e8bce70 100644 --- a/src/commands/send/get.command.ts +++ b/src/commands/send/get.command.ts @@ -1,5 +1,6 @@ import * as program from 'commander'; +import { ApiService } from 'jslib/abstractions/api.service'; import { CryptoService } from 'jslib/abstractions/crypto.service'; import { EnvironmentService } from 'jslib/abstractions/environment.service'; import { SearchService } from 'jslib/abstractions/search.service'; @@ -40,12 +41,6 @@ export class SendGetCommand extends DownloadCommand { return Response.success(); }; } - if (options.file != null) { - filter = s => { - return filter(s) && s.file != null && s.file.url != null; - }; - selector = async s => await this.saveAttachmentToFile(s.file.url, s.cryptoKey, s.file.fileName, options.output); - } if (Array.isArray(sends)) { if (filter != null) { diff --git a/src/commands/send/receive.command.ts b/src/commands/send/receive.command.ts index a85de76826..819edee5e3 100644 --- a/src/commands/send/receive.command.ts +++ b/src/commands/send/receive.command.ts @@ -28,6 +28,7 @@ import { DownloadCommand } from '../download.command'; export class SendReceiveCommand extends DownloadCommand { private canInteract: boolean; private decKey: SymmetricCryptoKey; + private sendAccessRequest: SendAccessRequest; constructor(private apiService: ApiService, cryptoService: CryptoService, private cryptoFunctionService: CryptoFunctionService, private platformUtilsService: PlatformUtilsService, @@ -53,7 +54,7 @@ export class SendReceiveCommand extends DownloadCommand { } const keyArray = Utils.fromUrlB64ToArray(key); - const request = new SendAccessRequest(); + this.sendAccessRequest = new SendAccessRequest(); let password = options.password; if (password == null || password === '') { @@ -65,10 +66,10 @@ export class SendReceiveCommand extends DownloadCommand { } if (password != null && password !== '') { - request.password = await this.getUnlockedPassword(password, keyArray); + this.sendAccessRequest.password = await this.getUnlockedPassword(password, keyArray); } - const response = await this.sendRequest(request, apiUrl, id, keyArray); + const response = await this.sendRequest(apiUrl, id, keyArray); if (response instanceof Response) { // Error scenario @@ -85,7 +86,8 @@ export class SendReceiveCommand extends DownloadCommand { process.stdout.write(response?.text?.text); return Response.success(); case SendType.File: - return await this.saveAttachmentToFile(response?.file?.url, this.decKey, response?.file?.fileName, options.output); + const downloadData = await this.apiService.getSendFileDownloadData(response, this.sendAccessRequest); + return await this.saveAttachmentToFile(downloadData.url, this.decKey, response?.file?.fileName, options.output); default: return Response.success(new SendAccessResponse(response)); } @@ -111,9 +113,9 @@ export class SendReceiveCommand extends DownloadCommand { return Utils.fromBufferToB64(passwordHash); } - private async sendRequest(request: SendAccessRequest, url: string, id: string, key: ArrayBuffer): Promise { + private async sendRequest(url: string, id: string, key: ArrayBuffer): Promise { try { - const sendResponse = await this.apiService.postSendAccess(id, request, url); + const sendResponse = await this.apiService.postSendAccess(id, this.sendAccessRequest, url); const sendAccess = new SendAccess(sendResponse); this.decKey = await this.cryptoService.makeSendKey(key); @@ -129,8 +131,8 @@ export class SendReceiveCommand extends DownloadCommand { }); // reattempt with new password - request.password = await this.getUnlockedPassword(answer.password, key); - return await this.sendRequest(request, url, id, key); + this.sendAccessRequest.password = await this.getUnlockedPassword(answer.password, key); + return await this.sendRequest(url, id, key); } return Response.badRequest('Incorrect or missing password'); diff --git a/src/models/response/sendFileResponse.ts b/src/models/response/sendFileResponse.ts index 2a4880c41f..94773bdfae 100644 --- a/src/models/response/sendFileResponse.ts +++ b/src/models/response/sendFileResponse.ts @@ -13,7 +13,6 @@ export class SendFileResponse { } view.id = file.id; - view.url = file.url; view.size = file.size; view.sizeName = file.sizeName; view.fileName = file.fileName; @@ -21,7 +20,6 @@ export class SendFileResponse { } id: string; - url: string; size: string; sizeName: string; fileName: string; @@ -31,7 +29,6 @@ export class SendFileResponse { return; } this.id = o.id; - this.url = o.url; this.size = o.size; this.sizeName = o.sizeName; this.fileName = o.fileName; diff --git a/src/program.ts b/src/program.ts index f5d04ef39f..26481c2c82 100644 --- a/src/program.ts +++ b/src/program.ts @@ -153,7 +153,7 @@ export class Program extends BaseProgram { await this.exitIfNotAuthed(); const command = new LogoutCommand(this.main.authService, this.main.i18nService, async () => await this.main.logout()); - const response = await command.run(cmd); + const response = await command.run(); this.processResponse(response); }); diff --git a/src/send.program.ts b/src/send.program.ts index 15ec34d33d..8aad04dd1b 100644 --- a/src/send.program.ts +++ b/src/send.program.ts @@ -132,7 +132,6 @@ export class SendProgram extends Program { .description('Get Sends owned by you.') .option('--output ', 'Output directory or filename for attachment.') .option('--text', 'Specifies to return the text content of a Send') - .option('--file', 'Specifies to return the file content of a Send. This can be paired with --output or --raw to output to stdout') .on('--help', () => { writeLn(''); writeLn(' Id:');