Instantly share code, notes, and snippets.
Last active
January 28, 2021 09:14
-
Star
(4)
4
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save Lightnet/f7285e06abb08337fcaeed27af267a03 to your computer and use it in GitHub Desktop.
gunjstrustsharekeyv3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Self contain Sandbox Gun Module chain for auth sea.js: | |
Created by: Lightnet | |
License: MIT | |
Version: 3.0 | |
Last Update:2019.08.17 | |
Credit: amark ( https://github.com/amark/gun) | |
Status(Work in progress!): | |
* Working on trust public key will conflict with share key functions! | |
* Work in progress to test dis/trust public key. | |
* encryptput not working to...get(...).encryptput() NO! Mismatched owner on 'ct'. | |
Information: This is addon chain to sea.js for user to test functions of acess write and read | |
in encryption. It is base on sea.js user functions that is current not improve yet. | |
Gun functions: | |
* trustkey(to, cb, opt) - writable: allow, public key (wip) | |
* distrustkey(to, cb, opt) - writable: denied, public key (wip) | |
* grantkey(to, cb, opt) - readable: allow, share key (working for user root) | |
* revokekey(to, cb, opt) - readable: denied, share key (working for user root / wip trust key) | |
* encryptput(data, cb, opt) - encrypt: value (working for user root / wip trust key) | |
* decryptonce( cb, opt) - decrypt: value (working for user root / wip trust key) | |
dis/trustkey: | |
The owner user key graph to dis/allow for other users write access of the value or data. | |
The writable key user public key is store in put(data | value) | |
Example: | |
gun.get('namespace').get('foo').put({SEA{ct:"",iv:"",s:""},~@publickey1,~@publickey2}); //does not work | |
Example put:(wip might not work) | |
* sea: "SEA{ct: "...",iv: "...",s: "..."}}" | |
* ~@publickey1:{'#': ~@publickey1} | |
* ~@publickey2:{'#': ~@publickey2} | |
* _:{...} | |
To create public key map list that is to need encrypt data and then alias list. | |
Note: | |
* This part of sea.js function security call/filter check for sea key and alias public keys. | |
* This base on understanding of security node checks. | |
grantkey/revokekey: | |
To able to dis/allow user share key access to read data. The share key are store in user trust map key and path. | |
Gun Notes: | |
* sea.js and gun.js are buggy with auth checks. | |
* There is a bug in gun.user('publickey') will return as gun not user object. | |
*/ | |
(function() { | |
var Gun = (typeof window !== "undefined")? window.Gun : require('gun/gun'); | |
Gun.on('opt', function(context) { | |
context.opt.sharekeydebug = true; | |
context.opt.sharekeyvalue = 'value'; | |
context.opt.sharekeytrust = 'trust'; | |
context.opt.sharekeybbase = true; //btoa, atob //base64 ecode and decode | |
this.to.next(context); | |
}); | |
function trustlist(cb, opt){ | |
console.log("`.trustlist` PROTOTYPE API DO NOT USE, TESTING!"); | |
cb = cb || function(ctx) { return ctx }; | |
opt = opt || {}; | |
let gun = this, user = gun.back(-1).user(), pair = user._.sea, path = ''; | |
gun.back(function(at){ if(at.is){ return } path += (at.get||'') }); | |
let sharetype; | |
if (gun._.$ instanceof Gun.User){//check gun node is user object | |
sharetype = "user"; | |
}else{ | |
sharetype = "gun"; | |
} | |
(async function(){ | |
//make sure that user root | |
if(sharetype == "user"){ | |
let data = await gun.then(); | |
console.log(data); | |
} | |
//if(sharetype == "gun"){} | |
}()); | |
return gun; | |
} | |
function trustkey(to, cb, opt){ | |
console.log("`.trustkey` PROTOTYPE API MAY BE CHANGED OR RENAMED USE!"); | |
cb = cb || function(ctx) { return ctx }; | |
opt = opt || {}; | |
let gun = this, user = gun.back(-1).user(), pair = user._.sea, path = ''; | |
gun.back(function(at){ if(at.is){ return } path += (at.get||'') }); | |
//let debug = opt.debug || gun._.root.opt.sharekeydebug; | |
//let valueid = opt.valueid || gun._.root.opt.sharekeyvalue; | |
//let trustid = opt.trustid || gun._.root.opt.sharekeytrust; | |
//let bbase = opt.bbase || gun._.root.opt.sharekeybbase; | |
let sharetype; | |
if (gun._.$ instanceof Gun.User){//check gun node is user object | |
sharetype = "user"; | |
}else{ | |
sharetype = "gun"; | |
} | |
let each = {}; | |
(async function(){ | |
//make sure that user root | |
if(sharetype == "user"){ | |
//console.log(gun); | |
//sea.js | |
//line 792 | |
//root.get(tmp = '~'+act.pair.pub).put(act.data); // awesome, now we can actually save the user with their public key as their ID. | |
//root.get('~@'+alias).put(Gun.obj.put({}, tmp, Gun.val.link.ify(tmp))); // next up, we want to associate the alias with the public key. So we add it to the alias list. | |
//let tmp = '~'+pair.pub; | |
//tmp = Gun.val.link.ify(tmp); | |
//tmp = Gun.obj.put({}, tmp, Gun.val.link.ify(tmp)); | |
//console.log(tmp); | |
let who = await to.get('alias').then(); | |
if(who!=null){ | |
console.log("FOUND!",who); | |
let pub = await to.get('pub').then(); | |
let sec = await gun.then(); | |
console.log(sec); | |
let tagalias = '~@'+who; | |
sec = Gun.obj.put(sec, tagalias, Gun.val.link.ify(tagalias)); | |
let tagpub = '~'+pub; | |
sec = Gun.obj.put(sec, tagpub, Gun.val.link.ify(tagpub)); | |
//Example: {_:#~asdf, hello:'world'~fdsa}} | |
gun.put(sec,cb); | |
} | |
console.log("done!"); | |
} | |
//if(sharetype == "gun"){} | |
}()); | |
return gun; | |
} | |
function distrustkey(to, cb, opt){ | |
console.log("`.distrustkey` PROTOTYPE API MAY BE CHANGED OR RENAMED USE!"); | |
cb = cb || function(ctx) { return ctx }; | |
opt = opt || {}; | |
let gun = this, user = gun.back(-1).user(), pair = user._.sea, path = ''; | |
gun.back(function(at){ if(at.is){ return } path += (at.get||'') }); | |
let debug = opt.debug || gun._.root.opt.sharekeydebug; | |
let valueid = opt.valueid || gun._.root.opt.sharekeyvalue; | |
let trustid = opt.trustid || gun._.root.opt.sharekeytrust; | |
let bbase = opt.bbase || gun._.root.opt.sharekeybbase; | |
let sharetype; | |
if (gun._.$ instanceof Gun.User){//check gun node is user object | |
sharetype = "user"; | |
}else{ | |
sharetype = "gun"; | |
} | |
let each = {}; | |
(async function(){ | |
if(sharetype == "user"){ | |
let who = await to.get('alias').then(); | |
if(who!=null){ | |
console.log("FOUND!",who); | |
let pub = await to.get('pub').then(); | |
let enc1 = await gun.then();//value | |
let tagpub = "~@"+pub;//PUBLIC KEY MATCH FOR DISTRUST LIST | |
//ENC VALUE AND ALIAS KEYS | |
let sec = await user.get('trust').get(pair.pub).get(path).then(); | |
sec = await SEA.decrypt(sec, pair); | |
//console.log(sec); | |
//DECRYPT VALUE | |
let gvalue = await SEA.decrypt(enc1, sec); | |
gun.put(gvalue, cb);//reset to clear map list else it will not revoke public key | |
//console.log(value); | |
//ENCRYPT VALUE | |
gvalue = await SEA.encrypt(gvalue, sec); | |
//console.log(typeof value); | |
if((typeof gvalue != 'object') && ("SEA" == gvalue.slice(0,3)) ){ | |
//console.log('FOUND!'); | |
gvalue = gvalue.substring(3, gvalue.length); | |
gvalue = JSON.parse(gvalue) | |
//console.log(enc); | |
} | |
let tmpp=gvalue;//json object | |
for(o in enc1){ | |
if("~@" == o.slice(0,2)){//check if public key tag | |
let tmppub = o; | |
if(tmppub == tagpub){//revoke to skip public key | |
//console.log("FOUND REVOKE!"); | |
}else{ | |
tmpp = Gun.obj.put(tmpp, tmppub, Gun.val.link.ify(tmppub)) | |
} | |
} | |
} | |
//console.log(tmpp); | |
gun.put(tmpp, cb); | |
} | |
} | |
if(sharetype == "gun"){ | |
} | |
}()); | |
return gun; | |
} | |
function grantkey(to, cb, opt){ | |
console.log("`.grantkey` PROTOTYPE API MAY BE CHANGED OR RENAMED USE!"); | |
cb = cb || function(ctx) { return ctx }; | |
opt = opt || {}; | |
let gun = this, user = gun.back(-1).user(), pair = user._.sea, path = ''; | |
gun.back(function(at){ if(at.is){ return } path += (at.get||'') }); | |
//let debug = opt.debug || gun._.root.opt.sharekeydebug; | |
//let valueid = opt.valueid || gun._.root.opt.sharekeyvalue; | |
//let trustid = opt.trustid || gun._.root.opt.sharekeytrust; | |
//let bbase = opt.bbase || gun._.root.opt.sharekeybbase; | |
let sharetype; | |
if (gun._.$ instanceof Gun.User){//check gun node is user object | |
sharetype = "user"; | |
}else{ | |
sharetype = "gun"; | |
} | |
(async function(){ | |
if(sharetype == "user"){ | |
let enc, sec = await user.get('trust').get(pair.pub).get(path).then(); | |
sec = await SEA.decrypt(sec, pair); | |
if(!sec){ | |
sec = SEA.random(16).toString(); | |
//sec = Gun.text.random(16); | |
enc = await SEA.encrypt(sec, pair); | |
user.get('trust').get(pair.pub).get(path).put(enc); | |
} | |
let pub = await to.get('pub').then(); | |
let epub = await to.get('epub').then(); | |
pub = await pub; epub = await epub; | |
let dh = await SEA.secret(epub, pair); | |
enc = await SEA.encrypt(sec, dh); | |
user.get('trust').get(pub).get(path).put(enc, cb); | |
} | |
}()); | |
return gun; | |
} | |
function revokekey(to, cb, opt){ | |
console.log("`.revokekey` PROTOTYPE API MAY BE CHANGED OR RENAMED USE!"); | |
cb = cb || function(ctx) { return ctx }; | |
opt = opt || {}; | |
let gun = this, user = gun.back(-1).user(), pair = user._.sea, path = ''; | |
gun.back(function(at){ if(at.is){ return } path += (at.get||'') }); | |
//let debug = opt.debug || gun._.root.opt.sharekeydebug; | |
//let valueid = opt.valueid || gun._.root.opt.sharekeyvalue; | |
//let trustid = opt.trustid || gun._.root.opt.sharekeytrust; | |
//let bbase = opt.bbase || gun._.root.opt.sharekeybbase; | |
let sharetype; | |
if (gun._.$ instanceof Gun.User){//check gun node is user object | |
sharetype = "user"; | |
}else{ | |
sharetype = "gun"; | |
} | |
(async function(){ | |
if(sharetype == "user"){ | |
let alias = await to.get("alias").then(); | |
if(!alias){ | |
cb({err:'Error alias not found!'}); | |
return gun; | |
} | |
let enc, sec; | |
sec = await user.get('trust').get(pair.pub).get(path).then(); | |
sec = await SEA.decrypt(sec, pair); | |
let key = await gun.once().then(); | |
//GET VALUE | |
let value = await SEA.decrypt(key, sec); | |
// CREATE SHARE KEY | |
sec = SEA.random(16).toString(); | |
//sec = Gun.text.random(16); | |
enc = await SEA.encrypt(sec, pair); | |
//ENCRYPT KEY | |
user.get('trust').get(pair.pub).get(path).put(enc); | |
let pub = await to.get('pub').then(); | |
console.log("pub",pub); | |
console.log("path: ",path) | |
user.get('trust').once().map().once(async (data,mkey)=>{//trust users | |
//console.log(data) | |
//let p = await user.get('trust').get(mkey).then(); | |
//console.log(p) | |
let uname; | |
uname = await gun.back(-1).user(mkey).get('alias').then(); | |
//console.log("mkey",mkey); | |
uname = await gun.back(-1).user(mkey).get('alias').then(); | |
if(pair.pub != mkey){//check self user to be resalt | |
if(pub == mkey){ //check user to be revoke | |
//do nothing??? (revoke user) | |
console.log(uname, "REVOKE USER!"); | |
}else{ | |
console.log(uname, "PASS"); | |
//let op = await user.get('trust').get(mkey).then(); | |
//for (var p in op) { | |
//console.log(p); | |
//} | |
let ckey = await user.get('trust').get(mkey).get(path).then(); | |
if(ckey != "null"){//Check if there user are revoke key if they are null should be ignore. | |
//console.log(uname, "CREATE NEW SALT SHARE KEY "); | |
let mto = gun.back(-1).user(mkey); | |
let mpub = await mto.get('pub').then(); | |
let mepub = await mto.get('epub').then(); | |
let dh = await SEA.secret(mepub, pair); | |
let menc = await SEA.encrypt(sec, dh); | |
//NEW SALT KEY | |
//console.log( uname,"NEW SHARE KEY: ",menc); | |
user.get('trust').get(mpub).get(path).put(menc); | |
} | |
} | |
} | |
}); | |
//ENCRYPT VALUE | |
let v = await SEA.encrypt(value, sec); | |
gun.put(v, cb); | |
// Remove Salt Key | |
//let pub = await to.get('pub').then(); | |
user.get('trust').get(pub).get(path).put("null", cb);//remove key | |
} | |
}()); | |
return gun; | |
} | |
function encryptput(data, cb, opt){ | |
console.log("`.encryptput` PROTOTYPE API MAY BE CHANGED OR RENAMED USE!"); | |
cb = cb || function(ctx) { return ctx }; | |
opt = opt || {}; | |
let gun = this, user = gun.back(-1).user(), pair = user._.sea, path = ''; | |
gun.back(function(at){ if(at.is){ return } path += (at.get||'') }); | |
//let debug = opt.debug || gun._.root.opt.sharekeydebug; | |
//let valueid = opt.valueid || gun._.root.opt.sharekeyvalue; | |
//let trustid = opt.trustid || gun._.root.opt.sharekeytrust; | |
//let bbase = opt.bbase || gun._.root.opt.sharekeybbase; | |
let sharetype; | |
if (gun._.$ instanceof Gun.User){//check gun node is user object | |
sharetype = "user"; | |
}else{ | |
sharetype = "gun"; | |
} | |
(async function(){ | |
let enc, sec; | |
if(sharetype == "user"){ | |
sec = await user.get('trust').get(pair.pub).get(path).then(); | |
sec = await SEA.decrypt(sec, pair); | |
//console.log(sec); | |
if(!sec){ | |
console.log("CREATE SHARE KEY!"); | |
sec = SEA.random(16).toString(); | |
//sec = Gun.text.random(16); | |
enc = await SEA.encrypt(sec, pair); | |
user.get('trust').get(pair.pub).get(path).put(enc); | |
} | |
enc = await SEA.encrypt(data, sec); | |
let enc2 = await gun.then(); | |
// value enc and public keys from current gun graph | |
//need to be convert into array not string 'SEA{...}' > {...} | |
let tmpp=enc;//json object | |
//tmpp= | |
for(o in enc2){ | |
if("~" == o.slice(0,1)){ | |
console.log("FOUND PUB KEY"); | |
let tmppub = o; | |
//console.log(tmppub); | |
tmpp = Gun.obj.put(tmpp, tmppub, Gun.val.link.ify(tmppub)) | |
//console.log(tmpp); | |
} | |
} | |
gun.put(tmpp, cb); | |
//console.log("enc",enc); | |
//gun.put(enc, cb); | |
} | |
//if user is not root graph | |
if(sharetype == "gun"){ | |
let countmax = 10;//limit back to root loop | |
let root; | |
for(let i=0;i<countmax;i++){//look for user soul root from let to = gun.user('key'); | |
let tmp = gun.back(i);//loop to find user root | |
if(tmp._.soul){ | |
console.log("FOUND SOUL!"); | |
root = tmp; | |
break; | |
} | |
} | |
if(root !=null){ | |
let to = root;//user root graph | |
let enc1 = await to.get('trust').get(pair.pub).get(path).then(); | |
let epub = await to.get('epub').then(); | |
let mix = await SEA.secret(epub, pair); | |
let key = await SEA.decrypt(enc1, mix);//SECRET | |
//console.log(key); | |
//GET VALUE AND SHARE KEYS | |
let enc2 = await gun.then(); | |
console.log(enc2); | |
//ENCRYPT VALUE | |
let enc3 = await SEA.encrypt(data, key); | |
console.log(enc3); | |
let enc0 = enc3; | |
//enc0={alias:enc0+"~alias"}; | |
//enc0={alias:enc0}; | |
//let keylist = {}; | |
//console.log(user); | |
//list = Gun.obj.put(list, "~"+pair.pub, enc3+"~"+pair.pub); | |
//list = Gun.obj.put(list, "~@beta", enc3+"~"+pair.pub); | |
//list = Gun.obj.put(list, "~@beta", enc3+"~@beta"); | |
//list = Gun.obj.put(list, "alias", enc3+"~"+pair.pub);//nope | |
//enc0 = list; | |
if("SEA" == enc0.slice(0,3)){ | |
//console.log('FOUND!'); | |
enc0 = enc0.substring(3, enc0.length); | |
enc0 = JSON.parse(enc0) | |
} | |
console.log("enc0"); | |
console.log(enc0); | |
//let tmpp={}; | |
//let tmpp=enc0; | |
for(o in enc2){ | |
//if(o == "ct"){ | |
//tmpp[o] = enc0.ct; | |
//}else if (o == "iv"){//ignore | |
//tmpp[o] = enc0.iv; | |
//}else if(o == "s"){//ignore | |
//tmpp[o] = enc0.s; | |
//}] | |
if("~" == o.slice(0,1)){ | |
//console.log("FOUND PUB KEY"); | |
let tmppub = o; | |
//console.log(tmppub); | |
tmpp = Gun.obj.put(tmpp, tmppub, Gun.val.link.ify(tmppub)); | |
//console.log(tmpp); | |
} | |
} | |
console.log(enc0); | |
//enc0 = tmpp; | |
gun.put(enc0, cb); | |
//gun.put(enc, cb); | |
} | |
} | |
}()); | |
return gun; | |
} | |
function decryptonce( cb, opt){ | |
console.log("`.decryptonce` PROTOTYPE API MAY BE CHANGED OR RENAMED USE!"); | |
cb = cb || function(ctx) { return ctx }; | |
opt = opt || {}; | |
let gun = this, user = gun.back(-1).user(), pair = user._.sea, path = ''; | |
//console.log(user); | |
gun.back(function(at){ if(at.is){ return } path += (at.get||'') }); | |
//let debug = opt.debug || gun._.root.opt.sharekeydebug; | |
//let valueid = opt.valueid || gun._.root.opt.sharekeyvalue; | |
//let trustid = opt.trustid || gun._.root.opt.sharekeytrust; | |
//let bbase = opt.bbase || gun._.root.opt.sharekeybbase; | |
let sharetype; | |
if (gun._.$ instanceof Gun.User){//check gun node is user object | |
sharetype = "user"; | |
}else{ | |
sharetype = "gun"; | |
} | |
(async function(){ | |
//console.log(sharetype); | |
if(sharetype == "user"){ | |
let sec = await user.get('trust').get(pair.pub).get(path).then(); | |
sec = await SEA.decrypt(sec, pair); | |
let key = await gun.then(); | |
console.log(key) | |
if(key === undefined){ | |
//console.log("FOUND NULL"); | |
cb(undefined); | |
return gun; | |
} | |
//if(key.sea === undefined){ | |
//cb(undefined); | |
//return gun; | |
//} | |
//key = key.sea;//TESTING.... | |
let value = await SEA.decrypt(key, sec); | |
cb(value); | |
} | |
//console.log(gun); | |
if(sharetype == "gun"){ | |
//console.log(gun); | |
let countmax = 10; | |
let root; | |
//need to work this fixed later | |
for(let i=0;i<countmax;i++){//look for user soul root from let to = gun.user('key'); | |
let tmp = gun.back(i);//loop to find user root | |
if(tmp._.soul){ | |
console.log("FOUND SOUL!"); | |
root = tmp; | |
break; | |
} | |
} | |
if('~' === root._.soul.slice(0,1)){//public key | |
//let soul;// = root._.soul.slice(0,1); | |
//console.log(SEA.opt.pub(root._.soul)); | |
//soul=SEA.opt.pub(root._.soul); | |
//let to = gun.user(soul); | |
let to = root;//user root graph | |
let enc1 = await to.get('trust').get(pair.pub).get(path).then(); | |
let epub = await to.get('epub').then(); | |
let mix = await SEA.secret(epub, pair); | |
let key = await SEA.decrypt(enc1, mix); | |
//console.log(key); | |
let enc2 = await gun.then(); | |
if(enc2 === undefined){ | |
//console.log("FOUND NULL"); | |
cb(undefined); | |
return gun; | |
} | |
//if(enc2.sea === undefined){ | |
//cb(undefined); | |
//return gun; | |
//} | |
//console.log(enc2); | |
//enc2 = enc2.sea;//TESTING.... | |
console.log(enc2); | |
//enc2 = "SEA"+ JSON.stringify(enc2); | |
let value = await SEA.decrypt(enc2, key); | |
//console.log(value); | |
cb(value); | |
} | |
} | |
}()); | |
return gun; | |
} | |
//SETUP FUNCTION for GUN | |
Gun.chain.trustkey = trustkey; | |
Gun.chain.distrustkey = distrustkey; | |
Gun.chain.grantkey = grantkey; | |
Gun.chain.revokekey = revokekey; | |
Gun.chain.encryptput = encryptput; | |
Gun.chain.decryptonce = decryptonce; | |
//TESTING... | |
Gun.chain.trustlist = trustlist; | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment