mirror of
https://github.com/bitwarden/browser
synced 2025-12-25 20:53:22 +00:00
[fix] Force send attachment to always download and never open (#2908)
* [refactor] Introduce a file download service * [refactor] Point platformUtilsService.saveFile() callers to fileDownloadService.download() instead * [refactor] Remove platformUtilsService.saveFile() * [fix] Force send attachments to always download and never open * [fix] Remove the window property from FileDownloadRequest * [fix] Move FileDownloadRequest to /abstractions/fileDownload * [fix] Simplify FileDownloadRequest to a type * [fix] Move BrowserApi.saveFile logic into BrowserFileDownloadService * [fix] Use proper blob types for file downloads * [fix] forceDownload -> downloadMethod on FileDownloadRequest * [fix] Remove fileType from FileDownloadRequest * [fix] Make fileType private
This commit is contained in:
@@ -1,7 +1,3 @@
|
||||
import { Utils } from "@bitwarden/common/misc/utils";
|
||||
|
||||
import { SafariApp } from "./safariApp";
|
||||
|
||||
export class BrowserApi {
|
||||
static isWebExtensionsApi: boolean = typeof browser !== "undefined";
|
||||
static isSafariApi: boolean =
|
||||
@@ -150,39 +146,6 @@ export class BrowserApi {
|
||||
}
|
||||
}
|
||||
|
||||
static downloadFile(win: Window, blobData: any, blobOptions: any, fileName: string) {
|
||||
if (BrowserApi.isSafariApi) {
|
||||
const type = blobOptions != null ? blobOptions.type : null;
|
||||
let data: string = null;
|
||||
if (type === "text/plain" && typeof blobData === "string") {
|
||||
data = blobData;
|
||||
} else {
|
||||
data = Utils.fromBufferToB64(blobData);
|
||||
}
|
||||
SafariApp.sendMessageToApp(
|
||||
"downloadFile",
|
||||
JSON.stringify({
|
||||
blobData: data,
|
||||
blobOptions: blobOptions,
|
||||
fileName: fileName,
|
||||
}),
|
||||
true
|
||||
);
|
||||
} else {
|
||||
const blob = new Blob([blobData], blobOptions);
|
||||
if (navigator.msSaveOrOpenBlob) {
|
||||
navigator.msSaveBlob(blob, fileName);
|
||||
} else {
|
||||
const a = win.document.createElement("a");
|
||||
a.href = URL.createObjectURL(blob);
|
||||
a.download = fileName;
|
||||
win.document.body.appendChild(a);
|
||||
a.click();
|
||||
win.document.body.removeChild(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gaFilter() {
|
||||
return process.env.ENV !== "production";
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import { CryptoFunctionService } from "@bitwarden/common/abstractions/cryptoFunc
|
||||
import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service";
|
||||
import { EventService } from "@bitwarden/common/abstractions/event.service";
|
||||
import { ExportService } from "@bitwarden/common/abstractions/export.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/abstractions/fileDownload/fileDownload.service";
|
||||
import { FileUploadService } from "@bitwarden/common/abstractions/fileUpload.service";
|
||||
import { FolderService } from "@bitwarden/common/abstractions/folder.service";
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||
@@ -51,6 +52,7 @@ import MainBackground from "../../background/main.background";
|
||||
import { BrowserApi } from "../../browser/browserApi";
|
||||
import { AutofillService } from "../../services/abstractions/autofill.service";
|
||||
import { StateService as StateServiceAbstraction } from "../../services/abstractions/state.service";
|
||||
import { BrowserFileDownloadService } from "../../services/browserFileDownloadService";
|
||||
import BrowserMessagingService from "../../services/browserMessaging.service";
|
||||
import BrowserMessagingPrivateModePopupService from "../../services/browserMessagingPrivateModePopup.service";
|
||||
import { VaultFilterService } from "../../services/vaultFilter.service";
|
||||
@@ -272,6 +274,10 @@ function getBgService<T>(service: keyof MainBackground) {
|
||||
useExisting: StateServiceAbstraction,
|
||||
deps: [],
|
||||
},
|
||||
{
|
||||
provide: FileDownloadService,
|
||||
useClass: BrowserFileDownloadService,
|
||||
},
|
||||
],
|
||||
})
|
||||
export class ServicesModule {}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { ExportComponent as BaseExportComponent } from "@bitwarden/angular/compo
|
||||
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
|
||||
import { EventService } from "@bitwarden/common/abstractions/event.service";
|
||||
import { ExportService } from "@bitwarden/common/abstractions/export.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/abstractions/fileDownload/fileDownload.service";
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
@@ -27,7 +28,8 @@ export class ExportComponent extends BaseExportComponent {
|
||||
private router: Router,
|
||||
logService: LogService,
|
||||
userVerificationService: UserVerificationService,
|
||||
formBuilder: FormBuilder
|
||||
formBuilder: FormBuilder,
|
||||
fileDownloadService: FileDownloadService
|
||||
) {
|
||||
super(
|
||||
cryptoService,
|
||||
@@ -39,7 +41,8 @@ export class ExportComponent extends BaseExportComponent {
|
||||
window,
|
||||
logService,
|
||||
userVerificationService,
|
||||
formBuilder
|
||||
formBuilder,
|
||||
fileDownloadService
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import { AttachmentsComponent as BaseAttachmentsComponent } from "@bitwarden/ang
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { CipherService } from "@bitwarden/common/abstractions/cipher.service";
|
||||
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/abstractions/fileDownload/fileDownload.service";
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
@@ -28,7 +29,8 @@ export class AttachmentsComponent extends BaseAttachmentsComponent {
|
||||
private location: Location,
|
||||
private route: ActivatedRoute,
|
||||
stateService: StateService,
|
||||
logService: LogService
|
||||
logService: LogService,
|
||||
fileDownloadService: FileDownloadService
|
||||
) {
|
||||
super(
|
||||
cipherService,
|
||||
@@ -38,7 +40,8 @@ export class AttachmentsComponent extends BaseAttachmentsComponent {
|
||||
apiService,
|
||||
window,
|
||||
logService,
|
||||
stateService
|
||||
stateService,
|
||||
fileDownloadService
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.s
|
||||
import { CipherService } from "@bitwarden/common/abstractions/cipher.service";
|
||||
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
|
||||
import { EventService } from "@bitwarden/common/abstractions/event.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/abstractions/fileDownload/fileDownload.service";
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
||||
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
|
||||
@@ -61,7 +62,8 @@ export class ViewComponent extends BaseViewComponent {
|
||||
private popupUtilsService: PopupUtilsService,
|
||||
apiService: ApiService,
|
||||
passwordRepromptService: PasswordRepromptService,
|
||||
logService: LogService
|
||||
logService: LogService,
|
||||
fileDownloadService: FileDownloadService
|
||||
) {
|
||||
super(
|
||||
cipherService,
|
||||
@@ -79,7 +81,8 @@ export class ViewComponent extends BaseViewComponent {
|
||||
apiService,
|
||||
passwordRepromptService,
|
||||
logService,
|
||||
stateService
|
||||
stateService,
|
||||
fileDownloadService
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
46
apps/browser/src/services/browserFileDownloadService.ts
Normal file
46
apps/browser/src/services/browserFileDownloadService.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { FileDownloadService } from "@bitwarden/common/abstractions/fileDownload/fileDownload.service";
|
||||
import { FileDownloadBuilder } from "@bitwarden/common/abstractions/fileDownload/fileDownloadBuilder";
|
||||
import { FileDownloadRequest } from "@bitwarden/common/abstractions/fileDownload/fileDownloadRequest";
|
||||
import { Utils } from "@bitwarden/common/misc/utils";
|
||||
|
||||
import { BrowserApi } from "../browser/browserApi";
|
||||
import { SafariApp } from "../browser/safariApp";
|
||||
|
||||
@Injectable()
|
||||
export class BrowserFileDownloadService implements FileDownloadService {
|
||||
download(request: FileDownloadRequest): void {
|
||||
const builder = new FileDownloadBuilder(request);
|
||||
if (BrowserApi.isSafariApi) {
|
||||
let data: BlobPart = null;
|
||||
if (builder.blobOptions.type === "text/plain" && typeof request.blobData === "string") {
|
||||
data = request.blobData;
|
||||
} else {
|
||||
builder.blob.arrayBuffer().then((buf) => {
|
||||
data = Utils.fromBufferToB64(buf);
|
||||
});
|
||||
}
|
||||
SafariApp.sendMessageToApp(
|
||||
"downloadFile",
|
||||
JSON.stringify({
|
||||
blobData: data,
|
||||
blobOptions: request.blobOptions,
|
||||
fileName: request.fileName,
|
||||
}),
|
||||
true
|
||||
);
|
||||
} else {
|
||||
if (navigator.msSaveOrOpenBlob) {
|
||||
navigator.msSaveBlob(builder.blob, request.fileName);
|
||||
} else {
|
||||
const a = window.document.createElement("a");
|
||||
a.href = URL.createObjectURL(builder.blob);
|
||||
a.download = request.fileName;
|
||||
window.document.body.appendChild(a);
|
||||
a.click();
|
||||
window.document.body.removeChild(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,10 +122,6 @@ export default class BrowserPlatformUtilsService implements PlatformUtilsService
|
||||
BrowserApi.createNewTab(uri, options && options.extensionPage === true);
|
||||
}
|
||||
|
||||
saveFile(win: Window, blobData: any, blobOptions: any, fileName: string): void {
|
||||
BrowserApi.downloadFile(win, blobData, blobOptions, fileName);
|
||||
}
|
||||
|
||||
getApplicationVersion(): Promise<string> {
|
||||
return Promise.resolve(BrowserApi.getApplicationVersion());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user