Change pad password with a team owner

pull/1/head
yflory 5 years ago
parent 7c4bc1d583
commit 5ad5e32ec8

@ -357,27 +357,48 @@ define([
if (data.owners && data.owners.length) { if (data.owners && data.owners.length) {
if (data.owners.indexOf(edPublic) !== -1) { if (data.owners.indexOf(edPublic) !== -1) {
owned = true; owned = true;
} else {
Object.keys(priv.teams || {}).some(function (id) {
var team = priv.teams[id] || {};
if (data.owners.indexOf(team.edPublic) === -1) { return; }
owned = id;
return true;
});
} }
var names = []; var names = [];
var strangers = 0; var strangers = 0;
data.owners.forEach(function (ed) { data.owners.forEach(function (ed) {
// If a friend is an owner, add their name to the list // If a friend is an owner, add their name to the list
// otherwise, increment the list of strangers // otherwise, increment the list of strangers
// Our edPublic? print "Yourself"
if (ed === edPublic) { if (ed === edPublic) {
names.push(Messages.yourself); names.push(Messages.yourself);
return; return;
} }
if (!Object.keys(priv.friends || {}).some(function (c) { // One of our teams? print the team name
if (Object.keys(priv.teams || {}).some(function (id) {
var team = priv.teams[id] || {};
if (team.edPublic !== ed) { return; }
names.push('TEAM: '+team.name); // XXX
return true;
})) {
return;
}
// One of our friends? print the friend name
if (Object.keys(priv.friends || {}).some(function (c) {
var friend = priv.friends[c] || {}; var friend = priv.friends[c] || {};
if (friend.edPublic !== ed || c === 'me') { return; } if (friend.edPublic !== ed || c === 'me') { return; }
names.push(friend.displayName); names.push(friend.displayName);
return true; return true;
})) { })) {
strangers++; return;
} }
// Otherwise it's a stranger
strangers++;
}); });
if (strangers) { if (strangers) {
names.push(Messages._getKey('properties_unknownUser', [strangers])); names.push(Messages._getKey('properties_unknownUser', [strangers])); // XXX unknown owner?
} }
owners = names.join(', '); owners = names.join(', ');
} }
@ -388,6 +409,7 @@ define([
if (data.href || data.roHref) { if (data.href || data.roHref) {
parsed = Hash.parsePadUrl(data.href || data.roHref); parsed = Hash.parsePadUrl(data.href || data.roHref);
} }
// XXX Teams owner: transfer ownership
if (owned && data.roHref && parsed.type !== 'drive' && parsed.hashData.type === 'pad') { if (owned && data.roHref && parsed.type !== 'drive' && parsed.hashData.type === 'pad') {
var manageOwners = h('button.no-margin', Messages.owner_openModalButton); var manageOwners = h('button.no-margin', Messages.owner_openModalButton);
$(manageOwners).click(function () { $(manageOwners).click(function () {
@ -455,6 +477,7 @@ define([
UI.confirm(changePwConfirm, function (yes) { UI.confirm(changePwConfirm, function (yes) {
if (!yes) { return; } if (!yes) { return; }
sframeChan.query("Q_PAD_PASSWORD_CHANGE", { sframeChan.query("Q_PAD_PASSWORD_CHANGE", {
teamId: typeof(owned) !== "boolean" ? owned : undefined,
href: data.href || data.roHref, href: data.href || data.roHref,
password: newPass password: newPass
}, function (err, data) { }, function (err, data) {

@ -209,15 +209,23 @@ define([
// RPC // RPC
common.pinPads = function (pads, cb) { common.pinPads = function (pads, cb, teamId) {
postMessage("PIN_PADS", pads, function (obj) { var data = {
teamId: teamId,
pads: pads
};
postMessage("PIN_PADS", data, function (obj) {
if (obj && obj.error) { return void cb(obj.error); } if (obj && obj.error) { return void cb(obj.error); }
cb(null, obj.hash); cb(null, obj.hash);
}); });
}; };
common.unpinPads = function (pads, cb) { common.unpinPads = function (pads, cb, teamId) {
postMessage("UNPIN_PADS", pads, function (obj) { var data = {
teamId: teamId,
pads: pads
};
postMessage("UNPIN_PADS", data, function (obj) {
if (obj && obj.error) { return void cb(obj.error); } if (obj && obj.error) { return void cb(obj.error); }
cb(null, obj.hash); cb(null, obj.hash);
}); });
@ -831,7 +839,10 @@ define([
}; };
// XXX Teams: change the password of a pad owned by the team // XXX Teams: change the password of a pad owned by the team
common.changePadPassword = function (Crypt, Crypto, href, newPassword, edPublic, cb) { common.changePadPassword = function (Crypt, Crypto, data, cb) {
var href = data.href;
var newPassword = data.password;
var teamId = data.teamId;
if (!href) { return void cb({ error: 'EINVAL_HREF' }); } if (!href) { return void cb({ error: 'EINVAL_HREF' }); }
var parsed = Hash.parsePadUrl(href); var parsed = Hash.parsePadUrl(href);
if (!parsed.hash) { return void cb({ error: 'EINVAL_HREF' }); } if (!parsed.hash) { return void cb({ error: 'EINVAL_HREF' }); }
@ -842,6 +853,7 @@ define([
var oldSecret; var oldSecret;
var oldMetadata; var oldMetadata;
var newSecret; var newSecret;
var privateData;
if (parsed.hashData.version >= 2) { if (parsed.hashData.version >= 2) {
newSecret = Hash.getSecrets(parsed.type, parsed.hash, newPassword); newSecret = Hash.getSecrets(parsed.type, parsed.hash, newPassword);
@ -874,16 +886,26 @@ define([
common.getPadMetadata({channel: oldChannel}, waitFor(function (metadata) { common.getPadMetadata({channel: oldChannel}, waitFor(function (metadata) {
oldMetadata = metadata; oldMetadata = metadata;
})); }));
common.getMetadata(waitFor(function (err, data) {
if (err) {
waitFor.abort();
return void cb({ error: err });
}
privateData = data.priv;
}));
}).nThen(function (waitFor) { }).nThen(function (waitFor) {
// Get owners, mailbox and expiration time // Get owners, mailbox and expiration time
var owners = oldMetadata.owners; var owners = oldMetadata.owners;
if (!Array.isArray(owners) || owners.indexOf(edPublic) === -1) { optsPut.metadata.owners = owners;
// Check if we're allowed to change the password
var edPublic = teamId ? (privateData.teams[teamId] || {}).edPublic : privateData.edPublic;
var isOwner = Array.isArray(owners) && edPublic && owners.indexOf(edPublic) !== -1;
if (!isOwner) {
// We're not an owner, we shouldn't be able to change the password! // We're not an owner, we shouldn't be able to change the password!
waitFor.abort(); waitFor.abort();
return void cb({ error: 'EPERM' }); return void cb({ error: 'EPERM' });
} }
optsPut.metadata.owners = owners;
var mailbox = oldMetadata.mailbox; var mailbox = oldMetadata.mailbox;
if (mailbox) { if (mailbox) {
@ -933,15 +955,15 @@ define([
}).nThen(function (waitFor) { }).nThen(function (waitFor) {
common.removeOwnedChannel({ common.removeOwnedChannel({
channel: oldChannel, channel: oldChannel,
teamId: null // TODO teamId: teamId
}, waitFor(function (obj) { }, waitFor(function (obj) {
if (obj && obj.error) { if (obj && obj.error) {
waitFor.abort(); waitFor.abort();
return void cb(obj); return void cb(obj);
} }
})); }));
common.unpinPads([oldChannel], waitFor()); common.unpinPads([oldChannel], waitFor(), teamId);
common.pinPads([newSecret.channel], waitFor()); common.pinPads([newSecret.channel], waitFor(), teamId);
}).nThen(function (waitFor) { }).nThen(function (waitFor) {
common.setPadAttribute('password', newPassword, waitFor(function (err) { common.setPadAttribute('password', newPassword, waitFor(function (err) {
if (err) { warning = true; } if (err) { warning = true; }

@ -203,22 +203,36 @@ define([
/////////////////////// RPC ////////////////////////////////////// /////////////////////// RPC //////////////////////////////////////
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
// pinPads needs to support the old format where data is an array of channel IDs
// and the new format where data is an object with "teamId" and "pads"
Store.pinPads = function (clientId, data, cb) { Store.pinPads = function (clientId, data, cb) {
if (!store.rpc) { return void cb({error: 'RPC_NOT_READY'}); } if (!data) { return void cb({error: 'EINVAL'}); }
var s = getStore(data && data.teamId);
if (!s.rpc) { return void cb({error: 'RPC_NOT_READY'}); }
if (typeof(cb) !== 'function') { if (typeof(cb) !== 'function') {
console.error('expected a callback'); console.error('expected a callback');
cb = function () {};
} }
store.rpc.pin(data, function (e, hash) { var pads = data.pads || data;
s.rpc.pin(pads, function (e, hash) {
if (e) { return void cb({error: e}); } if (e) { return void cb({error: e}); }
cb({hash: hash}); cb({hash: hash});
}); });
}; };
// unpinPads needs to support the old format where data is an array of channel IDs
// and the new format where data is an object with "teamId" and "pads"
Store.unpinPads = function (clientId, data, cb) { Store.unpinPads = function (clientId, data, cb) {
if (!store.rpc) { return void cb({error: 'RPC_NOT_READY'}); } if (!data) { return void cb({error: 'EINVAL'}); }
var s = getStore(data && data.teamId);
if (!s.rpc) { return void cb({error: 'RPC_NOT_READY'}); }
store.rpc.unpin(data, function (e, hash) { var pads = data.pads || data;
s.rpc.unpin(pads, function (e, hash) {
if (e) { return void cb({error: e}); } if (e) { return void cb({error: e}); }
cb({hash: hash}); cb({hash: hash});
}); });

@ -928,8 +928,8 @@ define([
}); });
sframeChan.on('Q_PAD_PASSWORD_CHANGE', function (data, cb) { sframeChan.on('Q_PAD_PASSWORD_CHANGE', function (data, cb) {
var href = data.href || window.location.href; data.href = data.href || window.location.href;
Cryptpad.changePadPassword(Cryptget, Crypto, href, data.password, edPublic, cb); Cryptpad.changePadPassword(Cryptget, Crypto, data, cb);
}); });
sframeChan.on('Q_CHANGE_USER_PASSWORD', function (data, cb) { sframeChan.on('Q_CHANGE_USER_PASSWORD', function (data, cb) {

Loading…
Cancel
Save