253 lines
8.3 KiB
JavaScript
253 lines
8.3 KiB
JavaScript
/*
|
|
* (c) Copyright Ascensio System SIA 2010-2024
|
|
*
|
|
* This program is a free software product. You can redistribute it and/or
|
|
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
|
* version 3 as published by the Free Software Foundation. In accordance with
|
|
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
|
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
|
* of any third-party rights.
|
|
*
|
|
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
|
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
|
*
|
|
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
|
|
* street, Riga, Latvia, EU, LV-1050.
|
|
*
|
|
* The interactive user interfaces in modified source and object code versions
|
|
* of the Program must display Appropriate Legal Notices, as required under
|
|
* Section 5 of the GNU AGPL version 3.
|
|
*
|
|
* Pursuant to Section 7(b) of the License you must retain the original Product
|
|
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
|
* grant you any rights under trademark law for use of our trademarks.
|
|
*
|
|
* All the Product's GUI elements, including illustrations and icon sets, as
|
|
* well as technical writing content are licensed under the terms of the
|
|
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
|
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
|
*
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
(function(exports){
|
|
|
|
exports.AscCrypto = exports.AscCrypto || {};
|
|
var AscCrypto = exports.AscCrypto;
|
|
|
|
AscCrypto.Storage = {};
|
|
|
|
// тип команды. "private" - значит доступно только для того юзера, который делает запрос
|
|
AscCrypto.Storage.CommandType = {
|
|
private : "private",
|
|
public : "public"
|
|
};
|
|
|
|
// ключи команды.
|
|
AscCrypto.Storage.CommandKey = {
|
|
keySign : "keySign",
|
|
keyCrypt : "keyCrypt"
|
|
};
|
|
|
|
/* storage:
|
|
{
|
|
id : { type : AscCrypto.Storage.CommandKey, value { date : ..., ... } },
|
|
...
|
|
}
|
|
*/
|
|
|
|
// перечень команд.
|
|
AscCrypto.Storage.CommandName = {
|
|
// добавляем к текущему юзеру запись
|
|
// { type : add, value : [{value},{value}] }
|
|
add : "add",
|
|
// удаляем запись по id. пока не используем
|
|
// { type : remove, value : [id1, id2, ...] }
|
|
remove : "remove",
|
|
// заменяем у текущего юзера запись по id (если записи нет - то ничего не делаем)
|
|
// { type : remove, value : [{rec, rec}] }
|
|
replace : "replace",
|
|
// для текущего юзера. отдаем все записи с указанным ключом
|
|
// { type : get, value : [key1, key2] }
|
|
// для себя - отдаем и private. для остальных- нет
|
|
get : "get",
|
|
// вернуть объект юзера (данные его) по одному из значений ключа.
|
|
// если ничего не указано - то вернуть для текущего юзера
|
|
// (в принципе можно присылать еще и ключ, по которому смотреть, записей будет мало => ключ можно упустить)
|
|
getUserInfo : "getUserInfo"
|
|
};
|
|
|
|
function CItem()
|
|
{
|
|
this["id"] = undefined;
|
|
this["key"] = undefined;
|
|
this["value"] = undefined;
|
|
}
|
|
CItem.prototype.generate = function(key, value)
|
|
{
|
|
this["id"] = AscCommon.randomBytes(20).base58();
|
|
this["key"] = key;
|
|
this["value"] = {};
|
|
|
|
if (value)
|
|
{
|
|
for (let prop in value)
|
|
{
|
|
if (value.hasOwnProperty(prop))
|
|
this["value"][prop] = value[prop];
|
|
}
|
|
}
|
|
|
|
let date = new Date();
|
|
this["value"]["date"] = date.toISOString();
|
|
};
|
|
CItem.prototype.store = function(obj)
|
|
{
|
|
obj[this["id"]] = { "key" : this["key"], "value" : this["value"] };
|
|
};
|
|
|
|
function IStorage()
|
|
{
|
|
}
|
|
// interface
|
|
CStorageLocalStorage.prototype.command = function(items, callback) {}
|
|
|
|
/**
|
|
* @extends {IStorage}
|
|
*/
|
|
function CStorageLocalStorage()
|
|
{
|
|
IStorage.call(this);
|
|
}
|
|
CStorageLocalStorage.prototype = Object.create(IStorage.prototype);
|
|
CStorageLocalStorage.prototype.constructor = CStorageLocalStorage;
|
|
|
|
CStorageLocalStorage.prototype.getStorageValue = function()
|
|
{
|
|
try
|
|
{
|
|
return JSON.parse(window.localStorage.getItem("oo-crypto-object"));
|
|
}
|
|
catch (e)
|
|
{
|
|
return {};
|
|
}
|
|
};
|
|
CStorageLocalStorage.prototype.setStorageValue = function(value)
|
|
{
|
|
try
|
|
{
|
|
window.localStorage.setItem("oo-crypto-object", JSON.stringify(value));
|
|
return true;
|
|
}
|
|
catch (e)
|
|
{
|
|
}
|
|
return false;
|
|
};
|
|
|
|
CStorageLocalStorage.prototype.command = function(command, callback)
|
|
{
|
|
let localValue = this.getStorageValue();
|
|
if (!localValue)
|
|
localValue = {};
|
|
|
|
let isUpdate = false;
|
|
|
|
let records = command.value;
|
|
let returnKeys = command.callback;
|
|
|
|
switch (command["type"])
|
|
{
|
|
case AscCrypto.Storage.CommandName.add:
|
|
{
|
|
for (let i = 0, len = records.length; i < len; i++)
|
|
{
|
|
let newItem = new CItem();
|
|
newItem.generate(records[i]["key"], records[i]["value"]);
|
|
newItem.store(localValue);
|
|
isUpdate = true;
|
|
}
|
|
break;
|
|
}
|
|
case AscCrypto.Storage.CommandName.remove:
|
|
{
|
|
for (let i = 0, len = records.length; i < len; i++)
|
|
{
|
|
if (localValue[records[i]])
|
|
{
|
|
delete localValue[records[i]];
|
|
isUpdate = true;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case AscCrypto.Storage.CommandName.replace:
|
|
{
|
|
for (let prop in records)
|
|
{
|
|
if (records.hasOwnProperty(prop) && localValue[prop])
|
|
{
|
|
delete localValue[prop];
|
|
localValue[prop] = records[prop];
|
|
isUpdate = true;
|
|
}
|
|
}
|
|
|
|
for (let i = 0, len = records.length; i < len; i++)
|
|
{
|
|
if (localValue[records[i]["id"]])
|
|
{
|
|
delete localValue[records[i]["id"]];
|
|
localValue[records[i]["id"]] = { "key" : records[i]["key"], "value" : records[i]["value"] };
|
|
isUpdate = true;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case AscCrypto.Storage.CommandName.get:
|
|
{
|
|
returnKeys = records;
|
|
break;
|
|
}
|
|
case AscCrypto.Storage.CommandName.getUserInfo:
|
|
{
|
|
// в локальной версии юзеров нет
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (isUpdate)
|
|
this.setStorageValue(localValue);
|
|
|
|
let mapReturnKeys = {};
|
|
for (let i = 0, len = returnKeys.length; i < len; i++)
|
|
{
|
|
mapReturnKeys[returnKeys[i]] = true;
|
|
}
|
|
|
|
let returnObj = {};
|
|
for (let prop in localValue)
|
|
{
|
|
if (localValue.hasOwnProperty(prop) && mapReturnKeys[localValue[prop]["key"]] === true)
|
|
{
|
|
returnObj[prop] = localValue[prop];
|
|
// тут приватные не удаляем (это нужно на юзерах делать)
|
|
}
|
|
}
|
|
|
|
setTimeout(function(){
|
|
callback && callback(returnObj);
|
|
}, 10);
|
|
};
|
|
|
|
AscCrypto.Storage.CItem = CItem;
|
|
AscCrypto.Storage.IStorage = IStorage;
|
|
AscCrypto.Storage.CStorageLocalStorage = CStorageLocalStorage;
|
|
|
|
})(window);
|