Async store part 1
This commit is contained in:
parent
96cf83af34
commit
0840570fbf
@ -4,8 +4,9 @@ define([
|
|||||||
'/common/common-constants.js',
|
'/common/common-constants.js',
|
||||||
'/common/outer/local-store.js',
|
'/common/outer/local-store.js',
|
||||||
'/common/test.js',
|
'/common/test.js',
|
||||||
|
'/bower_components/nthen/index.js',
|
||||||
'/bower_components/tweetnacl/nacl-fast.min.js'
|
'/bower_components/tweetnacl/nacl-fast.min.js'
|
||||||
], function ($, Cryptpad, Constants, LocalStore, Test) {
|
], function ($, Cryptpad, Constants, LocalStore, Test, nThen) {
|
||||||
var Nacl = window.nacl;
|
var Nacl = window.nacl;
|
||||||
|
|
||||||
var signMsg = function (msg, privKey) {
|
var signMsg = function (msg, privKey) {
|
||||||
@ -25,11 +26,18 @@ define([
|
|||||||
localStorage[Constants.userHashKey] = localStorage[Constants.userHashKey] ||
|
localStorage[Constants.userHashKey] = localStorage[Constants.userHashKey] ||
|
||||||
sessionStorage[Constants.userHashKey];
|
sessionStorage[Constants.userHashKey];
|
||||||
|
|
||||||
Cryptpad.ready(function () {
|
var proxy;
|
||||||
|
nThen(function (waitFor) {
|
||||||
|
Cryptpad.ready(waitFor());
|
||||||
|
}).nThen(function (waitFor) {
|
||||||
|
Cryptpad.getUserObject(waitFor(function (obj) {
|
||||||
|
proxy = obj;
|
||||||
|
}));
|
||||||
|
}).nThen(function () {
|
||||||
console.log('IFRAME READY');
|
console.log('IFRAME READY');
|
||||||
Test(function () {
|
Test(function () {
|
||||||
// This is only here to maybe trigger an error.
|
// This is only here to maybe trigger an error.
|
||||||
window.drive = Cryptpad.getStore().getProxy().proxy['drive'];
|
window.drive = proxy['drive'];
|
||||||
Test.passed();
|
Test.passed();
|
||||||
});
|
});
|
||||||
$(window).on("message", function (jqe) {
|
$(window).on("message", function (jqe) {
|
||||||
@ -46,7 +54,6 @@ define([
|
|||||||
} else if (!LocalStore.isLoggedIn()) {
|
} else if (!LocalStore.isLoggedIn()) {
|
||||||
ret.error = "NOT_LOGGED_IN";
|
ret.error = "NOT_LOGGED_IN";
|
||||||
} else {
|
} else {
|
||||||
var proxy = Cryptpad.getStore().getProxy().proxy;
|
|
||||||
var sig = signMsg(data.data, proxy.edPrivate);
|
var sig = signMsg(data.data, proxy.edPrivate);
|
||||||
ret.res = {
|
ret.res = {
|
||||||
uname: proxy.login_name,
|
uname: proxy.login_name,
|
||||||
|
|||||||
@ -10,5 +10,6 @@ define(function () {
|
|||||||
displayNameKey: 'cryptpad.username',
|
displayNameKey: 'cryptpad.username',
|
||||||
oldStorageKey: 'CryptPad_RECENTPADS',
|
oldStorageKey: 'CryptPad_RECENTPADS',
|
||||||
storageKey: 'filesData',
|
storageKey: 'filesData',
|
||||||
|
tokenKey: 'loginToken',
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@ -626,10 +626,11 @@ define([
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO displayName
|
||||||
messenger.getMyInfo = function (cb) {
|
messenger.getMyInfo = function (cb) {
|
||||||
cb(void 0, {
|
cb(void 0, {
|
||||||
curvePublic: proxy.curvePublic,
|
curvePublic: proxy.curvePublic,
|
||||||
displayName: common.getDisplayName(),
|
displayName: '' //common.getDisplayName(),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,17 +1,17 @@
|
|||||||
define([
|
define([
|
||||||
'/customize/application_config.js',
|
//'/customize/application_config.js',
|
||||||
'/customize/messages.js',
|
//'/customize/messages.js',
|
||||||
'/common/common-interface.js',
|
//'/common/common-interface.js',
|
||||||
], function (AppConfig, Messages, UI) {
|
], function (/*AppConfig, Messages, UI*/) {
|
||||||
var common = {};
|
var common = {};
|
||||||
|
|
||||||
common.infiniteSpinnerDetected = false;
|
//common.infiniteSpinnerDetected = false;
|
||||||
var BAD_STATE_TIMEOUT = typeof(AppConfig.badStateTimeout) === 'number'?
|
//var BAD_STATE_TIMEOUT = typeof(AppConfig.badStateTimeout) === 'number'?
|
||||||
AppConfig.badStateTimeout: 30000;
|
// AppConfig.badStateTimeout: 30000;
|
||||||
|
|
||||||
var connected = false;
|
//var connected = false;
|
||||||
var intr;
|
//var intr;
|
||||||
var infiniteSpinnerHandlers = [];
|
//var infiniteSpinnerHandlers = [];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO make this not blow up when disconnected or lagging...
|
TODO make this not blow up when disconnected or lagging...
|
||||||
@ -20,7 +20,7 @@ define([
|
|||||||
if (typeof(realtime.getAuthDoc) !== 'function') {
|
if (typeof(realtime.getAuthDoc) !== 'function') {
|
||||||
return void console.error('improper use of this function');
|
return void console.error('improper use of this function');
|
||||||
}
|
}
|
||||||
window.setTimeout(function () {
|
self.setTimeout(function () {
|
||||||
if (realtime.getAuthDoc() === realtime.getUserDoc()) {
|
if (realtime.getAuthDoc() === realtime.getUserDoc()) {
|
||||||
return void cb();
|
return void cb();
|
||||||
} else {
|
} else {
|
||||||
@ -29,6 +29,7 @@ define([
|
|||||||
}, 0);
|
}, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
common.beginDetectingInfiniteSpinner = function (realtime) {
|
common.beginDetectingInfiniteSpinner = function (realtime) {
|
||||||
if (intr) { return; }
|
if (intr) { return; }
|
||||||
intr = window.setInterval(function () {
|
intr = window.setInterval(function () {
|
||||||
@ -52,13 +53,14 @@ define([
|
|||||||
common.infiniteSpinnerDetected = true;
|
common.infiniteSpinnerDetected = true;
|
||||||
}, 2000);
|
}, 2000);
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
common.onInfiniteSpinner = function (f) { infiniteSpinnerHandlers.push(f); };
|
//common.onInfiniteSpinner = function (f) { infiniteSpinnerHandlers.push(f); };
|
||||||
|
|
||||||
common.setConnectionState = function (bool) {
|
/*common.setConnectionState = function (bool) {
|
||||||
if (typeof(bool) !== 'boolean') { return; }
|
if (typeof(bool) !== 'boolean') { return; }
|
||||||
connected = bool;
|
connected = bool;
|
||||||
};
|
};*/
|
||||||
|
|
||||||
return common;
|
return common;
|
||||||
});
|
});
|
||||||
|
|||||||
@ -73,12 +73,12 @@ define([
|
|||||||
|
|
||||||
realtime.contentUpdate(doc);
|
realtime.contentUpdate(doc);
|
||||||
|
|
||||||
var to = window.setTimeout(function () {
|
var to = self.setTimeout(function () {
|
||||||
cb(new Error("Timeout"));
|
cb(new Error("Timeout"));
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
||||||
Realtime.whenRealtimeSyncs(realtime, function () {
|
Realtime.whenRealtimeSyncs(realtime, function () {
|
||||||
window.clearTimeout(to);
|
self.clearTimeout(to);
|
||||||
realtime.abort();
|
realtime.abort();
|
||||||
finish(Session, void 0);
|
finish(Session, void 0);
|
||||||
});
|
});
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -194,8 +194,8 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
var onReady = function (f, proxy, Cryptpad, exp) {
|
var onReady = function (f, proxy, Cryptpad, exp) {
|
||||||
var fo = exp.fo = FO.init(proxy.drive, {
|
var fo = exp.userObject = exp.fo = FO.init(proxy.drive, {
|
||||||
Cryptpad: Cryptpad,
|
pinPads: Cryptpad.pinPads,
|
||||||
loggedIn: LocalStore.isLoggedIn()
|
loggedIn: LocalStore.isLoggedIn()
|
||||||
});
|
});
|
||||||
var todo = function () {
|
var todo = function () {
|
||||||
@ -265,15 +265,15 @@ define([
|
|||||||
|
|
||||||
proxy.on('change', [Constants.displayNameKey], function (o, n) {
|
proxy.on('change', [Constants.displayNameKey], function (o, n) {
|
||||||
if (typeof(n) !== "string") { return; }
|
if (typeof(n) !== "string") { return; }
|
||||||
Cryptpad.changeDisplayName(n);
|
Cryptpad.changeMetadata();
|
||||||
});
|
});
|
||||||
proxy.on('change', ['profile'], function () {
|
proxy.on('change', ['profile'], function () {
|
||||||
// Trigger userlist update when the avatar has changed
|
// Trigger userlist update when the avatar has changed
|
||||||
Cryptpad.changeDisplayName(proxy[Constants.displayNameKey]);
|
Cryptpad.changeMetadata();
|
||||||
});
|
});
|
||||||
proxy.on('change', ['friends'], function () {
|
proxy.on('change', ['friends'], function () {
|
||||||
// Trigger userlist update when the avatar has changed
|
// Trigger userlist update when the friendlist has changed
|
||||||
Cryptpad.changeDisplayName(proxy[Constants.displayNameKey]);
|
Cryptpad.changeMetadata();
|
||||||
});
|
});
|
||||||
proxy.on('change', [tokenKey], function () {
|
proxy.on('change', [tokenKey], function () {
|
||||||
var localToken = tryParsing(localStorage.getItem(tokenKey));
|
var localToken = tryParsing(localStorage.getItem(tokenKey));
|
||||||
@ -315,6 +315,7 @@ define([
|
|||||||
|
|
||||||
exp.realtime = rt.realtime;
|
exp.realtime = rt.realtime;
|
||||||
exp.proxy = rt.proxy;
|
exp.proxy = rt.proxy;
|
||||||
|
exp.loggedIn = Cryptpad.isLoggedIn()
|
||||||
rt.proxy.on('create', function (info) {
|
rt.proxy.on('create', function (info) {
|
||||||
exp.info = info;
|
exp.info = info;
|
||||||
if (!LocalStore.getUserHash()) {
|
if (!LocalStore.getUserHash()) {
|
||||||
|
|||||||
@ -2,8 +2,8 @@ define([
|
|||||||
'/common/cryptget.js',
|
'/common/cryptget.js',
|
||||||
'/common/userObject.js',
|
'/common/userObject.js',
|
||||||
'/common/common-hash.js',
|
'/common/common-hash.js',
|
||||||
'/common/outer/local-store.js',
|
'/common/common-realtime.js',
|
||||||
], function (Crypt, FO, Hash, LocalStore) {
|
], function (Crypt, FO, Hash, Realtime) {
|
||||||
var exp = {};
|
var exp = {};
|
||||||
|
|
||||||
var getType = function (el) {
|
var getType = function (el) {
|
||||||
@ -86,7 +86,7 @@ define([
|
|||||||
|
|
||||||
exp.anonDriveIntoUser = function (proxyData, fsHash, cb) {
|
exp.anonDriveIntoUser = function (proxyData, fsHash, cb) {
|
||||||
// Make sure we have an FS_hash and we don't use it, otherwise just stop the migration and cb
|
// Make sure we have an FS_hash and we don't use it, otherwise just stop the migration and cb
|
||||||
if (!fsHash || !LocalStore.isLoggedIn()) {
|
if (!fsHash || !proxyData.loggedIn) {
|
||||||
if (typeof(cb) === "function") { return void cb(); }
|
if (typeof(cb) === "function") { return void cb(); }
|
||||||
}
|
}
|
||||||
// Get the content of FS_hash and then merge the objects, remove the migration key and cb
|
// Get the content of FS_hash and then merge the objects, remove the migration key and cb
|
||||||
@ -105,11 +105,11 @@ define([
|
|||||||
if (parsed) {
|
if (parsed) {
|
||||||
var proxy = proxyData.proxy;
|
var proxy = proxyData.proxy;
|
||||||
var oldFo = FO.init(parsed.drive, {
|
var oldFo = FO.init(parsed.drive, {
|
||||||
loggedIn: LocalStore.isLoggedIn()
|
loggedIn: proxyData.loggedIn
|
||||||
});
|
});
|
||||||
var onMigrated = function () {
|
var onMigrated = function () {
|
||||||
oldFo.fixFiles();
|
oldFo.fixFiles();
|
||||||
var newFo = proxyData.fo;
|
var newFo = proxyData.userObject;
|
||||||
var oldRecentPads = parsed.drive[newFo.FILES_DATA];
|
var oldRecentPads = parsed.drive[newFo.FILES_DATA];
|
||||||
var newRecentPads = proxy.drive[newFo.FILES_DATA];
|
var newRecentPads = proxy.drive[newFo.FILES_DATA];
|
||||||
var oldFiles = oldFo.getFiles([newFo.FILES_DATA]);
|
var oldFiles = oldFo.getFiles([newFo.FILES_DATA]);
|
||||||
@ -154,7 +154,9 @@ define([
|
|||||||
proxy.FS_hashes = [];
|
proxy.FS_hashes = [];
|
||||||
}
|
}
|
||||||
proxy.FS_hashes.push(fsHash);
|
proxy.FS_hashes.push(fsHash);
|
||||||
if (typeof(cb) === "function") { cb(); }
|
if (typeof(cb) === "function") {
|
||||||
|
Realtime.whenRealtimeSyncs(proxyData.realtime, cb);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
oldFo.migrate(onMigrated);
|
oldFo.migrate(onMigrated);
|
||||||
return;
|
return;
|
||||||
|
|||||||
766
www/common/outer/async-store.js
Normal file
766
www/common/outer/async-store.js
Normal file
@ -0,0 +1,766 @@
|
|||||||
|
define([
|
||||||
|
'/common/userObject.js',
|
||||||
|
'/common/migrate-user-object.js',
|
||||||
|
'/common/common-hash.js',
|
||||||
|
'/common/common-util.js',
|
||||||
|
'/common/common-constants.js',
|
||||||
|
'/common/common-feedback.js',
|
||||||
|
'/common/common-realtime.js',
|
||||||
|
'/common/outer/network-config.js',
|
||||||
|
|
||||||
|
'/bower_components/chainpad-crypto/crypto.js?v=0.1.5',
|
||||||
|
'/bower_components/chainpad/chainpad.dist.js',
|
||||||
|
'/bower_components/chainpad-listmap/chainpad-listmap.js',
|
||||||
|
], function (UserObject, Migrate, Hash, Util, Constants, Feedback, Realtime, NetConfig,
|
||||||
|
Crypto, ChainPad, Listmap) {
|
||||||
|
var Store = {};
|
||||||
|
|
||||||
|
var postMessage = function (cmd, data, cb) {};
|
||||||
|
var tryParsing = function (x) {
|
||||||
|
try { return JSON.parse(x); }
|
||||||
|
catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var storeHash;
|
||||||
|
|
||||||
|
var store = {};
|
||||||
|
|
||||||
|
|
||||||
|
var onSync = function (cb) {
|
||||||
|
Realtime.whenRealtimeSyncs(store.realtime, cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Store.get = function (key, cb) {
|
||||||
|
cb({result: Util.find(store.proxy, key)});
|
||||||
|
};
|
||||||
|
Store.set = function (data, cb) {
|
||||||
|
var path = data.key.slice();
|
||||||
|
var key = path.pop();
|
||||||
|
var obj = Util.find(store.proxy, path);
|
||||||
|
if (!obj || typeof(obj) !== "object") { return void cb({error: 'INVALID_PATH'}); }
|
||||||
|
obj[key] = data.value;
|
||||||
|
onSync(cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
Store.hasSigningKeys = function () {
|
||||||
|
if (!store.proxy) { return; }
|
||||||
|
return typeof(store.proxy.edPrivate) === 'string' &&
|
||||||
|
typeof(store.proxy.edPublic) === 'string';
|
||||||
|
};
|
||||||
|
|
||||||
|
Store.hasCurveKeys = function () {
|
||||||
|
if (!store.proxy) { return; }
|
||||||
|
return typeof(store.proxy.curvePrivate) === 'string' &&
|
||||||
|
typeof(store.proxy.curvePublic) === 'string';
|
||||||
|
};
|
||||||
|
|
||||||
|
var getUserChannelList = function () {
|
||||||
|
// start with your userHash...
|
||||||
|
var userHash = storeHash;
|
||||||
|
if (!userHash) { return null; }
|
||||||
|
|
||||||
|
var userParsedHash = Hash.parseTypeHash('drive', userHash);
|
||||||
|
var userChannel = userParsedHash && userParsedHash.channel;
|
||||||
|
if (!userChannel) { return null; }
|
||||||
|
|
||||||
|
var list = store.userObject.getFiles([store.userObject.FILES_DATA]).map(function (id) {
|
||||||
|
return Hash.hrefToHexChannelId(store.userObject.getFileData(id).href);
|
||||||
|
})
|
||||||
|
.filter(function (x) { return x; });
|
||||||
|
|
||||||
|
// Get the avatar
|
||||||
|
var profile = store.proxy.profile;
|
||||||
|
if (profile) {
|
||||||
|
var profileChan = profile.edit ? Hash.hrefToHexChannelId('/profile/#' + profile.edit) : null;
|
||||||
|
if (profileChan) { list.push(profileChan); }
|
||||||
|
var avatarChan = profile.avatar ? Hash.hrefToHexChannelId(profile.avatar) : null;
|
||||||
|
if (avatarChan) { list.push(avatarChan); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
/*if (store.proxy.friends) {
|
||||||
|
var fList = Messaging.getFriendChannelsList(common);
|
||||||
|
list = list.concat(fList);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
list.push(Util.base64ToHex(userChannel));
|
||||||
|
list.sort();
|
||||||
|
|
||||||
|
return list;
|
||||||
|
};
|
||||||
|
|
||||||
|
var getCanonicalChannelList = function () {
|
||||||
|
return Util.deduplicateString(getUserChannelList()).sort();
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////// RPC //////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Store.arePinsSynced = function (cb) {
|
||||||
|
if (!store.rpc) { return void cb({error: 'RPC_NOT_READY'}); }
|
||||||
|
|
||||||
|
var list = getCanonicalChannelList();
|
||||||
|
var local = Hash.hashChannelList(list);
|
||||||
|
store.rpc.getServerHash(function (e, hash) {
|
||||||
|
if (e) { return void cb({error: e}); }
|
||||||
|
cb({synced: hash === local});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Store.resetPins = function (data, cb) {
|
||||||
|
if (!store.rpc) { return void cb({error: 'RPC_NOT_READY'}); }
|
||||||
|
|
||||||
|
var list = getCanonicalChannelList();
|
||||||
|
store.rpc.reset(list, function (e, hash) {
|
||||||
|
if (e) { return void cb({error: e}); }
|
||||||
|
cb({hash: hash});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Store.pinPads = function (data, cb) {
|
||||||
|
if (!store.rpc) { return void cb({error: 'RPC_NOT_READY'}); }
|
||||||
|
if (typeof(cb) !== 'function') {
|
||||||
|
console.error('expected a callback');
|
||||||
|
}
|
||||||
|
|
||||||
|
store.rpc.pin(data.pads, function (e, hash) {
|
||||||
|
if (e) { return void cb({error: e}); }
|
||||||
|
cb({hash: hash});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Store.unpinPads = function (data, cb) {
|
||||||
|
if (!store.rpc) { return void cb({error: 'RPC_NOT_READY'}); }
|
||||||
|
|
||||||
|
store.rpc.unpin(data.pads, function (e, hash) {
|
||||||
|
if (e) { return void cb({error: e}); }
|
||||||
|
cb({hash: hash});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var account = {};
|
||||||
|
|
||||||
|
Store.getPinnedUsage = function (data, cb) {
|
||||||
|
if (!store.rpc) { return void cb({error: 'RPC_NOT_READY'}); }
|
||||||
|
|
||||||
|
store.rpc.getFileListSize(function (err, bytes) {
|
||||||
|
if (typeof(bytes) === 'number') {
|
||||||
|
account.usage = bytes;
|
||||||
|
}
|
||||||
|
cb({bytes: bytes});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update for all users from accounts and return current user limits
|
||||||
|
Store.updatePinLimit = function (cb) {
|
||||||
|
if (!store.rpc) { return void cb({error: 'RPC_NOT_READY'}); }
|
||||||
|
store.rpc.updatePinLimits(function (e, limit, plan, note) {
|
||||||
|
if (e) { return void cb({error: e}); }
|
||||||
|
account.limit = limit;
|
||||||
|
account.plan = plan;
|
||||||
|
account.note = note;
|
||||||
|
cb(account);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// Get current user limits
|
||||||
|
Store.getPinLimit = function (cb) {
|
||||||
|
if (!store.rpc) { return void cb({error: 'RPC_NOT_READY'}); }
|
||||||
|
|
||||||
|
var ALWAYS_REVALIDATE = true;
|
||||||
|
if (ALWAYS_REVALIDATE || typeof(account.limit) !== 'number' ||
|
||||||
|
typeof(account.plan) !== 'string' ||
|
||||||
|
typeof(account.note) !== 'string') {
|
||||||
|
return void store.rpc.getLimit(function (e, limit, plan, note) {
|
||||||
|
if (e) { return void cb({error: e}); }
|
||||||
|
account.limit = limit;
|
||||||
|
account.plan = plan;
|
||||||
|
account.note = note;
|
||||||
|
cb(account);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
cb(account);
|
||||||
|
};
|
||||||
|
|
||||||
|
Store.clearOwnedChannel = function (data, cb) {
|
||||||
|
if (!store.rpc) { return void cb({error: 'RPC_NOT_READY'}); }
|
||||||
|
rpc.clearOwnedChannel(data.channel, cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
Store.uploadComplete = function (data, cb) {
|
||||||
|
if (!store.rpc) { return void cb({error: 'RPC_NOT_READY'}); }
|
||||||
|
rpc.uploadComplete(cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
Store.uploadStatus = function (data, cb) {
|
||||||
|
if (!store.rpc) { return void cb({error: 'RPC_NOT_READY'}); }
|
||||||
|
rpc.uploadStatus(data.size, cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
Store.uploadCancel = function (data, cb) {
|
||||||
|
if (!store.rpc) { return void cb({error: 'RPC_NOT_READY'}); }
|
||||||
|
rpc.uploadCancel(cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
Store.initRpc = function (data, cb) {
|
||||||
|
require(['/common/pinpad.js', function (Pinpad) {
|
||||||
|
Pinpad.create(store.network, store.proxy, function (e, call) {
|
||||||
|
if (e) { return void cb({error: e}); }
|
||||||
|
|
||||||
|
store.rpc = call;
|
||||||
|
|
||||||
|
common.getPinLimit(function (e, limit, plan, note) {
|
||||||
|
if (e) { return void console.error(e); }
|
||||||
|
common.account.limit = limit;
|
||||||
|
localStorage.plan = common.account.plan = plan;
|
||||||
|
common.account.note = note;
|
||||||
|
cb();
|
||||||
|
});
|
||||||
|
|
||||||
|
common.arePinsSynced(function (err, yes) {
|
||||||
|
if (!yes) {
|
||||||
|
common.resetPins(function (err) {
|
||||||
|
if (err) { return console.error(err); }
|
||||||
|
console.log('RESET DONE');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
////////////////// ANON RPC //////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
Store.anonRpcMsg = function (data, cb) {
|
||||||
|
if (!store.anon_rpc) { return void cb({error: 'ANON_RPC_NOT_READY'}); }
|
||||||
|
store.anon_rpc.send(data.msg, data.data, cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
Store.getFileSize = function (data, cb) {
|
||||||
|
if (!store.anon_rpc) { return void cb({error: 'ANON_RPC_NOT_READY'}); }
|
||||||
|
|
||||||
|
var channelId = Hash.hrefToHexChannelId(data.href);
|
||||||
|
store.anon_rpc.send("GET_FILE_SIZE", channelId, function (e, response) {
|
||||||
|
if (e) { return void cb({error: e}); }
|
||||||
|
if (response && response.length && typeof(response[0]) === 'number') {
|
||||||
|
return void cb({size: response[0]});
|
||||||
|
} else {
|
||||||
|
cb({error: 'INVALID_RESPONSE'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Store.getMultipleFileSize = function (data, cb) {
|
||||||
|
if (!store.anon_rpc) { return void cb({error: 'ANON_RPC_NOT_READY'}); }
|
||||||
|
if (!Array.isArray(data.files)) {
|
||||||
|
return void cb({error: 'INVALID_FILE_LIST'});
|
||||||
|
}
|
||||||
|
|
||||||
|
store.anon_rpc.send('GET_MULTIPLE_FILE_SIZE', data.files, function (e, res) {
|
||||||
|
if (e) { return void cb({error: e}); }
|
||||||
|
if (res && res.length && typeof(res[0]) === 'object') {
|
||||||
|
cb({size: res[0]});
|
||||||
|
} else {
|
||||||
|
cb({error: 'UNEXPECTED_RESPONSE'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Store.initAnonRpc = function (data, cb) {
|
||||||
|
require([
|
||||||
|
'/common/rpc.js',
|
||||||
|
], function (Rpc) {
|
||||||
|
Rpc.createAnonymous(store.network, function (e, call) {
|
||||||
|
if (e) { return void cb({error: e}); }
|
||||||
|
store.anon_rpc = call;
|
||||||
|
cb();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////// Store ////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Get the metadata for sframe-common-outer
|
||||||
|
Store.getMetadata = function (data, cb) {
|
||||||
|
var metadata = {
|
||||||
|
// "user" is shared with everybody via the userlist
|
||||||
|
user: {
|
||||||
|
name: store.proxy[Constants.displayNameKey],
|
||||||
|
uid: store.proxy.uid,
|
||||||
|
avatar: Util.find(store.proxy, ['profile', 'avatar']),
|
||||||
|
profile: Util.find(store.proxy, ['profile', 'view']),
|
||||||
|
curvePublic: store.proxy.curvePublic,
|
||||||
|
netfluxId: store.network.webChannels[0].myID
|
||||||
|
},
|
||||||
|
// "priv" is not shared with other users but is needed by the apps
|
||||||
|
priv: {
|
||||||
|
edPublic: store.proxy.edPublic,
|
||||||
|
friends: store.proxy.friends,
|
||||||
|
settings: store.proxy.settings,
|
||||||
|
thumbnails: !((store.proxy.settings || {}).general || {}).disableThumbnails
|
||||||
|
}
|
||||||
|
};
|
||||||
|
cb(JSON.parse(JSON.stringify(metadata)));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Reset the drive part of the userObject (from settings)
|
||||||
|
Store.resetDrive = function (data, cb) {
|
||||||
|
store.proxy.drive = store.fo.getStructure();
|
||||||
|
onSync(cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a "What is CryptPad?" pad in the drive
|
||||||
|
* data
|
||||||
|
* - driveReadme
|
||||||
|
* - driveReadmeTitle
|
||||||
|
*/
|
||||||
|
Store.createReadme = function (data, cb) {
|
||||||
|
require(['/common/cryptget.js'], function (Crypt) {
|
||||||
|
var hash = Hash.createRandomHash();
|
||||||
|
Crypt.put(hash, data.driveReadme, function (e) {
|
||||||
|
if (e) {
|
||||||
|
return void cb({ error: "Error while creating the default pad:"+ e});
|
||||||
|
}
|
||||||
|
var href = '/pad/#' + hash;
|
||||||
|
var fileData = {
|
||||||
|
href: href,
|
||||||
|
title: data.driveReadmeTitle,
|
||||||
|
atime: +new Date(),
|
||||||
|
ctime: +new Date()
|
||||||
|
};
|
||||||
|
store.userObject.pushData(fileData, function (e, id) {
|
||||||
|
if (e) {
|
||||||
|
return void cb({ error: "Error while creating the default pad:"+ e});
|
||||||
|
}
|
||||||
|
store.userObject.add(id);
|
||||||
|
onSync(cb);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge the anonymous drive into the user drive at registration
|
||||||
|
* data
|
||||||
|
* - anonHash
|
||||||
|
*/
|
||||||
|
Store.migrateAnonDrive = function (data, cb) {
|
||||||
|
require(['/common/mergeDrive.js'], function (Merge) {
|
||||||
|
var hash = data.anonHash;
|
||||||
|
Merge.anonDriveIntoUser(store, hash, cb);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var getAttributeObject = function (attr) {
|
||||||
|
if (typeof attr === "string") {
|
||||||
|
console.error('DEPRECATED: use setAttribute with an array, not a string');
|
||||||
|
return {
|
||||||
|
obj: storeObj.settings,
|
||||||
|
key: attr
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (!Array.isArray(attr)) { throw new Error("Attribute must be string or array"); }
|
||||||
|
if (attr.length === 0) { throw new Error("Attribute can't be empty"); }
|
||||||
|
var obj = storeObj.settings;
|
||||||
|
attr.forEach(function (el, i) {
|
||||||
|
if (i === attr.length-1) { return; }
|
||||||
|
if (!obj[el]) {
|
||||||
|
obj[el] = {};
|
||||||
|
}
|
||||||
|
else if (typeof obj[el] !== "object") { throw new Error("Wrong attribute"); }
|
||||||
|
obj = obj[el];
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
obj: obj,
|
||||||
|
key: attr[attr.length-1]
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set the display name (username) in the proxy
|
||||||
|
Store.setDisplayName = function (value, cb) {
|
||||||
|
store.proxy[Constants.displayNameKey] = value;
|
||||||
|
onSync(cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Settings & pad attributes
|
||||||
|
* data
|
||||||
|
* - href (String)
|
||||||
|
* - attr (Array)
|
||||||
|
* - value (String)
|
||||||
|
*/
|
||||||
|
Store.setPadAttribute = function (data, cb) {
|
||||||
|
store.userObject.setPadAttribute(data.href, date.attr, data.value, function () {
|
||||||
|
onSync(cb);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Store.getPadAttribute = function (data, cb) {
|
||||||
|
filesOp.getPadAttribute(data.href, data.attr, function (err, val) {
|
||||||
|
if (err) { return void cb({error: err}); }
|
||||||
|
cb(val);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Store.setAttribute = function (data, cb) {
|
||||||
|
try {
|
||||||
|
var object = getAttributeObject(data.attr);
|
||||||
|
object.obj[object.key] = data.value;
|
||||||
|
} catch (e) { return void cb({error: e}); }
|
||||||
|
onSync(cb);
|
||||||
|
};
|
||||||
|
Store.getAttribute = function (data, cb) {
|
||||||
|
var object;
|
||||||
|
try {
|
||||||
|
object = getAttributeObject(data.attr);
|
||||||
|
} catch (e) { return void cb({error: e}); }
|
||||||
|
cb(object.obj[object.key]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Tags
|
||||||
|
Store.listAllTags = function (data, cb) {
|
||||||
|
var all = [];
|
||||||
|
var files = Util.find(store.proxy, ['drive', 'filesData']);
|
||||||
|
|
||||||
|
if (typeof(files) !== 'object') { return cb({error: 'invalid_drive'}); }
|
||||||
|
Object.keys(files).forEach(function (k) {
|
||||||
|
var file = files[k];
|
||||||
|
if (!Array.isArray(file.tags)) { return; }
|
||||||
|
file.tags.forEach(function (tag) {
|
||||||
|
if (all.indexOf(tag) === -1) { all.push(tag); }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
cb(all);
|
||||||
|
};
|
||||||
|
|
||||||
|
var makePad = common.makePad = function (href, title) {
|
||||||
|
var now = +new Date();
|
||||||
|
return {
|
||||||
|
href: href,
|
||||||
|
atime: now,
|
||||||
|
ctime: now,
|
||||||
|
title: title || Hash.getDefaultName(Hash.parsePadUrl(href)),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Store.addPad = function (data, cb) {
|
||||||
|
if (!data.href) { return void cb({error:'NO_HREF'}); }
|
||||||
|
var pad = makePad(data.href, data.title);
|
||||||
|
store.userObject.pushData(pad, function (e, id) {
|
||||||
|
if (e) { return void cb({error: "Error while adding a template:"+ e}); }
|
||||||
|
store.userObject.add(id, ['template']);
|
||||||
|
onSync(cb);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Templates
|
||||||
|
Store.getTemplates = function (data, cb) {
|
||||||
|
var templateFiles = filesOp.getFiles(['template']);
|
||||||
|
var res = [];
|
||||||
|
templateFiles.forEach(function (f) {
|
||||||
|
var data = filesOp.getFileData(f);
|
||||||
|
res.push(JSON.parse(JSON.stringify(data)));
|
||||||
|
});
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Pads
|
||||||
|
Store.moveToTrash = function (data, cb) {
|
||||||
|
var href = Hash.getRelativeHref(data.href);
|
||||||
|
store.userObject.forget(href);
|
||||||
|
onSync(cb);
|
||||||
|
};
|
||||||
|
Store.setPadTitle = function (data, cb) {
|
||||||
|
var title = data.title;
|
||||||
|
var href = data.href;
|
||||||
|
var p = Hash.parsePadUrl(href);
|
||||||
|
var h = p.hashData;
|
||||||
|
|
||||||
|
var allPads = Util.find(store.proxy, ['drive', 'filesData']) || {};
|
||||||
|
var isStronger;
|
||||||
|
|
||||||
|
// If we don't find the new channel in our existing pads, we'll have to add the pads
|
||||||
|
// to filesData
|
||||||
|
var contains;
|
||||||
|
|
||||||
|
// Update all pads that use the same channel but with a weaker hash
|
||||||
|
// Edit > Edit (present) > View > View (present)
|
||||||
|
for (var id in allPads) {
|
||||||
|
var pad = recent[id];
|
||||||
|
if (!pad.href) { continue; }
|
||||||
|
|
||||||
|
var p2 = Hash.parsePadUrl(pad.href);
|
||||||
|
var h2 = p2.hashData;
|
||||||
|
|
||||||
|
// Different types, proceed to the next one
|
||||||
|
// No hash data: corrupted pad?
|
||||||
|
if (p.type !== p2.type || !h2) { continue; }
|
||||||
|
|
||||||
|
var shouldUpdate = p.hash.replace(/\/$/, '') === p2.hash.replace(/\/$/, '');
|
||||||
|
|
||||||
|
// If the hash is different but represents the same channel, check if weaker or stronger
|
||||||
|
if (!shouldUpdate &&
|
||||||
|
h.version === 1 && h2.version === 1 &&
|
||||||
|
h.channel === h2.channel) {
|
||||||
|
// We had view & now we have edit, update
|
||||||
|
if (h2.mode === 'view' && h.mode === 'edit') { shouldUpdate = true; }
|
||||||
|
// Same mode and we had present URL, update
|
||||||
|
else if (h.mode === h2.mode && h2.present) { shouldUpdate = true; }
|
||||||
|
// If we're here it means we have a weaker URL:
|
||||||
|
// update the date but keep the existing hash
|
||||||
|
else {
|
||||||
|
pad.atime = +new Date();
|
||||||
|
contains = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldUpdate) {
|
||||||
|
contains = true;
|
||||||
|
pad.atime = +new Date();
|
||||||
|
pad.title = title;
|
||||||
|
|
||||||
|
// If the href is different, it means we have a stronger one
|
||||||
|
if (href !== pad.href) { isStronger = true; }
|
||||||
|
pad.href = href;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isStronger) {
|
||||||
|
// If we have a stronger url, remove the possible weaker from the trash.
|
||||||
|
// If all of the weaker ones were in the trash, add the stronger to ROOT
|
||||||
|
store.userObject.restoreHref(obj.n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the pad if it does not exist in our drive
|
||||||
|
if (!contains) {
|
||||||
|
Store.addPad({
|
||||||
|
href: href,
|
||||||
|
title: title
|
||||||
|
}, cb);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
onSync(cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Filepicker app
|
||||||
|
Store.getSecureFilesList = function (query, cb) {
|
||||||
|
var list = {};
|
||||||
|
var hashes = [];
|
||||||
|
var types = query.types;
|
||||||
|
var where = query.where;
|
||||||
|
var filter = query.filter || {};
|
||||||
|
var isFiltered = function (type, data) {
|
||||||
|
var filtered;
|
||||||
|
var fType = filter.fileType || [];
|
||||||
|
if (type === 'file' && fType.length) {
|
||||||
|
if (!data.fileType) { return true; }
|
||||||
|
filtered = !fType.some(function (t) {
|
||||||
|
return data.fileType.indexOf(t) === 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return filtered;
|
||||||
|
};
|
||||||
|
store.userObject.getFiles(where).forEach(function (id) {
|
||||||
|
var data = store.userObject.getFileData(id);
|
||||||
|
var parsed = Hash.parsePadUrl(data.href);
|
||||||
|
if ((!types || types.length === 0 || types.indexOf(parsed.type) !== -1) &&
|
||||||
|
hashes.indexOf(parsed.hash) === -1 &&
|
||||||
|
!isFiltered(parsed.type, data)) {
|
||||||
|
hashes.push(parsed.hash);
|
||||||
|
list[id] = data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cb(list);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get hashes for the share button
|
||||||
|
common.getStrongerHash = function (data, cb) {
|
||||||
|
var allPads = Util.find(store.proxy, ['drive', 'filesData']) || {};
|
||||||
|
|
||||||
|
// If we have a stronger version in drive, add it and add a redirect button
|
||||||
|
var stronger = Hash.findStronger(data.href, allPads);
|
||||||
|
if (stronger) {
|
||||||
|
var parsed2 = Hash.parsePadUrl(stronger);
|
||||||
|
return void cb(parsed2.hash);
|
||||||
|
}
|
||||||
|
cb();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var onReady = function (returned, cb) {
|
||||||
|
var proxy = store.proxy;
|
||||||
|
var userObject = store.userObject = UserObject.init(proxy.drive, {
|
||||||
|
pinPads: function (pads, cb) { Store.pinPads({pads: pads}, cb); },
|
||||||
|
loggedIn: store.loggedIn
|
||||||
|
});
|
||||||
|
var todo = function () {
|
||||||
|
fo.fixFiles();
|
||||||
|
|
||||||
|
Migrate(proxy, Cryptpad);
|
||||||
|
|
||||||
|
var requestLogin = function () {
|
||||||
|
postMessage("REQUEST_LOGIN");
|
||||||
|
};
|
||||||
|
|
||||||
|
if (store.loggedIn) {
|
||||||
|
/* This isn't truly secure, since anyone who can read the user's object can
|
||||||
|
set their local loginToken to match that in the object. However, it exposes
|
||||||
|
a UI that will work most of the time. */
|
||||||
|
|
||||||
|
// every user object should have a persistent, random number
|
||||||
|
if (typeof(proxy.loginToken) !== 'number') {
|
||||||
|
proxy[Constants.tokenKey] = Math.floor(Math.random()*Number.MAX_SAFE_INTEGER);
|
||||||
|
}
|
||||||
|
returned[Constants.tokenKey] = proxy[Constants.tokenKey];
|
||||||
|
|
||||||
|
if (store.data.localToken && store.data.localToken !== proxy[tokenKey]) {
|
||||||
|
// the local number doesn't match that in
|
||||||
|
// the user object, request that they reauthenticate.
|
||||||
|
return void requestLogin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!proxy.settings || !proxy.settings.general ||
|
||||||
|
typeof(proxy.settings.general.allowUserFeedback) !== 'boolean') {
|
||||||
|
proxy.settings = proxy.settings || {};
|
||||||
|
proxy.settings.general = proxy.settings.general || {};
|
||||||
|
proxy.settings.general.allowUserFeedback = true;
|
||||||
|
}
|
||||||
|
returned.feedback = proxy.settings.general.allowUserFeedback;
|
||||||
|
|
||||||
|
if (typeof(cb) === 'function') { cb(returned); }
|
||||||
|
|
||||||
|
if (typeof(proxy.uid) !== 'string' || proxy.uid.length !== 32) {
|
||||||
|
// even anonymous users should have a persistent, unique-ish id
|
||||||
|
console.log('generating a persistent identifier');
|
||||||
|
proxy.uid = Hash.createChannelId();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the user is logged in, but does not have signing keys...
|
||||||
|
if (store.loggedIn && (!Store.hasSigningKeys() ||
|
||||||
|
!Store.hasCurveKeys())) {
|
||||||
|
return void requestLogin();
|
||||||
|
}
|
||||||
|
|
||||||
|
proxy.on('change', [Constants.displayNameKey], function (o, n) {
|
||||||
|
if (typeof(n) !== "string") { return; }
|
||||||
|
postMessage("UPDATE_METADATA");
|
||||||
|
});
|
||||||
|
proxy.on('change', ['profile'], function () {
|
||||||
|
// Trigger userlist update when the avatar has changed
|
||||||
|
postMessage("UPDATE_METADATA");
|
||||||
|
});
|
||||||
|
proxy.on('change', ['friends'], function () {
|
||||||
|
// Trigger userlist update when the friendlist has changed
|
||||||
|
postMessage("UPDATE_METADATA");
|
||||||
|
});
|
||||||
|
proxy.on('change', [Constants.tokenKey], function () {
|
||||||
|
postMessage("UPDATE_TOKEN", { data: proxy[Constants.tokenKey] });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
userObject.migrate(todo);
|
||||||
|
};
|
||||||
|
|
||||||
|
var connect = function (data, cb) {
|
||||||
|
var hash = data.userHash || data.anonHash || Hash.createRandomHash();
|
||||||
|
storeHash = hash;
|
||||||
|
if (!hash) {
|
||||||
|
throw new Error('[Store.init] Unable to find or create a drive hash. Aborting...');
|
||||||
|
}
|
||||||
|
var secret = Hash.getSecrets('drive', hash);
|
||||||
|
var listmapConfig = {
|
||||||
|
data: {},
|
||||||
|
websocketURL: NetConfig.getWebsocketURL(),
|
||||||
|
channel: secret.channel,
|
||||||
|
readOnly: false,
|
||||||
|
validateKey: secret.keys.validateKey || undefined,
|
||||||
|
crypto: Crypto.createEncryptor(secret.keys),
|
||||||
|
userName: 'fs',
|
||||||
|
logLevel: 1,
|
||||||
|
ChainPad: ChainPad,
|
||||||
|
classic: true,
|
||||||
|
};
|
||||||
|
var rt = Listmap.create(listmapConfig);
|
||||||
|
store.proxy = rt.proxy,
|
||||||
|
store.realtime = rt.realtime;
|
||||||
|
store.network = rt.network;
|
||||||
|
store.loggedIn = typeof(data.userHash) !== "undefined";
|
||||||
|
|
||||||
|
var returned = {};
|
||||||
|
rt.proxy.on('create', function (info) {
|
||||||
|
exp.info = info;
|
||||||
|
if (!data.userHash) {
|
||||||
|
returned.anonHash = Hash.getEditHashFromKeys(info.channel, secret.keys);
|
||||||
|
}
|
||||||
|
}).on('ready', function () {
|
||||||
|
if (store.userObject) { return; } // the store is already ready, it is a reconnection
|
||||||
|
if (!rt.proxy.drive || typeof(rt.proxy.drive) !== 'object') { rt.proxy.drive = {}; }
|
||||||
|
var drive = rt.proxy.drive;
|
||||||
|
// Creating a new anon drive: import anon pads from localStorage
|
||||||
|
if ((!drive[Constants.oldStorageKey] || !Array.isArray(drive[Constants.oldStorageKey]))
|
||||||
|
&& !drive['filesData']) {
|
||||||
|
drive[Constants.oldStorageKey] = [];
|
||||||
|
}
|
||||||
|
// Drive already exist: return the existing drive, don't load data from legacy store
|
||||||
|
onReady(returned, cb);
|
||||||
|
})
|
||||||
|
.on('change', ['drive', 'migrate'], function () {
|
||||||
|
var path = arguments[2];
|
||||||
|
var value = arguments[1];
|
||||||
|
if (path[0] === 'drive' && path[1] === "migrate" && value === 1) {
|
||||||
|
rt.network.disconnect();
|
||||||
|
rt.realtime.abort();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data:
|
||||||
|
* - userHash or anonHash
|
||||||
|
* Todo in cb
|
||||||
|
* - LocalStore.setFSHash if needed
|
||||||
|
* - sessionStorage.User_Hash
|
||||||
|
* - stuff with tokenKey
|
||||||
|
* Event to outer
|
||||||
|
* - requestLogin
|
||||||
|
*/
|
||||||
|
var initialized = false;
|
||||||
|
Store.init = function (data, callback) {
|
||||||
|
if (initialized) {
|
||||||
|
return void callback({
|
||||||
|
error: 'ALREADY_INIT'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
initialized = true;
|
||||||
|
postMessage = function (cmd, data, cb) {
|
||||||
|
setTimeout(function () {
|
||||||
|
data.query(cmd, data, cb); // TODO temporary, will be rzplaced by webworker channel
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
connect(data, function (ret) {
|
||||||
|
if (Object.keys(store.proxy).length === 1) {
|
||||||
|
Feedback.send("FIRST_APP_USE", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(ret);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Store.disconnect = function () {
|
||||||
|
if (!store.network) { return; }
|
||||||
|
store.network.disconnect();
|
||||||
|
};
|
||||||
|
return Store;
|
||||||
|
});
|
||||||
130
www/common/outer/store-rpc.js
Normal file
130
www/common/outer/store-rpc.js
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
define([
|
||||||
|
'/common/outer/async-store.js'
|
||||||
|
], function (Store) {
|
||||||
|
var Rpc = {};
|
||||||
|
|
||||||
|
Rpc.query = function (cmd, data, cb) {
|
||||||
|
switch (cmd) {
|
||||||
|
// READY
|
||||||
|
case 'CONNECT': {
|
||||||
|
Store.init(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'DISCONNECT': {
|
||||||
|
Store.disconnect(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'CREATE_README': {
|
||||||
|
Store.createReadme(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'MIGRATE_ANON_DRIVE': {
|
||||||
|
Store.migrateAnonDrive(data, cb); break;
|
||||||
|
}
|
||||||
|
// RPC
|
||||||
|
case 'INIT_RPC': {
|
||||||
|
Store.initRpc(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'UPDATE_PIN_LIMIT': {
|
||||||
|
Store.updatePinLimit(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'GET_PIN_LIMIT': {
|
||||||
|
Store.getPinLimit(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'CLEAR_OWNED_CHANNEL': {
|
||||||
|
Store.clearOwnedChannel(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'UPLOAD_COMPLETE': {
|
||||||
|
Store.uploadComplete(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'UPLOAD_STATUS': {
|
||||||
|
Store.uploadStatus(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'UPLOAD_CANCEL': {
|
||||||
|
Store.uploadCancel(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'ARE_PINS_SYNCED': {
|
||||||
|
Store.arePinsSynced(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'RESET_PINS': {
|
||||||
|
Store.resetPins(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'PIN_PADS': {
|
||||||
|
Store.pinPads(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'UNPIN_PADS': {
|
||||||
|
Store.unpinPads(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'GET_PINNED_USAGE': {
|
||||||
|
Store.getPinnedUsage(data, cb); break;
|
||||||
|
}
|
||||||
|
// ANON RPC
|
||||||
|
case 'INIT_ANON_RPC': {
|
||||||
|
Store.initAnonRpc(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'ANON_RPC_MESSAGE': {
|
||||||
|
Store.anonRpcMsg(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'GET_FILE_SIZE': {
|
||||||
|
Store.getFileSize(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'GET_MULTIPLE_FILE_SIZE': {
|
||||||
|
Store.getMultipleFileSize(data, cb); break;
|
||||||
|
}
|
||||||
|
// Store
|
||||||
|
case 'GET': {
|
||||||
|
Store.get(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'SET': {
|
||||||
|
Store.set(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'ADD_PAD': {
|
||||||
|
Store.addPad(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'SET_PAD_TITLE': {
|
||||||
|
Store.setPadTitle(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'MOVE_TO_TRASH': {
|
||||||
|
Store.moveToTrash(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'RESET_DRIVE': {
|
||||||
|
Store.resetDrive(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'GET_METADATA': {
|
||||||
|
Store.getMetadata(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'SET_DISPLAY_NAME': {
|
||||||
|
Store.setDisplayName(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'SET_PAD_ATTRIBUTE': {
|
||||||
|
Store.setPadAttribute(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'GET_PAD_ATTRIBUTE': {
|
||||||
|
Store.getPadAttribute(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'SET_ATTRIBUTE': {
|
||||||
|
Store.setAttribute(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'GET_ATTRIBUTE': {
|
||||||
|
Store.getAttribute(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'LIST_ALL_TAGS': {
|
||||||
|
Store.listAllTags(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'GET_TEMPLATES': {
|
||||||
|
Store.getTemplates(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'GET_SECURE_FILES_LIST': {
|
||||||
|
Store.getSecureFilesList(data, cb); break;
|
||||||
|
}
|
||||||
|
case 'GET_STRONGER_HASH': {
|
||||||
|
Store.getStrongerHash(data, cb); break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return Rpc;
|
||||||
|
});
|
||||||
|
|
||||||
@ -3,13 +3,13 @@ define([
|
|||||||
], function (Rpc) {
|
], function (Rpc) {
|
||||||
var create = function (network, proxy, cb) {
|
var create = function (network, proxy, cb) {
|
||||||
if (!network) {
|
if (!network) {
|
||||||
window.setTimeout(function () {
|
self.setTimeout(function () {
|
||||||
cb('INVALID_NETWORK');
|
cb('INVALID_NETWORK');
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!proxy) {
|
if (!proxy) {
|
||||||
window.setTimeout(function () {
|
self.setTimeout(function () {
|
||||||
cb('INVALID_PROXY');
|
cb('INVALID_PROXY');
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -19,7 +19,7 @@ define([
|
|||||||
var edPublic = proxy.edPublic;
|
var edPublic = proxy.edPublic;
|
||||||
|
|
||||||
if (!(edPrivate && edPublic)) {
|
if (!(edPrivate && edPublic)) {
|
||||||
window.setTimeout(function () {
|
self.setTimeout(function () {
|
||||||
cb('INVALID_KEYS');
|
cb('INVALID_KEYS');
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -39,7 +39,7 @@ define([
|
|||||||
// you can ask the server to pin a particular channel for you
|
// you can ask the server to pin a particular channel for you
|
||||||
exp.pin = function (channels, cb) {
|
exp.pin = function (channels, cb) {
|
||||||
if (!Array.isArray(channels)) {
|
if (!Array.isArray(channels)) {
|
||||||
window.setTimeout(function () {
|
self.setTimeout(function () {
|
||||||
cb('[TypeError] pin expects an array');
|
cb('[TypeError] pin expects an array');
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -50,7 +50,7 @@ define([
|
|||||||
// you can also ask to unpin a particular channel
|
// you can also ask to unpin a particular channel
|
||||||
exp.unpin = function (channels, cb) {
|
exp.unpin = function (channels, cb) {
|
||||||
if (!Array.isArray(channels)) {
|
if (!Array.isArray(channels)) {
|
||||||
window.setTimeout(function () {
|
self.setTimeout(function () {
|
||||||
cb('[TypeError] pin expects an array');
|
cb('[TypeError] pin expects an array');
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -71,7 +71,7 @@ define([
|
|||||||
// if local and remote hashes don't match, send a reset
|
// if local and remote hashes don't match, send a reset
|
||||||
exp.reset = function (channels, cb) {
|
exp.reset = function (channels, cb) {
|
||||||
if (!Array.isArray(channels)) {
|
if (!Array.isArray(channels)) {
|
||||||
window.setTimeout(function () {
|
self.setTimeout(function () {
|
||||||
cb('[TypeError] pin expects an array');
|
cb('[TypeError] pin expects an array');
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -163,7 +163,7 @@ define([
|
|||||||
|
|
||||||
exp.uploadStatus = function (size, cb) {
|
exp.uploadStatus = function (size, cb) {
|
||||||
if (typeof(size) !== 'number') {
|
if (typeof(size) !== 'number') {
|
||||||
return void window.setTimeout(function () {
|
return void self.setTimeout(function () {
|
||||||
cb('INVALID_SIZE');
|
cb('INVALID_SIZE');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ define([
|
|||||||
'/common/common-util.js',
|
'/common/common-util.js',
|
||||||
'/bower_components/tweetnacl/nacl-fast.min.js',
|
'/bower_components/tweetnacl/nacl-fast.min.js',
|
||||||
], function (Util) {
|
], function (Util) {
|
||||||
var Nacl = window.nacl;
|
var Nacl = self.nacl;
|
||||||
|
|
||||||
var uid = Util.uid;
|
var uid = Util.uid;
|
||||||
var signMsg = function (data, signKey) {
|
var signMsg = function (data, signKey) {
|
||||||
@ -140,7 +140,7 @@ types of messages:
|
|||||||
|
|
||||||
var send = ctx.send = function (type, msg, cb) {
|
var send = ctx.send = function (type, msg, cb) {
|
||||||
if (!ctx.connected && type !== 'COOKIE') {
|
if (!ctx.connected && type !== 'COOKIE') {
|
||||||
return void window.setTimeout(function () {
|
return void self.setTimeout(function () {
|
||||||
cb('DISCONNECTED');
|
cb('DISCONNECTED');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -185,7 +185,7 @@ types of messages:
|
|||||||
|
|
||||||
send.unauthenticated = function (type, msg, cb) {
|
send.unauthenticated = function (type, msg, cb) {
|
||||||
if (!ctx.connected) {
|
if (!ctx.connected) {
|
||||||
return void window.setTimeout(function () {
|
return void self.setTimeout(function () {
|
||||||
cb('DISCONNECTED');
|
cb('DISCONNECTED');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -276,7 +276,7 @@ types of messages:
|
|||||||
|
|
||||||
var send = ctx.send = function (type, msg, cb) {
|
var send = ctx.send = function (type, msg, cb) {
|
||||||
if (!ctx.connected) {
|
if (!ctx.connected) {
|
||||||
return void window.setTimeout(function () {
|
return void self.setTimeout(function () {
|
||||||
cb('DISCONNECTED');
|
cb('DISCONNECTED');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -104,11 +104,17 @@ define([
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
secret = cfg.getSecrets ? cfg.getSecrets(Cryptpad, Utils) : Utils.Hash.getSecrets();
|
if (cfg.getSecrets) {
|
||||||
|
cfg.getSecrets(Cryptpad, Utils, waitFor(function (err, s) {
|
||||||
|
secret = s;
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
secret = Utils.Hash.getSecrets();
|
||||||
if (!secret.channel) {
|
if (!secret.channel) {
|
||||||
// New pad: create a new random channel id
|
// New pad: create a new random channel id
|
||||||
secret.channel = Utils.Hash.createChannelId();
|
secret.channel = Utils.Hash.createChannelId();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Cryptpad.getShareHashes(secret, waitFor(function (err, h) { hashes = h; }));
|
Cryptpad.getShareHashes(secret, waitFor(function (err, h) { hashes = h; }));
|
||||||
|
|
||||||
}).nThen(function () {
|
}).nThen(function () {
|
||||||
@ -120,54 +126,46 @@ define([
|
|||||||
var proxy = Cryptpad.getProxy();
|
var proxy = Cryptpad.getProxy();
|
||||||
var updateMeta = function () {
|
var updateMeta = function () {
|
||||||
//console.log('EV_METADATA_UPDATE');
|
//console.log('EV_METADATA_UPDATE');
|
||||||
var name;
|
var metaObj, isTemplate;
|
||||||
nThen(function (waitFor) {
|
nThen(function (waitFor) {
|
||||||
Cryptpad.getLastName(waitFor(function (err, n) {
|
Cryptpad.getMetadata(waitFor(function (err, m) {
|
||||||
if (err) { console.log(err); }
|
if (err) { console.log(err); }
|
||||||
name = n;
|
metaObj = m;
|
||||||
|
}));
|
||||||
|
Cryptpad.isTemplate(window.location.href, waitFor(function (err, t) {
|
||||||
|
if (err) { console.log(err); }
|
||||||
|
isTemplate = t;
|
||||||
}));
|
}));
|
||||||
}).nThen(function (/*waitFor*/) {
|
}).nThen(function (/*waitFor*/) {
|
||||||
var metaObj = {
|
metaObj.doc: {
|
||||||
doc: {
|
|
||||||
defaultTitle: defaultTitle,
|
defaultTitle: defaultTitle,
|
||||||
type: parsed.type
|
type: parsed.type
|
||||||
},
|
};
|
||||||
user: {
|
var additionalPriv = {
|
||||||
name: name,
|
|
||||||
uid: Cryptpad.getUid(),
|
|
||||||
avatar: Cryptpad.getAvatarUrl(),
|
|
||||||
profile: Cryptpad.getProfileUrl(),
|
|
||||||
curvePublic: proxy.curvePublic,
|
|
||||||
netfluxId: Cryptpad.getNetwork().webChannels[0].myID,
|
|
||||||
},
|
|
||||||
priv: {
|
|
||||||
edPublic: proxy.edPublic,
|
|
||||||
accountName: Utils.LocalStore.getAccountName(),
|
accountName: Utils.LocalStore.getAccountName(),
|
||||||
origin: window.location.origin,
|
origin: window.location.origin,
|
||||||
pathname: window.location.pathname,
|
pathname: window.location.pathname,
|
||||||
fileHost: ApiConfig.fileHost,
|
fileHost: ApiConfig.fileHost,
|
||||||
readOnly: readOnly,
|
readOnly: readOnly,
|
||||||
availableHashes: hashes,
|
availableHashes: hashes,
|
||||||
isTemplate: Cryptpad.isTemplate(window.location.href),
|
isTemplate: isTemplate,
|
||||||
feedbackAllowed: Utils.Feedback.state,
|
feedbackAllowed: Utils.Feedback.state,
|
||||||
friends: proxy.friends || {},
|
|
||||||
settings: proxy.settings || {},
|
|
||||||
isPresent: parsed.hashData && parsed.hashData.present,
|
isPresent: parsed.hashData && parsed.hashData.present,
|
||||||
isEmbed: parsed.hashData && parsed.hashData.embed,
|
isEmbed: parsed.hashData && parsed.hashData.embed,
|
||||||
thumbnails: !((proxy.settings || {}).general || {}).disableThumbnails,
|
|
||||||
accounts: {
|
accounts: {
|
||||||
donateURL: Cryptpad.donateURL,
|
donateURL: Cryptpad.donateURL,
|
||||||
upgradeURL: Cryptpad.upgradeURL
|
upgradeURL: Cryptpad.upgradeURL
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
for (var k in additionalPriv) { metaObj.priv[k] = additionalPriv[k]; }
|
||||||
|
|
||||||
if (cfg.addData) {
|
if (cfg.addData) {
|
||||||
cfg.addData(metaObj.priv, Cryptpad);
|
cfg.addData(metaObj.priv, Cryptpad);
|
||||||
}
|
}
|
||||||
sframeChan.event('EV_METADATA_UPDATE', metaObj);
|
sframeChan.event('EV_METADATA_UPDATE', metaObj);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
Cryptpad.onDisplayNameChanged(updateMeta);
|
Cryptpad.onMetadataChanged(updateMeta);
|
||||||
sframeChan.onReg('EV_METADATA_UPDATE', updateMeta);
|
sframeChan.onReg('EV_METADATA_UPDATE', updateMeta);
|
||||||
proxy.on('change', 'settings', updateMeta);
|
proxy.on('change', 'settings', updateMeta);
|
||||||
|
|
||||||
@ -445,8 +443,9 @@ define([
|
|||||||
Cryptpad.useTemplate(href, Cryptget, cb);
|
Cryptpad.useTemplate(href, Cryptget, cb);
|
||||||
});
|
});
|
||||||
sframeChan.on('Q_TEMPLATE_EXIST', function (type, cb) {
|
sframeChan.on('Q_TEMPLATE_EXIST', function (type, cb) {
|
||||||
var hasTemplate = Cryptpad.listTemplates(type).length > 0;
|
Cryptpad.listTemplates(type, function (err, templates) {
|
||||||
cb(hasTemplate);
|
cb(templates.length > 0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
sframeChan.on('EV_GOTO_URL', function (url) {
|
sframeChan.on('EV_GOTO_URL', function (url) {
|
||||||
|
|||||||
@ -373,10 +373,6 @@ define([
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
ctx.sframeChan.on('EV_RT_CONNECT', function () { CommonRealtime.setConnectionState(true); });
|
|
||||||
ctx.sframeChan.on('EV_RT_DISCONNECT', function () { CommonRealtime.setConnectionState(false); });
|
|
||||||
|
|
||||||
|
|
||||||
ctx.sframeChan.on('Q_INCOMING_FRIEND_REQUEST', function (confirmMsg, cb) {
|
ctx.sframeChan.on('Q_INCOMING_FRIEND_REQUEST', function (confirmMsg, cb) {
|
||||||
UI.confirm(confirmMsg, cb, null, true);
|
UI.confirm(confirmMsg, cb, null, true);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -21,13 +21,13 @@ define([
|
|||||||
|
|
||||||
module.init = function (files, config) {
|
module.init = function (files, config) {
|
||||||
var exp = {};
|
var exp = {};
|
||||||
var Cryptpad = config.Cryptpad;
|
var pinPads = config.pinPads;
|
||||||
var loggedIn = config.loggedIn;
|
var loggedIn = config.loggedIn;
|
||||||
|
|
||||||
var FILES_DATA = module.FILES_DATA = exp.FILES_DATA = Constants.storageKey;
|
var FILES_DATA = module.FILES_DATA = exp.FILES_DATA = Constants.storageKey;
|
||||||
var OLD_FILES_DATA = module.OLD_FILES_DATA = exp.OLD_FILES_DATA = Constants.oldStorageKey;
|
var OLD_FILES_DATA = module.OLD_FILES_DATA = exp.OLD_FILES_DATA = Constants.oldStorageKey;
|
||||||
var NEW_FOLDER_NAME = Messages.fm_newFolder;
|
var NEW_FOLDER_NAME = Messages.fm_newFolder || 'New folder';
|
||||||
var NEW_FILE_NAME = Messages.fm_newFile;
|
var NEW_FILE_NAME = Messages.fm_newFile || 'New file';
|
||||||
|
|
||||||
exp.ROOT = ROOT;
|
exp.ROOT = ROOT;
|
||||||
exp.UNSORTED = UNSORTED;
|
exp.UNSORTED = UNSORTED;
|
||||||
@ -488,7 +488,7 @@ define([
|
|||||||
// FILES DATA
|
// FILES DATA
|
||||||
exp.pushData = function (data, cb) {
|
exp.pushData = function (data, cb) {
|
||||||
// TODO: can only be called from outside atm
|
// TODO: can only be called from outside atm
|
||||||
if (!Cryptpad) { return; }
|
if (!pinPads) { return; }
|
||||||
if (typeof cb !== "function") { cb = function () {}; }
|
if (typeof cb !== "function") { cb = function () {}; }
|
||||||
var todo = function () {
|
var todo = function () {
|
||||||
var id = Util.createRandomInteger();
|
var id = Util.createRandomInteger();
|
||||||
@ -498,7 +498,7 @@ define([
|
|||||||
if (!loggedIn || !AppConfig.enablePinning || config.testMode) {
|
if (!loggedIn || !AppConfig.enablePinning || config.testMode) {
|
||||||
return void todo();
|
return void todo();
|
||||||
}
|
}
|
||||||
Cryptpad.pinPads([Hash.hrefToHexChannelId(data.href)], function (e) {
|
pinPads([Hash.hrefToHexChannelId(data.href)], function (e) {
|
||||||
if (e) { return void cb(e); }
|
if (e) { return void cb(e); }
|
||||||
todo();
|
todo();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -70,7 +70,7 @@ define([
|
|||||||
|
|
||||||
module.test = function (assert) {
|
module.test = function (assert) {
|
||||||
var config = {
|
var config = {
|
||||||
Cryptpad: Cryptpad,
|
pinPads: Cryptpad.pinPads,
|
||||||
workgroup: false,
|
workgroup: false,
|
||||||
testMode: true,
|
testMode: true,
|
||||||
loggedIn: false
|
loggedIn: false
|
||||||
|
|||||||
@ -49,36 +49,27 @@ define([
|
|||||||
var proxy = Cryptpad.getProxy();
|
var proxy = Cryptpad.getProxy();
|
||||||
var updateMeta = function () {
|
var updateMeta = function () {
|
||||||
//console.log('EV_METADATA_UPDATE');
|
//console.log('EV_METADATA_UPDATE');
|
||||||
var name;
|
var metaObj;
|
||||||
nThen(function (waitFor) {
|
nThen(function (waitFor) {
|
||||||
Cryptpad.getLastName(waitFor(function (err, n) {
|
Cryptpad.getMetadata(waitFor(function (err, n) {
|
||||||
if (err) { console.log(err); }
|
if (err) { console.log(err); }
|
||||||
name = n;
|
metaObj = n;
|
||||||
}));
|
}));
|
||||||
}).nThen(function (/*waitFor*/) {
|
}).nThen(function (/*waitFor*/) {
|
||||||
sframeChan.event('EV_METADATA_UPDATE', {
|
metaObj.doc: {};
|
||||||
doc: {},
|
var additionalPriv = {
|
||||||
user: {
|
|
||||||
name: name,
|
|
||||||
uid: Cryptpad.getUid(),
|
|
||||||
avatar: Cryptpad.getAvatarUrl(),
|
|
||||||
profile: Cryptpad.getProfileUrl(),
|
|
||||||
curvePublic: proxy.curvePublic,
|
|
||||||
netfluxId: Cryptpad.getNetwork().webChannels[0].myID,
|
|
||||||
},
|
|
||||||
priv: {
|
|
||||||
accountName: Utils.LocalStore.getAccountName(),
|
accountName: Utils.LocalStore.getAccountName(),
|
||||||
origin: window.location.origin,
|
origin: window.location.origin,
|
||||||
pathname: window.location.pathname,
|
pathname: window.location.pathname,
|
||||||
feedbackAllowed: Utils.Feedback.state,
|
feedbackAllowed: Utils.Feedback.state,
|
||||||
friends: proxy.friends || {},
|
|
||||||
settings: proxy.settings || {},
|
|
||||||
types: config.types
|
types: config.types
|
||||||
}
|
};
|
||||||
});
|
for (var k in additionalPriv) { metaObj.priv[k] = additionalPriv[k]; }
|
||||||
|
|
||||||
|
sframeChan.event('EV_METADATA_UPDATE', metaObj);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
Cryptpad.onDisplayNameChanged(updateMeta);
|
Cryptpad.onMetadataChanged(updateMeta);
|
||||||
sframeChan.onReg('EV_METADATA_UPDATE', updateMeta);
|
sframeChan.onReg('EV_METADATA_UPDATE', updateMeta);
|
||||||
proxy.on('change', 'settings', updateMeta);
|
proxy.on('change', 'settings', updateMeta);
|
||||||
|
|
||||||
|
|||||||
@ -395,15 +395,6 @@ define([
|
|||||||
var onReady = function () {
|
var onReady = function () {
|
||||||
APP.$container.find('#'+CREATE_ID).remove();
|
APP.$container.find('#'+CREATE_ID).remove();
|
||||||
|
|
||||||
/*var obj = APP.lm && APP.lm.proxy;
|
|
||||||
if (!APP.readOnly) {
|
|
||||||
var pubKeys = Cryptpad.getPublicKeys();
|
|
||||||
if (pubKeys && pubKeys.curve) {
|
|
||||||
obj.curveKey = pubKeys.curve;
|
|
||||||
obj.edKey = pubKeys.ed;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (!APP.initialized) {
|
if (!APP.initialized) {
|
||||||
var $header = $('<div>', {id: HEADER_ID}).appendTo(APP.$rightside);
|
var $header = $('<div>', {id: HEADER_ID}).appendTo(APP.$rightside);
|
||||||
addAvatar($header);
|
addAvatar($header);
|
||||||
|
|||||||
@ -36,19 +36,24 @@ define([
|
|||||||
};
|
};
|
||||||
window.addEventListener('message', onMsg);
|
window.addEventListener('message', onMsg);
|
||||||
}).nThen(function (/*waitFor*/) {
|
}).nThen(function (/*waitFor*/) {
|
||||||
var getSecrets = function (Cryptpad, Utils) {
|
var getSecrets = function (Cryptpad, Utils, cb) {
|
||||||
var Hash = Utils.Hash;
|
var Hash = Utils.Hash;
|
||||||
// 1st case: visiting someone else's profile with hash in the URL
|
// 1st case: visiting someone else's profile with hash in the URL
|
||||||
if (window.location.hash) {
|
if (window.location.hash) {
|
||||||
return Hash.getSecrets('profile', window.location.hash.slice(1));
|
return void cb(null, Hash.getSecrets('profile', window.location.hash.slice(1)));
|
||||||
}
|
}
|
||||||
|
var editHash;
|
||||||
|
nThen(function (waitFor) {
|
||||||
// 2nd case: visiting our own existing profile
|
// 2nd case: visiting our own existing profile
|
||||||
var obj = Cryptpad.getProxy();
|
Cryptpad.getProfileEditUrl(waitFor(function (hash) {
|
||||||
if (obj.profile && obj.profile.view && obj.profile.edit) {
|
editHash = hash;
|
||||||
return Hash.getSecrets('profile', obj.profile.edit);
|
}));
|
||||||
|
}).nThen(function () {
|
||||||
|
if (!editHash) {
|
||||||
|
return void cb(null, Hash.getSecrets('profile', editHash));
|
||||||
}
|
}
|
||||||
// 3rd case: profile creation (create a new random hash, store it later if needed)
|
// 3rd case: profile creation (create a new random hash, store it later if needed)
|
||||||
if (!Utils.LocalStore.isLoggedIn()) { return; }
|
if (!Utils.LocalStore.isLoggedIn()) { return void cb(); }
|
||||||
var hash = Hash.createRandomHash();
|
var hash = Hash.createRandomHash();
|
||||||
var secret = Hash.getSecrets('profile', hash);
|
var secret = Hash.getSecrets('profile', hash);
|
||||||
Cryptpad.pinPads([secret.channel], function (e) {
|
Cryptpad.pinPads([secret.channel], function (e) {
|
||||||
@ -59,11 +64,13 @@ define([
|
|||||||
return;
|
return;
|
||||||
//return void UI.log(Messages._getKey('profile_error', [e])) // TODO
|
//return void UI.log(Messages._getKey('profile_error', [e])) // TODO
|
||||||
}
|
}
|
||||||
obj.profile = {};
|
var profile = {};
|
||||||
obj.profile.edit = Utils.Hash.getEditHashFromKeys(secret.channel, secret.keys);
|
profile.edit = Utils.Hash.getEditHashFromKeys(secret.channel, secret.keys);
|
||||||
obj.profile.view = Utils.Hash.getViewHashFromKeys(secret.channel, secret.keys);
|
profile.view = Utils.Hash.getViewHashFromKeys(secret.channel, secret.keys);
|
||||||
|
Cryptpad.setNewProfile(profile);
|
||||||
|
});
|
||||||
|
cb(null, secret);
|
||||||
});
|
});
|
||||||
return secret;
|
|
||||||
};
|
};
|
||||||
var addRpc = function (sframeChan, Cryptpad, Utils) {
|
var addRpc = function (sframeChan, Cryptpad, Utils) {
|
||||||
// Adding a new avatar from the profile: pin it and store it in the object
|
// Adding a new avatar from the profile: pin it and store it in the object
|
||||||
|
|||||||
@ -43,7 +43,7 @@ define([
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
sframeChan.on('Q_SETTINGS_DRIVE_GET', function (d, cb) {
|
sframeChan.on('Q_SETTINGS_DRIVE_GET', function (d, cb) {
|
||||||
cb(Cryptpad.getProxy());
|
Cryptpad.getUserObject(cb);
|
||||||
});
|
});
|
||||||
sframeChan.on('Q_SETTINGS_DRIVE_SET', function (data, cb) {
|
sframeChan.on('Q_SETTINGS_DRIVE_SET', function (data, cb) {
|
||||||
var sjson = JSON.stringify(data);
|
var sjson = JSON.stringify(data);
|
||||||
@ -57,26 +57,13 @@ define([
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
sframeChan.on('Q_SETTINGS_DRIVE_RESET', function (data, cb) {
|
sframeChan.on('Q_SETTINGS_DRIVE_RESET', function (data, cb) {
|
||||||
var proxy = Cryptpad.getProxy();
|
Cryptpad.resetDrive(cb);
|
||||||
var realtime = Cryptpad.getRealtime();
|
|
||||||
proxy.drive = Cryptpad.getStore().getEmptyObject();
|
|
||||||
Utils.Realtime.whenRealtimeSyncs(realtime, cb);
|
|
||||||
});
|
});
|
||||||
sframeChan.on('Q_SETTINGS_LOGOUT', function (data, cb) {
|
sframeChan.on('Q_SETTINGS_LOGOUT', function (data, cb) {
|
||||||
var proxy = Cryptpad.getProxy();
|
Cryptpad.logoutFromAll(cb);
|
||||||
var realtime = Cryptpad.getRealtime();
|
|
||||||
var token = Math.floor(Math.random()*Number.MAX_SAFE_INTEGER);
|
|
||||||
localStorage.setItem('loginToken', token);
|
|
||||||
proxy.loginToken = token;
|
|
||||||
Utils.Realtime.whenRealtimeSyncs(realtime, cb);
|
|
||||||
});
|
});
|
||||||
sframeChan.on('Q_SETTINGS_IMPORT_LOCAL', function (data, cb) {
|
sframeChan.on('Q_SETTINGS_IMPORT_LOCAL', function (data, cb) {
|
||||||
var proxyData = Cryptpad.getStore().getProxy();
|
Cryptpad.mergeAnonDrive(cb);
|
||||||
require([
|
|
||||||
'/common/mergeDrive.js',
|
|
||||||
], function (Merge) {
|
|
||||||
Merge.anonDriveIntoUser(proxyData, Utils.LocalStore.getFSHash(), cb);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
SFCommonO.start({
|
SFCommonO.start({
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user