1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-11-27 12:36:14 +01:00

move attachment sharing logic to service

This commit is contained in:
Kyle Spearrin 2018-10-23 22:10:08 -04:00
parent 43c0cbce45
commit 4165a78277
3 changed files with 49 additions and 54 deletions

View File

@ -28,8 +28,6 @@ export abstract class CipherService {
saveWithServer: (cipher: Cipher) => Promise<any>; saveWithServer: (cipher: Cipher) => Promise<any>;
shareWithServer: (cipher: CipherView, organizationId: string, collectionIds: string[]) => Promise<any>; shareWithServer: (cipher: CipherView, organizationId: string, collectionIds: string[]) => Promise<any>;
shareManyWithServer: (ciphers: CipherView[], organizationId: string, collectionIds: string[]) => Promise<any>; shareManyWithServer: (ciphers: CipherView[], organizationId: string, collectionIds: string[]) => Promise<any>;
shareAttachmentWithServer: (attachmentView: AttachmentView, cipherId: string,
organizationId: string) => Promise<any>;
saveAttachmentWithServer: (cipher: Cipher, unencryptedFile: any, admin?: boolean) => Promise<Cipher>; saveAttachmentWithServer: (cipher: Cipher, unencryptedFile: any, admin?: boolean) => Promise<Cipher>;
saveAttachmentRawWithServer: (cipher: Cipher, filename: string, data: ArrayBuffer, saveAttachmentRawWithServer: (cipher: Cipher, filename: string, data: ArrayBuffer,
admin?: boolean) => Promise<Cipher>; admin?: boolean) => Promise<Cipher>;

View File

@ -65,19 +65,10 @@ export class ShareComponent implements OnInit {
const cipherDomain = await this.cipherService.get(this.cipherId); const cipherDomain = await this.cipherService.get(this.cipherId);
const cipherView = await cipherDomain.decrypt(); const cipherView = await cipherDomain.decrypt();
const attachmentPromises: Array<Promise<any>> = [];
if (cipherView.attachments != null) {
for (const attachment of cipherView.attachments) {
const promise = this.cipherService.shareAttachmentWithServer(attachment, cipherView.id,
this.organizationId);
attachmentPromises.push(promise);
}
}
const checkedCollectionIds = this.collections.filter((c) => (c as any).checked).map((c) => c.id); const checkedCollectionIds = this.collections.filter((c) => (c as any).checked).map((c) => c.id);
try { try {
this.formPromise = Promise.all(attachmentPromises).then(async () => { this.formPromise = this.cipherService.shareWithServer(cipherView, this.organizationId,
await this.cipherService.shareWithServer(cipherView, this.organizationId, checkedCollectionIds); checkedCollectionIds).then(async () => {
this.onSharedCipher.emit(); this.onSharedCipher.emit();
this.platformUtilsService.eventTrack('Shared Cipher'); this.platformUtilsService.eventTrack('Shared Cipher');
this.platformUtilsService.showToast('success', null, this.i18nService.t('sharedItem')); this.platformUtilsService.showToast('success', null, this.i18nService.t('sharedItem'));

View File

@ -461,6 +461,14 @@ export class CipherService implements CipherServiceAbstraction {
} }
async shareWithServer(cipher: CipherView, organizationId: string, collectionIds: string[]): Promise<any> { async shareWithServer(cipher: CipherView, organizationId: string, collectionIds: string[]): Promise<any> {
const attachmentPromises: Array<Promise<any>> = [];
if (cipher.attachments != null) {
cipher.attachments.forEach((attachment) => {
attachmentPromises.push(this.shareAttachmentWithServer(attachment, cipher.id, organizationId));
});
}
await Promise.all(attachmentPromises);
cipher.organizationId = organizationId; cipher.organizationId = organizationId;
cipher.collectionIds = collectionIds; cipher.collectionIds = collectionIds;
const encCipher = await this.encrypt(cipher); const encCipher = await this.encrypt(cipher);
@ -488,43 +496,6 @@ export class CipherService implements CipherServiceAbstraction {
await this.upsert(encCiphers.map((c) => c.toCipherData(userId))); await this.upsert(encCiphers.map((c) => c.toCipherData(userId)));
} }
async shareAttachmentWithServer(attachmentView: AttachmentView, cipherId: string,
organizationId: string): Promise<any> {
const attachmentResponse = await fetch(new Request(attachmentView.url, { cache: 'no-cache' }));
if (attachmentResponse.status !== 200) {
throw Error('Failed to download attachment: ' + attachmentResponse.status.toString());
}
const buf = await attachmentResponse.arrayBuffer();
const decBuf = await this.cryptoService.decryptFromBytes(buf, null);
const key = await this.cryptoService.getOrgKey(organizationId);
const encData = await this.cryptoService.encryptToBytes(decBuf, key);
const encFileName = await this.cryptoService.encrypt(attachmentView.fileName, 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 && !Utils.isBrowser) {
fd.append('data', Buffer.from(encData) as any, {
filepath: encFileName.encryptedString,
contentType: 'application/octet-stream',
} as any);
} else {
throw e;
}
}
let response: CipherResponse;
try {
response = await this.apiService.postShareCipherAttachment(cipherId, attachmentView.id, fd,
organizationId);
} catch (e) {
throw new Error((e as ErrorResponse).getSingleMessage());
}
}
saveAttachmentWithServer(cipher: Cipher, unencryptedFile: any, admin = false): Promise<Cipher> { saveAttachmentWithServer(cipher: Cipher, unencryptedFile: any, admin = false): Promise<Cipher> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const reader = new FileReader(); const reader = new FileReader();
@ -772,6 +743,41 @@ export class CipherService implements CipherServiceAbstraction {
// Helpers // Helpers
private async shareAttachmentWithServer(attachmentView: AttachmentView, cipherId: string,
organizationId: string): Promise<any> {
const attachmentResponse = await fetch(new Request(attachmentView.url, { cache: 'no-cache' }));
if (attachmentResponse.status !== 200) {
throw Error('Failed to download attachment: ' + attachmentResponse.status.toString());
}
const buf = await attachmentResponse.arrayBuffer();
const decBuf = await this.cryptoService.decryptFromBytes(buf, null);
const key = await this.cryptoService.getOrgKey(organizationId);
const encData = await this.cryptoService.encryptToBytes(decBuf, key);
const encFileName = await this.cryptoService.encrypt(attachmentView.fileName, 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 && !Utils.isBrowser) {
fd.append('data', Buffer.from(encData) as any, {
filepath: encFileName.encryptedString,
contentType: 'application/octet-stream',
} as any);
} else {
throw e;
}
}
try {
await this.apiService.postShareCipherAttachment(cipherId, attachmentView.id, fd, organizationId);
} catch (e) {
throw new Error((e as ErrorResponse).getSingleMessage());
}
}
private async encryptObjProperty<V extends View, D extends Domain>(model: V, obj: D, private async encryptObjProperty<V extends View, D extends Domain>(model: V, obj: D,
map: any, key: SymmetricCryptoKey): Promise<void> { map: any, key: SymmetricCryptoKey): Promise<void> {
const promises = []; const promises = [];