Open and Scrypt invitation link

pull/1/head
yflory 5 years ago
parent 9391698f54
commit be9dce674f

@ -20,7 +20,7 @@ define(function() {
* users and these users will be redirected to the login page if they still try to access * users and these users will be redirected to the login page if they still try to access
* the app * the app
*/ */
config.registeredOnlyTypes = ['teams', 'file', 'contacts', 'oodoc', 'ooslide', 'sheet', 'notifications']; config.registeredOnlyTypes = ['file', 'contacts', 'oodoc', 'ooslide', 'sheet', 'notifications'];
/* CryptPad is available is multiple languages, but only English and French are maintained /* CryptPad is available is multiple languages, but only English and French are maintained
* by the developers. The other languages may be outdated, and any missing string for a langauge * by the developers. The other languages may be outdated, and any missing string for a langauge

@ -1651,7 +1651,7 @@ define([
}), }),
h('br'), h('br'),
linkMessage = h('textarea', { linkMessage = h('textarea', {
placeholder: 'note...' placeholder: 'note...' // XXX
}) })
]), ]),
linkSpin = h('div', { linkSpin = h('div', {
@ -1677,7 +1677,6 @@ define([
var hash = Hash.createRandomHash('invite', pw); var hash = Hash.createRandomHash('invite', pw);
var hashData = Hash.parseTypeHash('invite', hash); var hashData = Hash.parseTypeHash('invite', hash);
href = origin + '/teams/#' + hash; href = origin + '/teams/#' + hash;
console.log(hashData);
if (!name || !name.trim()) { if (!name || !name.trim()) {
$(linkError).text('empty name...').show(); // XXX $(linkError).text('empty name...').show(); // XXX
return true; return true;
@ -1707,7 +1706,7 @@ define([
password: pw, password: pw,
message: msg, message: msg,
bytes64: bytes64, bytes64: bytes64,
href: href, hash: hash,
teamId: config.teamId, teamId: config.teamId,
}, waitFor(function (obj) { }, waitFor(function (obj) {
if (obj && obj.error) { if (obj && obj.error) {

@ -1267,7 +1267,7 @@ define([
var name = data.name; var name = data.name;
var password = data.password; var password = data.password;
var msg = data.message; var msg = data.message;
var href = data.href; var hash = data.hash;
var bytes64 = data.bytes64; var bytes64 = data.bytes64;
*/ */
return void cb(); return void cb();
@ -1277,6 +1277,20 @@ define([
}); });
*/ */
}; };
var getLinkData = function (ctx, data, cId, cb) {
/*
var password = data.password;
var hash = data.hash;
var bytes64 = data.bytes64;
*/
return void cb();
/*
cb({
error: 'NOT_IMPLEMENTED'
});
*/
};
Team.init = function (cfg, waitFor, emit) { Team.init = function (cfg, waitFor, emit) {
var team = {}; var team = {};
@ -1434,6 +1448,9 @@ define([
if (cmd === 'CREATE_INVITE_LINK') { if (cmd === 'CREATE_INVITE_LINK') {
return void createInviteLink(ctx, data, clientId, cb); return void createInviteLink(ctx, data, clientId, cb);
} }
if (cmd === 'GET_LINK_DATA') {
return void getLinkData(ctx, data, clientId, cb);
}
}; };
return team; return team;

@ -17,6 +17,7 @@ define([
'/common/messenger-ui.js', '/common/messenger-ui.js',
'/customize/messages.js', '/customize/messages.js',
'/bower_components/scrypt-async/scrypt-async.min.js',
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css', 'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
'css!/bower_components/components-font-awesome/css/font-awesome.min.css', 'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
'less!/teams/app-team.less', 'less!/teams/app-team.less',
@ -42,6 +43,7 @@ define([
var APP = {}; var APP = {};
var driveAPP = {}; var driveAPP = {};
//var SHARED_FOLDER_NAME = Messages.fm_sharedFolderName; //var SHARED_FOLDER_NAME = Messages.fm_sharedFolderName;
var Scrypt = window.scrypt;
var copyObjectValue = function (objRef, objToCopy) { var copyObjectValue = function (objRef, objToCopy) {
for (var k in objRef) { delete objRef[k]; } for (var k in objRef) { delete objRef[k]; }
@ -137,6 +139,9 @@ define([
'general': [ 'general': [
'cp-team-info', 'cp-team-info',
], ],
'link': [
'cp-team-link',
],
}; };
var teamCategories = { var teamCategories = {
'back': { 'back': {
@ -179,8 +184,10 @@ define([
var $categories = $('<div>', {'class': 'cp-sidebarlayout-categories'}) var $categories = $('<div>', {'class': 'cp-sidebarlayout-categories'})
.appendTo(APP.$leftside); .appendTo(APP.$leftside);
var hash = common.getMetadataMgr().getPrivateData().teamInviteHash;
var categories = team ? teamCategories : mainCategories; var categories = team ? teamCategories : mainCategories;
var active = team ? 'drive' : 'list'; var active = team ? 'drive' : (hash ? 'link' : 'list');
if (team && APP.team) { if (team && APP.team) {
var $category = $('<div>', {'class': 'cp-sidebarlayout-category cp-team-cat-header'}).appendTo($categories); var $category = $('<div>', {'class': 'cp-sidebarlayout-category cp-team-cat-header'}).appendTo($categories);
@ -1012,6 +1019,90 @@ define([
]); ]);
}, true); }, true);
makeBlock('link', function (common, cb) {
// XXX get team data first or login first?
if (!driveAPP.loggedIn) {
var anonLogin, anonRegister;
var anonContent = h('div', [
h('p', "You've been invited to a team. Only registered users can join a team. Login or register..."), // XXX
h('div', [
anonLogin = h('button.btn.btn-primary', Messages.login_login),
anonRegister = h('button.btn.btn-secondary', Messages.login_register),
])
]);
$(anonLogin).click(function () {
common.setLoginRedirect(function () {
common.gotoURL('/login/');
});
});
$(anonRegister).click(function () {
common.setLoginRedirect(function () {
common.gotoURL('/register/');
});
});
return void cb(anonContent);
}
var hash = common.getMetadataMgr().getPrivateData().teamInviteHash;
var hashData = Hash.parseTypeHash('invite', hash);
var password = hashData.password;
var div;
var process = function (pw) {
var $div = $(div);
$div.empty();
var bytes64;
nThen(function (waitFor) {
$div.append(h('div', [
h('i.fa.fa-spin.fa-spinner'),
h('span', 'Scrypt...') // XXX
]));
setTimeout(waitFor(), 150);
}).nThen(function (waitFor) {
Scrypt(hashData.key,
(pw || '') + (AppConfig.loginSalt || ''), // salt
8, // memoryCost (n)
1024, // block size parameter (r)
192, // dkLen
200, // interruptStep
waitFor(function (_bytes) {
bytes64 = _bytes;
}),
'base64'); // format, could be 'base64'
}).nThen(function (waitFor) {
APP.module.execCommand('GET_LINK_DATA', {
bytes64: bytes64,
hash: hash,
pw: pw,
}, waitFor(function () {
$div.empty();
// TODO
// Accept/decline/decide later UI
}));
});
};
var content = [];
if (password) {
// 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();
content.push(pwInput);
var submitPw = h('button.btn.btn-secondary', Messages.password_submit);
$(submitPw).click(function () {
var val = $(pwInput).find('input').val();
if (!val) { return; }
process(val);
});
content.push(submitPw);
}
div = h('div', content);
cb(div);
if (!password) { process(); }
});
var redrawTeam = function (common) { var redrawTeam = function (common) {
if (!APP.team) { return; } if (!APP.team) { return; }
var teamId = APP.team; var teamId = APP.team;
@ -1053,7 +1144,7 @@ define([
readOnly = driveAPP.readOnly = metadataMgr.getPrivateData().readOnly; readOnly = driveAPP.readOnly = metadataMgr.getPrivateData().readOnly;
driveAPP.loggedIn = common.isLoggedIn(); driveAPP.loggedIn = common.isLoggedIn();
if (!driveAPP.loggedIn) { throw new Error('NOT_LOGGED_IN'); } //if (!driveAPP.loggedIn) { throw new Error('NOT_LOGGED_IN'); }
common.setTabTitle(Messages.type.teams); common.setTabTitle(Messages.type.teams);
@ -1103,6 +1194,22 @@ define([
onEvent: onEvent onEvent: onEvent
}); });
var hash = privateData.teamInviteHash;
if (!hash && !driveAPP.loggedIn) {
UI.alert(Messages.mustLogin, function () {
common.setLoginRedirect(function () {
common.gotoURL('/login/');
});
}, {forefront: true});
return;
}
if (!hash) {
delete mainCategories.link;
} else if (!driveAPP.loggedIn) {
delete mainCategories.list;
delete mainCategories.create;
}
$('body').css('display', ''); $('body').css('display', '');
loadMain(common); loadMain(common);

@ -37,6 +37,7 @@ define([
window.addEventListener('message', onMsg); window.addEventListener('message', onMsg);
}).nThen(function (/*waitFor*/) { }).nThen(function (/*waitFor*/) {
var teamId; var teamId;
var hash = window.location.hash.slice(1);
var addRpc = function (sframeChan, Cryptpad) { var addRpc = function (sframeChan, Cryptpad) {
sframeChan.on('Q_SET_TEAM', function (data, cb) { sframeChan.on('Q_SET_TEAM', function (data, cb) {
teamId = data; teamId = data;
@ -86,11 +87,23 @@ define([
} }
}); });
}; };
var getSecrets = function (Cryptpad, Utils, cb) {
var Hash = Utils.Hash;
var hash = Hash.createRandomHash('profile');
var secret = Hash.getSecrets('team', hash);
cb(null, secret);
};
var addData = function (meta) {
if (!hash) { return; }
meta.teamInviteHash = hash;
};
SFCommonO.start({ SFCommonO.start({
getSecrets: getSecrets,
noHash: true, noHash: true,
noRealtime: true, noRealtime: true,
//driveEvents: true, //driveEvents: true,
addRpc: addRpc, addRpc: addRpc,
addData: addData,
isDrive: true, // Used for history... isDrive: true, // Used for history...
}); });
}); });

Loading…
Cancel
Save