raw attachment saves with node form data
This commit is contained in:
parent
ed89dfaba7
commit
a421f6e64a
|
@ -84,6 +84,15 @@
|
|||
"tslib": "1.9.0"
|
||||
}
|
||||
},
|
||||
"@types/form-data": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz",
|
||||
"integrity": "sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "8.0.19"
|
||||
}
|
||||
},
|
||||
"@types/jasmine": {
|
||||
"version": "2.8.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.8.6.tgz",
|
||||
|
@ -383,8 +392,7 @@
|
|||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
|
||||
"dev": true
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||
},
|
||||
"atob": {
|
||||
"version": "2.1.0",
|
||||
|
@ -1249,7 +1257,6 @@
|
|||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
|
||||
"integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"delayed-stream": "1.0.0"
|
||||
}
|
||||
|
@ -1759,8 +1766,7 @@
|
|||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
|
||||
"dev": true
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
|
||||
},
|
||||
"depd": {
|
||||
"version": "1.1.2",
|
||||
|
@ -2575,7 +2581,6 @@
|
|||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
|
||||
"integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"asynckit": "0.4.0",
|
||||
"combined-stream": "1.0.6",
|
||||
|
@ -5642,14 +5647,12 @@
|
|||
"mime-db": {
|
||||
"version": "1.33.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
|
||||
"integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.18",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
|
||||
"integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mime-db": "1.33.0"
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
"test:node:watch": "concurrently -k -n TSC,Node -c yellow,cyan \"npm run build:watch\" \"nodemon -w ./dist --delay 500ms --exec jasmine\""
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/form-data": "^2.2.1",
|
||||
"@types/jasmine": "^2.8.2",
|
||||
"@types/keytar": "^4.0.1",
|
||||
"@types/lunr": "2.1.5",
|
||||
|
@ -72,6 +73,7 @@
|
|||
"electron-log": "2.2.14",
|
||||
"electron-store": "1.3.0",
|
||||
"electron-updater": "2.21.4",
|
||||
"form-data": "2.3.2",
|
||||
"keytar": "4.1.0",
|
||||
"lunr": "2.1.6",
|
||||
"node-fetch": "2.1.2",
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue