diff --git a/client/components/Reader/ServerStorage/ServerStorage.vue b/client/components/Reader/ServerStorage/ServerStorage.vue index 22a09db5..93e3efac 100644 --- a/client/components/Reader/ServerStorage/ServerStorage.vue +++ b/client/components/Reader/ServerStorage/ServerStorage.vue @@ -26,6 +26,8 @@ class ServerStorage extends Vue { //генерируем новый ключ this.generateNewServerStorageKey(); } + //console.log(await this.storageSet({'id1': {rev: 1, data: {test: 123}}})); + //console.log(await this.storageGet({'id1': {rev: 1, data: {test: 123}}})); } get settings() { @@ -42,48 +44,70 @@ class ServerStorage extends Vue { } async storageCheck(items) { - return this.decodeStorageItems(await readerApi.storage({action: 'check', items})); + return await this.decodeStorageItems(await readerApi.storage({action: 'check', items})); } async storageGet(items) { - return this.decodeStorageItems(await readerApi.storage({action: 'get', items})); + return await this.decodeStorageItems(await readerApi.storage({action: 'get', items})); } async storageSet(items, force) { - return await readerApi.storage(this.encodeStorageItems({action: 'set', force, items})); + return await readerApi.storage(await this.encodeStorageItems({action: 'set', force, items})); } - encodeStorageItems(request) { + async encodeStorageItems(request) { + if (!_.isObject(request.items)) + throw new Error('items is not an object'); + let result = Object.assign({}, request); - let items = []; - for (const item of request.items) { + let items = {}; + for (const id of Object.keys(request.items)) { + const item = request.items[id]; if (!_.isObject(item.data)) throw new Error('encodeStorageItems: data is not an object'); let encoded = Object.assign({}, item); const comp = utils.pako.deflate(JSON.stringify(item.data), {level: 1}); - encoded.data = utils.toBase64(Buffer.from(comp)); - items.push(encoded); + let encrypted = null; + try { + encrypted = await cryptoUtils.aesEncrypt(comp, this.serverStorageKey); + } catch(e) { + throw new Error('encrypt failed'); + } + encoded.data = '1' + utils.toBase64(Buffer.from(encrypted)); + items[id] = encoded; } result.items = items; return result; } - decodeStorageItems(response) { + async decodeStorageItems(response) { + if (!_.isObject(response.items)) + throw new Error('items is not an object'); + let result = Object.assign({}, response); - let items = []; - for (const item of response.items) { + let items = {}; + for (const id of Object.keys(response.items)) { + const item = response.items[id]; let decoded = Object.assign({}, item); if (item.data) { - if (!_.isString(item.data)) + if (!_.isString(item.data) || !item.data.length) throw new Error('decodeStorageItems: data is not a string'); - - const a = utils.fromBase64(item.data); - decoded.data = JSON.parse(utils.pako.inflate(a, {to: 'string'})); + if (item.data[0] !== '1') + throw new Error('decodeStorageItems: unknown data format'); + + const a = utils.fromBase64(item.data.substr(1)); + let decrypted = null; + try { + decrypted = await cryptoUtils.aesDecrypt(a, this.serverStorageKey); + } catch(e) { + throw new Error('decrypt failed'); + } + decoded.data = JSON.parse(utils.pako.inflate(decrypted, {to: 'string'})); } - items.push(decoded); + items[id] = decoded; } result.items = items; diff --git a/server/core/readerStorage.js b/server/core/readerStorage.js index 490cd53f..c223e816 100644 --- a/server/core/readerStorage.js +++ b/server/core/readerStorage.js @@ -10,6 +10,9 @@ class ReaderStorage { } async doAction(act) { + if (!_.isObject(act.items)) + throw new Error('items is not an object'); + let result = {}; switch (act.action) { case 'check':