update gun

This commit is contained in:
Martti Malmi 2020-05-16 14:59:34 +03:00
parent 1d53130dc0
commit f76416c11c
3 changed files with 85 additions and 95 deletions

View File

@ -49,6 +49,17 @@
if(u !== o['>'] && t >= o['>']){ return true } if(u !== o['>'] && t >= o['>']){ return true }
if(u !== o['<'] && t <= o['<']){ return true } if(u !== o['<'] && t <= o['<']){ return true }
return false; return false;
}
Type.text.hash = function(s, c){ // via SO
if(typeof s !== 'string'){ return }
c = c || 0;
if(!s.length){ return c }
for(var i=0,l=s.length,n; i<l; ++i){
n = s.charCodeAt(i);
c = ((c<<5)-c)+n;
c |= 0;
}
return c;
} }
Type.list = {is: function(l){ return (l instanceof Array) }} Type.list = {is: function(l){ return (l instanceof Array) }}
Type.list.slit = Array.prototype.slice; Type.list.slit = Array.prototype.slice;
@ -724,10 +735,10 @@
} }
function put(msg){ function put(msg){
if(!msg){ return } if(!msg){ return }
var ctx = msg._||'', root = ctx.root = ((msg.$||'')._||'').root; var ctx = msg._||'', root = ctx.root = ((ctx.$ = msg.$||'')._||'').root;
var put = msg.put, id = msg['#'], err, tmp; var put = msg.put, id = msg['#'], err, tmp;
var DBG = ctx.DBG = msg.DBG; var DBG = ctx.DBG = msg.DBG;
if(put['#']){ root.on('put', msg); return } if(put['#'] && put['.']){ root.on('put', msg); return } // TODO: BUG! This needs to call HAM instead.
/*root.on(id, function(m){ /*root.on(id, function(m){
console.log('ack:', m); console.log('ack:', m);
});*/ });*/
@ -766,10 +777,11 @@
setTimeout(function(){ setTimeout(function(){
ham(val, key, soul, state, msg); ham(val, key, soul, state, msg);
}, to > MD? MD : to); // setTimeout Max Defer 32bit :( }, to > MD? MD : to); // setTimeout Max Defer 32bit :(
if(!ctx.to){ root.on('in', {'@': msg['#'], err: to}) } ctx.to = 1; if(!ctx.to){ root.on('in', {'@': msg['#'], err: to}) } ctx.to = 1; // TODO: This causes too many problems unless sending peers auto-retry.
return to; return to;
} }
return; //return; // it should be this
if(!ctx.miss){ return } // but some chains have a cache miss that need to re-fire. // TODO: Improve in future.
} }
(lot = ctx.lot||'').s++; lot.more++; (lot = ctx.lot||'').s++; lot.more++;
(ctx.stun || (ctx.stun = {}))[soul+key] = 1; (ctx.stun || (ctx.stun = {}))[soul+key] = 1;
@ -784,7 +796,7 @@
if((tmp = ctx.out) && (tmp = tmp.put)){ if((tmp = ctx.out) && (tmp = tmp.put)){
tmp[soul] = state_ify(tmp[soul], key, state, val, soul); // TODO: Hacky, fix & come back later, for actual pushing messages. tmp[soul] = state_ify(tmp[soul], key, state, val, soul); // TODO: Hacky, fix & come back later, for actual pushing messages.
} }
if(!(--ctx.lot.more)){ fire(ctx) } if(!(--ctx.lot.more)){ fire(ctx) } // TODO: 'forget' feature in SEA tied to this, bad approach, but hacked in for now. Any changes here must update there.
eve.to.next(msg); eve.to.next(msg);
} }
function chain(ctx, soul, key,val, state){ function chain(ctx, soul, key,val, state){
@ -797,7 +809,7 @@
function fire(ctx){ function fire(ctx){
if(ctx.err){ return } if(ctx.err){ return }
var stop = {}; var stop = {};
var root = ctx.root, next = root.next||'', put = ctx.put, tmp; var root = ((ctx.$||'')._||'').root, next = (root||'').next||'', put = ctx.put, tmp;
var S = +new Date; var S = +new Date;
//Gun.graph.is(put, function(node, soul){ //Gun.graph.is(put, function(node, soul){
for(var soul in put){ var node = put[soul]; // Gun.obj.native() makes this safe. for(var soul in put){ var node = put[soul]; // Gun.obj.native() makes this safe.
@ -920,6 +932,7 @@
node = Gun.graph.node(node); node = Gun.graph.node(node);
tmp = (at||empty).ack; tmp = (at||empty).ack;
var faith = function(){}; faith.ram = faith.faith = true; // HNPERF: We're testing performance improvement by skipping going through security again, but this should be audited. var faith = function(){}; faith.ram = faith.faith = true; // HNPERF: We're testing performance improvement by skipping going through security again, but this should be audited.
faith.$ = msg.$;
DBG && (DBG.ga = +new Date); DBG && (DBG.ga = +new Date);
root.on('in', { root.on('in', {
'@': msg['#'], '@': msg['#'],
@ -956,7 +969,7 @@
obj_map(v, each, this[k]); obj_map(v, each, this[k]);
}, at.opt); }, at.opt);
Gun.on('opt', at); Gun.on('opt', at);
at.opt.uuid = at.opt.uuid || function(){ return state_lex() + text_rand(12) } //at.opt.uuid = at.opt.uuid || function(){ return state_lex() + text_rand(12) }
Gun.obj.native(); Gun.obj.native();
return gun; return gun;
} }
@ -1320,6 +1333,9 @@
at.on('in', {get: at.get, put: Gun.val.link.ify(get['#']), $: at.$, '@': msg['@']}); at.on('in', {get: at.get, put: Gun.val.link.ify(get['#']), $: at.$, '@': msg['@']});
return; return;
} }
if(at.$ === (msg._||'').$){ // replying to self, for perf, skip ham/security tho needs audit.
(msg._).miss = (at.put === u);
}
Gun.on.put(msg); Gun.on.put(msg);
} }
var empty = {}, u; var empty = {}, u;
@ -1402,7 +1418,7 @@
if(cat.jam){ return cat.jam.push([cb, as]) } if(cat.jam){ return cat.jam.push([cb, as]) }
cat.jam = [[cb,as]]; cat.jam = [[cb,as]];
gun.get(function go(msg, eve){ gun.get(function go(msg, eve){
if(u === msg.put && (tmp = Object.keys(cat.root.opt.peers).length) && ++acks < tmp){ if(u === msg.put && !cat.root.opt.super && (tmp = Object.keys(cat.root.opt.peers).length) && ++acks <= tmp){ // TODO: super should not be in core code, bring AXE up into core instead to fix?
return; return;
} }
eve.rid(msg); eve.rid(msg);
@ -1489,6 +1505,7 @@
return gun; return gun;
} }
as.soul = as.soul || (as.not = Gun.node.soul(as.data) || (as.via.back('opt.uuid') || Gun.text.random)()); as.soul = as.soul || (as.not = Gun.node.soul(as.data) || (as.via.back('opt.uuid') || Gun.text.random)());
as.via._.stun = {};
if(!as.soul){ // polyfill async uuid for SEA if(!as.soul){ // polyfill async uuid for SEA
as.via.back('opt.uuid')(function(err, soul){ // TODO: improve perf without anonymous callback as.via.back('opt.uuid')(function(err, soul){ // TODO: improve perf without anonymous callback
if(err){ return Gun.log(err) } // TODO: Handle error! if(err){ return Gun.log(err) } // TODO: Handle error!
@ -1501,9 +1518,11 @@
ify(as); ify(as);
return gun; return gun;
} }
as.via._.stun = {};
if(Gun.is(data)){ if(Gun.is(data)){
data.get(function(soul, o, msg){ data.get(function(soul, o, msg){
if(!soul){ if(!soul){
delete as.via._.stun;
return Gun.log("The reference you are saving is a", typeof msg.put, '"'+ msg.put +'", not a node (object)!'); return Gun.log("The reference you are saving is a", typeof msg.put, '"'+ msg.put +'", not a node (object)!');
} }
gun.put(Gun.val.link.ify(soul), cb, as); gun.put(Gun.val.link.ify(soul), cb, as);
@ -1567,6 +1586,7 @@
if(!as.graph || !obj_empty(as.stun)){ return } if(!as.graph || !obj_empty(as.stun)){ return }
as.res = as.res || function(cb){ if(cb){ cb() } }; as.res = as.res || function(cb){ if(cb){ cb() } };
as.res(function(){ as.res(function(){
delete as.via._.stun;
var cat = (as.$.back(-1)._), ask = cat.ask(function(ack){ var cat = (as.$.back(-1)._), ask = cat.ask(function(ack){
cat.root.on('ack', ack); cat.root.on('ack', ack);
if(ack.err){ Gun.log(ack) } if(ack.err){ Gun.log(ack) }
@ -1587,6 +1607,7 @@
}); });
cat.root.mum = mum? obj.to(mum, cat.root.mum) : mum; cat.root.mum = mum? obj.to(mum, cat.root.mum) : mum;
cat.root.now = tmp; cat.root.now = tmp;
as.via._.on('res', {}); delete as.via._.tag.res; // emitting causes mem leak?
}, as); }, as);
if(as.res){ as.res() } if(as.res){ as.res() }
} function no(v,k){ if(v){ return true } } } function no(v,k){ if(v){ return true } }
@ -1609,15 +1630,22 @@
return; return;
} }
(as.stun = as.stun || {})[path] = 1; (as.stun = as.stun || {})[path] = 1;
ref.get(soul, true, {as: {at: at, as: as, p:path}}); ref.get(soul, true, {as: {at: at, as: as, p:path, ref: ref}});
}, {as: as, at: at}); }, {as: as, at: at});
//if(is){ return {} } //if(is){ return {} }
} }
var G = String.fromCharCode(31);
function soul(id, as, msg, eve){ function soul(id, as, msg, eve){
var as = as.as, cat = as.at; as = as.as; var as = as.as, path = as.p, ref = as.ref, cat = as.at, pat = []; as = as.as;
ref.back(function(at){
if(sat = at.soul || at.link || at.dub){ return sat }
pat.push(at.has || at.get);
});
pat = [sat || as.soul].concat(pat.reverse());
var at = ((msg || {}).$ || {})._ || {}; var at = ((msg || {}).$ || {})._ || {};
id = at.dub = at.dub || id || Gun.node.soul(cat.obj) || Gun.node.soul(msg.put || at.put) || Gun.val.link.is(msg.put || at.put) || (as.via.back('opt.uuid') || Gun.text.random)(); // TODO: BUG!? Do we really want the soul of the object given to us? Could that be dangerous? id = at.dub = at.dub || id || Gun.node.soul(cat.obj) || Gun.node.soul(msg.put || at.put) || Gun.val.link.is(msg.put || at.put) || pat.join('/') /* || (function(){
return (as.soul+'.')+Gun.text.hash(path.join(G)).toString(32);
})(); // TODO: BUG!? Do we really want the soul of the object given to us? Could that be dangerous? What about copy operations? */
if(eve){ eve.stun = true } if(eve){ eve.stun = true }
if(!id){ // polyfill async uuid for SEA if(!id){ // polyfill async uuid for SEA
as.via.back('opt.uuid')(function(err, id){ // TODO: improve perf without anonymous callback as.via.back('opt.uuid')(function(err, id){ // TODO: improve perf without anonymous callback
@ -1649,6 +1677,7 @@
if(as.ref !== as.$){ if(as.ref !== as.$){
tmp = (as.$._).get || at.get; tmp = (as.$._).get || at.get;
if(!tmp){ // TODO: Handle if(!tmp){ // TODO: Handle
delete as.via._.stun;
Gun.log("Please report this as an issue! Put.no.get"); // TODO: BUG!?? Gun.log("Please report this as an issue! Put.no.get"); // TODO: BUG!??
return; return;
} }
@ -1656,7 +1685,7 @@
tmp = null; tmp = null;
} }
if(u === data){ if(u === data){
if(!at.get){ return } // TODO: Handle if(!at.get){ delete as.via._.stun; return } // TODO: Handle
if(!soul){ if(!soul){
tmp = at.$.back(function(at){ tmp = at.$.back(function(at){
if(at.link || at.soul){ return at.link || at.soul } if(at.link || at.soul){ return at.link || at.soul }
@ -1681,7 +1710,7 @@
} }
if(!as.soul){ // polyfill async uuid for SEA if(!as.soul){ // polyfill async uuid for SEA
as.via.back('opt.uuid')(function(err, soul){ // TODO: improve perf without anonymous callback as.via.back('opt.uuid')(function(err, soul){ // TODO: improve perf without anonymous callback
if(err){ return Gun.log(err) } // Handle error. if(err){ delete as.via._.stun; return Gun.log(err) } // Handle error.
as.ref.put(as.data, as.soul = soul, as); as.ref.put(as.data, as.soul = soul, as);
}); });
return; return;
@ -1790,9 +1819,10 @@
} }
if((tmp = eve.wait) && (tmp = tmp[at.id])){ clearTimeout(tmp) } if((tmp = eve.wait) && (tmp = tmp[at.id])){ clearTimeout(tmp) }
eve.ack = (eve.ack||0)+1; eve.ack = (eve.ack||0)+1;
if(!to && u === data && eve.ack <= (opt.acks || Object.keys(at.root.opt.peers).length)){ return } // TODO: super should not be in core code, bring AXE up into core instead to fix?
if(!to && u === data && !at.root.opt.super && eve.ack <= (opt.acks || Object.keys(at.root.opt.peers).length)){ return }
if((!to && (u === data || at.soul || at.link || (link && !(0 < link.ack)))) if((!to && (u === data || at.soul || at.link || (link && !(0 < link.ack))))
|| (u === data && (tmp = Object.keys(at.root.opt.peers).length) && (!to && (link||at).ack < tmp))){ || (u === data && !at.root.opt.super && (tmp = Object.keys(at.root.opt.peers).length) && (!to && (link||at).ack < tmp))){
tmp = (eve.wait = {})[at.id] = setTimeout(function(){ tmp = (eve.wait = {})[at.id] = setTimeout(function(){
val.call({as:opt}, msg, eve, tmp || 1); val.call({as:opt}, msg, eve, tmp || 1);
}, opt.wait || 99); }, opt.wait || 99);
@ -1890,17 +1920,20 @@
opt = opt || {}; opt.item = opt.item || item; opt = opt || {}; opt.item = opt.item || item;
if(soul = Gun.node.soul(item)){ item = Gun.obj.put({}, soul, Gun.val.link.ify(soul)) } if(soul = Gun.node.soul(item)){ item = Gun.obj.put({}, soul, Gun.val.link.ify(soul)) }
if(!Gun.is(item)){ if(!Gun.is(item)){
if(Gun.obj.is(item)){; if(Gun.obj.is(item)){
item = gun.back(-1).get(soul = soul || Gun.node.soul(item) || gun.back('opt.uuid')()).put(item); //item = gun.back(-1).get(soul = soul || Gun.node.soul(item) || (gun.back('opt.uuid') || uuid)()).put(item);
soul = soul || Gun.node.soul(item) || uuid(); // this just key now, not a soul.
} }
return gun.get(soul || (Gun.state.lex() + Gun.text.random(7))).put(item, cb, opt); return gun.get(soul || uuid()).put(item, cb, opt);
} }
item.get(function(soul, o, msg){ item.get(function(soul, o, msg){
if(!soul && item._.stun){ item._.on('res', function(){ this.off(); gun.set(item, cb, opt) }); return }
if(!soul){ return cb.call(gun, {err: Gun.log('Only a node can be linked! Not "' + msg.put + '"!')}) } if(!soul){ return cb.call(gun, {err: Gun.log('Only a node can be linked! Not "' + msg.put + '"!')}) }
gun.put(Gun.obj.put({}, soul, Gun.val.link.ify(soul)), cb, opt); gun.put(Gun.obj.put({}, soul, Gun.val.link.ify(soul)), cb, opt);
},true); },true);
return item; return item;
} }
function uuid(){ return Gun.state.lex() + Gun.text.random(7) }
})(USE, './set'); })(USE, './set');
;USE(function(module){ ;USE(function(module){
@ -2133,10 +2166,10 @@
var SMIA = 0; var SMIA = 0;
var message, loop; var message, loop;
function each(peer){ mesh.say(message, peer) } function each(peer){ mesh.say(message, peer) }
var say = mesh.say = function(msg, peer){ var say = mesh.say = function(msg, peer){ var tmp;
if(this.to){ this.to.next(msg) } // compatible with middleware adapters. if((tmp = this) && (tmp = tmp.to) && tmp.next){ tmp.next(msg) } // compatible with middleware adapters.
if(!msg){ return false } if(!msg){ return false }
var id, hash, tmp, raw; var id, hash, raw;
var DBG = msg.DBG, S; if(!peer){ S = +new Date ; DBG && (DBG.y = S) } var DBG = msg.DBG, S; if(!peer){ S = +new Date ; DBG && (DBG.y = S) }
var meta = msg._||(msg._=function(){}); var meta = msg._||(msg._=function(){});
if(!(id = msg['#'])){ id = msg['#'] = Type.text.random(9) } if(!(id = msg['#'])){ id = msg['#'] = Type.text.random(9) }
@ -2325,18 +2358,6 @@
} }
;(function(){ ;(function(){
Type.text.hash = function(s){ // via SO
if(typeof s !== 'string'){ return {err: 1} }
var c = 0;
if(!s.length){ return c }
for(var i=0,l=s.length,n; i<l; ++i){
n = s.charCodeAt(i);
c = ((c<<5)-c)+n;
c |= 0;
}
return c; // Math.abs(c);
}
var $ = JSON.stringify, u; var $ = JSON.stringify, u;
Type.obj.hash = function(obj, hash){ Type.obj.hash = function(obj, hash){
@ -2392,7 +2413,7 @@
mesh.wire = opt.wire = open; mesh.wire = opt.wire = open;
function open(peer){ try{ function open(peer){ try{
if(!peer || !peer.url){ return wire && wire(peer) } if(!peer || !peer.url){ return wire && wire(peer) }
var url = peer.url.replace('http', 'ws'); var url = peer.url.replace(/^http/, 'ws');
var wire = peer.wire = new opt.WebSocket(url); var wire = peer.wire = new opt.WebSocket(url);
wire.onclose = function(){ wire.onclose = function(){
opt.mesh.bye(peer); opt.mesh.bye(peer);

View File

@ -164,7 +164,7 @@
var o = {}; var o = {};
if(SEA.window){ if(SEA.window){
api.crypto = window.crypto || window.msCrypto api.crypto = navigator && navigator.product === 'ReactNative' ? require('isomorphic-webcrypto') : window.crypto || window.msCrypto || require('isomorphic-webcrypto');
api.subtle = (api.crypto||o).subtle || (api.crypto||o).webkitSubtle; api.subtle = (api.crypto||o).subtle || (api.crypto||o).webkitSubtle;
api.TextEncoder = window.TextEncoder; api.TextEncoder = window.TextEncoder;
api.TextDecoder = window.TextDecoder; api.TextDecoder = window.TextDecoder;
@ -176,20 +176,17 @@
api.TextDecoder = TextDecoder; api.TextDecoder = TextDecoder;
api.TextEncoder = TextEncoder; api.TextEncoder = TextEncoder;
} }
if(!api.crypto) if(!api.crypto){try{
{
try
{
var crypto = USE('crypto', 1); var crypto = USE('crypto', 1);
Object.assign(api, { Object.assign(api, {
crypto, crypto,
random: (len) => Buffer.from(crypto.randomBytes(len)) random: (len) => Buffer.from(crypto.randomBytes(len))
}); });
const { Crypto: WebCrypto } = USE('@peculiar/webcrypto', 1); const isocrypto = require('isomorphic-webcrypto');
api.ossl = api.subtle = new WebCrypto({directory: 'ossl'}).subtle // ECDH api.ossl = api.subtle = isocrypto.subtle;
} }catch(e){
catch(e){ console.log("text-encoding and @peculiar/webcrypto may not be included by default, please add it to your package.json!");
console.log("text-encoding and peculiar/nwebcrypto may not be included by default, please add it to your package.json!"); TEXT_ENCODING_OR_PECULIAR_WEBCRYPTO_NOT_INSTALLED;
}} }}
module.exports = api module.exports = api
@ -710,10 +707,9 @@
;USE(function(module){ ;USE(function(module){
var Gun = USE('./sea').Gun; var Gun = USE('./sea').Gun;
Gun.chain.then = function(cb, opt = {}){ Gun.chain.then = function(cb){
opt = {wait: 200, ...opt}
var gun = this, p = (new Promise(function(res, rej){ var gun = this, p = (new Promise(function(res, rej){
gun.once(res, opt); gun.once(res);
})); }));
return cb? p.then(cb) : p; return cb? p.then(cb) : p;
} }
@ -741,7 +737,7 @@
at.opt.uuid = function(cb){ at.opt.uuid = function(cb){
var id = uuid(), pub = root.user; var id = uuid(), pub = root.user;
if(!pub || !(pub = pub.is) || !(pub = pub.pub)){ return id } if(!pub || !(pub = pub.is) || !(pub = pub.pub)){ return id }
id = id + '~' + pub + '.'; id = id + '~' + pub + '/';
if(cb && cb.call){ cb(null, id) } if(cb && cb.call){ cb(null, id) }
return id; return id;
} }
@ -1087,43 +1083,6 @@
}()); }());
return gun; return gun;
} }
/**
* returns the decrypted value, encrypted by secret
* @returns {Promise<any>}
*/
User.prototype.decrypt = function(cb) {
let gun = this,
path = ''
gun.back(function(at) {
if (at.is) {
return
}
path += at.get || ''
})
return gun
.then(async data => {
if (data == null) {
return
}
const user = gun.back(-1).user()
const pair = user.pair()
let sec = await user
.get('trust')
.get(pair.pub)
.get(path)
sec = await SEA.decrypt(sec, pair)
if (!sec) {
return data
}
let decrypted = await SEA.decrypt(data, sec)
return decrypted
})
.then(res => {
cb && cb(res)
return res
})
}
module.exports = User module.exports = User
})(USE, './create'); })(USE, './create');
@ -1190,6 +1149,7 @@
var u; var u;
function check(msg){ // REVISE / IMPROVE, NO NEED TO PASS MSG/EVE EACH SUB? function check(msg){ // REVISE / IMPROVE, NO NEED TO PASS MSG/EVE EACH SUB?
var eve = this, at = eve.as, put = msg.put, soul = put['#'], key = put['.'], val = put[':'], state = put['>'], id = msg['#'], tmp; var eve = this, at = eve.as, put = msg.put, soul = put['#'], key = put['.'], val = put[':'], state = put['>'], id = msg['#'], tmp;
if(!soul || !key){ return }
if((msg._||'').faith && (at.opt||'').faith && 'function' == typeof msg._){ if((msg._||'').faith && (at.opt||'').faith && 'function' == typeof msg._){
SEA.verify(SEA.opt.pack(put), false, function(data){ // this is synchronous if false SEA.verify(SEA.opt.pack(put), false, function(data){ // this is synchronous if false
put['='] = SEA.opt.unpack(data); put['='] = SEA.opt.unpack(data);
@ -1200,8 +1160,13 @@
var no = function(why){ at.on('in', {'@': id, err: why}) }; var no = function(why){ at.on('in', {'@': id, err: why}) };
//var no = function(why){ msg.ack(why) }; //var no = function(why){ msg.ack(why) };
(msg._||'').DBG && ((msg._||'').DBG.c = +new Date); (msg._||'').DBG && ((msg._||'').DBG.c = +new Date);
if('#' === soul[0]){ // special case for content addressing immutable hashed data. if(0 <= soul.indexOf('<?')){ // special case for "do not sync data X old"
check.hash(eve, msg, val, key, soul, at, no); return; // 'a~pub.key/b<?9'
tmp = parseFloat(soul.split('<?')[1]||'');
if(tmp && (state < (Gun.state() - (tmp * 1000)))){ // sec to ms
(tmp = msg._) && (tmp = tmp.lot) && (tmp.more--); // THIS IS BAD CODE! It assumes GUN internals do something that will probably change in future, but hacking in now.
return; // omit!
}
} }
if('~@' === soul){ // special case for shared system data, the list of aliases. if('~@' === soul){ // special case for shared system data, the list of aliases.
check.alias(eve, msg, val, key, soul, at, no); return; check.alias(eve, msg, val, key, soul, at, no); return;
@ -1213,6 +1178,9 @@
if(tmp = SEA.opt.pub(soul)){ // special case, account data for a public key. if(tmp = SEA.opt.pub(soul)){ // special case, account data for a public key.
check.pub(eve, msg, val, key, soul, at, no, at.user||'', tmp); return; check.pub(eve, msg, val, key, soul, at, no, at.user||'', tmp); return;
} }
if(0 <= soul.indexOf('#')){ // special case for content addressing immutable hashed data.
check.hash(eve, msg, val, key, soul, at, no); return;
}
check.any(eve, msg, val, key, soul, at, no, at.user||''); return; check.any(eve, msg, val, key, soul, at, no, at.user||''); return;
eve.to.next(msg); // not handled eve.to.next(msg); // not handled
} }
@ -1420,13 +1388,14 @@
} }
to.next(msg); // pass forward any data we do not know how to handle or process (this allows custom security protocols). to.next(msg); // pass forward any data we do not know how to handle or process (this allows custom security protocols).
} }
var pubcut = /[^\w_-]/; // anything not alphanumeric or _ -
SEA.opt.pub = function(s){ SEA.opt.pub = function(s){
if(!s){ return } if(!s){ return }
s = s.split('~'); s = s.split('~');
if(!s || !(s = s[1])){ return } if(!s || !(s = s[1])){ return }
s = s.split('.'); s = s.split(pubcut).slice(0,2);
if(!s || 2 > s.length){ return } if(!s || 2 != s.length){ return }
if('@' === (s[0]||'')[0]){ return } // TODO: Should check ~X.Y. are alphanumeric, not just not @. if('@' === (s[0]||'')[0]){ return }
s = s.slice(0,2).join('.'); s = s.slice(0,2).join('.');
return s; return s;
} }

View File

@ -8,7 +8,7 @@ Gun.on('create', function(root){
var Radisk = (Gun.window && Gun.window.Radisk) || require('./radisk'); var Radisk = (Gun.window && Gun.window.Radisk) || require('./radisk');
var Radix = Radisk.Radix; var Radix = Radisk.Radix;
var ST = 0; var ST = 0;
// TODO: BUG! For RN storage, RN does not like the following require:
opt.store = opt.store || (!Gun.window && require('./rfs')(opt)); opt.store = opt.store || (!Gun.window && require('./rfs')(opt));
var dare = Radisk(opt), esc = String.fromCharCode(27); var dare = Radisk(opt), esc = String.fromCharCode(27);