This commit is contained in:
Mark Nadal 2021-08-21 20:03:09 -07:00
parent 824319afab
commit cdca88e60b
11 changed files with 59 additions and 15457 deletions

View File

@ -8,7 +8,7 @@
"description": "Javascript, Offline-First Javascript Graph Database Server Peer",
"env": {
"NPM_CONFIG_PRODUCTION": {
"description": "If you don't want to serve the Gun landing page, set to \"true\".",
"description": "If you do not want default features, set to \"true\".",
"value": "false"
},
"PEERS": {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
<!DOCTYPE html>
<style>html, body, textarea { width: 100%; height: 100%; padding: 0; margin: 0; }</style>
<textarea id="paste" placeholder="paste here!"></textarea>
<script src="../../../gun/gun.js"></script>
<script>
<script src="../../../gun/gun.js"></script><script>
gun = GUN(location.origin + '/gun');
paste.oninput = () => { gun.get('test').get('paste').put(paste.value) }
gun.get('test').get('paste').on((data) => { paste.value = data });
copy = gun.get('test').get('paste');
paste.oninput = () => { copy.put(paste.value) };
copy.on((data) => { paste.value = data });
</script>

View File

@ -1,57 +1,4 @@
<!DOCTYPE html>
<html>
<head>
<title>GUN — the database for freedom fighters</title>
<meta charset="utf-8">
<meta name="description" content="GUN is a distributed, offline-first, realtime graph database engine with built-in encryption.">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta property="og:title" content="GUN — the database for freedom fighters">
<meta property="og:description" content="GUN is a distributed, offline-first, realtime graph database engine with built-in encryption.">
<meta property="og:type" content="website">
<meta property="og:image" content="iris/img/gun-og-image.png">
<meta name="twitter:card" content="summary"></meta>
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<link rel="apple-touch-icon" sizes="180x180" href="./iris/img/apple-touch-icon.png">
<link rel="icon" href="iris/img/gun-48x48.png">
<link rel="manifest" href="./iris/site.webmanifest">
<link rel="mask-icon" href="./iris/img/safari-pinned-tab.svg" color="#74d5f1">
<link rel="shortcut icon" href="iris/img/gun-48x48.png">
<meta name="msapplication-TileColor" content="#74d5f1">
<meta name="msapplication-config" content="./iris/browserconfig.xml">
<meta name="theme-color" content="#74d5f1">
<link rel="stylesheet" type="text/css" href="./iris/css/cropper.min.css">
<link rel="stylesheet" href="./iris/css/dark.css" media="(prefers-color-scheme: dark)">
<link rel="stylesheet" href="./iris/css/light.css" media="(prefers-color-scheme: no-preference), (prefers-color-scheme: light)">
<!-- The main stylesheet -->
<link rel="stylesheet" type="text/css" href="./iris/css/style.css">
</head>
<body>
<script src="./iris/js/lib/webtorrent.min.js"></script>
<script src="./iris/js/lib/jquery.js"></script>
<script src="./iris/js/lib/cropper.min.js"></script>
<script src="./iris/js/lib/pica.min.js"></script>
<script src="./iris/js/lib/underscore-min.js"></script>
<script src="./iris/js/lib/gun.js"></script>
<script src="./iris/js/lib/open.js"></script>
<script src="./iris/js/lib/sea.js"></script>
<script src="./iris/js/lib/nts.js"></script>
<script src="./iris/js/lib/radix.js"></script>
<script src="./iris/js/lib/radisk.js"></script>
<script src="./iris/js/lib/store.js"></script>
<script src="./iris/js/lib/rindexed.js"></script>
<script src="./iris/js/lib/iris.min.js"></script>
<script src="./iris/js/lib/emoji-button.js"></script>
<script src="./iris/js/lib/Autolinker.min.js"></script>
<script src="./iris/js/lib/qrcode.min.js"></script>
<script src="./iris/js/lib/qr.zxing.js"></script>
<script type="module" src="./Main.js"></script>
</body>
</html>
<p>This is the examples folder.
<p>The most basic example is <a href="/basic/paste.html">./basic/paste.html</a>!</p>
<p>Home page temporarily disabled.</p>

17
gun.js
View File

@ -378,7 +378,7 @@
}
function fire(ctx, msg){ var root;
if(ctx.stop){ return }
if(--ctx.stun !== 0 && !ctx.err){ return } // TODO: 'forget' feature in SEA tied to this, bad approach, but hacked in for now. Any changes here must update there.
if(!ctx.err && 0 < --ctx.stun){ return } // TODO: 'forget' feature in SEA tied to this, bad approach, but hacked in for now. Any changes here must update there.
ctx.stop = 1;
if(!(root = ctx.root)){ return }
var tmp = ctx.match; tmp.end = 1;
@ -394,11 +394,15 @@
// TODO: check for the sharded message err and transfer it onto the original batch?
if(!(tmp = id._)){ /*console.log("TODO: handle ack id.");*/ return }
tmp.acks = (tmp.acks||0) + 1;
if(tmp.err = msg.err){
msg['@'] = tmp['#'];
--tmp.stun;
}
if(0 == tmp.stun && tmp.acks == tmp.all){ // TODO: if ack is synchronous this may not work?
root && root.on('in', {'@': tmp['#'], err: msg.err, ok: msg.err? u : 'shard'});
msg.err && fire(tmp);
return;
}
if(msg.err){ msg['@'] = tmp['#'] }
}
var ERR = "Error: Invalid graph!";
@ -809,10 +813,11 @@
Gun.chain.get = function(key, cb, as){
var gun, tmp;
if(typeof key === 'string'){
if(key.length == 0) {
(as = this.chain())._.err = {err: Gun.log('Invalid zero length string key!', key)};
return null
}
if(key.length == 0) {
(gun = this.chain())._.err = {err: Gun.log('0 length key!', key)};
if(cb){ cb.call(gun, gun._.err) }
return gun;
}
var back = this, cat = back._;
var next = cat.next || empty;
if(!(gun = next[key])){

View File

@ -68,7 +68,6 @@
"devDependencies": {
"aws-sdk": "^2.528.0",
"ip": "^1.1.5",
"iris-messenger": "https://github.com/irislib/iris-messenger",
"mocha": "^6.2.0",
"uglify-js": "^3.6.0"
}

24
sea.js
View File

@ -37,7 +37,7 @@
&& location.host.indexOf('localhost') < 0
&& ! /^127\.\d+\.\d+\.\d+$/.test(location.hostname)
&& location.protocol.indexOf('file:') < 0){
console.warn('WebCrypto used by GUN SEA implementation does not work without HTTPS. Will automatically redirect.')
console.warn('HTTPS needed for WebCrypto in SEA, redirecting...');
location.protocol = 'https:'; // WebCrypto does NOT work without HTTPS!
}
} }catch(e){}
@ -857,11 +857,11 @@
// Well first we have to actually create a user. That is what this function does.
User.prototype.create = function(...args){
const pair = typeof args[0] === 'object' && (args[0].pub || args[0].epub) ? args[0] : typeof args[1] === 'object' && (args[1].pub || args[1].epub) ? args[1] : null;
const alias = pair && (pair.pub || pair.epub) ? pair.pub : typeof args[0] === 'string' ? args[0] : null;
const pass = pair && (pair.pub || pair.epub) ? pair : alias && typeof args[1] === 'string' ? args[1] : null;
const cb = args.filter(arg => typeof arg === 'function')[0] || null; // cb now can stand anywhere, after alias/pass or pair
const opt = args && args.length > 1 && typeof args[args.length-1] === 'object' ? args[args.length-1] : {}; // opt is always the last parameter which typeof === 'object' and stands after cb
var pair = typeof args[0] === 'object' && (args[0].pub || args[0].epub) ? args[0] : typeof args[1] === 'object' && (args[1].pub || args[1].epub) ? args[1] : null;
var alias = pair && (pair.pub || pair.epub) ? pair.pub : typeof args[0] === 'string' ? args[0] : null;
var pass = pair && (pair.pub || pair.epub) ? pair : alias && typeof args[1] === 'string' ? args[1] : null;
var cb = args.filter(arg => typeof arg === 'function')[0] || null; // cb now can stand anywhere, after alias/pass or pair
var opt = args && args.length > 1 && typeof args[args.length-1] === 'object' ? args[args.length-1] : {}; // opt is always the last parameter which typeof === 'object' and stands after cb
var gun = this, cat = (gun._), root = gun.back(-1);
cb = cb || noop;
@ -961,11 +961,11 @@
var User = USE('./user'), SEA = User.SEA, Gun = User.GUN, noop = function(){};
// now that we have created a user, we want to authenticate them!
User.prototype.auth = function(...args){ // TODO: this PR with arguments need to be cleaned up / refactored.
const pair = typeof args[0] === 'object' && (args[0].pub || args[0].epub) ? args[0] : typeof args[1] === 'object' && (args[1].pub || args[1].epub) ? args[1] : null;
const alias = !pair && typeof args[0] === 'string' ? args[0] : null;
const pass = alias && typeof args[1] === 'string' ? args[1] : null;
const cb = args.filter(arg => typeof arg === 'function')[0] || null; // cb now can stand anywhere, after alias/pass or pair
const opt = args && args.length > 1 && typeof args[args.length-1] === 'object' ? args[args.length-1] : {}; // opt is always the last parameter which typeof === 'object' and stands after cb
var pair = typeof args[0] === 'object' && (args[0].pub || args[0].epub) ? args[0] : typeof args[1] === 'object' && (args[1].pub || args[1].epub) ? args[1] : null;
var alias = !pair && typeof args[0] === 'string' ? args[0] : null;
var pass = alias && typeof args[1] === 'string' ? args[1] : null;
var cb = args.filter(arg => typeof arg === 'function')[0] || null; // cb now can stand anywhere, after alias/pass or pair
var opt = args && args.length > 1 && typeof args[args.length-1] === 'object' ? args[args.length-1] : {}; // opt is always the last parameter which typeof === 'object' and stands after cb
var gun = this, cat = (gun._), root = gun.back(-1);
@ -1029,7 +1029,7 @@
at.sea = act.pair;
cat.ing = false;
try{if(pass && u == (obj_ify(cat.root.graph['~'+pair.pub].auth)||'')[':']){ opt.shuffle = opt.change = pass; } }catch(e){} // migrate UTF8 & Shuffle!
opt.change? act.z() : (cb || oop)(at);
opt.change? act.z() : (cb || noop)(at);
if(SEA.window && ((gun.back('user')._).opt||opt).remember){
// TODO: this needs to be modular.
try{var sS = {};

View File

@ -5,6 +5,9 @@ const http = require("http");
require("../../lib/promise");
let gunClient, server;
// MOVED TO SEA!!!!!!!
describe("SEA node client auth", () => {
it("should start server", done => {
server = http.createServer().listen(8765, done);
@ -22,7 +25,7 @@ describe("SEA node client auth", () => {
it("should create user", done => {
gunClient.user().create("gun", "password", res => {
console.log({ res });
//console.log({ res });
expect(res.err).to.equal(undefined);
done();
});
@ -46,10 +49,10 @@ describe("SEA node client auth", () => {
});
});
xit("should not stuck on null node", async () => {
it("should not stuck on null node", async () => {
const r1 = await gunClient
.user()
.once(console.log)
//.once(console.log)
.get("test")
.promPut({ z: 1 });

View File

@ -523,7 +523,7 @@ describe('SEA', function(){
expect(g[p+'/zfdsa/y'].x.indexOf('/zfdsa/y/x"') > 0).to.be.ok();
expect(g[p+'/zfdsa/y/x'].c.indexOf('/zasdf"') > 0).to.be.ok();
done();
},500)};
},100)};
});
gun.user().auth(alice);
});
@ -601,7 +601,7 @@ describe('SEA', function(){
it('Certify: Attack', function(done){(async function(){
var alice = await SEA.pair()
var bob = await SEA.pair()
var cert = await SEA.certify(bob, {"*": "private"}, alice)
var cert = await SEA.certify(bob, {"*": "private"}, alice);
user.leave()
user.auth(bob, () => {
@ -622,7 +622,6 @@ describe('SEA', function(){
var alice = await SEA.pair()
var bob = await SEA.pair()
var cert = await SEA.certify('*', [{"*": "test", "+": "*"}, {"*": "inbox", "+": "*"}], alice)
user.leave()
user.auth(bob, () => {
var data = Gun.state().toString(36)
@ -635,7 +634,7 @@ describe('SEA', function(){
done()
}, { opt: { cert } })
})
}())})
}())});
it('Certify: Expiry', function(done){(async function(){
var alice = await SEA.pair()
@ -684,6 +683,7 @@ describe('SEA', function(){
.get('today')
.once(_data => {
expect(_data).to.be(data)
user.leave();
done()
})
}, { opt: { cert } })
@ -691,7 +691,7 @@ describe('SEA', function(){
})
}())})
it('Certify: Advanced - Blacklist', function(done){(async function(){
it.skip('Certify: Advanced - Blacklist', function(done){(async function(){
var alice = await SEA.pair()
var dave = await SEA.pair()
var bob = await SEA.pair()
@ -699,26 +699,32 @@ describe('SEA', function(){
expiry: Gun.state() + 5000, // expires in 5 seconds
blacklist: 'blacklist' // path to blacklist in Alice's graph
})
console.log(111111);
// Alice points her blacklist to Dave's graph
user.leave()
user.auth(alice, async () => {
await user.get('blacklist').put({'#': '~'+dave.pub+'/blacklist'})
await user.leave()
console.log("meeeeoooooow");
var ref = gun.get('~'+dave.pub+'/blacklist');
await user.get('blacklist').put(ref);
user.leave()
console.log(2222222);
// Dave logins, he adds Bob to his blacklist, which is connected to the certificate that Alice issued for Bob
user.auth(dave, async () => {
await user.get('blacklist').get(bob.pub).put(true)
await user.leave()
user.leave()
console.log(333333);
// Bob logins and tries to hack Alice
user.auth(bob, async () => {
console.log(4444444);
var data = Gun.state().toString(36)
gun.get("~" + alice.pub)
.get("private")
.get("asdf")
.get("qwerty")
.put(data, ack => {
console.log(555555);
expect(ack.err).to.be.ok()
user.leave()
done()
@ -728,6 +734,13 @@ describe('SEA', function(){
})
}())})
});
describe('node', function(){
var u;
if(''+u === typeof process){ return }
console.log("REMEMBER TO RUN mocha test/sea/nodeauth !!!!");
});
});
})