Работа над ServerStorage
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -63,4 +63,8 @@ export async function aesDecrypt(data, password) {
|
|||||||
key, //from generateKey or importKey above
|
key, //from generateKey or importKey above
|
||||||
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));
|
||||||
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user