mirror of
https://github.com/bitwarden/browser
synced 2025-12-17 08:43:33 +00:00
raw attachment saves with node form data
This commit is contained in:
@@ -25,7 +25,8 @@ export abstract class CipherService {
|
||||
updateLastUsedDate: (id: string) => Promise<void>;
|
||||
saveNeverDomain: (domain: string) => Promise<void>;
|
||||
saveWithServer: (cipher: Cipher) => Promise<any>;
|
||||
saveAttachmentWithServer: (cipher: Cipher, unencryptedFile: any) => Promise<any>;
|
||||
saveAttachmentWithServer: (cipher: Cipher, unencryptedFile: any) => Promise<Cipher>;
|
||||
saveAttachmentRawWithServer: (cipher: Cipher, filename: string, data: ArrayBuffer) => Promise<Cipher>;
|
||||
upsert: (cipher: CipherData | CipherData[]) => Promise<any>;
|
||||
replace: (ciphers: { [id: string]: CipherData; }) => Promise<any>;
|
||||
clear: (userId: string) => Promise<any>;
|
||||
|
||||
@@ -322,43 +322,58 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
await this.upsert(data);
|
||||
}
|
||||
|
||||
saveAttachmentWithServer(cipher: Cipher, unencryptedFile: any): Promise<any> {
|
||||
const self = this;
|
||||
|
||||
saveAttachmentWithServer(cipher: Cipher, unencryptedFile: any): Promise<Cipher> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.readAsArrayBuffer(unencryptedFile);
|
||||
|
||||
reader.onload = async (evt: any) => {
|
||||
const key = await self.cryptoService.getOrgKey(cipher.organizationId);
|
||||
const encFileName = await self.cryptoService.encrypt(unencryptedFile.name, key);
|
||||
const encData = await self.cryptoService.encryptToBytes(evt.target.result, key);
|
||||
|
||||
const fd = new FormData();
|
||||
const blob = new Blob([encData], { type: 'application/octet-stream' });
|
||||
fd.append('data', blob, encFileName.encryptedString);
|
||||
|
||||
let response: CipherResponse;
|
||||
try {
|
||||
response = await self.apiService.postCipherAttachment(cipher.id, fd);
|
||||
const cData = await this.saveAttachmentRawWithServer(cipher,
|
||||
unencryptedFile.name, evt.target.result);
|
||||
resolve(cData);
|
||||
} catch (e) {
|
||||
reject((e as ErrorResponse).getSingleMessage());
|
||||
return;
|
||||
reject(e);
|
||||
}
|
||||
|
||||
const userId = await self.userService.getUserId();
|
||||
const data = new CipherData(response, userId, cipher.collectionIds);
|
||||
this.upsert(data);
|
||||
resolve(new Cipher(data));
|
||||
|
||||
};
|
||||
|
||||
reader.onerror = (evt) => {
|
||||
reject('Error reading file.');
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async saveAttachmentRawWithServer(cipher: Cipher, filename: string, data: ArrayBuffer): Promise<Cipher> {
|
||||
const key = await this.cryptoService.getOrgKey(cipher.organizationId);
|
||||
const encFileName = await this.cryptoService.encrypt(filename, key);
|
||||
const encData = await this.cryptoService.encryptToBytes(data, key);
|
||||
|
||||
const fd = new FormData();
|
||||
try {
|
||||
const blob = new Blob([encData], { type: 'application/octet-stream' });
|
||||
fd.append('data', blob, encFileName.encryptedString);
|
||||
} catch (e) {
|
||||
if (Utils.isNode) {
|
||||
fd.append('data', new Buffer(encData) as any, {
|
||||
filename: encFileName.encryptedString,
|
||||
contentType: 'application/octet-stream',
|
||||
} as any);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
let response: CipherResponse;
|
||||
try {
|
||||
response = await this.apiService.postCipherAttachment(cipher.id, fd);
|
||||
} catch (e) {
|
||||
throw new Error((e as ErrorResponse).getSingleMessage());
|
||||
}
|
||||
|
||||
const userId = await this.userService.getUserId();
|
||||
const cData = new CipherData(response, userId, cipher.collectionIds);
|
||||
this.upsert(cData);
|
||||
return new Cipher(cData);
|
||||
}
|
||||
|
||||
async upsert(cipher: CipherData | CipherData[]): Promise<any> {
|
||||
const userId = await this.userService.getUserId();
|
||||
let ciphers = await this.storageService.get<{ [id: string]: CipherData; }>(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import * as FormData from 'form-data';
|
||||
import * as fe from 'node-fetch';
|
||||
|
||||
import { ApiService } from './api.service';
|
||||
@@ -9,6 +10,7 @@ import { TokenService } from '../abstractions/token.service';
|
||||
(global as any).Request = fe.Request;
|
||||
(global as any).Response = fe.Response;
|
||||
(global as any).Headers = fe.Headers;
|
||||
(global as any).FormData = FormData;
|
||||
|
||||
export class NodeApiService extends ApiService {
|
||||
constructor(tokenService: TokenService, platformUtilsService: PlatformUtilsService,
|
||||
|
||||
Reference in New Issue
Block a user