1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-18 09:13:33 +00:00

Attachment azure upload blobs (#312)

* Add direct attachment download and upload API endpoints

* Use direct download method

Enable download of emergency access attachments through EmergencyAccessId

* Match new Server model items

* New Server model for creating attachments.

Provides a url to upload data to, the type of upload, and the Cipher Response expected by the previous call

* Use direct upload url and scheme

* Report Failed single shot azure uploads

* Add cipher attachment upload to file upload service

* Deprecate legacy api methods

* Handle old servers missing new upload api methods

* Improve Send error handling

* Fallback attachment downloads on new endpoint not found

Limit upload size to the new 500MB

* Improve error handling

* lint fixes
This commit is contained in:
Matt Gibson
2021-03-26 16:57:07 -05:00
committed by GitHub
parent 0735569479
commit afac694e9a
11 changed files with 189 additions and 29 deletions

View File

@@ -6,6 +6,7 @@ import {
Output,
} from '@angular/core';
import { ApiService } from '../../abstractions/api.service';
import { CipherService } from '../../abstractions/cipher.service';
import { CryptoService } from '../../abstractions/crypto.service';
import { I18nService } from '../../abstractions/i18n.service';
@@ -13,6 +14,7 @@ import { PlatformUtilsService } from '../../abstractions/platformUtils.service';
import { UserService } from '../../abstractions/user.service';
import { Cipher } from '../../models/domain/cipher';
import { ErrorResponse } from '../../models/response';
import { AttachmentView } from '../../models/view/attachmentView';
import { CipherView } from '../../models/view/cipherView';
@@ -31,10 +33,12 @@ export class AttachmentsComponent implements OnInit {
formPromise: Promise<any>;
deletePromises: { [id: string]: Promise<any>; } = {};
reuploadPromises: { [id: string]: Promise<any>; } = {};
emergencyAccessId?: string = null;
constructor(protected cipherService: CipherService, protected i18nService: I18nService,
protected cryptoService: CryptoService, protected userService: UserService,
protected platformUtilsService: PlatformUtilsService, protected win: Window) { }
protected platformUtilsService: PlatformUtilsService, protected apiService: ApiService,
protected win: Window) { }
async ngOnInit() {
await this.init();
@@ -55,7 +59,7 @@ export class AttachmentsComponent implements OnInit {
return;
}
if (files[0].size > 104857600) { // 100 MB
if (files[0].size > 524288000) { // 500 MB
this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),
this.i18nService.t('maxFileSize'));
return;
@@ -116,8 +120,23 @@ export class AttachmentsComponent implements OnInit {
return;
}
let url: string;
try {
const attachmentDownloadResponse = await this.apiService.getAttachmentData(this.cipher.id, attachment.id,
this.emergencyAccessId);
url = attachmentDownloadResponse.url;
} catch (e) {
if (e instanceof ErrorResponse && (e as ErrorResponse).statusCode === 404) {
url = attachment.url;
} else if (e instanceof ErrorResponse) {
throw new Error((e as ErrorResponse).getSingleMessage());
} else {
throw e;
}
}
a.downloading = true;
const response = await fetch(new Request(attachment.url, { cache: 'no-store' }));
const response = await fetch(new Request(url, { cache: 'no-store' }));
if (response.status !== 200) {
this.platformUtilsService.showToast('error', null, this.i18nService.t('errorOccurred'));
a.downloading = false;