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);
|