mirror of
https://github.com/amark/gun.git
synced 2025-03-30 15:08:33 +00:00
fix once, unbuild NAB fix
This commit is contained in:
parent
5289126d13
commit
c16c41807e
2
gun.js
2
gun.js
@ -1662,7 +1662,7 @@
|
||||
}
|
||||
if((tmp = eve.wait) && (tmp = tmp[at.id])){ clearTimeout(tmp) }
|
||||
if((!to && (u === data || at.soul || at.link || (link && !(0 < link.ack))))
|
||||
|| (u === data && (link||at).ack <= ((obj_map(at.root.opt.peers, function(v,k,t){t(k)}))||[]).length)){
|
||||
|| (u === data && (tmp = (obj_map(at.root.opt.peers, function(v,k,t){t(k)})||[]).length) && (link||at).ack <= tmp)){
|
||||
tmp = (eve.wait = {})[at.id] = setTimeout(function(){
|
||||
val.call({as:opt}, msg, eve, tmp || 1);
|
||||
}, opt.wait || 99);
|
||||
|
4
gun.min.js
vendored
4
gun.min.js
vendored
File diff suppressed because one or more lines are too long
@ -7,7 +7,7 @@
|
||||
const authenticate = async (alias, pass, gunRoot) => {
|
||||
// load all public keys associated with the username alias we want to log in with.
|
||||
const aliases = (await queryGunAliases(alias, gunRoot))
|
||||
.filter(({ pub, at: { put } = {} } = {}) => !!pub && !!put)
|
||||
.filter(a => !!a.pub && !!a.put)
|
||||
// Got any?
|
||||
if (!aliases.length) {
|
||||
throw { err: 'Public key does not exist!' }
|
||||
@ -15,14 +15,14 @@
|
||||
let err
|
||||
// then attempt to log into each one until we find ours!
|
||||
// (if two users have the same username AND the same password... that would be bad)
|
||||
const users = await Promise.all(aliases.map(async ({ at: at, pub: pub }, i) => {
|
||||
const users = await Promise.all(aliases.map(async (a, i) => {
|
||||
// attempt to PBKDF2 extend the password with the salt. (Verifying the signature gives us the plain text salt.)
|
||||
const auth = parseProps(at.put.auth)
|
||||
const auth = parseProps(a.put.auth)
|
||||
// NOTE: aliasquery uses `gun.get` which internally SEA.read verifies the data for us, so we do not need to re-verify it here.
|
||||
// SEA.verify(at.put.auth, pub).then(function(auth){
|
||||
try {
|
||||
const proof = await SEA.work(pass, auth.s)
|
||||
const props = { pub: pub, proof: proof, at: at }
|
||||
//const props = { pub: pub, proof: proof, at: at }
|
||||
// the proof of work is evidence that we've spent some time/effort trying to log in, this slows brute force.
|
||||
/*
|
||||
MARK TO @mhelander : pub vs epub!???
|
||||
@ -30,24 +30,24 @@
|
||||
const salt = auth.salt
|
||||
const sea = await SEA.decrypt(auth.ek, proof)
|
||||
if (!sea) {
|
||||
err = 'Failed to decrypt secret! ' + i +'/'+aliases.length;
|
||||
err = 'Failed to decrypt secret! ' + (i+1) +'/'+aliases.length;
|
||||
return
|
||||
}
|
||||
// now we have AES decrypted the private key, from when we encrypted it with the proof at registration.
|
||||
// if we were successful, then that meanswe're logged in!
|
||||
const priv = sea.priv
|
||||
const epriv = sea.epriv
|
||||
const epub = at.put.epub
|
||||
const epub = a.put.epub
|
||||
// TODO: 'salt' needed?
|
||||
err = null
|
||||
if(typeof window !== 'undefined'){
|
||||
var tmp = window.sessionStorage;
|
||||
if(SEA.window){
|
||||
var tmp = SEA.window.sessionStorage;
|
||||
if(tmp && gunRoot._.opt.remember){
|
||||
window.sessionStorage.alias = alias;
|
||||
window.sessionStorage.tmp = pass;
|
||||
SEA.window.sessionStorage.alias = alias;
|
||||
SEA.window.sessionStorage.tmp = pass;
|
||||
}
|
||||
}
|
||||
return Object.assign(props, { priv: priv, salt: salt, epub: epub, epriv: epriv })
|
||||
return {priv: priv, pub: a.put.pub, salt: salt, epub: epub, epriv: epriv };
|
||||
} catch (e) {
|
||||
err = 'Failed to decrypt secret!'
|
||||
throw { err }
|
||||
|
@ -202,7 +202,8 @@
|
||||
}
|
||||
// If authentication is to be remembered over reloads or browser closing,
|
||||
// set validity time in minutes.
|
||||
User.prototype.recall = async function(setvalidity, options){
|
||||
User.prototype.recall = function(setvalidity, options){
|
||||
var gun = this;
|
||||
const gunRoot = this.back(-1)
|
||||
|
||||
let validity
|
||||
@ -219,7 +220,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
return gun;
|
||||
}
|
||||
|
||||
if (!Gun.val.is(setvalidity)) {
|
||||
@ -242,13 +243,15 @@
|
||||
authsettings.hook = (Gun.obj.has(opts, 'hook') && typeof opts.hook === 'function')
|
||||
? opts.hook : _initial_authsettings.hook
|
||||
// All is good. Should we do something more with actual recalled data?
|
||||
return await authRecall(gunRoot)
|
||||
(async function(){ await authRecall(gunRoot) }());
|
||||
return gun;
|
||||
} catch (e) {
|
||||
const err = 'No session!'
|
||||
Gun.log(err)
|
||||
// NOTE! It's fine to resolve recall with reason why not successful
|
||||
// instead of rejecting...
|
||||
return { err: (e && e.err) || err }
|
||||
//return { err: (e && e.err) || err }
|
||||
return gun;
|
||||
}
|
||||
}
|
||||
User.prototype.alive = async function(){
|
||||
|
@ -5,23 +5,22 @@
|
||||
var aeskey = require('./aeskey');
|
||||
var parse = require('./parse');
|
||||
|
||||
SEA.decrypt = async (data, pair, cb, opt) => { try {
|
||||
SEA.decrypt = SEA.decrypt || (async (data, pair, cb, opt) => { try {
|
||||
var opt = opt || {};
|
||||
const key = pair.epriv || pair;
|
||||
const json = parse(data)
|
||||
const ct = await aeskey(key, shim.Buffer.from(json.s, 'utf8'), opt)
|
||||
.then((aes) => shim.subtle.decrypt({ // Keeping aesKey scope as private as possible...
|
||||
.then((aes) => (/*shim.ossl ||*/ shim.subtle).decrypt({ // Keeping aesKey scope as private as possible...
|
||||
name: opt.name || 'AES-GCM', iv: new Uint8Array(shim.Buffer.from(json.iv, 'utf8'))
|
||||
}, aes, new Uint8Array(shim.Buffer.from(json.ct, 'utf8'))))
|
||||
const r = parse(new shim.TextDecoder('utf8').decode(ct))
|
||||
|
||||
if(cb){ try{ cb(r) }catch(e){console.log(e)} }
|
||||
return r;
|
||||
} catch(e) {
|
||||
SEA.err = e;
|
||||
if(cb){ cb() }
|
||||
return;
|
||||
}}
|
||||
}});
|
||||
|
||||
module.exports = SEA.decrypt;
|
||||
|
@ -4,13 +4,13 @@
|
||||
var S = require('./settings');
|
||||
var aeskey = require('./aeskey');
|
||||
|
||||
SEA.encrypt = async (data, pair, cb, opt) => { try {
|
||||
SEA.encrypt = SEA.encrypt || (async (data, pair, cb, opt) => { try {
|
||||
var opt = opt || {};
|
||||
const key = pair.epriv || pair;
|
||||
const msg = JSON.stringify(data)
|
||||
const rand = {s: shim.random(8), iv: shim.random(16)};
|
||||
const ct = await aeskey(key, rand.s, opt)
|
||||
.then((aes) => shim.subtle.encrypt({ // Keeping the AES key scope as private as possible...
|
||||
.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)
|
||||
}, aes, new shim.TextEncoder().encode(msg)))
|
||||
const r = 'SEA'+JSON.stringify({
|
||||
@ -25,7 +25,7 @@
|
||||
SEA.err = e;
|
||||
if(cb){ cb() }
|
||||
return;
|
||||
}}
|
||||
}});
|
||||
|
||||
module.exports = SEA.encrypt;
|
||||
|
@ -62,6 +62,7 @@
|
||||
// if there is a request to read data from us, then...
|
||||
var soul = msg.get['#'];
|
||||
if(soul){ // for now, only allow direct IDs to be read.
|
||||
if(soul !== 'string'){ return to.next(msg) } // do not handle lexical cursors.
|
||||
if('alias' === soul){ // Allow reading the list of usernames/aliases in the system?
|
||||
return to.next(msg); // yes.
|
||||
} else
|
||||
@ -149,7 +150,7 @@
|
||||
if(tmp = relpub(soul)){
|
||||
check['any'+soul+key] = 1;
|
||||
SEA.verify(val, pub = tmp, function(data){ var rel;
|
||||
if(u === data){ return each.end({err: "Mismatched owner on '" + key + "'."}) }
|
||||
if(u === data){ return each.end({err: "Mismatched owner on '" + key + "'."}) } // thanks @rogowski !
|
||||
if((rel = Gun.val.link.is(data)) && pub === relpub(rel)){
|
||||
(at.sea.own[rel] = at.sea.own[rel] || {})[pub] = true;
|
||||
}
|
||||
@ -225,4 +226,4 @@
|
||||
to.next(msg); // pass forward any data we do not know how to handle or process (this allows custom security protocols).
|
||||
}
|
||||
|
||||
|
||||
|
22
sea/login.js
22
sea/login.js
@ -4,10 +4,25 @@
|
||||
const finalizeLogin = async (alias, key, gunRoot, opts) => {
|
||||
const user = gunRoot._.user
|
||||
// add our credentials in-memory only to our root gun instance
|
||||
//var tmp = user._.tag;
|
||||
var tmp = user._.tag;
|
||||
var opt = user._.opt;
|
||||
user._ = key.at.$._;
|
||||
user._ = gunRoot.get('~'+key.pub)._;
|
||||
user._.opt = opt;
|
||||
var tags = user._.tag;
|
||||
/*Object.values && Object.values(tmp).forEach(function(tag){
|
||||
// TODO: This is ugly & buggy code, it needs to be refactored & tested into a event "merge" utility.
|
||||
var t = tags[tag.tag];
|
||||
console.log("hm??", tag, t);
|
||||
if(!t){
|
||||
tags[tag.tag] = tag;
|
||||
return;
|
||||
}
|
||||
if(tag.last){
|
||||
tag.last.to = t.to;
|
||||
t.last = tag.last = t.last || tag.last;
|
||||
}
|
||||
t.to = tag.to;
|
||||
})*/
|
||||
//user._.tag = tmp || user._.tag;
|
||||
// so that way we can use the credentials to encrypt/decrypt data
|
||||
// that is input/output through gun (see below)
|
||||
@ -22,7 +37,8 @@
|
||||
//await authPersist(user._, key.proof, opts) // temporarily disabled
|
||||
// emit an auth event, useful for page redirects and stuff.
|
||||
try {
|
||||
gunRoot._.on('auth', user._)
|
||||
gunRoot._.on('auth', user._) // TODO: Deprecate this, emit on user instead! Update docs when you do.
|
||||
//user._.on('auth', user._) // Arrgh, this doesn't work without event "merge" code, but "merge" code causes stack overflow and crashes after logging in & trying to write data.
|
||||
} catch (e) {
|
||||
console.log('Your \'auth\' callback crashed with:', e)
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
var Buff = (typeof Buffer !== 'undefined')? Buffer : shim.Buffer;
|
||||
|
||||
//SEA.pair = async (data, proof, cb) => { try {
|
||||
SEA.pair = async (cb) => { try {
|
||||
SEA.pair = SEA.pair || (async (cb) => { try {
|
||||
|
||||
const ecdhSubtle = shim.ossl || shim.subtle
|
||||
// First: ECDSA keys for signing/verifying...
|
||||
@ -56,7 +56,7 @@
|
||||
SEA.err = e;
|
||||
if(cb){ cb() }
|
||||
return;
|
||||
}}
|
||||
}});
|
||||
|
||||
module.exports = SEA.pair;
|
||||
|
15
sea/query.js
15
sea/query.js
@ -4,9 +4,9 @@
|
||||
// This is internal func queries public key(s) for alias.
|
||||
const queryGunAliases = (alias, gunRoot) => new Promise((resolve, reject) => {
|
||||
// load all public keys associated with the username alias we want to log in with.
|
||||
gunRoot.get('~@'+alias).get((rat, rev) => {
|
||||
rev.off();
|
||||
if (!rat.put) {
|
||||
gunRoot.get('~@'+alias).once((data, key) => {
|
||||
//rev.off();
|
||||
if (!data) {
|
||||
// if no user, don't do anything.
|
||||
const err = 'No user!'
|
||||
Gun.log(err)
|
||||
@ -16,19 +16,18 @@
|
||||
const aliases = []
|
||||
let c = 0
|
||||
// TODO: how about having real chainable map without callback ?
|
||||
Gun.obj.map(rat.put, (at, pub) => {
|
||||
Gun.obj.map(data, (at, pub) => {
|
||||
if (!pub.slice || '~' !== pub.slice(0, 1)) {
|
||||
// TODO: ... this would then be .filter((at, pub))
|
||||
return
|
||||
}
|
||||
++c
|
||||
// grab the account associated with this public key.
|
||||
gunRoot.get(pub).get((at, ev) => {
|
||||
gunRoot.get(pub).once(data => {
|
||||
pub = pub.slice(1)
|
||||
ev.off()
|
||||
--c
|
||||
if (at.put){
|
||||
aliases.push({ pub, at })
|
||||
if (data){
|
||||
aliases.push({ pub, put: data })
|
||||
}
|
||||
if (!c && (c = -1)) {
|
||||
resolve(aliases)
|
||||
|
18
sea/root.js
18
sea/root.js
@ -1,10 +1,22 @@
|
||||
|
||||
// Security, Encryption, and Authorization: SEA.js
|
||||
// MANDATORY READING: http://gun.js.org/explainers/data/security.html
|
||||
// MANDATORY READING: https://gun.eco/explainers/data/security.html
|
||||
// IT IS IMPLEMENTED IN A POLYFILL/SHIM APPROACH.
|
||||
// THIS IS AN EARLY ALPHA!
|
||||
|
||||
function SEA(){}
|
||||
if(typeof window !== "undefined"){ (SEA.window = window).SEA = SEA }
|
||||
if(typeof window !== "undefined"){ module.window = window }
|
||||
|
||||
var tmp = module.window || module;
|
||||
var SEA = tmp.SEA || function(){};
|
||||
|
||||
if(SEA.window = module.window){ try{
|
||||
SEA.window.SEA = SEA;
|
||||
tmp = document.createEvent('CustomEvent');
|
||||
tmp.initCustomEvent('extension', false, false, {type: "SEA"});
|
||||
(window.dispatchEvent || window.fireEvent)(tmp);
|
||||
window.postMessage({type: "SEA"}, '*');
|
||||
} catch(e){} }
|
||||
|
||||
try{ if(typeof common !== "undefined"){ common.exports = SEA } }catch(e){}
|
||||
module.exports = SEA;
|
||||
|
10
sea/sea.js
10
sea/sea.js
@ -29,7 +29,7 @@
|
||||
SEA.encrypt = require('./encrypt');
|
||||
SEA.decrypt = require('./decrypt');
|
||||
|
||||
SEA.random = getRandomBytes;
|
||||
SEA.random = SEA.random || getRandomBytes;
|
||||
|
||||
// This is easy way to use IndexedDB, all methods are Promises
|
||||
// Note: Not all SEA interfaces have to support this.
|
||||
@ -37,7 +37,7 @@
|
||||
|
||||
// This is Buffer used in SEA and usable from Gun/SEA application also.
|
||||
// For documentation see https://nodejs.org/api/buffer.html
|
||||
SEA.Buffer = Buffer;
|
||||
SEA.Buffer = SEA.Buffer || Buffer;
|
||||
|
||||
// These SEA functions support now ony Promises or
|
||||
// async/await (compatible) code, use those like Promises.
|
||||
@ -45,7 +45,7 @@
|
||||
// Creates a wrapper library around Web Crypto API
|
||||
// for various AES, ECDSA, PBKDF2 functions we called above.
|
||||
// Calculate public key KeyID aka PGPv4 (result: 8 bytes as hex string)
|
||||
SEA.keyid = async (pub) => {
|
||||
SEA.keyid = SEA.keyid || (async (pub) => {
|
||||
try {
|
||||
// base64('base64(x):base64(y)') => Buffer(xy)
|
||||
const pb = Buffer.concat(
|
||||
@ -63,7 +63,7 @@
|
||||
console.log(e)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
});
|
||||
// all done!
|
||||
// Obviously it is missing MANY necessary features. This is only an alpha release.
|
||||
// Please experiment with it, audit what I've done so far, and complain about what needs to be added.
|
||||
@ -73,7 +73,7 @@
|
||||
// But all other behavior needs to be equally easy, like opinionated ways of
|
||||
// Adding friends (trusted public keys), sending private messages, etc.
|
||||
// Cheers! Tell me what you think.
|
||||
var Gun = (SEA.window||{}).Gun || require('./gun');
|
||||
var Gun = (SEA.window||{}).Gun || require('./gun', 1);
|
||||
Gun.SEA = SEA;
|
||||
SEA.Gun = Gun;
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
var shim = require('./shim');
|
||||
var S = require('./settings');
|
||||
// Derive shared secret from other's pub and my epub/epriv
|
||||
SEA.secret = async (key, pair, cb) => { try {
|
||||
SEA.secret = SEA.secret || (async (key, pair, cb) => { try {
|
||||
const pub = key.epub || key
|
||||
const epub = pair.epub
|
||||
const epriv = pair.epriv
|
||||
@ -27,7 +27,7 @@
|
||||
SEA.err = e;
|
||||
if(cb){ cb() }
|
||||
return;
|
||||
}}
|
||||
}});
|
||||
|
||||
const keysToEcdhJwk = (pub, d) => { // d === priv
|
||||
//const [ x, y ] = Buffer.from(pub, 'base64').toString('utf8').split(':') // old
|
||||
|
@ -1,4 +1,5 @@
|
||||
|
||||
const SEA = require('./root');
|
||||
const Buffer = require('./buffer')
|
||||
const settings = {}
|
||||
// Encryption parameters
|
||||
@ -35,5 +36,6 @@
|
||||
jwk: keysToEcdsaJwk,
|
||||
recall: authsettings
|
||||
})
|
||||
SEA.opt = settings;
|
||||
module.exports = settings
|
||||
|
10
sea/shim.js
10
sea/shim.js
@ -2,7 +2,7 @@
|
||||
const Buffer = require('./buffer')
|
||||
const api = {Buffer: Buffer}
|
||||
|
||||
if (typeof __webpack_require__ === 'function' || typeof window !== 'undefined') {
|
||||
if (typeof window !== 'undefined') {
|
||||
var crypto = window.crypto || window.msCrypto;
|
||||
var subtle = crypto.subtle || crypto.webkitSubtle;
|
||||
const TextEncoder = window.TextEncoder
|
||||
@ -16,9 +16,9 @@
|
||||
})
|
||||
} else {
|
||||
try{
|
||||
var crypto = require('crypto');
|
||||
const { subtle } = require('@trust/webcrypto') // All but ECDH
|
||||
const { TextEncoder, TextDecoder } = require('text-encoding')
|
||||
var crypto = require('crypto', 1);
|
||||
const { subtle } = require('@trust/webcrypto', 1) // All but ECDH
|
||||
const { TextEncoder, TextDecoder } = require('text-encoding', 1)
|
||||
Object.assign(api, {
|
||||
crypto,
|
||||
subtle,
|
||||
@ -27,7 +27,7 @@
|
||||
random: (len) => Buffer.from(crypto.randomBytes(len))
|
||||
});
|
||||
//try{
|
||||
const WebCrypto = require('node-webcrypto-ossl')
|
||||
const WebCrypto = require('node-webcrypto-ossl', 1)
|
||||
api.ossl = new WebCrypto({directory: 'ossl'}).subtle // ECDH
|
||||
//}catch(e){
|
||||
//console.log("node-webcrypto-ossl is optionally needed for ECDH, please install if needed.");
|
||||
|
10
sea/sign.js
10
sea/sign.js
@ -4,8 +4,8 @@
|
||||
var S = require('./settings');
|
||||
var sha256hash = require('./sha256');
|
||||
|
||||
SEA.sign = async (data, pair, cb) => { try {
|
||||
if(data.slice
|
||||
SEA.sign = SEA.sign || (async (data, pair, cb) => { try {
|
||||
if(data && data.slice
|
||||
&& 'SEA{' === data.slice(0,4)
|
||||
&& '"m":' === data.slice(4,8)){
|
||||
// TODO: This would prevent pair2 signing pair1's signature.
|
||||
@ -19,8 +19,8 @@
|
||||
const jwk = S.jwk(pub, priv)
|
||||
const msg = JSON.stringify(data)
|
||||
const hash = await sha256hash(msg)
|
||||
const sig = await shim.subtle.importKey('jwk', jwk, S.ecdsa.pair, false, ['sign'])
|
||||
.then((key) => shim.subtle.sign(S.ecdsa.sign, key, new Uint8Array(hash))) // privateKey scope doesn't leak out from here!
|
||||
const sig = await (shim.ossl || shim.subtle).importKey('jwk', jwk, S.ecdsa.pair, false, ['sign'])
|
||||
.then((key) => (shim.ossl || shim.subtle).sign(S.ecdsa.sign, key, new Uint8Array(hash))) // privateKey scope doesn't leak out from here!
|
||||
const r = 'SEA'+JSON.stringify({m: msg, s: shim.Buffer.from(sig, 'binary').toString('utf8')});
|
||||
|
||||
if(cb){ try{ cb(r) }catch(e){console.log(e)} }
|
||||
@ -30,7 +30,7 @@
|
||||
SEA.err = e;
|
||||
if(cb){ cb() }
|
||||
return;
|
||||
}}
|
||||
}});
|
||||
|
||||
module.exports = SEA.sign;
|
||||
|
@ -6,7 +6,7 @@
|
||||
var parse = require('./parse');
|
||||
var u;
|
||||
|
||||
SEA.verify = async (data, pair, cb) => { try {
|
||||
SEA.verify = SEA.verify || (async (data, pair, cb) => { try {
|
||||
const json = parse(data)
|
||||
if(false === pair){ // don't verify!
|
||||
const raw = (json !== data)?
|
||||
@ -31,7 +31,7 @@
|
||||
SEA.err = e;
|
||||
if(cb){ cb() }
|
||||
return;
|
||||
}}
|
||||
}});
|
||||
|
||||
module.exports = SEA.verify;
|
||||
|
47
sea/work.js
47
sea/work.js
@ -2,49 +2,40 @@
|
||||
var SEA = require('./root');
|
||||
var shim = require('./shim');
|
||||
var S = require('./settings');
|
||||
var sha = require('./sha256');
|
||||
var u;
|
||||
|
||||
SEA.work = async (data, pair, cb) => { try { // used to be named `proof`
|
||||
var salt = pair.epub || pair; // epub not recommended, salt should be random!
|
||||
SEA.work = SEA.work || (async (data, pair, cb, opt) => { try { // used to be named `proof`
|
||||
var salt = (pair||{}).epub || pair; // epub not recommended, salt should be random!
|
||||
var opt = opt || {};
|
||||
if(salt instanceof Function){
|
||||
cb = salt;
|
||||
salt = u;
|
||||
}
|
||||
salt = salt || shim.random(9);
|
||||
if (SEA.window) {
|
||||
// For browser subtle works fine
|
||||
const key = await shim.subtle.importKey(
|
||||
'raw', new shim.TextEncoder().encode(data), { name: 'PBKDF2' }, false, ['deriveBits']
|
||||
)
|
||||
const result = await shim.subtle.deriveBits({
|
||||
name: 'PBKDF2',
|
||||
iterations: S.pbkdf2.iter,
|
||||
salt: new shim.TextEncoder().encode(salt),
|
||||
hash: S.pbkdf2.hash,
|
||||
}, key, S.pbkdf2.ks * 8)
|
||||
data = shim.random(data.length) // Erase data in case of passphrase
|
||||
const r = shim.Buffer.from(result, 'binary').toString('utf8')
|
||||
if(cb){ try{ cb(r) }catch(e){console.log(e)} }
|
||||
return r;
|
||||
if('SHA-256' === opt.name){
|
||||
var rsha = shim.Buffer.from(await sha(data), 'binary').toString('utf8')
|
||||
if(cb){ try{ cb(rsha) }catch(e){console.log(e)} }
|
||||
return rsha;
|
||||
}
|
||||
// For NodeJS crypto.pkdf2 rocks
|
||||
const crypto = shim.crypto;
|
||||
const hash = crypto.pbkdf2Sync(
|
||||
data,
|
||||
new shim.TextEncoder().encode(salt),
|
||||
S.pbkdf2.iter,
|
||||
S.pbkdf2.ks,
|
||||
S.pbkdf2.hash.replace('-', '').toLowerCase()
|
||||
const key = await (shim.ossl || shim.subtle).importKey(
|
||||
'raw', new shim.TextEncoder().encode(data), { name: opt.name || 'PBKDF2' }, false, ['deriveBits']
|
||||
)
|
||||
data = shim.random(data.length) // Erase passphrase for app
|
||||
const r = hash && hash.toString('utf8')
|
||||
const result = await (shim.ossl || shim.subtle).deriveBits({
|
||||
name: opt.name || 'PBKDF2',
|
||||
iterations: opt.iterations || S.pbkdf2.iter,
|
||||
salt: new shim.TextEncoder().encode(opt.salt || salt),
|
||||
hash: opt.hash || S.pbkdf2.hash,
|
||||
}, key, opt.length || (S.pbkdf2.ks * 8))
|
||||
data = shim.random(data.length) // Erase data in case of passphrase
|
||||
const r = shim.Buffer.from(result, 'binary').toString('utf8')
|
||||
if(cb){ try{ cb(r) }catch(e){console.log(e)} }
|
||||
return r;
|
||||
} catch(e) {
|
||||
SEA.err = e;
|
||||
if(cb){ cb() }
|
||||
return;
|
||||
}}
|
||||
}});
|
||||
|
||||
module.exports = SEA.work;
|
||||
|
@ -21,7 +21,7 @@ Gun.on('opt', function(root){
|
||||
|
||||
var wire = opt.wire;
|
||||
opt.wire = open;
|
||||
function open(peer){
|
||||
function open(peer){ try{
|
||||
if(!peer || !peer.url){ return wire && wire(peer) }
|
||||
var url = peer.url.replace('http', 'ws');
|
||||
var wire = peer.wire = new opt.WebSocket(url);
|
||||
@ -44,7 +44,7 @@ Gun.on('opt', function(root){
|
||||
opt.mesh.hear(msg.data || msg, peer);
|
||||
};
|
||||
return wire;
|
||||
}
|
||||
}catch(e){}}
|
||||
|
||||
function reconnect(peer){
|
||||
clearTimeout(peer.defer);
|
||||
|
@ -84,7 +84,8 @@ function val(msg, eve, to){
|
||||
data = tmp.put;
|
||||
}
|
||||
if((tmp = eve.wait) && (tmp = tmp[at.id])){ clearTimeout(tmp) }
|
||||
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 = (obj_map(at.root.opt.peers, function(v,k,t){t(k)})||[]).length) && (link||at).ack <= tmp)){
|
||||
tmp = (eve.wait = {})[at.id] = setTimeout(function(){
|
||||
val.call({as:opt}, msg, eve, tmp || 1);
|
||||
}, opt.wait || 99);
|
||||
|
@ -1,16 +1,17 @@
|
||||
|
||||
var root;
|
||||
if(typeof window !== "undefined"){ root = window }
|
||||
if(typeof global !== "undefined"){ root = global }
|
||||
root = root || {};
|
||||
var console = root.console || {log: function(){}};
|
||||
function USE(arg){
|
||||
return arg.slice? USE[R(arg)] : function(mod, path){
|
||||
arg(mod = {exports: {}});
|
||||
USE[R(path)] = mod.exports;
|
||||
}
|
||||
function R(p){
|
||||
return p.split('/').slice(-1).toString().replace('.js','');
|
||||
}
|
||||
}
|
||||
if(typeof module !== "undefined"){ var common = module }
|
||||
var root;
|
||||
if(typeof window !== "undefined"){ root = window }
|
||||
if(typeof global !== "undefined"){ root = global }
|
||||
root = root || {};
|
||||
var console = root.console || {log: function(){}};
|
||||
function USE(arg, req){
|
||||
return req? require(arg) : arg.slice? USE[R(arg)] : function(mod, path){
|
||||
arg(mod = {exports: {}});
|
||||
USE[R(path)] = mod.exports;
|
||||
}
|
||||
function R(p){
|
||||
return p.split('/').slice(-1).toString().replace('.js','');
|
||||
}
|
||||
}
|
||||
if(typeof module !== "undefined"){ var common = module }
|
||||
|
Loading…
x
Reference in New Issue
Block a user