move required stdop files to docs/scripts/
This commit is contained in:
parent
85de9d4b96
commit
fd6e09b157
21
LICENCE
21
LICENCE
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Sai Raj
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
257
compactIDB.js
257
compactIDB.js
@ -1,257 +0,0 @@
|
||||
(function (EXPORTS) { //compactIDB v2.1.2
|
||||
/* Compact IndexedDB operations */
|
||||
'use strict';
|
||||
const compactIDB = EXPORTS;
|
||||
|
||||
var defaultDB;
|
||||
|
||||
const indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
|
||||
const IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
|
||||
const IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
|
||||
|
||||
if (!indexedDB) {
|
||||
console.error("Your browser doesn't support a stable version of IndexedDB.");
|
||||
return;
|
||||
}
|
||||
|
||||
compactIDB.setDefaultDB = dbName => defaultDB = dbName;
|
||||
|
||||
Object.defineProperty(compactIDB, 'default', {
|
||||
get: () => defaultDB,
|
||||
set: dbName => defaultDB = dbName
|
||||
});
|
||||
|
||||
function getDBversion(dbName = defaultDB) {
|
||||
return new Promise((resolve, reject) => {
|
||||
openDB(dbName).then(db => {
|
||||
resolve(db.version)
|
||||
db.close()
|
||||
}).catch(error => reject(error))
|
||||
})
|
||||
}
|
||||
|
||||
function upgradeDB(dbName, createList = null, deleteList = null) {
|
||||
return new Promise((resolve, reject) => {
|
||||
getDBversion(dbName).then(version => {
|
||||
var idb = indexedDB.open(dbName, version + 1);
|
||||
idb.onerror = (event) => reject("Error in opening IndexedDB");
|
||||
idb.onupgradeneeded = (event) => {
|
||||
let db = event.target.result;
|
||||
if (createList instanceof Object) {
|
||||
if (Array.isArray(createList)) {
|
||||
let tmp = {}
|
||||
createList.forEach(o => tmp[o] = {})
|
||||
createList = tmp
|
||||
}
|
||||
for (let o in createList) {
|
||||
let obs = db.createObjectStore(o, createList[o].options || {});
|
||||
if (createList[o].indexes instanceof Object)
|
||||
for (let i in createList[o].indexes)
|
||||
obs.createIndex(i, i, createList[o].indexes || {});
|
||||
}
|
||||
}
|
||||
if (Array.isArray(deleteList))
|
||||
deleteList.forEach(o => db.deleteObjectStore(o));
|
||||
resolve('Database upgraded')
|
||||
}
|
||||
idb.onsuccess = (event) => event.target.result.close();
|
||||
}).catch(error => reject(error))
|
||||
})
|
||||
}
|
||||
|
||||
compactIDB.initDB = function (dbName, objectStores = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!(objectStores instanceof Object))
|
||||
return reject('ObjectStores must be an object or array')
|
||||
defaultDB = defaultDB || dbName;
|
||||
var idb = indexedDB.open(dbName);
|
||||
idb.onerror = (event) => reject("Error in opening IndexedDB");
|
||||
idb.onsuccess = (event) => {
|
||||
var db = event.target.result;
|
||||
let cList = Object.values(db.objectStoreNames);
|
||||
var obs = {},
|
||||
a_obs = {},
|
||||
d_obs = [];
|
||||
if (!Array.isArray(objectStores))
|
||||
var obs = objectStores
|
||||
else
|
||||
objectStores.forEach(o => obs[o] = {})
|
||||
let nList = Object.keys(obs)
|
||||
for (let o of nList)
|
||||
if (!cList.includes(o))
|
||||
a_obs[o] = obs[o]
|
||||
for (let o of cList)
|
||||
if (!nList.includes(o))
|
||||
d_obs.push(o)
|
||||
if (!Object.keys(a_obs).length && !d_obs.length)
|
||||
resolve("Initiated IndexedDB");
|
||||
else
|
||||
upgradeDB(dbName, a_obs, d_obs)
|
||||
.then(result => resolve(result))
|
||||
.catch(error => reject(error))
|
||||
db.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const openDB = compactIDB.openDB = function (dbName = defaultDB) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var idb = indexedDB.open(dbName);
|
||||
idb.onerror = (event) => reject("Error in opening IndexedDB");
|
||||
idb.onupgradeneeded = (event) => {
|
||||
event.target.result.close();
|
||||
deleteDB(dbName).then(_ => null).catch(_ => null).finally(_ => reject("Datebase not found"))
|
||||
}
|
||||
idb.onsuccess = (event) => resolve(event.target.result);
|
||||
});
|
||||
}
|
||||
|
||||
const deleteDB = compactIDB.deleteDB = function (dbName = defaultDB) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var deleteReq = indexedDB.deleteDatabase(dbName);;
|
||||
deleteReq.onerror = (event) => reject("Error deleting database!");
|
||||
deleteReq.onsuccess = (event) => resolve("Database deleted successfully");
|
||||
});
|
||||
}
|
||||
|
||||
compactIDB.writeData = function (obsName, data, key = false, dbName = defaultDB) {
|
||||
return new Promise((resolve, reject) => {
|
||||
openDB(dbName).then(db => {
|
||||
var obs = db.transaction(obsName, "readwrite").objectStore(obsName);
|
||||
let writeReq = (key ? obs.put(data, key) : obs.put(data));
|
||||
writeReq.onsuccess = (evt) => resolve(`Write data Successful`);
|
||||
writeReq.onerror = (evt) => reject(
|
||||
`Write data unsuccessful [${evt.target.error.name}] ${evt.target.error.message}`
|
||||
);
|
||||
db.close();
|
||||
}).catch(error => reject(error));
|
||||
});
|
||||
}
|
||||
|
||||
compactIDB.addData = function (obsName, data, key = false, dbName = defaultDB) {
|
||||
return new Promise((resolve, reject) => {
|
||||
openDB(dbName).then(db => {
|
||||
var obs = db.transaction(obsName, "readwrite").objectStore(obsName);
|
||||
let addReq = (key ? obs.add(data, key) : obs.add(data));
|
||||
addReq.onsuccess = (evt) => resolve(`Add data successful`);
|
||||
addReq.onerror = (evt) => reject(
|
||||
`Add data unsuccessful [${evt.target.error.name}] ${evt.target.error.message}`
|
||||
);
|
||||
db.close();
|
||||
}).catch(error => reject(error));
|
||||
});
|
||||
}
|
||||
|
||||
compactIDB.removeData = function (obsName, key, dbName = defaultDB) {
|
||||
return new Promise((resolve, reject) => {
|
||||
openDB(dbName).then(db => {
|
||||
var obs = db.transaction(obsName, "readwrite").objectStore(obsName);
|
||||
let delReq = obs.delete(key);
|
||||
delReq.onsuccess = (evt) => resolve(`Removed Data ${key}`);
|
||||
delReq.onerror = (evt) => reject(
|
||||
`Remove data unsuccessful [${evt.target.error.name}] ${evt.target.error.message}`
|
||||
);
|
||||
db.close();
|
||||
}).catch(error => reject(error));
|
||||
});
|
||||
}
|
||||
|
||||
compactIDB.clearData = function (obsName, dbName = defaultDB) {
|
||||
return new Promise((resolve, reject) => {
|
||||
openDB(dbName).then(db => {
|
||||
var obs = db.transaction(obsName, "readwrite").objectStore(obsName);
|
||||
let clearReq = obs.clear();
|
||||
clearReq.onsuccess = (evt) => resolve(`Clear data Successful`);
|
||||
clearReq.onerror = (evt) => reject(`Clear data Unsuccessful`);
|
||||
db.close();
|
||||
}).catch(error => reject(error));
|
||||
});
|
||||
}
|
||||
|
||||
compactIDB.readData = function (obsName, key, dbName = defaultDB) {
|
||||
return new Promise((resolve, reject) => {
|
||||
openDB(dbName).then(db => {
|
||||
var obs = db.transaction(obsName, "readonly").objectStore(obsName);
|
||||
let getReq = obs.get(key);
|
||||
getReq.onsuccess = (evt) => resolve(evt.target.result);
|
||||
getReq.onerror = (evt) => reject(
|
||||
`Read data unsuccessful [${evt.target.error.name}] ${evt.target.error.message}`
|
||||
);
|
||||
db.close();
|
||||
}).catch(error => reject(error));
|
||||
});
|
||||
}
|
||||
|
||||
compactIDB.readAllData = function (obsName, dbName = defaultDB) {
|
||||
return new Promise((resolve, reject) => {
|
||||
openDB(dbName).then(db => {
|
||||
var obs = db.transaction(obsName, "readonly").objectStore(obsName);
|
||||
var tmpResult = {}
|
||||
let curReq = obs.openCursor();
|
||||
curReq.onsuccess = (evt) => {
|
||||
var cursor = evt.target.result;
|
||||
if (cursor) {
|
||||
tmpResult[cursor.primaryKey] = cursor.value;
|
||||
cursor.continue();
|
||||
} else
|
||||
resolve(tmpResult);
|
||||
}
|
||||
curReq.onerror = (evt) => reject(
|
||||
`Read-All data unsuccessful [${evt.target.error.name}] ${evt.target.error.message}`
|
||||
);
|
||||
db.close();
|
||||
}).catch(error => reject(error));
|
||||
});
|
||||
}
|
||||
|
||||
/* compactIDB.searchData = function (obsName, options = {}, dbName = defaultDB) {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
openDB(dbName).then(db => {
|
||||
var obs = db.transaction(obsName, "readonly").objectStore(obsName);
|
||||
var filteredResult = {}
|
||||
let keyRange;
|
||||
if(options.lowerKey!==null && options.upperKey!==null)
|
||||
keyRange = IDBKeyRange.bound(options.lowerKey, options.upperKey);
|
||||
else if(options.lowerKey!==null)
|
||||
keyRange = IDBKeyRange.lowerBound(options.lowerKey);
|
||||
else if (options.upperKey!==null)
|
||||
keyRange = IDBKeyRange.upperBound(options.upperBound);
|
||||
else if (options.atKey)
|
||||
let curReq = obs.openCursor(keyRange, )
|
||||
}).catch(error => reject(error))
|
||||
})
|
||||
}*/
|
||||
|
||||
compactIDB.searchData = function (obsName, options = {}, dbName = defaultDB) {
|
||||
options.lowerKey = options.atKey || options.lowerKey || 0
|
||||
options.upperKey = options.atKey || options.upperKey || false
|
||||
options.patternEval = options.patternEval || ((k, v) => true);
|
||||
options.limit = options.limit || false;
|
||||
options.reverse = options.reverse || false;
|
||||
options.lastOnly = options.lastOnly || false
|
||||
return new Promise((resolve, reject) => {
|
||||
openDB(dbName).then(db => {
|
||||
var obs = db.transaction(obsName, "readonly").objectStore(obsName);
|
||||
var filteredResult = {}
|
||||
let curReq = obs.openCursor(
|
||||
options.upperKey ? IDBKeyRange.bound(options.lowerKey, options.upperKey) : IDBKeyRange.lowerBound(options.lowerKey),
|
||||
options.lastOnly || options.reverse ? "prev" : "next");
|
||||
curReq.onsuccess = (evt) => {
|
||||
var cursor = evt.target.result;
|
||||
if (!cursor || (options.limit && options.limit <= Object.keys(filteredResult).length))
|
||||
return resolve(filteredResult); //reached end of key list or limit reached
|
||||
else if (options.patternEval(cursor.primaryKey, cursor.value)) {
|
||||
filteredResult[cursor.primaryKey] = cursor.value;
|
||||
options.lastOnly ? resolve(filteredResult) : cursor.continue();
|
||||
} else
|
||||
cursor.continue();
|
||||
}
|
||||
curReq.onerror = (evt) => reject(`Search unsuccessful [${evt.target.error.name}] ${evt.target.error.message}`);
|
||||
db.close();
|
||||
}).catch(error => reject(error));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
})(window.compactIDB = {});
|
||||
1055
floCloudAPI.js
1055
floCloudAPI.js
File diff suppressed because it is too large
Load Diff
845
floDapps.js
845
floDapps.js
@ -1,845 +0,0 @@
|
||||
(function (EXPORTS) { //floDapps v2.4.0
|
||||
/* General functions for FLO Dapps*/
|
||||
'use strict';
|
||||
const floDapps = EXPORTS;
|
||||
|
||||
const DEFAULT = {
|
||||
root: "floDapps",
|
||||
application: floGlobals.application,
|
||||
adminID: floGlobals.adminID
|
||||
};
|
||||
|
||||
Object.defineProperties(floDapps, {
|
||||
application: {
|
||||
get: () => DEFAULT.application
|
||||
},
|
||||
adminID: {
|
||||
get: () => DEFAULT.adminID
|
||||
},
|
||||
root: {
|
||||
get: () => DEFAULT.root
|
||||
}
|
||||
});
|
||||
|
||||
var user_priv_raw, aes_key, user_priv_wrap; //private variable inside capsule
|
||||
const raw_user = {
|
||||
get private() {
|
||||
if (!user_priv_raw)
|
||||
throw "User not logged in";
|
||||
return Crypto.AES.decrypt(user_priv_raw, aes_key);
|
||||
}
|
||||
}
|
||||
|
||||
var user_id, user_public, user_private;
|
||||
const user = floDapps.user = {
|
||||
get id() {
|
||||
if (!user_id)
|
||||
throw "User not logged in";
|
||||
return user_id;
|
||||
},
|
||||
get public() {
|
||||
if (!user_public)
|
||||
throw "User not logged in";
|
||||
return user_public;
|
||||
},
|
||||
get private() {
|
||||
if (!user_private)
|
||||
throw "User not logged in";
|
||||
else if (user_private instanceof Function)
|
||||
return user_private();
|
||||
else
|
||||
return Crypto.AES.decrypt(user_private, aes_key);
|
||||
},
|
||||
sign(message) {
|
||||
return floCrypto.signData(message, raw_user.private);
|
||||
},
|
||||
decrypt(data) {
|
||||
return floCrypto.decryptData(data, raw_user.private);
|
||||
},
|
||||
encipher(message) {
|
||||
return Crypto.AES.encrypt(message, raw_user.private);
|
||||
},
|
||||
decipher(data) {
|
||||
return Crypto.AES.decrypt(data, raw_user.private);
|
||||
},
|
||||
get db_name() {
|
||||
return "floDapps#" + floCrypto.toFloID(user.id);
|
||||
},
|
||||
lock() {
|
||||
user_private = user_priv_wrap;
|
||||
},
|
||||
async unlock() {
|
||||
if (await user.private === raw_user.private)
|
||||
user_private = user_priv_raw;
|
||||
},
|
||||
get_contact(id) {
|
||||
if (!user.contacts)
|
||||
throw "Contacts not available";
|
||||
else if (user.contacts[id])
|
||||
return user.contacts[id];
|
||||
else {
|
||||
let id_raw = floCrypto.decodeAddr(id).hex;
|
||||
for (let i in user.contacts)
|
||||
if (floCrypto.decodeAddr(i).hex == id_raw)
|
||||
return user.contacts[i];
|
||||
}
|
||||
},
|
||||
get_pubKey(id) {
|
||||
if (!user.pubKeys)
|
||||
throw "Contacts not available";
|
||||
else if (user.pubKeys[id])
|
||||
return user.pubKeys[id];
|
||||
else {
|
||||
let id_raw = floCrypto.decodeAddr(id).hex;
|
||||
for (let i in user.pubKeys)
|
||||
if (floCrypto.decodeAddr(i).hex == id_raw)
|
||||
return user.pubKeys[i];
|
||||
}
|
||||
},
|
||||
clear() {
|
||||
user_id = user_public = user_private = undefined;
|
||||
user_priv_raw = aes_key = undefined;
|
||||
delete user.contacts;
|
||||
delete user.pubKeys;
|
||||
delete user.messages;
|
||||
}
|
||||
};
|
||||
|
||||
Object.defineProperties(window, {
|
||||
myFloID: {
|
||||
get: () => {
|
||||
try {
|
||||
return user.id;
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
myUserID: {
|
||||
get: () => {
|
||||
try {
|
||||
return user.id;
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
myPubKey: {
|
||||
get: () => {
|
||||
try {
|
||||
return user.public;
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
myPrivKey: {
|
||||
get: () => {
|
||||
try {
|
||||
return user.private;
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var subAdmins, trustedIDs, settings;
|
||||
Object.defineProperties(floGlobals, {
|
||||
subAdmins: {
|
||||
get: () => subAdmins
|
||||
},
|
||||
trustedIDs: {
|
||||
get: () => trustedIDs
|
||||
},
|
||||
settings: {
|
||||
get: () => settings
|
||||
},
|
||||
contacts: {
|
||||
get: () => user.contacts
|
||||
},
|
||||
pubKeys: {
|
||||
get: () => user.pubKeys
|
||||
},
|
||||
messages: {
|
||||
get: () => user.messages
|
||||
}
|
||||
})
|
||||
|
||||
function initIndexedDB() {
|
||||
return new Promise((resolve, reject) => {
|
||||
var obs_g = {
|
||||
//general
|
||||
lastTx: {},
|
||||
//supernode (cloud list)
|
||||
supernodes: {
|
||||
indexes: {
|
||||
uri: null,
|
||||
pubKey: null
|
||||
}
|
||||
}
|
||||
}
|
||||
var obs_a = {
|
||||
//login credentials
|
||||
credentials: {},
|
||||
//for Dapps
|
||||
subAdmins: {},
|
||||
trustedIDs: {},
|
||||
settings: {},
|
||||
appObjects: {},
|
||||
generalData: {},
|
||||
lastVC: {}
|
||||
}
|
||||
//add other given objectStores
|
||||
initIndexedDB.appObs = initIndexedDB.appObs || {}
|
||||
for (let o in initIndexedDB.appObs)
|
||||
if (!(o in obs_a))
|
||||
obs_a[o] = initIndexedDB.appObs[o]
|
||||
Promise.all([
|
||||
compactIDB.initDB(DEFAULT.application, obs_a),
|
||||
compactIDB.initDB(DEFAULT.root, obs_g)
|
||||
]).then(result => {
|
||||
compactIDB.setDefaultDB(DEFAULT.application)
|
||||
resolve("IndexedDB App Storage Initated Successfully")
|
||||
}).catch(error => reject(error));
|
||||
})
|
||||
}
|
||||
|
||||
function initUserDB() {
|
||||
return new Promise((resolve, reject) => {
|
||||
var obs = {
|
||||
contacts: {},
|
||||
pubKeys: {},
|
||||
messages: {}
|
||||
}
|
||||
compactIDB.initDB(user.db_name, obs).then(result => {
|
||||
resolve("UserDB Initated Successfully")
|
||||
}).catch(error => reject('Init userDB failed'));
|
||||
})
|
||||
}
|
||||
|
||||
function loadUserDB() {
|
||||
return new Promise((resolve, reject) => {
|
||||
var loadData = ["contacts", "pubKeys", "messages"]
|
||||
var promises = []
|
||||
for (var i = 0; i < loadData.length; i++)
|
||||
promises[i] = compactIDB.readAllData(loadData[i], user.db_name)
|
||||
Promise.all(promises).then(results => {
|
||||
for (var i = 0; i < loadData.length; i++)
|
||||
user[loadData[i]] = results[i]
|
||||
resolve("Loaded Data from userDB")
|
||||
}).catch(error => reject('Load userDB failed'))
|
||||
})
|
||||
}
|
||||
|
||||
const startUpOptions = {
|
||||
cloud: true,
|
||||
app_config: true,
|
||||
}
|
||||
|
||||
floDapps.startUpOptions = {
|
||||
set app_config(val) {
|
||||
if (val === true || val === false)
|
||||
startUpOptions.app_config = val;
|
||||
},
|
||||
get app_config() { return startUpOptions.app_config },
|
||||
|
||||
set cloud(val) {
|
||||
if (val === true || val === false)
|
||||
startUpOptions.cloud = val;
|
||||
},
|
||||
get cloud() { return startUpOptions.cloud },
|
||||
}
|
||||
|
||||
const startUpFunctions = [];
|
||||
|
||||
startUpFunctions.push(function readSupernodeListFromAPI() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!startUpOptions.cloud)
|
||||
return resolve("No cloud for this app");
|
||||
compactIDB.readData("lastTx", floCloudAPI.SNStorageID, DEFAULT.root).then(lastTx => {
|
||||
var query_options = { sentOnly: true, pattern: floCloudAPI.SNStorageName };
|
||||
if (typeof lastTx == 'number') //lastTx is tx count (*backward support)
|
||||
query_options.ignoreOld = lastTx;
|
||||
else if (typeof lastTx == 'string') //lastTx is txid of last tx
|
||||
query_options.after = lastTx;
|
||||
//fetch data from flosight
|
||||
floBlockchainAPI.readData(floCloudAPI.SNStorageID, query_options).then(result => {
|
||||
for (var i = result.data.length - 1; i >= 0; i--) {
|
||||
var content = JSON.parse(result.data[i])[floCloudAPI.SNStorageName];
|
||||
for (let sn in content.removeNodes)
|
||||
compactIDB.removeData("supernodes", sn, DEFAULT.root);
|
||||
for (let sn in content.newNodes)
|
||||
compactIDB.writeData("supernodes", content.newNodes[sn], sn, DEFAULT.root);
|
||||
for (let sn in content.updateNodes)
|
||||
compactIDB.readData("supernodes", sn, DEFAULT.root).then(r => {
|
||||
r = r || {}
|
||||
r.uri = content.updateNodes[sn];
|
||||
compactIDB.writeData("supernodes", r, sn, DEFAULT.root);
|
||||
});
|
||||
}
|
||||
compactIDB.writeData("lastTx", result.lastItem, floCloudAPI.SNStorageID, DEFAULT.root);
|
||||
compactIDB.readAllData("supernodes", DEFAULT.root).then(nodes => {
|
||||
floCloudAPI.init(nodes)
|
||||
.then(result => resolve("Loaded Supernode list\n" + result))
|
||||
.catch(error => reject(error))
|
||||
})
|
||||
})
|
||||
}).catch(error => reject(error))
|
||||
})
|
||||
});
|
||||
|
||||
startUpFunctions.push(function readAppConfigFromAPI() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!startUpOptions.app_config)
|
||||
return resolve("No configs for this app");
|
||||
compactIDB.readData("lastTx", `${DEFAULT.application}|${DEFAULT.adminID}`, DEFAULT.root).then(lastTx => {
|
||||
var query_options = { sentOnly: true, pattern: DEFAULT.application };
|
||||
if (typeof lastTx == 'number') //lastTx is tx count (*backward support)
|
||||
query_options.ignoreOld = lastTx;
|
||||
else if (typeof lastTx == 'string') //lastTx is txid of last tx
|
||||
query_options.after = lastTx;
|
||||
//fetch data from flosight
|
||||
floBlockchainAPI.readData(DEFAULT.adminID, query_options).then(result => {
|
||||
for (var i = result.data.length - 1; i >= 0; i--) {
|
||||
var content = JSON.parse(result.data[i])[DEFAULT.application];
|
||||
if (!content || typeof content !== "object")
|
||||
continue;
|
||||
if (Array.isArray(content.removeSubAdmin))
|
||||
for (var j = 0; j < content.removeSubAdmin.length; j++)
|
||||
compactIDB.removeData("subAdmins", content.removeSubAdmin[j]);
|
||||
if (Array.isArray(content.addSubAdmin))
|
||||
for (var k = 0; k < content.addSubAdmin.length; k++)
|
||||
compactIDB.writeData("subAdmins", true, content.addSubAdmin[k]);
|
||||
if (Array.isArray(content.removeTrustedID))
|
||||
for (var j = 0; j < content.removeTrustedID.length; j++)
|
||||
compactIDB.removeData("trustedIDs", content.removeTrustedID[j]);
|
||||
if (Array.isArray(content.addTrustedID))
|
||||
for (var k = 0; k < content.addTrustedID.length; k++)
|
||||
compactIDB.writeData("trustedIDs", true, content.addTrustedID[k]);
|
||||
if (content.settings)
|
||||
for (let l in content.settings)
|
||||
compactIDB.writeData("settings", content.settings[l], l)
|
||||
}
|
||||
compactIDB.writeData("lastTx", result.lastItem, `${DEFAULT.application}|${DEFAULT.adminID}`, DEFAULT.root);
|
||||
compactIDB.readAllData("subAdmins").then(result => {
|
||||
subAdmins = Object.keys(result);
|
||||
compactIDB.readAllData("trustedIDs").then(result => {
|
||||
trustedIDs = Object.keys(result);
|
||||
compactIDB.readAllData("settings").then(result => {
|
||||
settings = result;
|
||||
resolve("Read app configuration from blockchain");
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}).catch(error => reject(error))
|
||||
})
|
||||
});
|
||||
|
||||
startUpFunctions.push(function loadDataFromAppIDB() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!startUpOptions.cloud)
|
||||
return resolve("No cloud for this app");
|
||||
var loadData = ["appObjects", "generalData", "lastVC"]
|
||||
var promises = []
|
||||
for (var i = 0; i < loadData.length; i++)
|
||||
promises[i] = compactIDB.readAllData(loadData[i])
|
||||
Promise.all(promises).then(results => {
|
||||
for (var i = 0; i < loadData.length; i++)
|
||||
floGlobals[loadData[i]] = results[i]
|
||||
resolve("Loaded Data from app IDB")
|
||||
}).catch(error => reject(error))
|
||||
})
|
||||
});
|
||||
|
||||
var keyInput = type => new Promise((resolve, reject) => {
|
||||
let inputVal = prompt(`Enter ${type}: `)
|
||||
if (inputVal === null)
|
||||
reject(null)
|
||||
else
|
||||
resolve(inputVal)
|
||||
});
|
||||
|
||||
function getCredentials() {
|
||||
|
||||
const readSharesFromIDB = indexArr => new Promise((resolve, reject) => {
|
||||
var promises = []
|
||||
for (var i = 0; i < indexArr.length; i++)
|
||||
promises.push(compactIDB.readData('credentials', indexArr[i]))
|
||||
Promise.all(promises).then(shares => {
|
||||
var secret = floCrypto.retrieveShamirSecret(shares)
|
||||
if (secret)
|
||||
resolve(secret)
|
||||
else
|
||||
reject("Shares are insufficient or incorrect")
|
||||
}).catch(error => {
|
||||
clearCredentials();
|
||||
location.reload();
|
||||
})
|
||||
});
|
||||
|
||||
const writeSharesToIDB = (shares, i = 0, resultIndexes = []) => new Promise(resolve => {
|
||||
if (i >= shares.length)
|
||||
return resolve(resultIndexes)
|
||||
var n = floCrypto.randInt(0, 100000)
|
||||
compactIDB.addData("credentials", shares[i], n).then(res => {
|
||||
resultIndexes.push(n)
|
||||
writeSharesToIDB(shares, i + 1, resultIndexes)
|
||||
.then(result => resolve(result))
|
||||
}).catch(error => {
|
||||
writeSharesToIDB(shares, i, resultIndexes)
|
||||
.then(result => resolve(result))
|
||||
})
|
||||
});
|
||||
|
||||
const getPrivateKeyCredentials = () => new Promise((resolve, reject) => {
|
||||
var indexArr = localStorage.getItem(`${DEFAULT.application}#privKey`)
|
||||
if (indexArr) {
|
||||
readSharesFromIDB(JSON.parse(indexArr))
|
||||
.then(result => resolve(result))
|
||||
.catch(error => reject(error))
|
||||
} else {
|
||||
var privKey;
|
||||
keyInput("PRIVATE_KEY").then(result => {
|
||||
if (!result)
|
||||
return reject("Empty Private Key")
|
||||
var floID = floCrypto.getFloID(result)
|
||||
if (!floID || !floCrypto.validateFloID(floID))
|
||||
return reject("Invalid Private Key")
|
||||
privKey = result;
|
||||
}).catch(error => {
|
||||
console.log(error, "Generating Random Keys")
|
||||
privKey = floCrypto.generateNewID().privKey
|
||||
}).finally(_ => {
|
||||
if (!privKey)
|
||||
return;
|
||||
var threshold = floCrypto.randInt(10, 20)
|
||||
var shares = floCrypto.createShamirsSecretShares(privKey, threshold, threshold)
|
||||
writeSharesToIDB(shares).then(resultIndexes => {
|
||||
//store index keys in localStorage
|
||||
localStorage.setItem(`${DEFAULT.application}#privKey`, JSON.stringify(resultIndexes))
|
||||
//also add a dummy privatekey to the IDB
|
||||
var randomPrivKey = floCrypto.generateNewID().privKey
|
||||
var randomThreshold = floCrypto.randInt(10, 20)
|
||||
var randomShares = floCrypto.createShamirsSecretShares(randomPrivKey, randomThreshold, randomThreshold)
|
||||
writeSharesToIDB(randomShares)
|
||||
//resolve private Key
|
||||
resolve(privKey)
|
||||
})
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
const checkIfPinRequired = key => new Promise((resolve, reject) => {
|
||||
if (key.length == 52)
|
||||
resolve(key)
|
||||
else {
|
||||
keyInput("PIN/Password").then(pwd => {
|
||||
try {
|
||||
let privKey = Crypto.AES.decrypt(key, pwd);
|
||||
resolve(privKey)
|
||||
} catch (error) {
|
||||
reject("Access Denied: Incorrect PIN/Password")
|
||||
}
|
||||
}).catch(error => reject("Access Denied: PIN/Password required"))
|
||||
}
|
||||
});
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
getPrivateKeyCredentials().then(key => {
|
||||
checkIfPinRequired(key).then(privKey => {
|
||||
try {
|
||||
user_public = floCrypto.getPubKeyHex(privKey);
|
||||
user_id = floCrypto.getAddress(privKey);
|
||||
if (startUpOptions.cloud)
|
||||
floCloudAPI.user(user_id, privKey); //Set user for floCloudAPI
|
||||
user_priv_wrap = () => checkIfPinRequired(key);
|
||||
let n = floCrypto.randInt(12, 20);
|
||||
aes_key = floCrypto.randString(n);
|
||||
user_priv_raw = Crypto.AES.encrypt(privKey, aes_key);
|
||||
user_private = user_priv_wrap;
|
||||
resolve('Login Credentials loaded successful')
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
reject("Corrupted Private Key")
|
||||
}
|
||||
}).catch(error => reject(error))
|
||||
}).catch(error => reject(error))
|
||||
})
|
||||
}
|
||||
|
||||
var startUpLog = (status, log) => status ? console.log(log) : console.error(log);
|
||||
|
||||
const callStartUpFunction = i => new Promise((resolve, reject) => {
|
||||
startUpFunctions[i]().then(result => {
|
||||
callStartUpFunction.completed += 1;
|
||||
startUpLog(true, `${result}\nCompleted ${callStartUpFunction.completed}/${callStartUpFunction.total} Startup functions`)
|
||||
resolve(true)
|
||||
}).catch(error => {
|
||||
callStartUpFunction.failed += 1;
|
||||
startUpLog(false, `${error}\nFailed ${callStartUpFunction.failed}/${callStartUpFunction.total} Startup functions`)
|
||||
reject(false)
|
||||
})
|
||||
});
|
||||
|
||||
var _midFunction;
|
||||
const midStartUp = () => new Promise((res, rej) => {
|
||||
if (_midFunction instanceof Function) {
|
||||
_midFunction()
|
||||
.then(r => res("Mid startup function completed"))
|
||||
.catch(e => rej("Mid startup function failed"))
|
||||
} else
|
||||
res("No mid startup function")
|
||||
});
|
||||
|
||||
const callAndLog = p => new Promise((res, rej) => {
|
||||
p.then(r => {
|
||||
startUpLog(true, r)
|
||||
res(r)
|
||||
}).catch(e => {
|
||||
startUpLog(false, e)
|
||||
rej(e)
|
||||
})
|
||||
});
|
||||
|
||||
floDapps.launchStartUp = function () {
|
||||
return new Promise((resolve, reject) => {
|
||||
initIndexedDB().then(log => {
|
||||
console.log(log)
|
||||
callStartUpFunction.total = startUpFunctions.length;
|
||||
callStartUpFunction.completed = 0;
|
||||
callStartUpFunction.failed = 0;
|
||||
let p1 = new Promise((res, rej) => {
|
||||
Promise.all(startUpFunctions.map((f, i) => callStartUpFunction(i))).then(r => {
|
||||
callAndLog(midStartUp())
|
||||
.then(r => res(true))
|
||||
.catch(e => rej(false))
|
||||
})
|
||||
});
|
||||
let p2 = new Promise((res, rej) => {
|
||||
callAndLog(getCredentials()).then(r => {
|
||||
callAndLog(initUserDB()).then(r => {
|
||||
callAndLog(loadUserDB())
|
||||
.then(r => res(true))
|
||||
.catch(e => rej(false))
|
||||
}).catch(e => rej(false))
|
||||
}).catch(e => rej(false))
|
||||
})
|
||||
Promise.all([p1, p2])
|
||||
.then(r => resolve('App Startup finished successful'))
|
||||
.catch(e => reject('App Startup failed'))
|
||||
}).catch(error => {
|
||||
startUpLog(false, error);
|
||||
reject("App database initiation failed")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
floDapps.addStartUpFunction = fn => fn instanceof Function && !startUpFunctions.includes(fn) ? startUpFunctions.push(fn) : false;
|
||||
|
||||
floDapps.setMidStartup = fn => fn instanceof Function ? _midFunction = fn : false;
|
||||
|
||||
floDapps.setCustomStartupLogger = fn => fn instanceof Function ? startUpLog = fn : false;
|
||||
|
||||
floDapps.setCustomPrivKeyInput = fn => fn instanceof Function ? keyInput = fn : false;
|
||||
|
||||
floDapps.setAppObjectStores = appObs => initIndexedDB.appObs = appObs;
|
||||
|
||||
floDapps.storeContact = function (floID, name) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!floCrypto.validateAddr(floID))
|
||||
return reject("Invalid floID!")
|
||||
compactIDB.writeData("contacts", name, floID, user.db_name).then(result => {
|
||||
user.contacts[floID] = name;
|
||||
resolve("Contact stored")
|
||||
}).catch(error => reject(error))
|
||||
});
|
||||
}
|
||||
|
||||
floDapps.storePubKey = function (floID, pubKey) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (floID in user.pubKeys)
|
||||
return resolve("pubKey already stored")
|
||||
if (!floCrypto.validateAddr(floID))
|
||||
return reject("Invalid floID!")
|
||||
if (!floCrypto.verifyPubKey(pubKey, floID))
|
||||
return reject("Incorrect pubKey")
|
||||
compactIDB.writeData("pubKeys", pubKey, floID, user.db_name).then(result => {
|
||||
user.pubKeys[floID] = pubKey;
|
||||
resolve("pubKey stored")
|
||||
}).catch(error => reject(error))
|
||||
});
|
||||
}
|
||||
|
||||
floDapps.sendMessage = function (floID, message) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let options = {
|
||||
receiverID: floID,
|
||||
application: DEFAULT.root,
|
||||
comment: DEFAULT.application
|
||||
}
|
||||
if (floID in user.pubKeys)
|
||||
message = floCrypto.encryptData(JSON.stringify(message), user.pubKeys[floID])
|
||||
floCloudAPI.sendApplicationData(message, "Message", options)
|
||||
.then(result => resolve(result))
|
||||
.catch(error => reject(error))
|
||||
})
|
||||
}
|
||||
|
||||
floDapps.requestInbox = function (callback) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let lastVC = Object.keys(user.messages).sort().pop()
|
||||
let options = {
|
||||
receiverID: user.id,
|
||||
application: DEFAULT.root,
|
||||
lowerVectorClock: lastVC + 1
|
||||
}
|
||||
let privKey = raw_user.private;
|
||||
options.callback = (d, e) => {
|
||||
for (let v in d) {
|
||||
try {
|
||||
if (d[v].message instanceof Object && "secret" in d[v].message)
|
||||
d[v].message = floCrypto.decryptData(d[v].message, privKey)
|
||||
} catch (error) { }
|
||||
compactIDB.writeData("messages", d[v], v, user.db_name)
|
||||
user.messages[v] = d[v]
|
||||
}
|
||||
if (callback instanceof Function)
|
||||
callback(d, e)
|
||||
}
|
||||
floCloudAPI.requestApplicationData("Message", options)
|
||||
.then(result => resolve(result))
|
||||
.catch(error => reject(error))
|
||||
})
|
||||
}
|
||||
|
||||
floDapps.manageAppConfig = function (adminPrivKey, addList, rmList, settings) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!startUpOptions.app_config)
|
||||
return reject("No configs for this app");
|
||||
if (!Array.isArray(addList) || !addList.length) addList = undefined;
|
||||
if (!Array.isArray(rmList) || !rmList.length) rmList = undefined;
|
||||
if (!settings || typeof settings !== "object" || !Object.keys(settings).length) settings = undefined;
|
||||
if (!addList && !rmList && !settings)
|
||||
return reject("No configuration change")
|
||||
var floData = {
|
||||
[DEFAULT.application]: {
|
||||
addSubAdmin: addList,
|
||||
removeSubAdmin: rmList,
|
||||
settings: settings
|
||||
}
|
||||
}
|
||||
var floID = floCrypto.getFloID(adminPrivKey)
|
||||
if (floID != DEFAULT.adminID)
|
||||
reject('Access Denied for Admin privilege')
|
||||
else
|
||||
floBlockchainAPI.writeData(floID, JSON.stringify(floData), adminPrivKey)
|
||||
.then(result => resolve(['Updated App Configuration', result]))
|
||||
.catch(error => reject(error))
|
||||
})
|
||||
}
|
||||
|
||||
floDapps.manageAppTrustedIDs = function (adminPrivKey, addList, rmList) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!startUpOptions.app_config)
|
||||
return reject("No configs for this app");
|
||||
if (!Array.isArray(addList) || !addList.length) addList = undefined;
|
||||
if (!Array.isArray(rmList) || !rmList.length) rmList = undefined;
|
||||
if (!addList && !rmList)
|
||||
return reject("No change in list")
|
||||
var floData = {
|
||||
[DEFAULT.application]: {
|
||||
addTrustedID: addList,
|
||||
removeTrustedID: rmList
|
||||
}
|
||||
}
|
||||
var floID = floCrypto.getFloID(adminPrivKey)
|
||||
if (floID != DEFAULT.adminID)
|
||||
reject('Access Denied for Admin privilege')
|
||||
else
|
||||
floBlockchainAPI.writeData(floID, JSON.stringify(floData), adminPrivKey)
|
||||
.then(result => resolve(['Updated App Configuration', result]))
|
||||
.catch(error => reject(error))
|
||||
})
|
||||
}
|
||||
|
||||
const clearCredentials = floDapps.clearCredentials = function () {
|
||||
return new Promise((resolve, reject) => {
|
||||
compactIDB.clearData('credentials', DEFAULT.application).then(result => {
|
||||
localStorage.removeItem(`${DEFAULT.application}#privKey`);
|
||||
user.clear();
|
||||
resolve("privKey credentials deleted!")
|
||||
}).catch(error => reject(error))
|
||||
})
|
||||
}
|
||||
|
||||
floDapps.deleteUserData = function (credentials = false) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let p = []
|
||||
p.push(compactIDB.deleteDB(user.db_name))
|
||||
if (credentials)
|
||||
p.push(clearCredentials())
|
||||
Promise.all(p)
|
||||
.then(result => resolve('User database(local) deleted'))
|
||||
.catch(error => reject(error))
|
||||
})
|
||||
}
|
||||
|
||||
floDapps.deleteAppData = function () {
|
||||
return new Promise((resolve, reject) => {
|
||||
compactIDB.deleteDB(DEFAULT.application).then(result => {
|
||||
localStorage.removeItem(`${DEFAULT.application}#privKey`)
|
||||
user.clear();
|
||||
compactIDB.removeData('lastTx', `${DEFAULT.application}|${DEFAULT.adminID}`, DEFAULT.root)
|
||||
.then(result => resolve("App database(local) deleted"))
|
||||
.catch(error => reject(error))
|
||||
}).catch(error => reject(error))
|
||||
})
|
||||
}
|
||||
|
||||
floDapps.securePrivKey = function (pwd) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
let indexArr = localStorage.getItem(`${DEFAULT.application}#privKey`)
|
||||
if (!indexArr)
|
||||
return reject("PrivKey not found");
|
||||
indexArr = JSON.parse(indexArr)
|
||||
let encryptedKey = Crypto.AES.encrypt(await user.private, pwd);
|
||||
let threshold = indexArr.length;
|
||||
let shares = floCrypto.createShamirsSecretShares(encryptedKey, threshold, threshold)
|
||||
let promises = [];
|
||||
let overwriteFn = (share, index) =>
|
||||
compactIDB.writeData("credentials", share, index, DEFAULT.application);
|
||||
for (var i = 0; i < threshold; i++)
|
||||
promises.push(overwriteFn(shares[i], indexArr[i]));
|
||||
Promise.all(promises)
|
||||
.then(results => resolve("Private Key Secured"))
|
||||
.catch(error => reject(error))
|
||||
})
|
||||
}
|
||||
|
||||
floDapps.verifyPin = function (pin = null) {
|
||||
const readSharesFromIDB = function (indexArr) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var promises = []
|
||||
for (var i = 0; i < indexArr.length; i++)
|
||||
promises.push(compactIDB.readData('credentials', indexArr[i]))
|
||||
Promise.all(promises).then(shares => {
|
||||
var secret = floCrypto.retrieveShamirSecret(shares)
|
||||
console.info(shares, secret)
|
||||
if (secret)
|
||||
resolve(secret)
|
||||
else
|
||||
reject("Shares are insufficient or incorrect")
|
||||
}).catch(error => {
|
||||
clearCredentials();
|
||||
location.reload();
|
||||
})
|
||||
})
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
var indexArr = localStorage.getItem(`${DEFAULT.application}#privKey`)
|
||||
console.info(indexArr)
|
||||
if (!indexArr)
|
||||
reject('No login credentials found')
|
||||
readSharesFromIDB(JSON.parse(indexArr)).then(key => {
|
||||
if (key.length == 52) {
|
||||
if (pin === null)
|
||||
resolve("Private key not secured")
|
||||
else
|
||||
reject("Private key not secured")
|
||||
} else {
|
||||
if (pin === null)
|
||||
return reject("PIN/Password required")
|
||||
try {
|
||||
let privKey = Crypto.AES.decrypt(key, pin);
|
||||
resolve("PIN/Password verified")
|
||||
} catch (error) {
|
||||
reject("Incorrect PIN/Password")
|
||||
}
|
||||
}
|
||||
}).catch(error => reject(error))
|
||||
})
|
||||
}
|
||||
|
||||
const getNextGeneralData = floDapps.getNextGeneralData = function (type, vectorClock = null, options = {}) {
|
||||
var fk = floCloudAPI.util.filterKey(type, options)
|
||||
vectorClock = vectorClock || getNextGeneralData[fk] || '0';
|
||||
var filteredResult = {}
|
||||
if (floGlobals.generalData[fk]) {
|
||||
for (let d in floGlobals.generalData[fk])
|
||||
if (d > vectorClock)
|
||||
filteredResult[d] = JSON.parse(JSON.stringify(floGlobals.generalData[fk][d]))
|
||||
} else if (options.comment) {
|
||||
let comment = options.comment;
|
||||
delete options.comment;
|
||||
let fk = floCloudAPI.util.filterKey(type, options);
|
||||
for (let d in floGlobals.generalData[fk])
|
||||
if (d > vectorClock && floGlobals.generalData[fk][d].comment == comment)
|
||||
filteredResult[d] = JSON.parse(JSON.stringify(floGlobals.generalData[fk][d]))
|
||||
}
|
||||
if (options.decrypt) {
|
||||
let decryptionKey = (options.decrypt === true) ? raw_user.private : options.decrypt;
|
||||
if (!Array.isArray(decryptionKey))
|
||||
decryptionKey = [decryptionKey];
|
||||
for (let f in filteredResult) {
|
||||
let data = filteredResult[f]
|
||||
try {
|
||||
if (data.message instanceof Object && "secret" in data.message) {
|
||||
for (let key of decryptionKey) {
|
||||
try {
|
||||
let tmp = floCrypto.decryptData(data.message, key)
|
||||
data.message = JSON.parse(tmp)
|
||||
break;
|
||||
} catch (error) { }
|
||||
}
|
||||
}
|
||||
} catch (error) { }
|
||||
}
|
||||
}
|
||||
getNextGeneralData[fk] = Object.keys(filteredResult).sort().pop();
|
||||
return filteredResult;
|
||||
}
|
||||
|
||||
const syncData = floDapps.syncData = {};
|
||||
|
||||
syncData.oldDevice = () => new Promise((resolve, reject) => {
|
||||
let sync = {
|
||||
contacts: user.contacts,
|
||||
pubKeys: user.pubKeys,
|
||||
messages: user.messages
|
||||
}
|
||||
let message = Crypto.AES.encrypt(JSON.stringify(sync), raw_user.private)
|
||||
let options = {
|
||||
receiverID: user.id,
|
||||
application: DEFAULT.root
|
||||
}
|
||||
floCloudAPI.sendApplicationData(message, "syncData", options)
|
||||
.then(result => resolve(result))
|
||||
.catch(error => reject(error))
|
||||
});
|
||||
|
||||
syncData.newDevice = () => new Promise((resolve, reject) => {
|
||||
var options = {
|
||||
receiverID: user.id,
|
||||
senderID: user.id,
|
||||
application: DEFAULT.root,
|
||||
mostRecent: true,
|
||||
}
|
||||
floCloudAPI.requestApplicationData("syncData", options).then(response => {
|
||||
let vc = Object.keys(response).sort().pop()
|
||||
let sync = JSON.parse(Crypto.AES.decrypt(response[vc].message, raw_user.private))
|
||||
let promises = []
|
||||
let store = (key, val, obs) => promises.push(compactIDB.writeData(obs, val, key, user.db_name));
|
||||
["contacts", "pubKeys", "messages"].forEach(c => {
|
||||
for (let i in sync[c]) {
|
||||
store(i, sync[c][i], c)
|
||||
user[c][i] = sync[c][i]
|
||||
}
|
||||
})
|
||||
Promise.all(promises)
|
||||
.then(results => resolve("Sync data successful"))
|
||||
.catch(error => reject(error))
|
||||
}).catch(error => reject(error))
|
||||
});
|
||||
})('object' === typeof module ? module.exports : window.floDapps = {});
|
||||
57
index.html
57
index.html
@ -1,57 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<title>FLO Standard Operators</title>
|
||||
<script id="floGlobals">
|
||||
/* Constants for FLO blockchain operations !!Make sure to add this at beginning!! */
|
||||
const floGlobals = {
|
||||
blockchain: "FLO",
|
||||
adminID: "FKAEdnPfjXLHSYwrXQu377ugN4tXU7VGdf",
|
||||
application: "TEST_MODE",
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
(function () {
|
||||
const urlSearchParams = new URLSearchParams(window.location.search);
|
||||
const params = Object.fromEntries(urlSearchParams.entries());
|
||||
if ('testnet' in params) {
|
||||
floGlobals.blockchain = "FLO_TEST";
|
||||
floGlobals.adminID = "oKKHdK5uYAJ52U91sYsWhnEaEAAhZP779B";
|
||||
floGlobals.application = "TEST_MODE_testnet";
|
||||
}
|
||||
|
||||
if ('quick' in params)
|
||||
window.quick = true;
|
||||
|
||||
})();
|
||||
</script>
|
||||
<script src="lib.js"></script>
|
||||
<script src="floCrypto.js"></script>
|
||||
<script src="btcOperator.js"></script>
|
||||
<script src="floBlockchainAPI.js"></script>
|
||||
<script src="floTokenAPI.js"></script>
|
||||
<script src="compactIDB.js"></script>
|
||||
<script src="floCloudAPI.js"></script>
|
||||
<script src="floDapps.js"></script>
|
||||
<script id="onLoadStartUp">
|
||||
function onLoadStartUp() {
|
||||
if (window.quick) return;
|
||||
//floDapps.addStartUpFunction('Sample', Promised Function)
|
||||
//floDapps.setAppObjectStores({sampleObs1:{}, sampleObs2:{options{autoIncrement:true, keyPath:'SampleKey'}, Indexes:{sampleIndex:{}}}})
|
||||
//floDapps.setCustomPrivKeyInput( () => { FUNCTION BODY *must resolve private key* } )
|
||||
floDapps.launchStartUp().then(result => {
|
||||
console.log(result)
|
||||
alert(`Welcome FLO_ID: ${myFloID}`)
|
||||
//App functions....
|
||||
}).catch(error => console.error(error))
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="onLoadStartUp()">
|
||||
TEST_MODE
|
||||
(use console)
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Loading…
Reference in New Issue
Block a user