|
|
@ -22,78 +22,104 @@ define([
|
|
|
|
SF.load = function (config, id, data, cb) {
|
|
|
|
SF.load = function (config, id, data, cb) {
|
|
|
|
var network = config.network;
|
|
|
|
var network = config.network;
|
|
|
|
var store = config.store;
|
|
|
|
var store = config.store;
|
|
|
|
var teamId = store.id || -1;
|
|
|
|
var isNew = config.isNew;
|
|
|
|
|
|
|
|
var isNewChannel = config.isNewChannel;
|
|
|
|
|
|
|
|
var teamId = store.id;
|
|
|
|
var handler = store.handleSharedFolder;
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
|
|
var sf = allSharedFolders[secret.channel];
|
|
|
|
// If we try to load en existing shared folder (isNew === false) but this folder
|
|
|
|
if (sf && sf.ready && sf.rt) {
|
|
|
|
// doesn't exist in the database, abort and cb
|
|
|
|
// The shared folder is already loaded, return its data
|
|
|
|
nThen(function (waitFor) {
|
|
|
|
setTimeout(function () {
|
|
|
|
isNewChannel(null, { channel: secret.channel }, waitFor(function (obj) {
|
|
|
|
var leave = function () { SF.leave(secret.channel, teamId); };
|
|
|
|
if (obj.isNew && !isNew) {
|
|
|
|
store.manager.addProxy(id, sf.rt.proxy, leave);
|
|
|
|
store.manager.deprecateProxy(id, secret.channel);
|
|
|
|
cb(sf.rt, sf.metadata);
|
|
|
|
waitFor.abort();
|
|
|
|
});
|
|
|
|
return void cb(null);
|
|
|
|
sf.team.push(teamId);
|
|
|
|
}
|
|
|
|
if (handler) { handler(id, sf.rt); }
|
|
|
|
}));
|
|
|
|
return sf.rt;
|
|
|
|
}).nThen(function () {
|
|
|
|
}
|
|
|
|
var sf = allSharedFolders[secret.channel];
|
|
|
|
if (sf && sf.queue && sf.rt) {
|
|
|
|
if (sf && sf.ready && sf.rt) {
|
|
|
|
// The shared folder is loading, add our callbacks to the queue
|
|
|
|
// The shared folder is already loaded, return its data
|
|
|
|
sf.queue.push({
|
|
|
|
setTimeout(function () {
|
|
|
|
cb: cb,
|
|
|
|
var leave = function () { SF.leave(secret.channel, teamId); };
|
|
|
|
store: store,
|
|
|
|
store.manager.addProxy(id, sf.rt.proxy, leave);
|
|
|
|
id: id
|
|
|
|
cb(sf.rt, sf.metadata);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
sf.team.push(teamId);
|
|
|
|
sf.teams.push(store);
|
|
|
|
if (handler) { handler(id, sf.rt); }
|
|
|
|
if (handler) { handler(id, sf.rt); }
|
|
|
|
return sf.rt;
|
|
|
|
return sf.rt;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sf = allSharedFolders[secret.channel] = {
|
|
|
|
|
|
|
|
queue: [{
|
|
|
|
|
|
|
|
cb: cb,
|
|
|
|
|
|
|
|
store: store,
|
|
|
|
|
|
|
|
id: id
|
|
|
|
|
|
|
|
}],
|
|
|
|
|
|
|
|
team: [store.id || -1]
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var owners = data.owners;
|
|
|
|
|
|
|
|
var listmapConfig = {
|
|
|
|
|
|
|
|
data: {},
|
|
|
|
|
|
|
|
channel: secret.channel,
|
|
|
|
|
|
|
|
readOnly: false,
|
|
|
|
|
|
|
|
crypto: Crypto.createEncryptor(secret.keys),
|
|
|
|
|
|
|
|
userName: 'sharedFolder',
|
|
|
|
|
|
|
|
logLevel: 1,
|
|
|
|
|
|
|
|
ChainPad: ChainPad,
|
|
|
|
|
|
|
|
classic: true,
|
|
|
|
|
|
|
|
network: network,
|
|
|
|
|
|
|
|
metadata: {
|
|
|
|
|
|
|
|
validateKey: secret.keys.validateKey || undefined,
|
|
|
|
|
|
|
|
owners: owners
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
if (sf && sf.queue && sf.rt) {
|
|
|
|
var rt = sf.rt = Listmap.create(listmapConfig);
|
|
|
|
// The shared folder is loading, add our callbacks to the queue
|
|
|
|
rt.proxy.on('ready', function (info) {
|
|
|
|
sf.queue.push({
|
|
|
|
if (!sf.queue) {
|
|
|
|
cb: cb,
|
|
|
|
return;
|
|
|
|
store: store,
|
|
|
|
|
|
|
|
id: id
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
sf.teams.push(store);
|
|
|
|
|
|
|
|
if (handler) { handler(id, sf.rt); }
|
|
|
|
|
|
|
|
return sf.rt;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sf.queue.forEach(function (obj) {
|
|
|
|
|
|
|
|
var leave = function () { SF.leave(secret.channel, teamId); };
|
|
|
|
sf = allSharedFolders[secret.channel] = {
|
|
|
|
obj.store.manager.addProxy(obj.id, rt.proxy, leave);
|
|
|
|
queue: [{
|
|
|
|
obj.cb(rt, info.metadata);
|
|
|
|
cb: cb,
|
|
|
|
|
|
|
|
store: store,
|
|
|
|
|
|
|
|
id: id
|
|
|
|
|
|
|
|
}],
|
|
|
|
|
|
|
|
teams: [store]
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var owners = data.owners;
|
|
|
|
|
|
|
|
var listmapConfig = {
|
|
|
|
|
|
|
|
data: {},
|
|
|
|
|
|
|
|
channel: secret.channel,
|
|
|
|
|
|
|
|
readOnly: false,
|
|
|
|
|
|
|
|
crypto: Crypto.createEncryptor(secret.keys),
|
|
|
|
|
|
|
|
userName: 'sharedFolder',
|
|
|
|
|
|
|
|
logLevel: 1,
|
|
|
|
|
|
|
|
ChainPad: ChainPad,
|
|
|
|
|
|
|
|
classic: true,
|
|
|
|
|
|
|
|
network: network,
|
|
|
|
|
|
|
|
metadata: {
|
|
|
|
|
|
|
|
validateKey: secret.keys.validateKey || undefined,
|
|
|
|
|
|
|
|
owners: owners
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
var rt = sf.rt = Listmap.create(listmapConfig);
|
|
|
|
|
|
|
|
rt.proxy.on('ready', function (info) {
|
|
|
|
|
|
|
|
if (!sf.queue) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
sf.queue.forEach(function (obj) {
|
|
|
|
|
|
|
|
var leave = function () { SF.leave(secret.channel, teamId); };
|
|
|
|
|
|
|
|
obj.store.manager.addProxy(obj.id, rt.proxy, leave);
|
|
|
|
|
|
|
|
obj.cb(rt, info.metadata);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
sf.metadata = info.metadata;
|
|
|
|
|
|
|
|
sf.ready = true;
|
|
|
|
|
|
|
|
delete sf.queue;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
rt.proxy.on('error', function (info) {
|
|
|
|
|
|
|
|
if (info && info.error) {
|
|
|
|
|
|
|
|
if (info.error === "EDELETED" ) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
// Deprecate the shared folder from each team
|
|
|
|
|
|
|
|
sf.teams.forEach(function (store) {
|
|
|
|
|
|
|
|
store.manager.deprecateProxy(id, secret.channel);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
} catch (e) {}
|
|
|
|
|
|
|
|
delete allSharedFolders[secret.channel];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
sf.leave = info.leave;
|
|
|
|
|
|
|
|
sf.metadata = info.metadata;
|
|
|
|
if (handler) { handler(id, rt); }
|
|
|
|
sf.ready = true;
|
|
|
|
|
|
|
|
delete sf.queue;
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
if (handler) { handler(id, rt); }
|
|
|
|
|
|
|
|
return rt;
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
SF.leave = function (channel, teamId) {
|
|
|
|
SF.leave = function (channel, teamId) {
|
|
|
@ -101,8 +127,14 @@ define([
|
|
|
|
if (!sf) { return; }
|
|
|
|
if (!sf) { return; }
|
|
|
|
var clients = sf.teams;
|
|
|
|
var clients = sf.teams;
|
|
|
|
if (!Array.isArray(clients)) { return; }
|
|
|
|
if (!Array.isArray(clients)) { return; }
|
|
|
|
var idx = clients.indexOf(teamId);
|
|
|
|
var idx;
|
|
|
|
if (idx === -1) { return; }
|
|
|
|
clients.some(function (store, i) {
|
|
|
|
|
|
|
|
if (store.id === teamId) {
|
|
|
|
|
|
|
|
idx = i;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
if (typeof (idx) === "undefined") { return; }
|
|
|
|
// Remove the selected team
|
|
|
|
// Remove the selected team
|
|
|
|
clients.splice(idx, 1);
|
|
|
|
clients.splice(idx, 1);
|
|
|
|
|
|
|
|
|
|
|
@ -113,6 +145,38 @@ define([
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SF.updatePassword = function (Store, data, network, cb) {
|
|
|
|
|
|
|
|
var oldChannel = data.oldChannel;
|
|
|
|
|
|
|
|
var href = data.href;
|
|
|
|
|
|
|
|
var password = data.password;
|
|
|
|
|
|
|
|
var parsed = Hash.parsePadUrl(href);
|
|
|
|
|
|
|
|
var secret = Hash.getSecrets(parsed.type, parsed.hash, password);
|
|
|
|
|
|
|
|
var sf = allSharedFolders[oldChannel];
|
|
|
|
|
|
|
|
if (!sf) { return void cb({ error: 'ENOTFOUND' }); }
|
|
|
|
|
|
|
|
if (sf.rt && sf.rt.stop) {
|
|
|
|
|
|
|
|
sf.rt.stop();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
var nt = nThen;
|
|
|
|
|
|
|
|
sf.teams.forEach(function (s) {
|
|
|
|
|
|
|
|
nt = nt(function (waitFor) {
|
|
|
|
|
|
|
|
var sfId = s.manager.user.userObject.getSFIdFromHref(href);
|
|
|
|
|
|
|
|
var shared = Util.find(s.proxy, ['drive', UserObject.SHARED_FOLDERS]) || {};
|
|
|
|
|
|
|
|
if (!sfId || !shared[sfId]) { return; }
|
|
|
|
|
|
|
|
var sf = JSON.parse(JSON.stringify(shared[sfId]));
|
|
|
|
|
|
|
|
sf.password = password;
|
|
|
|
|
|
|
|
SF.load({
|
|
|
|
|
|
|
|
network: network,
|
|
|
|
|
|
|
|
store: s,
|
|
|
|
|
|
|
|
isNewChannel: Store.isNewChannel
|
|
|
|
|
|
|
|
}, sfId, sf, waitFor());
|
|
|
|
|
|
|
|
if (!s.rpc) { return; }
|
|
|
|
|
|
|
|
s.rpc.unpin([oldChannel], waitFor());
|
|
|
|
|
|
|
|
s.rpc.pin([secret.channel], waitFor());
|
|
|
|
|
|
|
|
}).nThen;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
nt(cb);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* loadSharedFolders
|
|
|
|
/* loadSharedFolders
|
|
|
|
load all shared folder stored in a given drive
|
|
|
|
load all shared folder stored in a given drive
|
|
|
|
- store: user or team main store
|
|
|
|
- store: user or team main store
|
|
|
@ -121,35 +185,13 @@ define([
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
SF.loadSharedFolders = function (Store, network, store, userObject, waitFor) {
|
|
|
|
SF.loadSharedFolders = function (Store, network, store, userObject, waitFor) {
|
|
|
|
var shared = Util.find(store.proxy, ['drive', UserObject.SHARED_FOLDERS]) || {};
|
|
|
|
var shared = Util.find(store.proxy, ['drive', UserObject.SHARED_FOLDERS]) || {};
|
|
|
|
// 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
|
|
|
|
|
|
|
|
// the server.
|
|
|
|
|
|
|
|
nThen(function (waitFor) {
|
|
|
|
nThen(function (waitFor) {
|
|
|
|
var checkExpired = Object.keys(shared).map(function (fId) {
|
|
|
|
|
|
|
|
return shared[fId].channel;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
Store.getDeletedPads(null, {list: checkExpired}, waitFor(function (chans) {
|
|
|
|
|
|
|
|
if (chans && chans.error) { return void console.error(chans.error); }
|
|
|
|
|
|
|
|
if (!Array.isArray(chans) || !chans.length) { return; }
|
|
|
|
|
|
|
|
var toDelete = [];
|
|
|
|
|
|
|
|
Object.keys(shared).forEach(function (fId) {
|
|
|
|
|
|
|
|
if (chans.indexOf(shared[fId].channel) !== -1
|
|
|
|
|
|
|
|
&& toDelete.indexOf(fId) === -1) {
|
|
|
|
|
|
|
|
toDelete.push(fId);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
toDelete.forEach(function (fId) {
|
|
|
|
|
|
|
|
var paths = userObject.findFile(Number(fId));
|
|
|
|
|
|
|
|
userObject.delete(paths, waitFor(), true);
|
|
|
|
|
|
|
|
delete shared[fId];
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
}).nThen(function (waitFor) {
|
|
|
|
|
|
|
|
Object.keys(shared).forEach(function (id) {
|
|
|
|
Object.keys(shared).forEach(function (id) {
|
|
|
|
var sf = shared[id];
|
|
|
|
var sf = shared[id];
|
|
|
|
SF.load({
|
|
|
|
SF.load({
|
|
|
|
network: network,
|
|
|
|
network: network,
|
|
|
|
store: store
|
|
|
|
store: store,
|
|
|
|
|
|
|
|
isNewChannel: Store.isNewChannel
|
|
|
|
}, id, sf, waitFor());
|
|
|
|
}, id, sf, waitFor());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}).nThen(waitFor());
|
|
|
|
}).nThen(waitFor());
|
|
|
|