1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-09-18 02:41:15 +02:00

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
This commit is contained in:
Matt Gibson 2021-03-02 10:05:20 -06:00 committed by GitHub
parent e77e1c94e8
commit fcd0c529ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 15 additions and 22 deletions

2
jslib

@ -1 +1 @@
Subproject commit 09c444ddd4498b5417769e8a795671a6a8ef6ade Subproject commit 3942868cf488ed8c1983ffadab2c8900b8c78410

View File

@ -143,7 +143,7 @@ export class Main {
this.policyService); this.policyService);
this.totpService = new TotpService(this.storageService, this.cryptoFunctionService); this.totpService = new TotpService(this.storageService, this.cryptoFunctionService);
this.importService = new ImportService(this.cipherService, this.folderService, this.apiService, 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.exportService = new ExportService(this.folderService, this.cipherService, this.apiService);
this.authService = new AuthService(this.cryptoService, this.apiService, this.userService, this.tokenService, this.authService = new AuthService(this.cryptoService, this.apiService, this.userService, this.tokenService,
this.appIdService, this.i18nService, this.platformUtilsService, this.messagingService, this.appIdService, this.i18nService, this.platformUtilsService, this.messagingService,
@ -188,7 +188,7 @@ export class Main {
} }
private async init() { private async init() {
this.storageService.init(); await this.storageService.init();
this.containerService.attachToWindow(global); this.containerService.attachToWindow(global);
await this.environmentService.setUrlsFromStorage(); await this.environmentService.setUrlsFromStorage();
// Dev Server URLs. Comment out the line above. // Dev Server URLs. Comment out the line above.

View File

@ -1,5 +1,6 @@
import * as program from 'commander'; import * as program from 'commander';
import { ApiService } from 'jslib/abstractions/api.service';
import { CryptoService } from 'jslib/abstractions/crypto.service'; import { CryptoService } from 'jslib/abstractions/crypto.service';
import { EnvironmentService } from 'jslib/abstractions/environment.service'; import { EnvironmentService } from 'jslib/abstractions/environment.service';
import { SearchService } from 'jslib/abstractions/search.service'; import { SearchService } from 'jslib/abstractions/search.service';
@ -40,12 +41,6 @@ export class SendGetCommand extends DownloadCommand {
return Response.success(); 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 (Array.isArray(sends)) {
if (filter != null) { if (filter != null) {

View File

@ -28,6 +28,7 @@ import { DownloadCommand } from '../download.command';
export class SendReceiveCommand extends DownloadCommand { export class SendReceiveCommand extends DownloadCommand {
private canInteract: boolean; private canInteract: boolean;
private decKey: SymmetricCryptoKey; private decKey: SymmetricCryptoKey;
private sendAccessRequest: SendAccessRequest;
constructor(private apiService: ApiService, cryptoService: CryptoService, constructor(private apiService: ApiService, cryptoService: CryptoService,
private cryptoFunctionService: CryptoFunctionService, private platformUtilsService: PlatformUtilsService, private cryptoFunctionService: CryptoFunctionService, private platformUtilsService: PlatformUtilsService,
@ -53,7 +54,7 @@ export class SendReceiveCommand extends DownloadCommand {
} }
const keyArray = Utils.fromUrlB64ToArray(key); const keyArray = Utils.fromUrlB64ToArray(key);
const request = new SendAccessRequest(); this.sendAccessRequest = new SendAccessRequest();
let password = options.password; let password = options.password;
if (password == null || password === '') { if (password == null || password === '') {
@ -65,10 +66,10 @@ export class SendReceiveCommand extends DownloadCommand {
} }
if (password != null && password !== '') { 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) { if (response instanceof Response) {
// Error scenario // Error scenario
@ -85,7 +86,8 @@ export class SendReceiveCommand extends DownloadCommand {
process.stdout.write(response?.text?.text); process.stdout.write(response?.text?.text);
return Response.success(); return Response.success();
case SendType.File: 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: default:
return Response.success(new SendAccessResponse(response)); return Response.success(new SendAccessResponse(response));
} }
@ -111,9 +113,9 @@ export class SendReceiveCommand extends DownloadCommand {
return Utils.fromBufferToB64(passwordHash); return Utils.fromBufferToB64(passwordHash);
} }
private async sendRequest(request: SendAccessRequest, url: string, id: string, key: ArrayBuffer): Promise<Response | SendAccessView> { private async sendRequest(url: string, id: string, key: ArrayBuffer): Promise<Response | SendAccessView> {
try { 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); const sendAccess = new SendAccess(sendResponse);
this.decKey = await this.cryptoService.makeSendKey(key); this.decKey = await this.cryptoService.makeSendKey(key);
@ -129,8 +131,8 @@ export class SendReceiveCommand extends DownloadCommand {
}); });
// reattempt with new password // reattempt with new password
request.password = await this.getUnlockedPassword(answer.password, key); this.sendAccessRequest.password = await this.getUnlockedPassword(answer.password, key);
return await this.sendRequest(request, url, id, key); return await this.sendRequest(url, id, key);
} }
return Response.badRequest('Incorrect or missing password'); return Response.badRequest('Incorrect or missing password');

View File

@ -13,7 +13,6 @@ export class SendFileResponse {
} }
view.id = file.id; view.id = file.id;
view.url = file.url;
view.size = file.size; view.size = file.size;
view.sizeName = file.sizeName; view.sizeName = file.sizeName;
view.fileName = file.fileName; view.fileName = file.fileName;
@ -21,7 +20,6 @@ export class SendFileResponse {
} }
id: string; id: string;
url: string;
size: string; size: string;
sizeName: string; sizeName: string;
fileName: string; fileName: string;
@ -31,7 +29,6 @@ export class SendFileResponse {
return; return;
} }
this.id = o.id; this.id = o.id;
this.url = o.url;
this.size = o.size; this.size = o.size;
this.sizeName = o.sizeName; this.sizeName = o.sizeName;
this.fileName = o.fileName; this.fileName = o.fileName;

View File

@ -153,7 +153,7 @@ export class Program extends BaseProgram {
await this.exitIfNotAuthed(); await this.exitIfNotAuthed();
const command = new LogoutCommand(this.main.authService, this.main.i18nService, const command = new LogoutCommand(this.main.authService, this.main.i18nService,
async () => await this.main.logout()); async () => await this.main.logout());
const response = await command.run(cmd); const response = await command.run();
this.processResponse(response); this.processResponse(response);
}); });

View File

@ -132,7 +132,6 @@ export class SendProgram extends Program {
.description('Get Sends owned by you.') .description('Get Sends owned by you.')
.option('--output <output>', 'Output directory or filename for attachment.') .option('--output <output>', 'Output directory or filename for attachment.')
.option('--text', 'Specifies to return the text content of a Send') .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', () => { .on('--help', () => {
writeLn(''); writeLn('');
writeLn(' Id:'); writeLn(' Id:');