1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-06 00:13:28 +00:00

PM-26201 [Defect] [Safari] Cannot unzip vault export (#16909)

• ensure extension method can accept both `blob` type and `arrayBuffer` type 
• replace usage of Swift's `url.absoluteString` with `url.path`
• explicitly discard promise returned by `downloadSafari()`
• confine `data` type to `string` since code all code paths assign a `string` value
This commit is contained in:
John Harrington
2025-10-28 09:02:38 -07:00
committed by GitHub
parent 2058c772ac
commit 8d54ad7883
2 changed files with 32 additions and 19 deletions

View File

@@ -15,23 +15,9 @@ 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 {
data = Utils.fromBufferToB64(request.blobData as ArrayBuffer);
}
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
SafariApp.sendMessageToApp(
"downloadFile",
JSON.stringify({
blobData: data,
blobOptions: request.blobOptions,
fileName: request.fileName,
}),
true,
);
// Handle Safari download asynchronously to allow Blob conversion
// This function can't be async because the interface is not async
void this.downloadSafari(request, builder);
} else {
const a = window.document.createElement("a");
a.href = URL.createObjectURL(builder.blob);
@@ -41,4 +27,31 @@ export class BrowserFileDownloadService implements FileDownloadService {
window.document.body.removeChild(a);
}
}
private async downloadSafari(
request: FileDownloadRequest,
builder: FileDownloadBuilder,
): Promise<void> {
let data: string = null;
if (builder.blobOptions.type === "text/plain" && typeof request.blobData === "string") {
data = request.blobData;
} else if (request.blobData instanceof Blob) {
// Convert Blob to ArrayBuffer first, then to Base64
const arrayBuffer = await request.blobData.arrayBuffer();
data = Utils.fromBufferToB64(arrayBuffer);
} else {
// Already an ArrayBuffer
data = Utils.fromBufferToB64(request.blobData as ArrayBuffer);
}
await SafariApp.sendMessageToApp(
"downloadFile",
JSON.stringify({
blobData: data,
blobOptions: request.blobOptions,
fileName: request.fileName,
}),
true,
);
}
}

View File

@@ -69,8 +69,8 @@ class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling {
if let url = panel.url {
do {
let fileManager = FileManager.default
if !fileManager.fileExists(atPath: url.absoluteString) {
fileManager.createFile(atPath: url.absoluteString, contents: Data(),
if !fileManager.fileExists(atPath: url.path) {
fileManager.createFile(atPath: url.path, contents: Data(),
attributes: nil)
}
try data.write(to: url)