Работа над ServerStorage

This commit is contained in:
Book Pauk
2019-03-13 20:22:04 +07:00
parent 6904cfd224
commit cd5d3903fe
3 changed files with 68 additions and 37 deletions

View File

@@ -6,7 +6,6 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
import Vue from 'vue'; import Vue from 'vue';
import Component from 'vue-class-component'; import Component from 'vue-class-component';
import {Buffer} from 'safe-buffer';
import _ from 'lodash'; import _ from 'lodash';
import bookManager from '../share/bookManager'; import bookManager from '../share/bookManager';
@@ -26,8 +25,11 @@ class ServerStorage extends Vue {
//генерируем новый ключ //генерируем новый ключ
this.generateNewServerStorageKey(); this.generateNewServerStorageKey();
} }
//console.log(await this.storageSet({'id1': {rev: 1, data: {test: 123}}})); this.hashedStorageKey = utils.toBase58(await cryptoUtils.sha256(this.serverStorageKey));
//console.log(await this.storageGet({'id1': {rev: 1, data: {test: 123}}}));
//console.log(await this.storageSet({'id1': {rev: 3, data: {test: 123}}}));
//console.log(await this.storageGet({'id1': {}}));
//console.log(await this.storageCheck({'id1': {rev: 1, data: {test: 123}}}));
} }
get settings() { get settings() {
@@ -39,44 +41,60 @@ class ServerStorage extends Vue {
} }
generateNewServerStorageKey() { generateNewServerStorageKey() {
const key = utils.toBase58(Buffer.from(utils.randomArray(32))); const key = utils.toBase58(utils.randomArray(32));
this.commit('reader/setServerStorageKey', key); this.commit('reader/setServerStorageKey', key);
} }
async storageCheck(items) { async storageCheck(items) {
return await this.decodeStorageItems(await readerApi.storage({action: 'check', items})); return await this.storageApi('check', items);
} }
async storageGet(items) { async storageGet(items) {
return await this.decodeStorageItems(await readerApi.storage({action: 'get', items})); return await this.storageApi('get', items);
} }
async storageSet(items, force) { async storageSet(items, force) {
return await readerApi.storage(await this.encodeStorageItems({action: 'set', force, items})); return await this.storageApi('set', items, force);
}
async storageApi(action, items, force) {
const request = {action, items};
if (force)
request.force = true;
const encodedRequest = await this.encodeStorageItems(request);
return await this.decodeStorageItems(await readerApi.storage(encodedRequest));
} }
async encodeStorageItems(request) { async encodeStorageItems(request) {
if (!this.hashedStorageKey)
throw new Error('hashedStorageKey is empty');
if (!_.isObject(request.items)) if (!_.isObject(request.items))
throw new Error('items is not an object'); throw new Error('items is not an object');
let result = Object.assign({}, request); let result = Object.assign({}, request);
let items = {}; let items = {};
for (const id of Object.keys(request.items)) { for (const id of Object.keys(request.items)) {
if (id.indexOf('.') >= 0)
throw new Error(`encodeStorageItems: bad id - ${id}`);
const item = request.items[id]; const item = request.items[id];
if (!_.isObject(item.data)) if (request.action == 'set' && !_.isObject(item.data))
throw new Error('encodeStorageItems: data is not an object'); throw new Error('encodeStorageItems: data is not an object');
let encoded = Object.assign({}, item); let encoded = Object.assign({}, item);
const comp = utils.pako.deflate(JSON.stringify(item.data), {level: 1}); if (item.data) {
let encrypted = null; const comp = utils.pako.deflate(JSON.stringify(item.data), {level: 1});
try { let encrypted = null;
encrypted = await cryptoUtils.aesEncrypt(comp, this.serverStorageKey); try {
} catch (e) { encrypted = await cryptoUtils.aesEncrypt(comp, this.serverStorageKey);
throw new Error('encrypt failed'); } catch (e) {
throw new Error('encrypt failed');
}
encoded.data = '1' + utils.toBase64(encrypted);
} }
encoded.data = '1' + utils.toBase64(Buffer.from(encrypted)); items[`${this.hashedStorageKey}.${id}`] = encoded;
items[id] = encoded;
} }
result.items = items; result.items = items;
@@ -84,30 +102,39 @@ class ServerStorage extends Vue {
} }
async decodeStorageItems(response) { async decodeStorageItems(response) {
if (!_.isObject(response.items)) if (!this.hashedStorageKey)
throw new Error('items is not an object'); throw new Error('hashedStorageKey is empty');
let result = Object.assign({}, response); let result = Object.assign({}, response);
let items = {}; let items = {};
for (const id of Object.keys(response.items)) { if (response.items) {
const item = response.items[id]; if (!_.isObject(response.items))
let decoded = Object.assign({}, item); throw new Error('items is not an object');
if (item.data) {
if (!_.isString(item.data) || !item.data.length)
throw new Error('decodeStorageItems: data is not a string');
if (item.data[0] !== '1')
throw new Error('decodeStorageItems: unknown data format');
const a = utils.fromBase64(item.data.substr(1)); for (const id of Object.keys(response.items)) {
let decrypted = null; const item = response.items[id];
try { let decoded = Object.assign({}, item);
decrypted = await cryptoUtils.aesDecrypt(a, this.serverStorageKey); if (item.data) {
} catch (e) { if (!_.isString(item.data) || !item.data.length)
throw new Error('decrypt failed'); throw new Error('decodeStorageItems: data is not a 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'}));
} }
decoded.data = JSON.parse(utils.pako.inflate(decrypted, {to: 'string'}));
const ids = id.split('.');
if (!(ids.length == 2) || !(ids[0] == this.hashedStorageKey))
throw new Error(`decodeStorageItems: bad id - ${id}`);
items[ids[1]] = decoded;
} }
items[id] = decoded;
} }
result.items = items; result.items = items;

View File

@@ -64,3 +64,7 @@ export async function aesDecrypt(data, password) {
data //ArrayBuffer of the data data //ArrayBuffer of the data
); );
} }
export async function sha256(data) {
return await crypto.subtle.digest("SHA-256", Buffer.from(data));
}

View File

@@ -78,7 +78,7 @@ export async function copyTextToClipboard(text) {
} }
export function toBase58(data) { export function toBase58(data) {
return bs58.encode(data); return bs58.encode(Buffer.from(data));
} }
export function fromBase58(data) { export function fromBase58(data) {
@@ -86,7 +86,7 @@ export function fromBase58(data) {
} }
export function toBase64(data) { export function toBase64(data) {
return bs64.encode(data); return bs64.encode(Buffer.from(data));
} }
export function fromBase64(data) { export function fromBase64(data) {