Refactor async-store to make it work with teams

pull/1/head
yflory 5 years ago
parent a2edf5be64
commit 7222d34dc0

@ -77,7 +77,7 @@ define([
nThen(function (waitFor) { nThen(function (waitFor) {
Cryptpad.ready(waitFor()); Cryptpad.ready(waitFor());
}).nThen(function (waitFor) { }).nThen(function (waitFor) {
Cryptpad.getUserObject(waitFor(function (obj) { Cryptpad.getUserObject(null, waitFor(function (obj) {
proxy = obj; proxy = obj;
})); }));
}).nThen(function () { }).nThen(function () {

@ -91,13 +91,16 @@ define([
}); });
}; };
// Settings and drive and auth // Settings and drive and auth
common.getUserObject = function (cb) { common.getUserObject = function (teamId, cb) {
postMessage("GET", [], function (obj) { postMessage("GET", {
teamId: teamId,
key: []
}, function (obj) {
cb(obj); cb(obj);
}); });
}; };
common.getSharedFolder = function (id, cb) { common.getSharedFolder = function (data, cb) {
postMessage("GET_SHARED_FOLDER", id, function (obj) { postMessage("GET_SHARED_FOLDER", data, function (obj) {
cb(obj); cb(obj);
}); });
}; };
@ -137,6 +140,7 @@ define([
return; return;
} }
postMessage("SET", { postMessage("SET", {
teamId: data.teamId,
key:['drive'], key:['drive'],
value: data.drive value: data.drive
}, function (obj) { }, function (obj) {
@ -163,7 +167,7 @@ define([
common.drive.onRemove = Util.mkEvent(); common.drive.onRemove = Util.mkEvent();
// Profile // Profile
common.getProfileEditUrl = function (cb) { common.getProfileEditUrl = function (cb) {
postMessage("GET", ['profile', 'edit'], function (obj) { postMessage("GET", { key: ['profile', 'edit'] }, function (obj) {
cb(obj); cb(obj);
}); });
}; };
@ -184,7 +188,7 @@ define([
}; };
// Todo // Todo
common.getTodoHash = function (cb) { common.getTodoHash = function (cb) {
postMessage("GET", ['todo'], function (obj) { postMessage("GET", { key: ['todo'] }, function (obj) {
cb(obj); cb(obj);
}); });
}; };
@ -1038,6 +1042,7 @@ define([
if (!oldIsOwned) { if (!oldIsOwned) {
console.error('deprecating old drive.'); console.error('deprecating old drive.');
postMessage("SET", { postMessage("SET", {
teamId: data.teamId,
key: [Constants.deprecatedKey], key: [Constants.deprecatedKey],
value: true value: true
}, waitFor(function (obj) { }, waitFor(function (obj) {

@ -43,70 +43,88 @@ define([
modules: {} modules: {}
}; };
var getProxy = function (teamId) { var getStore = function (teamId) {
if (!teamId) { return store.proxy; } if (!teamId) { return store; }
try { try {
var teams = store.modules['team']; var teams = store.modules['team'];
var team = teams.getTeam(teamId); var team = teams.getTeam(teamId);
if (team) { return; } if (!team) {
return team.proxy; console.error('Team not found', teamId);
return;
}
return team;
} catch (e) { } catch (e) {
console.error(e); console.error(e);
console.error('Team not found', teamId);
return; return;
} }
}; };
var getProxy = function (teamId) {
var s = getStore(teamId);
if (!s) { return; }
return s.proxy;
};
var getManager = function (teamId) { var getManager = function (teamId) {
if (!teamId) { return store.manager; } var s = getStore(teamId);
try { if (!s) { return; }
var teams = store.modules['team']; return s.manager;
var team = teams.getTeam(teamId);
if (team) { return; }
return team.manager;
} catch (e) {
console.error(e);
return;
}
}; };
var onSync = function (cb) { // XXX search for all calls
var onSync = function (teamId, cb) {
var s = getStore(teamId);
if (!s) { return void cb({ error: 'ENOTFOUND' }); }
nThen(function (waitFor) { nThen(function (waitFor) {
Realtime.whenRealtimeSyncs(store.realtime, waitFor()); Realtime.whenRealtimeSyncs(s.realtime, waitFor());
if (store.sharedFolders) { if (s.sharedFolders) {
for (var k in store.sharedFolders) { for (var k in s.sharedFolders) {
Realtime.whenRealtimeSyncs(store.sharedFolders[k].realtime, waitFor()); Realtime.whenRealtimeSyncs(s.sharedFolders[k].realtime, waitFor());
} }
} }
}).nThen(function () { cb(); }); }).nThen(function () { cb(); });
}; };
Store.get = function (clientId, key, cb) { // OKTEAM
cb(Util.find(store.proxy, key)); Store.get = function (clientId, data, cb) {
var s = getStore(data.teamId);
if (!s) { return void cb({ error: 'ENOTFOUND' }); }
cb(Util.find(s.proxy, data.key));
}; };
Store.set = function (clientId, data, cb) { Store.set = function (clientId, data, cb) {
var s = getStore(data.teamId);
if (!s) { return void cb({ error: 'ENOTFOUND' }); }
var path = data.key.slice(); var path = data.key.slice();
var key = path.pop(); var key = path.pop();
var obj = Util.find(store.proxy, path); var obj = Util.find(s.proxy, path);
if (!obj || typeof(obj) !== "object") { return void cb({error: 'INVALID_PATH'}); } if (!obj || typeof(obj) !== "object") { return void cb({error: 'INVALID_PATH'}); }
if (typeof data.value === "undefined") { if (typeof data.value === "undefined") {
delete obj[key]; delete obj[key];
} else { } else {
obj[key] = data.value; obj[key] = data.value;
} }
if (!data.teamId) {
broadcast([clientId], "UPDATE_METADATA"); broadcast([clientId], "UPDATE_METADATA");
if (Array.isArray(path) && path[0] === 'profile' && store.messenger) { if (Array.isArray(path) && path[0] === 'profile' && store.messenger) {
Messaging.updateMyData(store); Messaging.updateMyData(store);
}
} }
onSync(cb); onSync(data.teamId, cb);
}; };
Store.getSharedFolder = function (clientId, id, cb) { Store.getSharedFolder = function (clientId, data, cb) {
if (store.manager.folders[id]) { var s = getStore(data.teamId);
return void cb(store.manager.folders[id].proxy); var id = data.id;
if (!s || !s.manager) { return void cb({ error: 'ENOTFOUND' }); }
if (s.manager.folders[id]) {
// If it is loaded, return the shared folder proxy
return void cb(s.manager.folders[id].proxy);
} else { } else {
var shared = Util.find(store.proxy, ['drive', UserObject.SHARED_FOLDERS]) || {}; // Otherwise, check if we know this shared folder
var shared = Util.find(s.proxy, ['drive', UserObject.SHARED_FOLDERS]) || {};
if (shared[id]) { if (shared[id]) {
return void Store.loadSharedFolder(id, shared[id], function () { // If we know the shared folder, load it and return the proxy
cb(store.manager.folders[id].proxy); return void Store.loadSharedFolder(data.teamId, id, shared[id], function () {
cb(s.manager.folders[id].proxy);
}); });
} }
} }
@ -115,30 +133,34 @@ define([
Store.restoreSharedFolder = function (clientId, data, cb) { Store.restoreSharedFolder = function (clientId, data, cb) {
if (!data.sfId || !data.drive) { return void cb({error:'EINVAL'}); } if (!data.sfId || !data.drive) { return void cb({error:'EINVAL'}); }
if (store.sharedFolders[data.sfId]) { var s = getStore(data.teamId);
if (s.sharedFolders[data.sfId]) {
Object.keys(data.drive).forEach(function (k) { Object.keys(data.drive).forEach(function (k) {
store.sharedFolders[data.sfId].proxy[k] = data.drive[k]; s.sharedFolders[data.sfId].proxy[k] = data.drive[k];
}); });
Object.keys(store.sharedFolders[data.sfId].proxy).forEach(function (k) { Object.keys(s.sharedFolders[data.sfId].proxy).forEach(function (k) {
if (data.drive[k]) { return; } if (data.drive[k]) { return; }
delete store.sharedFolders[data.sfId].proxy[k]; delete s.sharedFolders[data.sfId].proxy[k];
}); });
} }
onSync(cb); onSync(data.teamId, cb);
}; };
// XXX Teams
Store.hasSigningKeys = function () { Store.hasSigningKeys = function () {
if (!store.proxy) { return; } if (!store.proxy) { return; }
return typeof(store.proxy.edPrivate) === 'string' && return typeof(store.proxy.edPrivate) === 'string' &&
typeof(store.proxy.edPublic) === 'string'; typeof(store.proxy.edPublic) === 'string';
}; };
// XXX Teams
Store.hasCurveKeys = function () { Store.hasCurveKeys = function () {
if (!store.proxy) { return; } if (!store.proxy) { return; }
return typeof(store.proxy.curvePrivate) === 'string' && return typeof(store.proxy.curvePrivate) === 'string' &&
typeof(store.proxy.curvePublic) === 'string'; typeof(store.proxy.curvePublic) === 'string';
}; };
// XXX TODO Implement same behavior in team.js
var getUserChannelList = function () { var getUserChannelList = function () {
// start with your userHash... // start with your userHash...
var userHash = storeHash; var userHash = storeHash;
@ -181,10 +203,12 @@ define([
return list; return list;
}; };
// XXX TODO Implement same behavior in team.js
var getExpirableChannelList = function () { var getExpirableChannelList = function () {
return store.manager.getChannelsList('expirable'); return store.manager.getChannelsList('expirable');
}; };
// XXX TODO Implement same behavior in team.js
var getCanonicalChannelList = function (expirable) { var getCanonicalChannelList = function (expirable) {
var list = expirable ? getExpirableChannelList() : getUserChannelList(); var list = expirable ? getExpirableChannelList() : getUserChannelList();
return Util.deduplicateString(list).sort(); return Util.deduplicateString(list).sort();
@ -194,6 +218,7 @@ define([
/////////////////////// RPC ////////////////////////////////////// /////////////////////// RPC //////////////////////////////////////
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
// XXX Teams pin in teams
Store.pinPads = function (clientId, data, cb) { Store.pinPads = function (clientId, data, cb) {
if (!store.rpc) { return void cb({error: 'RPC_NOT_READY'}); } if (!store.rpc) { return void cb({error: 'RPC_NOT_READY'}); }
if (typeof(cb) !== 'function') { if (typeof(cb) !== 'function') {
@ -206,6 +231,7 @@ define([
}); });
}; };
// XXX Teams ...
Store.unpinPads = function (clientId, data, cb) { Store.unpinPads = function (clientId, data, cb) {
if (!store.rpc) { return void cb({error: 'RPC_NOT_READY'}); } if (!store.rpc) { return void cb({error: 'RPC_NOT_READY'}); }
@ -1529,24 +1555,29 @@ define([
}; };
// SHARED FOLDERS // SHARED FOLDERS
var handleSharedFolder = function (id, rt) { var addSharedFolderHandler = function () {
store.sharedFolders[id] = rt; store.sharedFolders = {};
if (store.driveEvents) { store.handleSharedFolder = function (id, rt) {
registerProxyEvents(rt.proxy, id); store.sharedFolders[id] = rt;
} if (store.driveEvents) {
registerProxyEvents(rt.proxy, id);
}
};
}; };
var loadSharedFolder = Store.loadSharedFolder = function (id, data, cb) { Store.loadSharedFolder = function (teamId, id, data, cb) {
var s = getStore(teamId);
if (!s) { return void cb({ error: 'ENOTFOUND' }); }
var rt = SF.load({ var rt = SF.load({
network: store.network, network: store.network,
manager: store.manager store: s
}, id, data, cb); }, id, data, cb);
handleSharedFolder(id, rt);
return rt; return rt;
}; };
var loadSharedFolder = function (id, data, cb) {
Store.loadSharedFolder(null, id, data, cb);
};
Store.loadSharedFolderAnon = function (clientId, data, cb) { Store.loadSharedFolderAnon = function (clientId, data, cb) {
loadSharedFolder(data.id, data.data, function () { Store.loadSharedFolder(null, data.id, data.data, cb);
cb();
});
}; };
Store.addSharedFolder = function (clientId, data, cb) { Store.addSharedFolder = function (clientId, data, cb) {
store.manager.addSharedFolder(data, function (id) { store.manager.addSharedFolder(data, function (id) {
@ -1827,6 +1858,8 @@ define([
} }
}); });
var userObject = store.userObject = manager.user.userObject; var userObject = store.userObject = manager.user.userObject;
addSharedFolderHandler();
nThen(function (waitFor) { nThen(function (waitFor) {
postMessage(clientId, 'LOADING_DRIVE', { postMessage(clientId, 'LOADING_DRIVE', {
state: 2 state: 2
@ -1848,7 +1881,7 @@ define([
state: 3 state: 3
}); });
userObject.fixFiles(); userObject.fixFiles();
SF.loadSharedFolders(store.proxy, userObject, handleSharedFolder, waitFor); SF.loadSharedFolders(Store, store.network, store, userObject, waitFor);
loadMessenger(); loadMessenger();
loadCursor(); loadCursor();
loadOnlyOffice(); loadOnlyOffice();

@ -18,7 +18,9 @@ define([
*/ */
SF.load = function (config, id, data, cb) { SF.load = function (config, id, data, cb) {
var network = config.network; var network = config.network;
var manager = config.manager; var store = config.store;
var manager = store.manager;
var handler = store.handleSharedFolder;
var parsed = Hash.parsePadUrl(data.href); var parsed = Hash.parsePadUrl(data.href);
var secret = Hash.getSecrets('drive', parsed.hash, data.password); var secret = Hash.getSecrets('drive', parsed.hash, data.password);
@ -43,18 +45,18 @@ define([
manager.addProxy(id, rt.proxy, info.leave); manager.addProxy(id, rt.proxy, info.leave);
cb(rt, info.metadata); cb(rt, info.metadata);
}); });
if (handler) { handler(id, rt); }
return rt; return rt;
}; };
/* loadSharedFolders /* loadSharedFolders
load all shared folder stored in a given drive load all shared folder stored in a given drive
- proxy: user or team main proxy - store: user or team main store
- userObject: userObject associated to the main drive - userObject: userObject associated to the main drive
- handler: a function (sfid, rt) called for each shared folder loaded - handler: a function (sfid, rt) called for each shared folder loaded
*/ */
SF.loadSharedFolders = function (proxy, userObject, handler, waitFor) { SF.loadSharedFolders = function (Store, network, store, userObject, waitFor) {
store.sharedFolders = {}; var shared = Util.find(store.proxy, ['drive', UserObject.SHARED_FOLDERS]) || {};
var shared = Util.find(proxy, ['drive', UserObject.SHARED_FOLDERS]) || {};
// Check if any of our shared folder is expired or deleted by its owner. // Check if any of our shared folder is expired or deleted by its owner.
// If we don't check now, Listmap will create an empty proxy if it no longer exists on // If we don't check now, Listmap will create an empty proxy if it no longer exists on
// the server. // the server.
@ -81,8 +83,10 @@ define([
}).nThen(function (waitFor) { }).nThen(function (waitFor) {
Object.keys(shared).forEach(function (id) { Object.keys(shared).forEach(function (id) {
var sf = shared[id]; var sf = shared[id];
var rt = loadSharedFolder(id, sf, waitFor()); var rt = SF.load({
handler(id, rt); network: network,
store: store
}, id, sf, waitFor());
}); });
}).nThen(waitFor()); }).nThen(waitFor());
}; };

@ -19,6 +19,15 @@ define([
cb(); cb();
}; };
var handleSharedFolder = function (ctx, id, sfId, rt) {
var t = ctx.teams[id];
if (!t) { return; }
t.sharedFolders[sfId] = rt;
// XXX register events
// rt.proxy.on('change',... emit change event
// TODO: pin or unpin document added to a shared folder from someone who is not a member of the team
};
var onready = function (ctx, team, id, cb) { var onready = function (ctx, team, id, cb) {
// XXX // XXX
// load manager // load manager
@ -49,8 +58,13 @@ define([
ctx.teams[id] = { ctx.teams[id] = {
proxy: lm.proxy, proxy: lm.proxy,
listmap: lm, listmap: lm,
clients: [] clients: [],
manager: undefined, // XXX
realtime: lm.realtime,
handleSharedFolder: function (sfId, rt) { handleSharedFolder(ctx, id, sfId, rt); },
sharedFolders: {} // equivalent of store.sharedFolders in async-store
}; };
onReady(ctx, team, id, function () { onReady(ctx, team, id, function () {
// TODO // TODO
}); });

@ -937,7 +937,7 @@ define([
// Manager // Manager
addProxy: callWithEnv(addProxy), addProxy: callWithEnv(addProxy),
removeProxy: callWithEnv(removeProxy), removeProxy: callWithEnv(removeProxy),
addSharedFolder: callWithEnv(addSharedFolder); addSharedFolder: callWithEnv(_addSharedFolder),
// Drive // Drive
command: callWithEnv(onCommand), command: callWithEnv(onCommand),
getPadAttribute: callWithEnv(getPadAttribute), getPadAttribute: callWithEnv(getPadAttribute),

@ -71,12 +71,14 @@ define([
}); });
sframeChan.on('Q_DRIVE_GETOBJECT', function (data, cb) { sframeChan.on('Q_DRIVE_GETOBJECT', function (data, cb) {
if (data && data.sharedFolder) { if (data && data.sharedFolder) {
Cryptpad.getSharedFolder(data.sharedFolder, function (obj) { Cryptpad.getSharedFolder({
id: data.sharedFolder
}, function (obj) {
cb(obj); cb(obj);
}); });
return; return;
} }
Cryptpad.getUserObject(function (obj) { Cryptpad.getUserObject(null, function (obj) {
cb(obj); cb(obj);
}); });
}); });

@ -43,7 +43,7 @@ define([
}); });
}); });
sframeChan.on('Q_SETTINGS_DRIVE_GET', function (d, cb) { sframeChan.on('Q_SETTINGS_DRIVE_GET', function (d, cb) {
Cryptpad.getUserObject(function (obj) { Cryptpad.getUserObject(null, function (obj) {
if (obj.error) { return void cb(obj); } if (obj.error) { return void cb(obj); }
if (d === "full") { if (d === "full") {
// We want shared folders too // We want shared folders too
@ -54,7 +54,9 @@ define([
if (!obj.drive || !obj.drive.sharedFolders) { return void cb(result); } if (!obj.drive || !obj.drive.sharedFolders) { return void cb(result); }
Utils.nThen(function (waitFor) { Utils.nThen(function (waitFor) {
Object.keys(obj.drive.sharedFolders).forEach(function (id) { Object.keys(obj.drive.sharedFolders).forEach(function (id) {
Cryptpad.getSharedFolder(id, waitFor(function (obj) { Cryptpad.getSharedFolder({
id: id
}, waitFor(function (obj) {
result.sf[id] = obj; result.sf[id] = obj;
})); }));
}); });

@ -36,6 +36,7 @@ define([
}; };
window.addEventListener('message', onMsg); window.addEventListener('message', onMsg);
}).nThen(function (/*waitFor*/) { }).nThen(function (/*waitFor*/) {
var teamId; // XXX
var afterSecrets = function (Cryptpad, Utils, secret, cb) { var afterSecrets = function (Cryptpad, Utils, secret, cb) {
var hash = window.location.hash.slice(1); var hash = window.location.hash.slice(1);
if (hash && Utils.LocalStore.isLoggedIn()) { if (hash && Utils.LocalStore.isLoggedIn()) {
@ -66,17 +67,22 @@ define([
sframeChan.on('Q_DRIVE_USEROBJECT', function (data, cb) { sframeChan.on('Q_DRIVE_USEROBJECT', function (data, cb) {
Cryptpad.userObjectCommand(data, cb); Cryptpad.userObjectCommand(data, cb);
}); });
sframeChan.on('Q_DRIVE_RESTORE', function (data, cb) { // XXX no drive restore in teams? you could restore old keys...
/*sframeChan.on('Q_DRIVE_RESTORE', function (data, cb) {
data.teamId = teamId;
Cryptpad.restoreDrive(data, cb); Cryptpad.restoreDrive(data, cb);
}); });*/
sframeChan.on('Q_DRIVE_GETOBJECT', function (data, cb) { sframeChan.on('Q_DRIVE_GETOBJECT', function (data, cb) {
if (data && data.sharedFolder) { if (data && data.sharedFolder) {
Cryptpad.getSharedFolder(data.sharedFolder, function (obj) { Cryptpad.getSharedFolder({
teamId: teamId,
id: data.sharedFolder
}, function (obj) {
cb(obj); cb(obj);
}); });
return; return;
} }
Cryptpad.getUserObject(function (obj) { Cryptpad.getUserObject(teamId, function (obj) {
cb(obj); cb(obj);
}); });
}); });

Loading…
Cancel
Save