|
|
|
@ -34,6 +34,8 @@ define([
|
|
|
|
|
NetConfig, AppConfig,
|
|
|
|
|
Crypto, ChainPad, CpNetflux, Listmap, nThen, Saferphore) {
|
|
|
|
|
|
|
|
|
|
var onReadyEvt = Util.mkEvent(true);
|
|
|
|
|
|
|
|
|
|
// Default settings for new users
|
|
|
|
|
var NEW_USER_SETTINGS = {
|
|
|
|
|
drive: {
|
|
|
|
@ -598,6 +600,7 @@ define([
|
|
|
|
|
pendingFriends: store.proxy.friends_pending || {},
|
|
|
|
|
supportPrivateKey: Util.find(store.proxy, ['mailboxes', 'supportadmin', 'keys', 'curvePrivate']),
|
|
|
|
|
accountName: store.proxy.login_name || '',
|
|
|
|
|
offline: store.offline,
|
|
|
|
|
teams: teams,
|
|
|
|
|
plan: account.plan
|
|
|
|
|
}
|
|
|
|
@ -1035,9 +1038,6 @@ define([
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
Store.setPadTitle = function (clientId, data, cb) {
|
|
|
|
|
if (store.offline) {
|
|
|
|
|
return void cb({ error: 'OFFLINE' });
|
|
|
|
|
}
|
|
|
|
|
var title = data.title;
|
|
|
|
|
var href = data.href;
|
|
|
|
|
var channel = data.channel;
|
|
|
|
@ -1110,6 +1110,11 @@ define([
|
|
|
|
|
Array.prototype.push.apply(allData, res);
|
|
|
|
|
});
|
|
|
|
|
var contains = allData.length !== 0;
|
|
|
|
|
if (store.offline && !contains) {
|
|
|
|
|
return void cb({ error: 'OFFLINE' });
|
|
|
|
|
} else if (store.offline) {
|
|
|
|
|
return void cb();
|
|
|
|
|
}
|
|
|
|
|
allData.forEach(function (obj) {
|
|
|
|
|
var pad = obj.data;
|
|
|
|
|
pad.atime = +new Date();
|
|
|
|
@ -1410,13 +1415,15 @@ define([
|
|
|
|
|
// Universal
|
|
|
|
|
Store.universal = {
|
|
|
|
|
execCommand: function (clientId, obj, cb) {
|
|
|
|
|
var type = obj.type;
|
|
|
|
|
var data = obj.data;
|
|
|
|
|
if (store.modules[type]) {
|
|
|
|
|
store.modules[type].execCommand(clientId, data, cb);
|
|
|
|
|
} else {
|
|
|
|
|
return void cb({error: type + ' is disabled'});
|
|
|
|
|
}
|
|
|
|
|
onReadyEvt.reg(function () {
|
|
|
|
|
var type = obj.type;
|
|
|
|
|
var data = obj.data;
|
|
|
|
|
if (store.modules[type]) {
|
|
|
|
|
store.modules[type].execCommand(clientId, data, cb);
|
|
|
|
|
} else {
|
|
|
|
|
return void cb({error: type + ' is disabled'});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
var loadUniversal = function (Module, type, waitFor, clientId) {
|
|
|
|
@ -1456,17 +1463,23 @@ define([
|
|
|
|
|
// Cursor
|
|
|
|
|
Store.cursor = {
|
|
|
|
|
execCommand: function (clientId, data, cb) {
|
|
|
|
|
if (!store.cursor) { return void cb ({error: 'Cursor channel is disabled'}); }
|
|
|
|
|
store.cursor.execCommand(clientId, data, cb);
|
|
|
|
|
// The cursor module can only be used when the store is ready
|
|
|
|
|
onReadyEvt.reg(function () {
|
|
|
|
|
if (!store.cursor) { return void cb ({error: 'Cursor channel is disabled'}); }
|
|
|
|
|
store.cursor.execCommand(clientId, data, cb);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Mailbox
|
|
|
|
|
Store.mailbox = {
|
|
|
|
|
execCommand: function (clientId, data, cb) {
|
|
|
|
|
if (!store.loggedIn) { return void cb(); }
|
|
|
|
|
if (!store.mailbox) { return void cb ({error: 'Mailbox is disabled'}); }
|
|
|
|
|
store.mailbox.execCommand(clientId, data, cb);
|
|
|
|
|
// The mailbox can only be used when the store is ready
|
|
|
|
|
onReadyEvt.reg(function () {
|
|
|
|
|
if (!store.loggedIn) { return void cb(); }
|
|
|
|
|
if (!store.mailbox) { return void cb ({error: 'Mailbox is disabled'}); }
|
|
|
|
|
store.mailbox.execCommand(clientId, data, cb);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -1723,7 +1736,7 @@ define([
|
|
|
|
|
noChainPad: true,
|
|
|
|
|
channel: data.channel,
|
|
|
|
|
metadata: data.metadata,
|
|
|
|
|
network: store.network,
|
|
|
|
|
network: store.network || store.networkPromise,
|
|
|
|
|
//readOnly: data.readOnly,
|
|
|
|
|
onConnect: function (wc, sendMessage) {
|
|
|
|
|
channel.sendMessage = function (msg, cId, cb) {
|
|
|
|
@ -1956,6 +1969,7 @@ define([
|
|
|
|
|
Store.getPadMetadata = function (clientId, data, _cb) {
|
|
|
|
|
var cb = Util.once(Util.mkAsync(_cb));
|
|
|
|
|
|
|
|
|
|
if (store.offline || !store.anon_rpc) { return void cb({ error: 'OFFLINE' }); }
|
|
|
|
|
if (!data.channel) { return void cb({ error: 'ENOTFOUND'}); }
|
|
|
|
|
if (data.channel.length !== 32) { return void cb({ error: 'EINVAL'}); }
|
|
|
|
|
store.anon_rpc.send('GET_METADATA', data.channel, function (err, obj) {
|
|
|
|
@ -2207,7 +2221,7 @@ define([
|
|
|
|
|
if (!s) { return void cb({ error: 'ENOTFOUND' }); }
|
|
|
|
|
SF.load({
|
|
|
|
|
isNew: isNew,
|
|
|
|
|
network: store.network,
|
|
|
|
|
network: store.network || store.networkPromise,
|
|
|
|
|
store: s,
|
|
|
|
|
isNewChannel: Store.isNewChannel
|
|
|
|
|
}, id, data, cb);
|
|
|
|
@ -2223,16 +2237,18 @@ define([
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
Store.addSharedFolder = function (clientId, data, cb) {
|
|
|
|
|
var s = getStore(data.teamId);
|
|
|
|
|
s.manager.addSharedFolder(data, function (id) {
|
|
|
|
|
if (id && typeof(id) === "object" && id.error) {
|
|
|
|
|
return void cb(id);
|
|
|
|
|
}
|
|
|
|
|
var send = data.teamId ? s.sendEvent : sendDriveEvent;
|
|
|
|
|
send('DRIVE_CHANGE', {
|
|
|
|
|
path: ['drive', UserObject.FILES_DATA]
|
|
|
|
|
}, clientId);
|
|
|
|
|
cb(id);
|
|
|
|
|
onReadyEvt.reg(function () {
|
|
|
|
|
var s = getStore(data.teamId);
|
|
|
|
|
s.manager.addSharedFolder(data, function (id) {
|
|
|
|
|
if (id && typeof(id) === "object" && id.error) {
|
|
|
|
|
return void cb(id);
|
|
|
|
|
}
|
|
|
|
|
var send = data.teamId ? s.sendEvent : sendDriveEvent;
|
|
|
|
|
send('DRIVE_CHANGE', {
|
|
|
|
|
path: ['drive', UserObject.FILES_DATA]
|
|
|
|
|
}, clientId);
|
|
|
|
|
cb(id);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
Store.updateSharedFolderPassword = function (clientId, data, cb) {
|
|
|
|
@ -2501,8 +2517,10 @@ define([
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var onReady = function (clientId, returned, cb) {
|
|
|
|
|
var onCacheReady = function (clientId, cb) {
|
|
|
|
|
var proxy = store.proxy;
|
|
|
|
|
if (!proxy.settings) { proxy.settings = NEW_USER_SETTINGS; }
|
|
|
|
|
if (!proxy.friends_pending) { proxy.friends_pending = {}; }
|
|
|
|
|
var unpin = function (data, cb) {
|
|
|
|
|
if (!store.loggedIn) { return void cb(); }
|
|
|
|
|
Store.unpinPads(null, data, cb);
|
|
|
|
@ -2511,8 +2529,6 @@ define([
|
|
|
|
|
if (!store.loggedIn) { return void cb(); }
|
|
|
|
|
Store.pinPads(null, data, cb);
|
|
|
|
|
};
|
|
|
|
|
if (!proxy.settings) { proxy.settings = NEW_USER_SETTINGS; }
|
|
|
|
|
if (!proxy.friends_pending) { proxy.friends_pending = {}; }
|
|
|
|
|
var manager = store.manager = ProxyManager.create(proxy.drive, {
|
|
|
|
|
onSync: function (cb) { onSync(null, cb); },
|
|
|
|
|
edPublic: proxy.edPublic,
|
|
|
|
@ -2534,9 +2550,24 @@ define([
|
|
|
|
|
});
|
|
|
|
|
var userObject = store.userObject = manager.user.userObject;
|
|
|
|
|
addSharedFolderHandler();
|
|
|
|
|
userObject.migrate(cb);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// onReady: called when the drive is synced (not using the cache anymore)
|
|
|
|
|
// "cb" is wrapped in Util.once() and may have already been called
|
|
|
|
|
// if we have a local cache
|
|
|
|
|
var onReady = function (clientId, returned, cb) {
|
|
|
|
|
console.error('READY');
|
|
|
|
|
store.ready = true;
|
|
|
|
|
var proxy = store.proxy;
|
|
|
|
|
var manager = store.manager;
|
|
|
|
|
var userObject = store.userObject;
|
|
|
|
|
|
|
|
|
|
nThen(function (waitFor) {
|
|
|
|
|
userObject.migrate(waitFor());
|
|
|
|
|
if (manager) { return; }
|
|
|
|
|
onCacheReady(clientId, waitFor());
|
|
|
|
|
manager = store.manager;
|
|
|
|
|
userObject = store.userObject;
|
|
|
|
|
}).nThen(function (waitFor) {
|
|
|
|
|
initAnonRpc(null, null, waitFor());
|
|
|
|
|
initRpc(null, null, waitFor());
|
|
|
|
@ -2569,7 +2600,7 @@ define([
|
|
|
|
|
loadUniversal(Messenger, 'messenger', waitFor);
|
|
|
|
|
store.messenger = store.modules['messenger'];
|
|
|
|
|
loadUniversal(Profile, 'profile', waitFor);
|
|
|
|
|
loadUniversal(Team, 'team', waitFor, clientId);
|
|
|
|
|
loadUniversal(Team, 'team', waitFor, clientId); // XXX load teams offline?
|
|
|
|
|
loadUniversal(History, 'history', waitFor);
|
|
|
|
|
}).nThen(function () {
|
|
|
|
|
var requestLogin = function () {
|
|
|
|
@ -2606,7 +2637,14 @@ define([
|
|
|
|
|
returned.feedback = Util.find(proxy, ['settings', 'general', 'allowUserFeedback']);
|
|
|
|
|
Feedback.init(returned.feedback);
|
|
|
|
|
|
|
|
|
|
// XXX send feedback and logintoken to outer...
|
|
|
|
|
// "cb" may have already been called by onCacheReady
|
|
|
|
|
if (typeof(cb) === 'function') { cb(returned); }
|
|
|
|
|
sendDriveEvent('NETWORK_RECONNECT');
|
|
|
|
|
broadcast([], "UPDATE_METADATA");
|
|
|
|
|
store.offline = false;
|
|
|
|
|
// XXX broadcast READY event with the missing data
|
|
|
|
|
// XXX we can improve feedback to queue the queries and send them when coming back online
|
|
|
|
|
|
|
|
|
|
if (typeof(proxy.uid) !== 'string' || proxy.uid.length !== 32) {
|
|
|
|
|
// even anonymous users should have a persistent, unique-ish id
|
|
|
|
@ -2662,6 +2700,8 @@ define([
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
loadMailbox();
|
|
|
|
|
|
|
|
|
|
onReadyEvt.fire();
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -2705,8 +2745,17 @@ define([
|
|
|
|
|
if (!data.userHash) {
|
|
|
|
|
returned.anonHash = Hash.getEditHashFromKeys(secret);
|
|
|
|
|
}
|
|
|
|
|
}).on('cacheready', function (info) {
|
|
|
|
|
if (!data.cache) { return; }
|
|
|
|
|
store.offline = true;
|
|
|
|
|
store.realtime = info.realtime;
|
|
|
|
|
store.networkPromise = info.networkPromise;
|
|
|
|
|
// XXX make sure we have a valid drive available
|
|
|
|
|
onCacheReady(clientId, function () {
|
|
|
|
|
if (typeof(cb) === "function") { cb(returned); }
|
|
|
|
|
});
|
|
|
|
|
}).on('ready', function (info) {
|
|
|
|
|
if (store.userObject) { return; } // the store is already ready, it is a reconnection
|
|
|
|
|
if (store.ready) { return; } // the store is already ready, it is a reconnection
|
|
|
|
|
store.driveMetadata = info.metadata;
|
|
|
|
|
if (!rt.proxy.drive || typeof(rt.proxy.drive) !== 'object') { rt.proxy.drive = {}; }
|
|
|
|
|
var drive = rt.proxy.drive;
|
|
|
|
@ -2732,10 +2781,12 @@ define([
|
|
|
|
|
rt.proxy.on('disconnect', function () {
|
|
|
|
|
store.offline = true;
|
|
|
|
|
sendDriveEvent('NETWORK_DISCONNECT');
|
|
|
|
|
broadcast([], "UPDATE_METADATA");
|
|
|
|
|
});
|
|
|
|
|
rt.proxy.on('reconnect', function () {
|
|
|
|
|
store.offline = false;
|
|
|
|
|
sendDriveEvent('NETWORK_RECONNECT');
|
|
|
|
|
broadcast([], "UPDATE_METADATA");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Ping clients regularly to make sure one tab was not closed without sending a removeClient()
|
|
|
|
|