diff --git a/README.md b/README.md index d24e168d5..433ca715e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Currently, [Internet Archive](https://news.ycombinator.com/item?id=17685682) and HackerNoon run GUN in production. -Decentralized alternatives to [Reddit](https://notabug.io/t/whatever/comments/36588a16b9008da4e3f15663c2225e949eca4a15/gpu-bot-test), [YouTube](https://d.tube/), [Wikipedia](https://news.ycombinator.com/item?id=17685682), etc. are already pushing terabytes of daily P2P traffic on GUN. We are a [friendly community](https://gitter.im/amark/gun) creating a free fun future for freedom: +Decentralized alternatives to [Reddit](https://notabug.io/t/whatever/comments/36588a16b9008da4e3f15663c2225e949eca4a15/gpu-bot-test), [YouTube](https://d.tube/), [Wikipedia](https://news.ycombinator.com/item?id=17685682), etc. have already pushed terabytes of daily P2P traffic on GUN. We are a [friendly community](https://gitter.im/amark/gun) creating a free fun future for freedom: @@ -186,28 +186,24 @@ rm -rf *data* ### Additional Cryptography Libraries -To install with npm, first install `npm install gun -S`. -For just the networking layer, import Gun: + > These are only needed for NodeJS, they shim the native Browser WebCrypto API. -```javascript -var Gun = require('gun/gun'); -``` - -If you also need to install SEA for user auth and crypto, also install some of its dependencies like this: +If you want to use [SEA](https://gun.eco/docs/SEA) for `User` auth and security, you will need to install: -`npm install text-encoding @peculiar/webcrypto --save` +`npm install text-encoding isomorphic-webcrypto --save` -You will need to require it too (it will be automatically added to the Gun object): +Then you can require [SEA](https://gun.eco/docs/SEA) without an error: ```javascript -var Gun = require('gun/gun'); -var Sea = require('gun/sea'); +var GUN = require('gun/gun'); +var SEA = require('gun/sea'); ``` - ## Deploy -To quickly spin up a Gun test server for your development team, utilize either [Heroku](http://heroku.com) or [Docker](http://docker.com) or any variant thereof [Dokku](http://dokku.viewdocs.io/dokku/), [Flynn.io](http://flynn.io), [now.sh](https://zeit.co/now), etc. ! + > Note: The default examples that get auto-deployed on `npm start` CDN-ify all GUN files, modules, & storage. + +To quickly spin up a GUN relay peer for your development team, utilize either [Heroku](http://heroku.com), [Docker](http://docker.com), any variant thereof [Dokku](http://dokku.viewdocs.io/dokku/), [Flynn.io](http://flynn.io), [now.sh](https://zeit.co/now), etc. ! Or use all of them so your relays are decentralized too! ### [Heroku](https://www.heroku.com/) @@ -244,6 +240,8 @@ Then visit the deployed app by following the 'view app' button, in your browser. ### [Docker](https://www.docker.com/) + > Warning: Docker image is community contributed and may be old with missing security updates, please check version numbers to compare. + [![Docker Automated buil](https://img.shields.io/docker/automated/gundb/gun.svg)](https://hub.docker.com/r/gundb/gun/) [![](https://images.microbadger.com/badges/image/gundb/gun.svg)](https://microbadger.com/images/gundb/gun "Get your own image badge on microbadger.com") [![Docker Pulls](https://img.shields.io/docker/pulls/gundb/gun.svg)](https://hub.docker.com/r/gundb/gun/) [![Docker Stars](https://img.shields.io/docker/stars/gundb/gun.svg)](https://hub.docker.com/r/gundb/gun/) Pull from the [Docker Hub](https://hub.docker.com/r/gundb/gun/) [![](https://images.microbadger.com/badges/commit/gundb/gun.svg)](https://microbadger.com/images/gundb/gun). Or: diff --git a/examples/install.sh b/examples/install.sh index 8e984fe5b..1af60ff7b 100644 --- a/examples/install.sh +++ b/examples/install.sh @@ -6,6 +6,7 @@ # Copy paste and run each line into your terminal. # If you are on Windows, http://nodejs.org/download/ has # an installer that will automatically do it for you. +# curl -o- https://raw.githubusercontent.com/amark/gun/master/examples/install.sh | bash #debian/ubuntu su - diff --git a/lib/multicast.js b/lib/multicast.js index e4c5e4ad1..d4023b222 100644 --- a/lib/multicast.js +++ b/lib/multicast.js @@ -22,11 +22,10 @@ Gun.on('create', function(root){ socket.bind({port: udp.port, exclusive: true}, function(){ socket.setBroadcast(true); socket.setMulticastTTL(128); - try{ socket.addMembership(udp.address); }catch(e){} }); socket.on("listening", function(){ - try { socket.addMembership(udp.address) }catch(e){ return } + try { socket.addMembership(udp.address) }catch(e){ console.error(e); return; } udp.peer = {id: udp.address + ':' + udp.port, wire: socket}; udp.peer.say = function(raw){ @@ -60,7 +59,7 @@ Gun.on('create', function(root){ var url = 'http://' + info.address + ':' + (port || (opt.web && opt.web.address()||{}).port) + '/gun'; if(root.opt.peers[url]){ return } - + //console.log('discovered', url, message, info); root.$.opt(url); diff --git a/lib/webrtc.js b/lib/webrtc.js index cc61ec602..b3539fca6 100644 --- a/lib/webrtc.js +++ b/lib/webrtc.js @@ -21,13 +21,16 @@ opt.RTCSessionDescription = rtcsd; opt.RTCIceCandidate = rtcic; opt.rtc = opt.rtc || {'iceServers': [ - {url: 'stun:stun.l.google.com:19302'}, - {url: "stun:stun.sipgate.net:3478"}, - {url: "stun:stun.stunprotocol.org"}, - {url: "stun:stun.sipgate.net:10000"}, - {url: "stun:217.10.68.152:10000"}, - {url: 'stun:stun.services.mozilla.com'} + {urls: 'stun:stun.l.google.com:19302'}, + {urls: "stun:stun.sipgate.net:3478"}/*, + {urls: "stun:stun.stunprotocol.org"}, + {urls: "stun:stun.sipgate.net:10000"}, + {urls: "stun:217.10.68.152:10000"}, + {urls: 'stun:stun.services.mozilla.com'}*/ ]}; + // TODO: Select the most appropriate stuns. + // FIXME: Find the wire throwing ICE Failed + // The above change corrects at least firefox RTC Peer handler where it **throws** on over 6 ice servers, and updates url: to urls: removing deprecation warning opt.rtc.dataChannel = opt.rtc.dataChannel || {ordered: false, maxRetransmits: 2}; opt.rtc.sdp = opt.rtc.sdp || {mandatory: {OfferToReceiveAudio: false, OfferToReceiveVideo: false}}; opt.announce = function(to){ diff --git a/sea.js b/sea.js index 213fe57f3..bd882e348 100644 --- a/sea.js +++ b/sea.js @@ -530,7 +530,7 @@ pair = await SEA.I(null, {what: data, how: 'encrypt', why: opt.why}); key = pair.epriv || pair; } - var msg = (typeof data == 'string')? data : JSON.stringify(data); + var msg = JSON.stringify(data); var rand = {s: shim.random(9), iv: shim.random(15)}; // consider making this 9 and 15 or 18 or 12 to reduce == padding. var ct = await aeskey(key, rand.s, opt).then((aes) => (/*shim.ossl ||*/ shim.subtle).encrypt({ // Keeping the AES key scope as private as possible... name: opt.name || 'AES-GCM', iv: new Uint8Array(rand.iv) @@ -1212,7 +1212,7 @@ } check['user'+soul+key] = 1; if(Gun.is(msg.$) && user && user.is && pub === user.is.pub){ - SEA.sign(SEA.opt.prep(tmp = SEA.opt.parse(val), key, node, soul), (user._).sea, function(data){ var rel; + SEA.sign(SEA.opt.prep(tmp = JSON.stringify(val), key, node, soul), (user._).sea, function(data){ var rel; if(u === data){ return each.end({err: SEA.err || 'Pub signature fail.'}) } if(rel = Gun.val.link.is(val)){ (at.sea.own[rel] = at.sea.own[rel] || {})[pub] = true; @@ -1260,7 +1260,7 @@ return; }*/ check['any'+soul+key] = 1; - SEA.sign(SEA.opt.prep(tmp = SEA.opt.parse(val), key, node, soul), (user._).sea, function(data){ + SEA.sign(SEA.opt.prep(tmp = JSON.stringify(val), key, node, soul), (user._).sea, function(data){ if(u === data){ return each.end({err: 'My signature fail.'}) } node[key] = JSON.stringify({':': SEA.opt.unpack(data.m), '~': data.s}); check['any'+soul+key] = 0; diff --git a/test/rad/rad.js b/test/rad/rad.js index d1a638d2e..bc2f5f5f3 100644 --- a/test/rad/rad.js +++ b/test/rad/rad.js @@ -19,16 +19,16 @@ var Gun; require('../../lib/store'); require('../../lib/rfs'); } - + try{ var expect = global.expect = require("../expect") }catch(e){} - + }(this)); - + ;(function(){ Gun = root.Gun if(Gun.window && !Gun.window.RindexedDB){ return } - + var opt = {}; opt.file = 'radatatest'; var Radisk = (Gun.window && Gun.window.Radisk) || require('../../lib/radisk'); @@ -36,11 +36,11 @@ opt.store = ((Gun.window && Gun.window.RindexedDB) || require('../../lib/rfs'))( opt.chunk = 1000; var Radix = Radisk.Radix; var rad = Radisk(opt), esc = String.fromCharCode(27); - + describe('RAD', function(){ - + var names = ["Adalard","Adora","Aia","Albertina","Alfie","Allyn","Amabil","Ammamaria","Andy","Anselme","Ardeen","Armand","Ashelman","Aube","Averyl","Baker","Barger","Baten","Bee","Benia","Bernat","Bevers","Bittner","Bobbe","Bonny","Boyce","Breech","Brittaney","Bryn","Burkitt","Cadmann","Campagna","Carlee","Carver","Cavallaro","Chainey","Chaunce","Ching","Cianca","Claudina","Clyve","Colon","Cooke","Corrina","Crawley","Cullie","Dacy","Daniela","Daryn","Deedee","Denie","Devland","Dimitri","Dolphin","Dorinda","Dream","Dunham","Eachelle","Edina","Eisenstark","Elish","Elvis","Eng","Erland","Ethan","Evelyn","Fairman","Faus","Fenner","Fillander","Flip","Foskett","Fredette","Fullerton","Gamali","Gaspar","Gemina","Germana","Gilberto","Giuditta","Goer","Gotcher","Greenstein","Grosvenor","Guthrey","Haldane","Hankins","Harriette","Hayman","Heise","Hepsiba","Hewie","Hiroshi","Holtorf","Howlond","Hurless","Ieso","Ingold","Isidora","Jacoba","Janelle","Jaye","Jennee","Jillana","Johnson","Josy","Justinian","Kannan","Kast","Keeley","Kennett","Kho","Kiran","Knowles","Koser","Kroll","LaMori","Lanctot","Lasky","Laverna","Leff","Leonanie","Lewert","Lilybel","Lissak","Longerich","Lou","Ludeman","Lyman","Madai","Maia","Malvina","Marcy","Maris","Martens","Mathilda","Maye","McLain","Melamie","Meras","Micco","Millburn","Mittel","Montfort","Moth","Mutz","Nananne","Nazler","Nesta","Nicolina","Noellyn","Nuli","Ody","Olympie","Orlena","Other","Pain","Parry","Paynter","Pentheas","Pettifer","Phyllida","Plath","Posehn","Proulx","Quinlan","Raimes","Ras","Redmer","Renelle","Ricard","Rior","Rocky","Ron","Rosetta","Rubia","Ruttger","Salbu","Sandy","Saw","Scholz","Secor","September","Shanleigh","Shenan","Sholes","Sig","Sisely","Soble","Spanos","Stanwinn","Stevie","Stu","Suzanne","Tacy","Tanney","Tekla","Thackeray","Thomasin","Tilla","Tomas","Tracay","Tristis","Ty","Urana","Valdis","Vasta","Vezza","Vitoria","Wait","Warring","Weissmann","Whetstone","Williamson","Wittenburg","Wymore","Yoho","Zamir","Zimmermann"]; - + //console.log("HYPER TEST");var z = 10000; while(--z){ names.push(Gun.text.random(7)) }this.timeout(9000); describe('Radix', function(){ @@ -59,7 +59,7 @@ var names = ["Adalard","Adora","Aia","Albertina","Alfie","Allyn","Amabil","Ammam expect(Gun.obj.empty(all)).to.be.ok(); done(); }); - + it('radix write read again', function(done){ var all = {}; names.forEach(function(v,i){ @@ -74,7 +74,7 @@ var names = ["Adalard","Adora","Aia","Albertina","Alfie","Allyn","Amabil","Ammam expect(Gun.obj.empty(all)).to.be.ok(); done(); }); - + it('radix read start end', function(done){ var all = {}, start = 'Warring'.toLowerCase(), end = 'Zamir'.toLowerCase(); names.forEach(function(v,i){ @@ -92,7 +92,7 @@ var names = ["Adalard","Adora","Aia","Albertina","Alfie","Allyn","Amabil","Ammam expect(Gun.obj.empty(all)).to.be.ok(); done(); }); - + it('radix read start- end+', function(done){ var all = {}, start = 'Warrinf'.toLowerCase(), end = 'Zamis'.toLowerCase(); names.forEach(function(v,i){ @@ -134,7 +134,7 @@ var names = ["Adalard","Adora","Aia","Albertina","Alfie","Allyn","Amabil","Ammam }); describe('Radisk', function(){ - + /*it('parse', function(done){ this.timeout(60000); if(Gun.window){ return done() } @@ -144,8 +144,8 @@ var names = ["Adalard","Adora","Aia","Albertina","Alfie","Allyn","Amabil","Ammam }, raw); return; });*/ - - + + it('write contacts', function(done){ var all = {}, to, start; names.forEach(function(v,i){ @@ -178,7 +178,7 @@ var names = ["Adalard","Adora","Aia","Albertina","Alfie","Allyn","Amabil","Ammam }, opt); }); console.log("UNDO THIS RETURN!!!");return;*/ - + it('read contacts start end', function(done){ var opt = {}; opt.start = 'Warring'.toLowerCase(); @@ -200,7 +200,7 @@ var names = ["Adalard","Adora","Aia","Albertina","Alfie","Allyn","Amabil","Ammam done(); }, opt); }); - + it('read contacts', function(done){ var all = {}, find = 'a'; names.forEach(function(v){ @@ -217,7 +217,7 @@ var names = ["Adalard","Adora","Aia","Albertina","Alfie","Allyn","Amabil","Ammam done(); }); }); - + it('read again', function(done){ var all = {}, find = 'm'; names.forEach(function(v){ @@ -252,12 +252,12 @@ var names = ["Adalard","Adora","Aia","Albertina","Alfie","Allyn","Amabil","Ammam }); }); - + var ntmp = names; describe('RAD + GUN', function(){ var ochunk = 1000; var gun = Gun({chunk: ochunk}); - + it('write same', function(done){ var all = {}, to, start, tmp; var names = [], c = 285; @@ -273,7 +273,7 @@ var names = ["Adalard","Adora","Aia","Albertina","Alfie","Allyn","Amabil","Ammam }) }); }); - + it('write contacts', function(done){ var all = {}, to, start, tmp; names.forEach(function(v,i){ @@ -342,9 +342,46 @@ var names = ["Adalard","Adora","Aia","Albertina","Alfie","Allyn","Amabil","Ammam },100); }); }); - + + it.skip('read contacts smaller than cursor', function(done){ // TODO!!! + var all = {}, cursor = 'm', to; + names.forEach(function(v){ + v = v.toLowerCase(); + if(v < cursor){ all[v] = true } + }); + gun.get('names').get({'.': {'<': cursor}, '%': 1000 * 100}).once().map().once(function(data, key){ + expect(data.name).to.be.ok(); + expect(data.age).to.be.ok(); + //if(!all.hasOwnProperty(key)){console.error(key);} + expect(all.hasOwnProperty(key)).to.be.ok(); + delete all[key]; + clearTimeout(to); + to = setTimeout(function(){ + expect(Gun.obj.empty(all)).to.be.ok(); + done(); + },100); + }); + }); + + it.skip('read contacts in descending order', function(done){ // TODO!!! + var all = {}, cursor = 'm', to; + names.forEach(function(v){ + all[v] = true; + }); + gun.get('names').get({'.': {'-': true}, '%': 1000 * 100}).once().map().once(function(data, key){ + expect(data.name).to.be.ok(); + expect(data.age).to.be.ok(); + delete all[key]; + clearTimeout(to); + to = setTimeout(function(){ + expect(Gun.obj.empty(all)).to.be.ok(); + done(); + },100); + }); + }); + }); - + }); - -}()); \ No newline at end of file + +}()); diff --git a/test/sea/sea.js b/test/sea/sea.js index 1a1668042..837bcaa6c 100644 --- a/test/sea/sea.js +++ b/test/sea/sea.js @@ -171,21 +171,49 @@ describe('SEA', function(){ expect({a:1}).to.eql(v); SEA.encrypt(JSON.stringify({a:1}), pair, function(s){ SEA.decrypt(s, pair, function(v){ - expect({a:1}).to.eql(v); + expect(JSON.stringify({a:1})).to.eql(v); done(); });});});});});});});});});});});});});});});});});});});});});});});});});});}); }) - - /*it('DOESNT DECRYPT SCIENTIFIC NOTATION', function(done){ - var pair, s, v; - SEA.pair(function(pair){ - SEA.encrypt('4e2', pair, function(s){ - SEA.decrypt(s, pair, function(v){ - expect(400).to.be(v); - done(); - });});}); - })*/ - + + it('Keep the data type.', function(done) { + this.timeout(9000); + var gun = Gun(); + var user = gun.user(); + user.create('mario', 'password'); + gun.on('auth', function(){ + var pubref = gun.get('Keep the data type').get('value').put(null); + var ref = user.get('test').get('data').put(null, function() { + /// For user nodes + ref.once(function(v) { expect(v).to.eql(null); + + ref.put(400, function() { + ref.once(function(v) { expect(v).to.eql(400); + + ref.put('null', function() { + ref.once(function(v) { expect(v).to.eql('null'); + + ref.put('4e2', function() { + ref.once(function(v) { expect(v).to.eql('4e2'); + + /// For pub nodes + pubref.put(400, function() { + pubref.once(function(v) { expect(v).to.eql(400); + + pubref.put('null', function() { + pubref.once(function(v) { expect(v).to.eql('null'); + + pubref.put('4e2', function() { + pubref.once(function(v) { expect(v).to.eql('4e2'); + + //ref.put('SEA{}', function() { + //ref.once(function(v) { expect(v).to.eql('SEA{}'); + //gun.get('keepdata').get('seaempty').put('SEA{}', function(ack) { console.log('ACKKK: ', ack); + //gun.get('keepdata').get('seaempty').once(function(v) { expect(v).to.eql('SEA{}'); console.log('ONCE %s: ', typeof v, v); + done();});});});});});});});});});});});});});});//});});});}); + }); + }); + it('legacy', function(done){ (async function(){ var pw = 'test123'; // https://cdn.jsdelivr.net/npm/gun@0.9.99999/sea.js !