Secure private key using capsule
This commit is contained in:
parent
80b4a8b9fe
commit
cfc36b80cd
@ -1,4 +1,4 @@
|
|||||||
(function(EXPORTS) { //floCloudAPI v2.3.0
|
(function(EXPORTS) { //floCloudAPI v2.4.0
|
||||||
/* FLO Cloud operations to send/request application data*/
|
/* FLO Cloud operations to send/request application data*/
|
||||||
'use strict';
|
'use strict';
|
||||||
const floCloudAPI = EXPORTS;
|
const floCloudAPI = EXPORTS;
|
||||||
@ -6,9 +6,32 @@
|
|||||||
const DEFAULT = {
|
const DEFAULT = {
|
||||||
SNStorageID: floGlobals.SNStorageID || "FNaN9McoBAEFUjkRmNQRYLmBF8SpS7Tgfk",
|
SNStorageID: floGlobals.SNStorageID || "FNaN9McoBAEFUjkRmNQRYLmBF8SpS7Tgfk",
|
||||||
adminID: floGlobals.adminID,
|
adminID: floGlobals.adminID,
|
||||||
application: floGlobals.application
|
application: floGlobals.application,
|
||||||
|
callback: (d, e) => console.debug(d, e)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var user_id, user_public, user_private;
|
||||||
|
const user = {
|
||||||
|
get id() {
|
||||||
|
if (!user_id)
|
||||||
|
throw "User not set";
|
||||||
|
return user_id;
|
||||||
|
},
|
||||||
|
get public() {
|
||||||
|
if (!user_public)
|
||||||
|
throw "User not set";
|
||||||
|
return user_public;
|
||||||
|
},
|
||||||
|
sign(msg) {
|
||||||
|
if (!user_private)
|
||||||
|
throw "User not set";
|
||||||
|
return floCrypto.signData(msg, user_private);
|
||||||
|
},
|
||||||
|
clear() {
|
||||||
|
user_id = user_public = user_private = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Object.defineProperties(floCloudAPI, {
|
Object.defineProperties(floCloudAPI, {
|
||||||
SNStorageID: {
|
SNStorageID: {
|
||||||
get: () => DEFAULT.SNStorageID
|
get: () => DEFAULT.SNStorageID
|
||||||
@ -18,6 +41,21 @@
|
|||||||
},
|
},
|
||||||
application: {
|
application: {
|
||||||
get: () => DEFAULT.application
|
get: () => DEFAULT.application
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
set: priv => {
|
||||||
|
if (!priv)
|
||||||
|
user_id = user_public = user_private = undefined;
|
||||||
|
else {
|
||||||
|
user_public = floCrypto.getPubKeyHex(priv);
|
||||||
|
user_id = floCrypto.getFloID(user_public);
|
||||||
|
if (!user_public || !user_id || !floCrypto.verifyPrivKey(priv, user_id))
|
||||||
|
user_id = user_public = user_private = undefined;
|
||||||
|
else
|
||||||
|
user_private = priv;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: () => user
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -392,19 +430,19 @@
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
//set status as online for myFloID
|
//set status as online for user_id
|
||||||
floCloudAPI.setStatus = function(options = {}) {
|
floCloudAPI.setStatus = function(options = {}) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let callback = options.callback instanceof Function ? options.callback : (d, e) => console.debug(d, e);
|
let callback = options.callback instanceof Function ? options.callback : DEFAULT.callback;
|
||||||
var request = {
|
var request = {
|
||||||
floID: myFloID,
|
floID: user.id,
|
||||||
application: options.application || DEFAULT.application,
|
application: options.application || DEFAULT.application,
|
||||||
time: Date.now(),
|
time: Date.now(),
|
||||||
status: true,
|
status: true,
|
||||||
pubKey: myPubKey
|
pubKey: user.public
|
||||||
}
|
}
|
||||||
let hashcontent = ["time", "application", "floID"].map(d => request[d]).join("|");
|
let hashcontent = ["time", "application", "floID"].map(d => request[d]).join("|");
|
||||||
request.sign = floCrypto.signData(hashcontent, myPrivKey);
|
request.sign = user.sign(hashcontent);
|
||||||
liveRequest(options.refID || DEFAULT.adminID, request, callback)
|
liveRequest(options.refID || DEFAULT.adminID, request, callback)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
@ -416,7 +454,7 @@
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!Array.isArray(trackList))
|
if (!Array.isArray(trackList))
|
||||||
trackList = [trackList];
|
trackList = [trackList];
|
||||||
let callback = options.callback instanceof Function ? options.callback : (d, e) => console.debug(d, e);
|
let callback = options.callback instanceof Function ? options.callback : DEFAULT.callback;
|
||||||
let request = {
|
let request = {
|
||||||
status: false,
|
status: false,
|
||||||
application: options.application || DEFAULT.application,
|
application: options.application || DEFAULT.application,
|
||||||
@ -432,9 +470,9 @@
|
|||||||
const sendApplicationData = floCloudAPI.sendApplicationData = function(message, type, options = {}) {
|
const sendApplicationData = floCloudAPI.sendApplicationData = function(message, type, options = {}) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
var data = {
|
var data = {
|
||||||
senderID: myFloID,
|
senderID: user.id,
|
||||||
receiverID: options.receiverID || DEFAULT.adminID,
|
receiverID: options.receiverID || DEFAULT.adminID,
|
||||||
pubKey: myPubKey,
|
pubKey: user.public,
|
||||||
message: encodeMessage(message),
|
message: encodeMessage(message),
|
||||||
time: Date.now(),
|
time: Date.now(),
|
||||||
application: options.application || DEFAULT.application,
|
application: options.application || DEFAULT.application,
|
||||||
@ -443,7 +481,7 @@
|
|||||||
}
|
}
|
||||||
let hashcontent = ["receiverID", "time", "application", "type", "message", "comment"]
|
let hashcontent = ["receiverID", "time", "application", "type", "message", "comment"]
|
||||||
.map(d => data[d]).join("|")
|
.map(d => data[d]).join("|")
|
||||||
data.sign = floCrypto.signData(hashcontent, myPrivKey);
|
data.sign = user.sign(hashcontent);
|
||||||
singleRequest(data.receiverID, data)
|
singleRequest(data.receiverID, data)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
@ -482,19 +520,20 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
//(NEEDS UPDATE) delete data from supernode cloud (received only)
|
/*(NEEDS UPDATE)
|
||||||
|
//delete data from supernode cloud (received only)
|
||||||
floCloudAPI.deleteApplicationData = function(vectorClocks, options = {}) {
|
floCloudAPI.deleteApplicationData = function(vectorClocks, options = {}) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
var delreq = {
|
var delreq = {
|
||||||
requestorID: myFloID,
|
requestorID: user.id,
|
||||||
pubKey: myPubKey,
|
pubKey: user.public,
|
||||||
time: Date.now(),
|
time: Date.now(),
|
||||||
delete: (Array.isArray(vectorClocks) ? vectorClocks : [vectorClocks]),
|
delete: (Array.isArray(vectorClocks) ? vectorClocks : [vectorClocks]),
|
||||||
application: options.application || DEFAULT.application
|
application: options.application || DEFAULT.application
|
||||||
}
|
}
|
||||||
let hashcontent = ["time", "application", "delete"]
|
let hashcontent = ["time", "application", "delete"]
|
||||||
.map(d => delreq[d]).join("|")
|
.map(d => delreq[d]).join("|")
|
||||||
delreq.sign = floCrypto.signData(hashcontent, myPrivKey)
|
delreq.sign = user.sign(hashcontent)
|
||||||
singleRequest(delreq.requestorID, delreq).then(result => {
|
singleRequest(delreq.requestorID, delreq).then(result => {
|
||||||
let success = [],
|
let success = [],
|
||||||
failed = [];
|
failed = [];
|
||||||
@ -507,8 +546,9 @@
|
|||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
//(NEEDS UPDATE) edit comment of data in supernode cloud (mutable comments only)
|
/*(NEEDS UPDATE)
|
||||||
|
//edit comment of data in supernode cloud (mutable comments only)
|
||||||
floCloudAPI.editApplicationData = function(vectorClock, newComment, oldData, options = {}) {
|
floCloudAPI.editApplicationData = function(vectorClock, newComment, oldData, options = {}) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let p0
|
let p0
|
||||||
@ -523,12 +563,12 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
p0.then(d => {
|
p0.then(d => {
|
||||||
if (d.senderID != myFloID)
|
if (d.senderID != user.id)
|
||||||
return reject("Invalid requestorID")
|
return reject("Invalid requestorID")
|
||||||
else if (!d.comment.startsWith("EDIT:"))
|
else if (!d.comment.startsWith("EDIT:"))
|
||||||
return reject("Data immutable")
|
return reject("Data immutable")
|
||||||
let data = {
|
let data = {
|
||||||
requestorID: myFloID,
|
requestorID: user.id,
|
||||||
receiverID: d.receiverID,
|
receiverID: d.receiverID,
|
||||||
time: Date.now(),
|
time: Date.now(),
|
||||||
application: d.application,
|
application: d.application,
|
||||||
@ -542,29 +582,30 @@
|
|||||||
"comment"
|
"comment"
|
||||||
]
|
]
|
||||||
.map(x => d[x]).join("|")
|
.map(x => d[x]).join("|")
|
||||||
data.edit.sign = floCrypto.signData(hashcontent, myPrivKey)
|
data.edit.sign = user.sign(hashcontent)
|
||||||
singleRequest(data.receiverID, data)
|
singleRequest(data.receiverID, data)
|
||||||
.then(result => resolve("Data comment updated"))
|
.then(result => resolve("Data comment updated"))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
//tag data in supernode cloud (subAdmin access only)
|
//tag data in supernode cloud (subAdmin access only)
|
||||||
floCloudAPI.tagApplicationData = function(vectorClock, tag, options = {}) {
|
floCloudAPI.tagApplicationData = function(vectorClock, tag, options = {}) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!floGlobals.subAdmins.includes(myFloID))
|
if (!floGlobals.subAdmins.includes(user.id))
|
||||||
return reject("Only subAdmins can tag data")
|
return reject("Only subAdmins can tag data")
|
||||||
var request = {
|
var request = {
|
||||||
receiverID: options.receiverID || DEFAULT.adminID,
|
receiverID: options.receiverID || DEFAULT.adminID,
|
||||||
requestorID: myFloID,
|
requestorID: user.id,
|
||||||
pubKey: myPubKey,
|
pubKey: user.public,
|
||||||
time: Date.now(),
|
time: Date.now(),
|
||||||
vectorClock: vectorClock,
|
vectorClock: vectorClock,
|
||||||
tag: tag,
|
tag: tag,
|
||||||
}
|
}
|
||||||
let hashcontent = ["time", "vectorClock", 'tag'].map(d => request[d]).join("|");
|
let hashcontent = ["time", "vectorClock", 'tag'].map(d => request[d]).join("|");
|
||||||
request.sign = floCrypto.signData(hashcontent, myPrivKey);
|
request.sign = user.sign(hashcontent);
|
||||||
singleRequest(request.receiverID, request)
|
singleRequest(request.receiverID, request)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
@ -576,14 +617,14 @@
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
var request = {
|
var request = {
|
||||||
receiverID: options.receiverID || DEFAULT.adminID,
|
receiverID: options.receiverID || DEFAULT.adminID,
|
||||||
requestorID: myFloID,
|
requestorID: user.id,
|
||||||
pubKey: myPubKey,
|
pubKey: user.public,
|
||||||
time: Date.now(),
|
time: Date.now(),
|
||||||
vectorClock: vectorClock,
|
vectorClock: vectorClock,
|
||||||
note: note,
|
note: note,
|
||||||
}
|
}
|
||||||
let hashcontent = ["time", "vectorClock", 'note'].map(d => request[d]).join("|");
|
let hashcontent = ["time", "vectorClock", 'note'].map(d => request[d]).join("|");
|
||||||
request.sign = floCrypto.signData(hashcontent, myPrivKey);
|
request.sign = user.sign(hashcontent);
|
||||||
singleRequest(request.receiverID, request)
|
singleRequest(request.receiverID, request)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
|
|||||||
235
floDapps.js
235
floDapps.js
@ -1,8 +1,88 @@
|
|||||||
(function(EXPORTS) { //floDapps v2.2.1
|
(function(EXPORTS) { //floDapps v2.3.0
|
||||||
/* General functions for FLO Dapps*/
|
/* General functions for FLO Dapps*/
|
||||||
//'use strict';
|
'use strict';
|
||||||
const floDapps = EXPORTS;
|
const floDapps = EXPORTS;
|
||||||
|
|
||||||
|
const DEFAULT = {
|
||||||
|
get root() {
|
||||||
|
return "floDapps"
|
||||||
|
},
|
||||||
|
application: floGlobals.application,
|
||||||
|
adminID: floGlobals.adminID
|
||||||
|
};
|
||||||
|
|
||||||
|
var raw_user_private; //private variable inside capsule
|
||||||
|
const raw_user = {
|
||||||
|
get private() {
|
||||||
|
if (!raw_user_private)
|
||||||
|
throw "User not logged in";
|
||||||
|
return raw_user_private;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 user_private;
|
||||||
|
},
|
||||||
|
get db_name() {
|
||||||
|
return "floDapps#" + user.id;
|
||||||
|
},
|
||||||
|
clear() {
|
||||||
|
user_id = user_public = user_private = undefined;
|
||||||
|
raw_user_private = undefined;
|
||||||
|
delete user.contacts;
|
||||||
|
delete user.pubKeys;
|
||||||
|
delete user.messages;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.defineProperties(window, {
|
||||||
|
myFloID: {
|
||||||
|
get: () => user.id
|
||||||
|
},
|
||||||
|
myPubKey: {
|
||||||
|
get: () => user.public
|
||||||
|
},
|
||||||
|
myPrivKey: {
|
||||||
|
get: () => user.private
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var subAdmins, settings
|
||||||
|
Object.defineProperties(floGlobals, {
|
||||||
|
subAdmins: {
|
||||||
|
get: () => subAdmins
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
get: () => settings
|
||||||
|
},
|
||||||
|
contacts: {
|
||||||
|
get: () => user.contacts
|
||||||
|
},
|
||||||
|
pubKeys: {
|
||||||
|
get: () => user.pubKeys
|
||||||
|
},
|
||||||
|
messages: {
|
||||||
|
get: () => user.messages
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
function initIndexedDB() {
|
function initIndexedDB() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
var obs_g = {
|
var obs_g = {
|
||||||
@ -32,37 +112,37 @@
|
|||||||
if (!(o in obs_a))
|
if (!(o in obs_a))
|
||||||
obs_a[o] = initIndexedDB.appObs[o]
|
obs_a[o] = initIndexedDB.appObs[o]
|
||||||
Promise.all([
|
Promise.all([
|
||||||
compactIDB.initDB(floGlobals.application, obs_a),
|
compactIDB.initDB(DEFAULT.application, obs_a),
|
||||||
compactIDB.initDB("floDapps", obs_g)
|
compactIDB.initDB(DEFAULT.root, obs_g)
|
||||||
]).then(result => {
|
]).then(result => {
|
||||||
compactIDB.setDefaultDB(floGlobals.application)
|
compactIDB.setDefaultDB(DEFAULT.application)
|
||||||
resolve("IndexedDB App Storage Initated Successfully")
|
resolve("IndexedDB App Storage Initated Successfully")
|
||||||
}).catch(error => reject(error));
|
}).catch(error => reject(error));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function initUserDB(floID) {
|
function initUserDB() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
var obs = {
|
var obs = {
|
||||||
contacts: {},
|
contacts: {},
|
||||||
pubKeys: {},
|
pubKeys: {},
|
||||||
messages: {}
|
messages: {}
|
||||||
}
|
}
|
||||||
compactIDB.initDB(`floDapps#${floID}`, obs).then(result => {
|
compactIDB.initDB(user.db_name, obs).then(result => {
|
||||||
resolve("UserDB Initated Successfully")
|
resolve("UserDB Initated Successfully")
|
||||||
}).catch(error => reject('Init userDB failed'));
|
}).catch(error => reject('Init userDB failed'));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadUserDB(floID) {
|
function loadUserDB() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
var loadData = ["contacts", "pubKeys", "messages"]
|
var loadData = ["contacts", "pubKeys", "messages"]
|
||||||
var promises = []
|
var promises = []
|
||||||
for (var i = 0; i < loadData.length; i++)
|
for (var i = 0; i < loadData.length; i++)
|
||||||
promises[i] = compactIDB.readAllData(loadData[i], `floDapps#${floID}`)
|
promises[i] = compactIDB.readAllData(loadData[i], user.db_name)
|
||||||
Promise.all(promises).then(results => {
|
Promise.all(promises).then(results => {
|
||||||
for (var i = 0; i < loadData.length; i++)
|
for (var i = 0; i < loadData.length; i++)
|
||||||
floGlobals[loadData[i]] = results[i]
|
user[loadData[i]] = results[i]
|
||||||
resolve("Loaded Data from userDB")
|
resolve("Loaded Data from userDB")
|
||||||
}).catch(error => reject('Load userDB failed'))
|
}).catch(error => reject('Load userDB failed'))
|
||||||
})
|
})
|
||||||
@ -72,7 +152,7 @@
|
|||||||
|
|
||||||
startUpFunctions.push(function readSupernodeListFromAPI() {
|
startUpFunctions.push(function readSupernodeListFromAPI() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
compactIDB.readData("lastTx", floCloudAPI.SNStorageID, "floDapps").then(lastTx => {
|
compactIDB.readData("lastTx", floCloudAPI.SNStorageID, DEFAULT.root).then(lastTx => {
|
||||||
floBlockchainAPI.readData(floCloudAPI.SNStorageID, {
|
floBlockchainAPI.readData(floCloudAPI.SNStorageID, {
|
||||||
ignoreOld: lastTx,
|
ignoreOld: lastTx,
|
||||||
sentOnly: true,
|
sentOnly: true,
|
||||||
@ -81,12 +161,12 @@
|
|||||||
for (var i = result.data.length - 1; i >= 0; i--) {
|
for (var i = result.data.length - 1; i >= 0; i--) {
|
||||||
var content = JSON.parse(result.data[i]).SuperNodeStorage;
|
var content = JSON.parse(result.data[i]).SuperNodeStorage;
|
||||||
for (sn in content.removeNodes)
|
for (sn in content.removeNodes)
|
||||||
compactIDB.removeData("supernodes", sn, "floDapps");
|
compactIDB.removeData("supernodes", sn, DEFAULT.root);
|
||||||
for (sn in content.newNodes)
|
for (sn in content.newNodes)
|
||||||
compactIDB.writeData("supernodes", content.newNodes[sn], sn, "floDapps");
|
compactIDB.writeData("supernodes", content.newNodes[sn], sn, DEFAULT.root);
|
||||||
}
|
}
|
||||||
compactIDB.writeData("lastTx", result.totalTxs, floCloudAPI.SNStorageID, "floDapps");
|
compactIDB.writeData("lastTx", result.totalTxs, floCloudAPI.SNStorageID, DEFAULT.root);
|
||||||
compactIDB.readAllData("supernodes", "floDapps").then(result => {
|
compactIDB.readAllData("supernodes", DEFAULT.root).then(result => {
|
||||||
floCloudAPI.init(result)
|
floCloudAPI.init(result)
|
||||||
.then(result => resolve("Loaded Supernode list\n" + result))
|
.then(result => resolve("Loaded Supernode list\n" + result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
@ -98,14 +178,14 @@
|
|||||||
|
|
||||||
startUpFunctions.push(function readAppConfigFromAPI() {
|
startUpFunctions.push(function readAppConfigFromAPI() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
compactIDB.readData("lastTx", `${floGlobals.application}|${floGlobals.adminID}`, "floDapps").then(lastTx => {
|
compactIDB.readData("lastTx", `${DEFAULT.application}|${DEFAULT.adminID}`, DEFAULT.root).then(lastTx => {
|
||||||
floBlockchainAPI.readData(floGlobals.adminID, {
|
floBlockchainAPI.readData(DEFAULT.adminID, {
|
||||||
ignoreOld: lastTx,
|
ignoreOld: lastTx,
|
||||||
sentOnly: true,
|
sentOnly: true,
|
||||||
pattern: floGlobals.application
|
pattern: DEFAULT.application
|
||||||
}).then(result => {
|
}).then(result => {
|
||||||
for (var i = result.data.length - 1; i >= 0; i--) {
|
for (var i = result.data.length - 1; i >= 0; i--) {
|
||||||
var content = JSON.parse(result.data[i])[floGlobals.application];
|
var content = JSON.parse(result.data[i])[DEFAULT.application];
|
||||||
if (!content || typeof content !== "object")
|
if (!content || typeof content !== "object")
|
||||||
continue;
|
continue;
|
||||||
if (Array.isArray(content.removeSubAdmin))
|
if (Array.isArray(content.removeSubAdmin))
|
||||||
@ -118,11 +198,11 @@
|
|||||||
for (let l in content.settings)
|
for (let l in content.settings)
|
||||||
compactIDB.writeData("settings", content.settings[l], l)
|
compactIDB.writeData("settings", content.settings[l], l)
|
||||||
}
|
}
|
||||||
compactIDB.writeData("lastTx", result.totalTxs, `${floGlobals.application}|${floGlobals.adminID}`, "floDapps");
|
compactIDB.writeData("lastTx", result.totalTxs, `${DEFAULT.application}|${DEFAULT.adminID}`, DEFAULT.root);
|
||||||
compactIDB.readAllData("subAdmins").then(result => {
|
compactIDB.readAllData("subAdmins").then(result => {
|
||||||
floGlobals.subAdmins = Object.keys(result);
|
subAdmins = Object.keys(result);
|
||||||
compactIDB.readAllData("settings").then(result => {
|
compactIDB.readAllData("settings").then(result => {
|
||||||
floGlobals.settings = result;
|
settings = result;
|
||||||
resolve("Read app configuration from blockchain");
|
resolve("Read app configuration from blockchain");
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -153,7 +233,7 @@
|
|||||||
resolve(inputVal)
|
resolve(inputVal)
|
||||||
});
|
});
|
||||||
|
|
||||||
function getCredentials() {
|
function getCredentials(invisible_key) {
|
||||||
|
|
||||||
const readSharesFromIDB = indexArr => new Promise((resolve, reject) => {
|
const readSharesFromIDB = indexArr => new Promise((resolve, reject) => {
|
||||||
var promises = []
|
var promises = []
|
||||||
@ -186,7 +266,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
const getPrivateKeyCredentials = () => new Promise((resolve, reject) => {
|
const getPrivateKeyCredentials = () => new Promise((resolve, reject) => {
|
||||||
var indexArr = localStorage.getItem(`${floGlobals.application}#privKey`)
|
var indexArr = localStorage.getItem(`${DEFAULT.application}#privKey`)
|
||||||
if (indexArr) {
|
if (indexArr) {
|
||||||
readSharesFromIDB(JSON.parse(indexArr))
|
readSharesFromIDB(JSON.parse(indexArr))
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
@ -210,7 +290,7 @@
|
|||||||
var shares = floCrypto.createShamirsSecretShares(privKey, threshold, threshold)
|
var shares = floCrypto.createShamirsSecretShares(privKey, threshold, threshold)
|
||||||
writeSharesToIDB(shares).then(resultIndexes => {
|
writeSharesToIDB(shares).then(resultIndexes => {
|
||||||
//store index keys in localStorage
|
//store index keys in localStorage
|
||||||
localStorage.setItem(`${floGlobals.application}#privKey`, JSON.stringify(resultIndexes))
|
localStorage.setItem(`${DEFAULT.application}#privKey`, JSON.stringify(resultIndexes))
|
||||||
//also add a dummy privatekey to the IDB
|
//also add a dummy privatekey to the IDB
|
||||||
var randomPrivKey = floCrypto.generateNewID().privKey
|
var randomPrivKey = floCrypto.generateNewID().privKey
|
||||||
var randomThreshold = floCrypto.randInt(10, 20)
|
var randomThreshold = floCrypto.randInt(10, 20)
|
||||||
@ -242,9 +322,13 @@
|
|||||||
getPrivateKeyCredentials().then(key => {
|
getPrivateKeyCredentials().then(key => {
|
||||||
checkIfPinRequired(key).then(privKey => {
|
checkIfPinRequired(key).then(privKey => {
|
||||||
try {
|
try {
|
||||||
myPrivKey = privKey
|
user_public = floCrypto.getPubKeyHex(privKey);
|
||||||
myPubKey = floCrypto.getPubKeyHex(myPrivKey)
|
user_id = floCrypto.getFloID(privKey);
|
||||||
myFloID = floCrypto.getFloID(myPubKey)
|
floCloudAPI.user = privKey; //Set user for floCloudAPI
|
||||||
|
if (!invisible_key)
|
||||||
|
user_private = privKey;
|
||||||
|
else
|
||||||
|
user_private = () => checkIfPinRequired(key);
|
||||||
resolve('Login Credentials loaded successful')
|
resolve('Login Credentials loaded successful')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
@ -289,7 +373,7 @@
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
floDapps.launchStartUp = function() {
|
floDapps.launchStartUp = function(options = {}) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
initIndexedDB().then(log => {
|
initIndexedDB().then(log => {
|
||||||
console.log(log)
|
console.log(log)
|
||||||
@ -304,9 +388,9 @@
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
let p2 = new Promise((res, rej) => {
|
let p2 = new Promise((res, rej) => {
|
||||||
callAndLog(getCredentials()).then(r => {
|
callAndLog(getCredentials(options.invisible_key)).then(r => {
|
||||||
callAndLog(initUserDB(myFloID)).then(r => {
|
callAndLog(initUserDB()).then(r => {
|
||||||
callAndLog(loadUserDB(myFloID))
|
callAndLog(loadUserDB())
|
||||||
.then(r => res(true))
|
.then(r => res(true))
|
||||||
.catch(e => rej(false))
|
.catch(e => rej(false))
|
||||||
}).catch(e => rej(false))
|
}).catch(e => rej(false))
|
||||||
@ -333,8 +417,8 @@
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!floCrypto.validateAddr(floID))
|
if (!floCrypto.validateAddr(floID))
|
||||||
return reject("Invalid floID!")
|
return reject("Invalid floID!")
|
||||||
compactIDB.writeData("contacts", name, floID, `floDapps#${myFloID}`).then(result => {
|
compactIDB.writeData("contacts", name, floID, user.db_name).then(result => {
|
||||||
floGlobals.contacts[floID] = name;
|
user.contacts[floID] = name;
|
||||||
resolve("Contact stored")
|
resolve("Contact stored")
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
});
|
});
|
||||||
@ -342,14 +426,14 @@
|
|||||||
|
|
||||||
floDapps.storePubKey = function(floID, pubKey) {
|
floDapps.storePubKey = function(floID, pubKey) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (floID in floGlobals.pubKeys)
|
if (floID in user.pubKeys)
|
||||||
return resolve("pubKey already stored")
|
return resolve("pubKey already stored")
|
||||||
if (!floCrypto.validateAddr(floID))
|
if (!floCrypto.validateAddr(floID))
|
||||||
return reject("Invalid floID!")
|
return reject("Invalid floID!")
|
||||||
if (floCrypto.getFloID(pubKey) != floID)
|
if (floCrypto.getFloID(pubKey) != floID)
|
||||||
return reject("Incorrect pubKey")
|
return reject("Incorrect pubKey")
|
||||||
compactIDB.writeData("pubKeys", pubKey, floID, `floDapps#${myFloID}`).then(result => {
|
compactIDB.writeData("pubKeys", pubKey, floID, user.db_name).then(result => {
|
||||||
floGlobals.pubKeys[floID] = pubKey;
|
user.pubKeys[floID] = pubKey;
|
||||||
resolve("pubKey stored")
|
resolve("pubKey stored")
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
});
|
});
|
||||||
@ -359,11 +443,11 @@
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let options = {
|
let options = {
|
||||||
receiverID: floID,
|
receiverID: floID,
|
||||||
application: "floDapps",
|
application: DEFAULT.root,
|
||||||
comment: floGlobals.application
|
comment: DEFAULT.application
|
||||||
}
|
}
|
||||||
if (floID in floGlobals.pubKeys)
|
if (floID in user.pubKeys)
|
||||||
message = floCrypto.encryptData(JSON.stringify(message), floGlobals.pubKeys[floID])
|
message = floCrypto.encryptData(JSON.stringify(message), user.pubKeys[floID])
|
||||||
floCloudAPI.sendApplicationData(message, "Message", options)
|
floCloudAPI.sendApplicationData(message, "Message", options)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
@ -372,20 +456,21 @@
|
|||||||
|
|
||||||
floDapps.requestInbox = function(callback) {
|
floDapps.requestInbox = function(callback) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let lastVC = Object.keys(floGlobals.messages).sort().pop()
|
let lastVC = Object.keys(user.messages).sort().pop()
|
||||||
let options = {
|
let options = {
|
||||||
receiverID: myFloID,
|
receiverID: user.id,
|
||||||
application: "floDapps",
|
application: DEFAULT.root,
|
||||||
lowerVectorClock: lastVC + 1
|
lowerVectorClock: lastVC + 1
|
||||||
}
|
}
|
||||||
|
let privKey = raw_user.private;
|
||||||
options.callback = (d, e) => {
|
options.callback = (d, e) => {
|
||||||
for (let v in d) {
|
for (let v in d) {
|
||||||
try {
|
try {
|
||||||
if (d[v].message instanceof Object && "secret" in d[v].message)
|
if (d[v].message instanceof Object && "secret" in d[v].message)
|
||||||
d[v].message = floCrypto.decryptData(d[v].message, myPrivKey)
|
d[v].message = floCrypto.decryptData(d[v].message, privKey)
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
compactIDB.writeData("messages", d[v], v, `floDapps#${myFloID}`)
|
compactIDB.writeData("messages", d[v], v, user.db_name)
|
||||||
floGlobals.messages[v] = d[v]
|
user.messages[v] = d[v]
|
||||||
}
|
}
|
||||||
if (callback instanceof Function)
|
if (callback instanceof Function)
|
||||||
callback(d, e)
|
callback(d, e)
|
||||||
@ -404,14 +489,14 @@
|
|||||||
if (!addList && !rmList && !settings)
|
if (!addList && !rmList && !settings)
|
||||||
return reject("No configuration change")
|
return reject("No configuration change")
|
||||||
var floData = {
|
var floData = {
|
||||||
[floGlobals.application]: {
|
[DEFAULT.application]: {
|
||||||
addSubAdmin: addList,
|
addSubAdmin: addList,
|
||||||
removeSubAdmin: rmList,
|
removeSubAdmin: rmList,
|
||||||
settings: settings
|
settings: settings
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var floID = floCrypto.getFloID(adminPrivKey)
|
var floID = floCrypto.getFloID(adminPrivKey)
|
||||||
if (floID != floGlobals.adminID)
|
if (floID != DEFAULT.adminID)
|
||||||
reject('Access Denied for Admin privilege')
|
reject('Access Denied for Admin privilege')
|
||||||
else
|
else
|
||||||
floBlockchainAPI.writeData(floID, JSON.stringify(floData), adminPrivKey)
|
floBlockchainAPI.writeData(floID, JSON.stringify(floData), adminPrivKey)
|
||||||
@ -422,9 +507,9 @@
|
|||||||
|
|
||||||
const clearCredentials = floDapps.clearCredentials = function() {
|
const clearCredentials = floDapps.clearCredentials = function() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
compactIDB.clearData('credentials', floGlobals.application).then(result => {
|
compactIDB.clearData('credentials', DEFAULT.application).then(result => {
|
||||||
localStorage.removeItem(`${floGlobals.application}#privKey`)
|
localStorage.removeItem(`${DEFAULT.application}#privKey`);
|
||||||
myPrivKey = myPubKey = myFloID = undefined;
|
user.clear();
|
||||||
resolve("privKey credentials deleted!")
|
resolve("privKey credentials deleted!")
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
})
|
})
|
||||||
@ -433,7 +518,7 @@
|
|||||||
floDapps.deleteUserData = function(credentials = false) {
|
floDapps.deleteUserData = function(credentials = false) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let p = []
|
let p = []
|
||||||
p.push(compactIDB.deleteDB(`floDapps#${myFloID}`))
|
p.push(compactIDB.deleteDB(user.db_name))
|
||||||
if (credentials)
|
if (credentials)
|
||||||
p.push(clearCredentials())
|
p.push(clearCredentials())
|
||||||
Promise.all(p)
|
Promise.all(p)
|
||||||
@ -444,10 +529,10 @@
|
|||||||
|
|
||||||
floDapps.deleteAppData = function() {
|
floDapps.deleteAppData = function() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
compactIDB.deleteDB(floGlobals.application).then(result => {
|
compactIDB.deleteDB(DEFAULT.application).then(result => {
|
||||||
localStorage.removeItem(`${floGlobals.application}#privKey`)
|
localStorage.removeItem(`${DEFAULT.application}#privKey`)
|
||||||
myPrivKey = myPubKey = myFloID = undefined;
|
user.clear();
|
||||||
compactIDB.removeData('lastTx', `${floGlobals.application}|${floGlobals.adminID}`, 'floDapps')
|
compactIDB.removeData('lastTx', `${DEFAULT.application}|${DEFAULT.adminID}`, DEFAULT.root)
|
||||||
.then(result => resolve("App database(local) deleted"))
|
.then(result => resolve("App database(local) deleted"))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
@ -455,17 +540,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
floDapps.securePrivKey = function(pwd) {
|
floDapps.securePrivKey = function(pwd) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
let indexArr = localStorage.getItem(`${floGlobals.application}#privKey`)
|
let indexArr = localStorage.getItem(`${DEFAULT.application}#privKey`)
|
||||||
if (!indexArr)
|
if (!indexArr)
|
||||||
return reject("PrivKey not found");
|
return reject("PrivKey not found");
|
||||||
indexArr = JSON.parse(indexArr)
|
indexArr = JSON.parse(indexArr)
|
||||||
let encryptedKey = Crypto.AES.encrypt(myPrivKey, pwd);
|
let encryptedKey = Crypto.AES.encrypt(await user.private, pwd);
|
||||||
let threshold = indexArr.length;
|
let threshold = indexArr.length;
|
||||||
let shares = floCrypto.createShamirsSecretShares(encryptedKey, threshold, threshold)
|
let shares = floCrypto.createShamirsSecretShares(encryptedKey, threshold, threshold)
|
||||||
let promises = [];
|
let promises = [];
|
||||||
let overwriteFn = (share, index) =>
|
let overwriteFn = (share, index) =>
|
||||||
compactIDB.writeData("credentials", share, index, floGlobals.application);
|
compactIDB.writeData("credentials", share, index, DEFAULT.application);
|
||||||
for (var i = 0; i < threshold; i++)
|
for (var i = 0; i < threshold; i++)
|
||||||
promises.push(overwriteFn(shares[i], indexArr[i]));
|
promises.push(overwriteFn(shares[i], indexArr[i]));
|
||||||
Promise.all(promises)
|
Promise.all(promises)
|
||||||
@ -494,7 +579,7 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
var indexArr = localStorage.getItem(`${floGlobals.application}#privKey`)
|
var indexArr = localStorage.getItem(`${DEFAULT.application}#privKey`)
|
||||||
console.info(indexArr)
|
console.info(indexArr)
|
||||||
if (!indexArr)
|
if (!indexArr)
|
||||||
reject('No login credentials found')
|
reject('No login credentials found')
|
||||||
@ -535,7 +620,7 @@
|
|||||||
filteredResult[d] = JSON.parse(JSON.stringify(floGlobals.generalData[fk][d]))
|
filteredResult[d] = JSON.parse(JSON.stringify(floGlobals.generalData[fk][d]))
|
||||||
}
|
}
|
||||||
if (options.decrypt) {
|
if (options.decrypt) {
|
||||||
let decryptionKey = (options.decrypt === true) ? myPrivKey : options.decrypt;
|
let decryptionKey = (options.decrypt === true) ? raw_user.private : options.decrypt;
|
||||||
if (!Array.isArray(decryptionKey))
|
if (!Array.isArray(decryptionKey))
|
||||||
decryptionKey = [decryptionKey];
|
decryptionKey = [decryptionKey];
|
||||||
for (let f in filteredResult) {
|
for (let f in filteredResult) {
|
||||||
@ -561,14 +646,14 @@
|
|||||||
|
|
||||||
syncData.oldDevice = () => new Promise((resolve, reject) => {
|
syncData.oldDevice = () => new Promise((resolve, reject) => {
|
||||||
let sync = {
|
let sync = {
|
||||||
contacts: floGlobals.contacts,
|
contacts: user.contacts,
|
||||||
pubKeys: floGlobals.pubKeys,
|
pubKeys: user.pubKeys,
|
||||||
messages: floGlobals.messages
|
messages: user.messages
|
||||||
}
|
}
|
||||||
let message = Crypto.AES.encrypt(JSON.stringify(sync), myPrivKey)
|
let message = Crypto.AES.encrypt(JSON.stringify(sync), raw_user.private)
|
||||||
let options = {
|
let options = {
|
||||||
receiverID: myFloID,
|
receiverID: user.id,
|
||||||
application: "floDapps"
|
application: DEFAULT.root
|
||||||
}
|
}
|
||||||
floCloudAPI.sendApplicationData(message, "syncData", options)
|
floCloudAPI.sendApplicationData(message, "syncData", options)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
@ -577,20 +662,20 @@
|
|||||||
|
|
||||||
syncData.newDevice = () => new Promise((resolve, reject) => {
|
syncData.newDevice = () => new Promise((resolve, reject) => {
|
||||||
var options = {
|
var options = {
|
||||||
receiverID: myFloID,
|
receiverID: user.id,
|
||||||
senderID: myFloID,
|
senderID: user.id,
|
||||||
application: "floDapps",
|
application: DEFAULT.root,
|
||||||
mostRecent: true,
|
mostRecent: true,
|
||||||
}
|
}
|
||||||
floCloudAPI.requestApplicationData("syncData", options).then(response => {
|
floCloudAPI.requestApplicationData("syncData", options).then(response => {
|
||||||
let vc = Object.keys(response).sort().pop()
|
let vc = Object.keys(response).sort().pop()
|
||||||
let sync = JSON.parse(Crypto.AES.decrypt(response[vc].message, myPrivKey))
|
let sync = JSON.parse(Crypto.AES.decrypt(response[vc].message, raw_user.private))
|
||||||
let promises = []
|
let promises = []
|
||||||
let store = (key, val, obs) => promises.push(compactIDB.writeData(obs, val, key, `floDapps#${floID}`));
|
let store = (key, val, obs) => promises.push(compactIDB.writeData(obs, val, key, user.db_name));
|
||||||
["contacts", "pubKeys", "messages"].forEach(c => {
|
["contacts", "pubKeys", "messages"].forEach(c => {
|
||||||
for (let i in sync[c]) {
|
for (let i in sync[c]) {
|
||||||
store(i, sync[c][i], c)
|
store(i, sync[c][i], c)
|
||||||
floGlobals[c][i] = sync[c][i]
|
user[c][i] = sync[c][i]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
Promise.all(promises)
|
Promise.all(promises)
|
||||||
|
|||||||
@ -24,8 +24,7 @@
|
|||||||
//floDapps.addStartUpFunction('Sample', Promised Function)
|
//floDapps.addStartUpFunction('Sample', Promised Function)
|
||||||
//floDapps.setAppObjectStores({sampleObs1:{}, sampleObs2:{options{autoIncrement:true, keyPath:'SampleKey'}, Indexes:{sampleIndex:{}}}})
|
//floDapps.setAppObjectStores({sampleObs1:{}, sampleObs2:{options{autoIncrement:true, keyPath:'SampleKey'}, Indexes:{sampleIndex:{}}}})
|
||||||
//floDapps.setCustomPrivKeyInput( () => { FUNCTION BODY *must resolve private key* } )
|
//floDapps.setCustomPrivKeyInput( () => { FUNCTION BODY *must resolve private key* } )
|
||||||
|
floDapps.launchStartUp( /*{invisible_key: true}*/ ).then(result => {
|
||||||
floDapps.launchStartUp().then(result => {
|
|
||||||
console.log(result)
|
console.log(result)
|
||||||
alert(`Welcome FLO_ID: ${myFloID}`)
|
alert(`Welcome FLO_ID: ${myFloID}`)
|
||||||
//App functions....
|
//App functions....
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user