Merge branch 'inviteUI' of github.com:xwiki-labs/cryptpad into inviteUI

pull/1/head
ansuz 5 years ago
commit da4399e3dc

@ -1,5 +1,5 @@
(function () { (function () {
var factory = function (Hash, Nacl, Scrypt/*, Util, Cred, nThen */) { var factory = function (Hash, Crypt, Nacl, Scrypt/*, Util, Cred, nThen */) {
var Invite = {}; var Invite = {};
Invite.deriveSeeds = function (seed) { Invite.deriveSeeds = function (seed) {
@ -44,14 +44,40 @@ var factory = function (Hash, Nacl, Scrypt/*, Util, Cred, nThen */) {
}; };
Invite.getPreviewContent = function (seeds, cb) { Invite.getPreviewContent = function (seeds, cb) {
setTimeout(function () {
cb(void 0, {
author: {
displayName: 'Bob',
curvePublic: 'pewpewpew'
},
team: 'CryptPad',
message: 'Hello bob'
});
});
/*
var secrets = Invite.derivePreviewSecrets(seeds); var secrets = Invite.derivePreviewSecrets(seeds);
secrets = secrets; secrets = secrets;
cb("NOT_IMPLEMENTED"); // XXX cryptget */
var hash = Invite.derivePreviewHash(seeds);
Crypt.get(hash, function (err, val) {
if (err) { return void cb(err); }
try {
cb(void 0, JSON.parse(val));
} catch (e) {
console.error(e);
cb(e);
}
});
// cb("NOT_IMPLEMENTED"); // XXX cryptget
}; };
// XXX remember to pin invites... // XXX remember to pin invites...
Invite.setPreviewContent = function (seeds, cb) { Invite.setPreviewContent = function (seeds, cb) {
cb = cb; var hash = Invite.derivePreviewHash(seeds);
Crypt.put(hash, '', function (err) { // value?
cb(err);
});
//cb = cb;
}; };
return Invite; return Invite;
@ -59,16 +85,18 @@ var factory = function (Hash, Nacl, Scrypt/*, Util, Cred, nThen */) {
if (typeof(module) !== 'undefined' && module.exports) { if (typeof(module) !== 'undefined' && module.exports) {
module.exports = factory( module.exports = factory(
require("../common-hash"), require("../common-hash"),
require("../cryptget"), // XXX npm cryptget?
require("tweetnacl/nacl-fast"), require("tweetnacl/nacl-fast"),
require("scrypt-async") require("scrypt-async")
); );
} else if ((typeof(define) !== 'undefined' && define !== null) && (define.amd !== null)) { } else if ((typeof(define) !== 'undefined' && define !== null) && (define.amd !== null)) {
define([ define([
'/common/common-hash.js', '/common/common-hash.js',
'/common/cryptget.js',
'/bower_components/tweetnacl/nacl-fast.min.js', '/bower_components/tweetnacl/nacl-fast.min.js',
'/bower_components/scrypt-async/scrypt-async.min.js', '/bower_components/scrypt-async/scrypt-async.min.js',
], function (Hash /*, Nacl, Scrypt */) { ], function (Hash, Crypt /*, Nacl, Scrypt */) {
return factory(Hash, window.nacl, window.scrypt); return factory(Hash, Crypt, window.nacl, window.scrypt);
}); });
} }
}()); }());

@ -1019,17 +1019,96 @@ define([
]); ]);
}, true); }, true);
var displayUser = function (common, data) {
var friends = common.getMetadataMgr().getPrivateData().friends;
var verified = false;
if (friends[data.curvePublic]) { verified = true; }
var avatar = h('span.cp-teams-invite-from-avatar.cp-avatar');
UIElements.displayAvatar(common, $(avatar), data.avatar, data.displayName);
return h('div.cp-teams-invite-from-author', [
avatar,
h('span.cp-teams-invite-from-name', data.displayName)
]);
};
makeBlock('link', function (common, cb) { makeBlock('link', function (common, cb) {
// XXX get team data first or login first? var hash = common.getMetadataMgr().getPrivateData().teamInviteHash;
if (!driveAPP.loggedIn) { var hashData = Hash.parseTypeHash('invite', hash);
var password = hashData.password;
var seeds = InviteInner.deriveSeeds(hashData.key);
var div = h('div', [
h('i.fa.fa-spin.fa-spinner')
]);
var $div = $(div);
cb([
h('h2', 'Team invitation'), // XXX
div
]);
var inviteDiv = h('div');
var $inviteDiv = $(inviteDiv);
var process = function (pw) {
$inviteDiv.empty();
var bytes64;
var button = h('button', 'XXX');
button.onclick = function () {
nThen(function (waitFor) {
$inviteDiv.append(h('div', [
h('i.fa.fa-spin.fa-spinner'),
h('span', 'Scrypt...') // XXX
]));
setTimeout(waitFor(), 150);
}).nThen(function (waitFor) {
var salt = InviteInner.deriveSalt(pw, AppConfig.loginSalt);
InviteInner.deriveBytes(seeds.scrypt, salt, waitFor(function (bytes) {
bytes64 = bytes;
}));
}).nThen(function (waitFor) {
APP.module.execCommand('GET_LINK_DATA', {
bytes64: bytes64,
hash: hash,
password: pw,
}, waitFor(function () {
$div.empty();
// TODO
// Accept/decline/decide later UI
}));
});
};
$inviteDiv.append(button);
};
nThen(function (waitFor) {
InviteInner.getPreviewContent(seeds, waitFor(function (err, json) {
if (err) {
// XXX handle errors
}
json = json; // XXX {message: "", author: "", ???}
$div.empty();
$div.append(h('div.cp-teams-invite-from', [
'From', // XXX
displayUser(common, json.author)
]));
$div.append(UI.setHTML(h('p.cp-teams-invite-to'), 'Bob has invited you to join the team <b>CryptPad</b>')); // XXX
$div.append(h('div.cp-teams-invite-message', [
UI.dialog.selectableArea(json.message || '')
]));
}));
}).nThen(function (waitFor) {
// If you're logged in, move on to the next nThen
if (driveAPP.loggedIn) { return; }
// If you're not logged in, display the login buttons
var anonLogin, anonRegister; var anonLogin, anonRegister;
var anonContent = h('div', [ $div.append(h('p', 'Please log in or register to accept this invitation...')); // XXX
h('p', "You've been invited to a team. Only registered users can join a team. Login or register..."), // XXX $div.append(h('div', [
h('div', [ anonLogin = h('button.btn.btn-primary', Messages.login_login),
anonLogin = h('button.btn.btn-primary', Messages.login_login), anonRegister = h('button.btn.btn-secondary', Messages.login_register),
anonRegister = h('button.btn.btn-secondary', Messages.login_register), ]));
])
]);
$(anonLogin).click(function () { $(anonLogin).click(function () {
common.setLoginRedirect(function () { common.setLoginRedirect(function () {
common.gotoURL('/login/'); common.gotoURL('/login/');
@ -1040,81 +1119,29 @@ define([
common.gotoURL('/register/'); common.gotoURL('/register/');
}); });
}); });
return void cb(anonContent); waitFor.abort();
} }).nThen(function () {
var hash = common.getMetadataMgr().getPrivateData().teamInviteHash; $div.append($inviteDiv);
var hashData = Hash.parseTypeHash('invite', hash); }).nThen(function (waitFor) {
var password = hashData.password; // If there is no password, move on to the next block
var seeds = InviteInner.deriveSeeds(hashData.key); if (!password) { return; }
var div;
var process = function (pw) {
var $div = $(div);
$div.empty();
var bytes64;
nThen(function (waitFor) {
// XXX show something while we're waiting for the invite preview content
waitFor = waitFor;
}).nThen(function (waitFor) {
InviteInner.getPreviewContent(seeds, waitFor(function (err, json) {
json = json; // XXX {message: "", author: "", ???}
if (err) {
// XXX handle errors
}
// XXX show invite preview content
var button = h('button', 'XXX');
button.onclick = function () {
nThen(function (waitFor) {
$div.append(h('div', [
h('i.fa.fa-spin.fa-spinner'),
h('span', 'Scrypt...') // XXX
]));
setTimeout(waitFor(), 150);
}).nThen(function (waitFor) {
var salt = InviteInner.deriveSalt(pw, AppConfig.loginSalt);
InviteInner.deriveBytes(seeds.scrypt, salt, waitFor(function (bytes) {
bytes64 = bytes;
}));
}).nThen(function (waitFor) {
APP.module.execCommand('GET_LINK_DATA', {
bytes64: bytes64,
hash: hash,
password: pw,
}, waitFor(function () {
$div.empty();
// TODO
// Accept/decline/decide later UI
}));
});
};
$div.append(button);
}));
});
};
var content = []; // If there is a password, display the password prompt
if (password) { $inviteDiv.append(h('p', 'Please enter the invitation password to continue...')); // XXX
// XXX XXX
content.push(h('p', "You've been invited to join a CryptPad Team, but the person who created the invitation protected it with a secret passphrase that they expect you to know."));
content.push(h('p', "Entering the correct phrase will decrypt the team's info and allow you to accept or decline the invitation."));
var pwInput = UI.passwordInput(); var pwInput = UI.passwordInput();
content.push(pwInput);
var submitPw = h('button.btn.btn-secondary', Messages.password_submit); var submitPw = h('button.btn.btn-secondary', Messages.password_submit);
$(submitPw).click(function () { $(submitPw).click(function () {
var val = $(pwInput).find('input').val(); var val = $(pwInput).find('input').val();
if (!val) { return; } if (!val) { return; }
process(val); process(val);
}); });
content.push(submitPw); $inviteDiv.append(pwInput);
} $inviteDiv.append(submitPw);
div = h('div', content); waitFor.abort();
cb(div); }).nThen(function () {
// No password, display the invitation proposal
if (!password) { process(); } process('');
});
}); });
var redrawTeam = function (common) { var redrawTeam = function (common) {

Loading…
Cancel
Save