Revocation: fix creation issues and store moderator box

This commit is contained in:
yflory 2023-04-12 16:17:58 +02:00
parent de448f0fab
commit b0d65139ce
8 changed files with 95 additions and 44 deletions

View file

@ -76,6 +76,7 @@
handlers.push(cb);
},
unreg: function (cb) {
console.error(handlers, handlers.indexOf(cb), cb);
if (handlers.indexOf(cb) === -1) {
return void console.error("event handler was already unregistered");
}

View file

@ -1268,6 +1268,15 @@ define([
};
universal.onEvent = Util.mkEvent();
common.universalCommand = function (module, cmd, data, cb) {
universal.execCommand({
type: module,
data: {
cmd: cmd,
data: data
}
}, cb);
};
// Pad RPC
var pad = common.padRpc = {};

View file

@ -1164,8 +1164,6 @@ define([
var openFile = function (el, isRo, app) {
var data = manager.getFileData(el);
console.error(el, data, app, isRo);
if (data.static) {
if (data.href) {
common.openUnsafeURL(data.href);
@ -1193,6 +1191,9 @@ console.error(el, data, app, isRo);
var priv = metadataMgr.getPrivateData();
var useUnsafe = Util.find(priv, ['settings', 'security', 'unsafeLinks']);
if (parsed.revocable) { useUnsafe = false; } // XXX
if (useUnsafe === true || APP.newSharedFolder) {
return void common.openURL(Hash.getNewPadURL(href, obj));
}

View file

@ -38,10 +38,6 @@ define([
var priv = common.getMetadataMgr().getPrivateData();
var hashes = opts.hashes || priv.hashes;
var channel;
if (hashes && hashes.revocableData) {
channel = hashes.revocableData.channel;
}
var base = priv.origin;
// this fetches attributes from your shared worker's memory
@ -77,11 +73,11 @@ define([
Util.extend(data, val);
if (data.href) { data.href = base + data.href; }
if (data.roHref) { data.roHref = base + data.roHref; }
}), opts.href, channel);
}), opts.href, opts.channel);
if (opts.channel) { data.channel = opts.channel; }
// If this is a file, don't try to look for metadata
if (opts.channel && opts.channel.length > 32) { return; }
if (opts.channel && opts.channel.length > 32 && !opts.revocable) { return; }
// this fetches data from the server
Modal.loadMetadata(Env, data, waitFor);
}).nThen(function () {
@ -112,6 +108,12 @@ define([
}];
var tabs = [];
nThen(function (waitFor) {
var priv = common.getMetadataMgr().getPrivateData();
var hashes = opts.hashes || priv.hashes;
if (hashes && hashes.revocableData) {
opts.revocable = true;
opts.channel = hashes.revocableData.channel;
}
Modal.getPadData(Env, opts, waitFor(function (e, _data) {
if (e) {
blocked = false;

View file

@ -1119,7 +1119,8 @@ define([
});
}
if (parsedHref.revocable) {
console.warn(parsedHref, href, hashes);
if (hashes.revocableData) {
tabs = [{
getTab: getRevocableTab,
title: 'REVOCABLE', // XXX

View file

@ -1230,17 +1230,18 @@ define([
}
// XXX REVOCATION auto-store new accesses to already stored pad
console.error(accessHref);
if (accessType === 'link') {
if (!Array.isArray(pad.accesses)) {
pad.accesses = [accessHref];
} else if (!pad.accesses.includes(accessHref)) {
pad.accesses.push(accessHref);
}
} else if (accessType) {
if (!pad.href) {
obj.userObject.setHref(channel, null, accessHref);
// XXX SF: roHref with revocable
if (h.version !== 3) { // Don't store safe links
if (accessType === 'link') {
if (!Array.isArray(pad.accesses)) {
pad.accesses = [accessHref];
} else if (!pad.accesses.includes(accessHref)) {
pad.accesses.push(accessHref);
}
} else if (accessType) {
if (!pad.href) {
obj.userObject.setHref(channel, null, accessHref);
// XXX SF: roHref with revocable
}
}
}

View file

@ -795,9 +795,14 @@ console.error('MODERATOR HASH', Hash.getRevocableHashFromKeys(type, moderator.ma
var data = {
// displayed hash
newHash: Hash.getRevocableHashFromKeys(type, editor.mailbox, password),
newHash: Hash.getRevocableHashFromKeys(type, editor.mailbox),
modHash: Hash.getRevocableHashFromKeys(type, moderator.mailbox),
docKeys: docKeys,
crypto: crypto,
seeds: {
moderator: moderator.mailbox.keys.seed,
editor: editor.mailbox.keys.seed
},
rtConfig: {
creation: {
creatorEdPrivate: doc.keys.creator,
@ -839,6 +844,19 @@ console.error(keyHashStr);
});
};
var joinCreatedPad = function (ctx, seeds, clientId, cb) {
nThen(function (waitFor) {
loadMailbox(ctx, clientId, { seed: seeds.moderator }, function (newKeys) {
// XXX new keys received
}, waitFor());
loadMailbox(ctx, clientId, { seed: seeds.editor }, function (newKeys) {
// XXX new keys received
}, waitFor());
}).nThen(function (waitFor) {
cb();
});
};
var leaveBox = function (ctx, box, boxChannel) {
if (box.cpNf) { box.cpNf.stop(); }
@ -885,6 +903,8 @@ console.error(keyHashStr);
mailboxes: {},
};
revocation.ctx = ctx; // debug
revocation.removeClient = function (clientId) {
removeClient(ctx, clientId);
};
@ -906,6 +926,9 @@ console.error(keyHashStr);
if (cmd === 'LOAD_PAD') {
return void loadPad(ctx, data, clientId, cb);
}
if (cmd === 'JOIN_CREATED_PAD') {
return void joinCreatedPad(ctx, data, clientId, cb);
}
if (cmd === 'CREATE_PAD') {
return void createPad(ctx, data, clientId, cb);
}

View file

@ -483,15 +483,10 @@ define([
var correctPassword = waitFor();
var revCommand = function (cmd, data, cb) {
Cryptpad.universal.execCommand({
type: 'revocation',
data: {
cmd: cmd,
data: data
}
}, cb)
Cryptpad.universalCommand('revocation', cmd, data, cb);
};
// Receive password requests from worker and relay them to inner
var lastUid;
sframeChan.on('Q_PAD_PASSWORD_VALUE', function (data, cb) {
password = data;
@ -533,7 +528,6 @@ define([
// XXX get access type (sf/team/user/link)
currentPad.type = 'link';
console.error(obj);
secret = Utils.secret = Utils.Hash.getRevocableSecret({
channel: obj.channel,
viewerSeedStr: obj.doc.viewer,
@ -548,7 +542,6 @@ define([
editHash: currentPad.hash,
revocableData: {
channel: secret.channel,
keys: secret.revocation
}
};
}));
@ -707,7 +700,7 @@ define([
// Check if the pad exists on server
if (!currentPad.hash) { isNewFile = true; return; }
if (realtime) {
if (realtime && !currentPad.type) {
// TODO we probably don't need to check again for password-protected pads
Cryptpad.hasChannelHistory(currentPad.href, password, waitFor(function (e, isNew) {
if (e) { return console.error(e); }
@ -1282,7 +1275,7 @@ define([
};
var setPadTitle = function (data, cb) {
if (currentPad.type) {
if (!data.href && currentPad.type) {
data.accessType = currentPad.type;
data.accessHref = Utils.Hash.getRelativeHref(currentPad.href);
}
@ -1299,6 +1292,13 @@ define([
// XXX REVOCATION USE SAFE HERE
}
}
// If we just created a pad, also store the moderator access
if (currentPad.revocationModerator) {
var data2 = Utils.Util.clone(data);
data2.accessHref = currentPad.revocationModerator.href;
data2.accessType = currentPad.revocationModerator.type;
Cryptpad.setPadTitle(data2, function () {});
}
cb({error: err});
});
};
@ -2177,16 +2177,10 @@ define([
var newHash = Utils.Hash.createRandomHash(parsed.type, password);
Cryptpad.universal.execCommand({
type: 'revocation',
data: {
cmd: 'CREATE_PAD',
data: {
type: parsed.type,
password: password,
edPublic: edPublic
}
}
Cryptpad.universalCommand('revocation', 'CREATE_PAD', {
type: parsed.type,
password: password,
edPublic: edPublic
}, function (data) {
var docKeys = data.docKeys;
secret = Utils.secret = Utils.Hash.getRevocableSecret({
@ -2197,11 +2191,32 @@ define([
var crypto = Utils.crypto = Crypto.createEncryptor(secret.keys);
var onCreated = function () {
Cryptpad.universalCommand('revocation', 'JOIN_CREATED_PAD', data.seeds);
setTimeout(function () {
Cryptpad.padRpc.onReadyEvent.unreg(onCreated);
});
};
Cryptpad.padRpc.onReadyEvent.reg(onCreated);
currentPad.revocationModerator = {
type: edPublic ? 'user' : 'link',
href: Utils.Hash.hashToHref(data.modHash, parsed.type)
};
// Update the hash in the address bar
currentPad.hash = data.newHash;
currentPad.href = '/' + parsed.type + '/#' + data.newHash;
currentPad.type = 'link'; // XXX editor seed
Cryptpad.setTabHash(data.newHash);
hashes = {
editHash: currentPad.hash,
revocableData: {
channel: secret.channel,
}
};
parsed = Utils.Hash.parsePadUrl(currentPad.href);
defaultTitle = Utils.UserObject.getDefaultName(parsed);
//hashes = Utils.Hash.getHashes(secret);
@ -2229,8 +2244,6 @@ define([
startRealtime(rtConfig); // XXX
cb(); // XXX
});