Skip to content

Instantly share code, notes, and snippets.

@zilveer
Forked from jabis/gun.helper.js
Created December 15, 2019 16:46
Show Gist options
  • Save zilveer/f03ca69c6c3a8fde5717e10fcf1e2e58 to your computer and use it in GitHub Desktop.
Save zilveer/f03ca69c6c3a8fde5717e10fcf1e2e58 to your computer and use it in GitHub Desktop.
Gun userspace get/set with encryption
/**
* get and put encrypted material to paths in Gun
* FIXME: Investigate why root level put doesn't work
* TODO: Add signing to make objects unwritable by others
**/
const decEnc = this.decEnc = async(...args)=> {
console.log(args);
let data = args.length > 0 ? args.shift() : false; // data as first argument
let pair = args.length > 0 ? args.shift() : false; // pair to use in decrypting/encrypting as second argument
let mode = args.length > 0 ? args.shift() : "decrypt"; // mode optional encrypt/decrypt on SEA defaults to decrypt
//TODO return Promise.reject if we don't have all mandatory arguments passed
let secret = await SEA.secret(pair.epub, pair);
let it = await SEA[mode](data, secret);
return it;
};
Gun.chain.putsenc = async function(){
let args = Array.from(arguments);
let gun = this;
let data = args.shift();
let pair = args.length > 0 ? args.shift() : (gun.user().is ? gun.user()._.sea : null)
if(!pair) return Promise.reject("No keypair provided or not logged in");
return await decEnc(data, pair, 'encrypt').then(async (d)=>{
return await gun.put("a"+d).then();
}).catch((err)=>{
console.log("whoops",err);
return gun;
})
};
Gun.chain.putenc = async function() {
let args = Array.from(arguments);
let gun = this;
let data = args.shift();
let pair =
args.length > 0 ? args.shift() : gun.user().is ? gun.user()._.sea : null;
//TODO: Implement checking with old pair as well as throw if error
if (!pair) return Promise.reject("No keypair provided or not logged in");
return this.once(async function(olddata, key) {
console.log("old data", olddata);
if(typeof olddata === "string" && /^(aSEA)/.test(olddata)) olddata = olddata.slice(1)
return await decEnc(olddata, pair)
.then(async old => {
console.log("old", old);
var nd = null;
if (!old) {
nd = data;
} else {
if (typeof old === "object") {
// trying to simulate regular put
nd = Object.assign({}, old, data);
} else {
nd = data;
}
}
console.log("new data", nd);
return await decEnc(nd, pair, "encrypt").then(async (enc) => {
console.log("encrypted", enc);
return await gun.put("a"+enc).then();
});
})
.catch(err => {
console.log("whoops", err);
return gun;
});
});
};
Gun.chain.getenc = async function(){
let args = Array.from(arguments);
let gun = this;
let path = args.shift();
let pair = args.length > 0 ? args.shift() : (gun.user().is ? gun.user()._.sea : null)
if(!pair) return Promise.reject("No keypair provided or not logged in");
let data = await this.get(path).then();
//console.log(data,pair,path);
if(typeof data === "string" && /^(aSEA)/.test(data)) data = data.slice(1)
let dec = await decEnc(data, pair);
return dec ? dec : gun;
};
const putMyDataEnc = this.putMyDataEnc = async (...args) => {
//let args = arguments; Array.from(arguments);
console.log(args);
let cb = false;
if(args && args.length > 0 && typeof args[args.length-1] === "function"){
cb = args.pop(); // if we have a cb function in last of the list, then pop that
}
let path = args.length > 0 ? args.shift() : false; // path as first argument
let data = args.length > 0 ? args.shift() : false; // data as second argument
let pair = args.length > 0 ? args.shift() : false; // pair optional pair to use in encrypting
if(!path || !data) return Promise.reject("No path or data!");
const me = gun.user();
if (me.is) {
//authenticated
const mypair = me._.sea;
let usePair = mypair;
if(pair && pair.epub && pair.epriv) usePair = pair;
let enc = await decEnc(data, usePair,"encrypt");
if (cb) {
return me
.get(path)
.put(enc,cb)
} else {
return await me
.get(path)
.put(enc)
.then();
}
} else {
return Promise.reject("Not authenticated");
}
};
const getMyDataEnc = this.getMyDataEnc = async (...args)=>{
console.log(args);
let path = args.shift(); // path as first argument
let pair = args.length > 0 ? args.shift() : false; // optional pair to decrypt with
const me = gun.user();
if(me.is) { //authenticated
const mypair = me._.sea;
let usePair = mypair;
if(pair && pair.epub && pair.epriv) usePair = pair;
let data = await me
.get(path)
.then()
//console.log(data);
let dec = await decEnc(data, usePair)
return dec;
} else {
return Promise.reject("Not authenticated")
}
};
// USAGE:
let example = await gun.get("testing/encryption/123").get("example").putsenc({"encrypted":"stuff"}); // overwrite whole example
console.log(example);
let readexample = await gun.get("testing/encryption/123").getenc("example");
console.log(readexample);
let updateexample = await gun.get("testing/encryption/123").get("example").putenc({"stuff":"encrypted stuff"});
console.log(updateexample);
setTimeout(async()=>{
let x = await gun.get("testing/encryption/123").getenc("example");
console.log("some wait time so we wont resolve from localstorage",x);
},250)
putMyDataEnc("testing/encryption/123",{socks:"wet"}).then((d)=>{ console.log(d); }).catch((err)=>{ console.log(err); })
getMyDataEnc("testing/encryption/123").then((d)=>{ console.log(d); }).catch((err)=>{ console.log(err); })
//testing decryption of the node:
gun.user().get("testing/encryption/123").once(function(data){
decEnc(data,gun.user()._.sea).then((d)=>{console.log(d)}).catch((err)=>{ console.log(err); })
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment