Revocation: Open read-only pad from the drive

This commit is contained in:
yflory 2023-04-03 15:30:25 +02:00
parent d6a9210190
commit 95e8133905
10 changed files with 28 additions and 19 deletions

View File

@ -737,9 +737,7 @@ const handleGetHistory = function (Env, Server, seq, userId, parsed) {
if (msgCount === 0 && !metadata_cache[channelName] && Server.channelContainsUser(channelName, userId)) {
// TODO this might be a good place to reject channel creation by anonymous users
console.log(1);
handleFirstMessage(Env, channelName, metadata, userId, (err) => {
console.log(2, err);
if (err) {
return void Server.send(userId,
[seq, 'ERROR', 'METADATA_ERROR', HISTORY_KEEPER_ID]);

View File

@ -518,6 +518,7 @@ Version 5: Revocable mailbox
if (idx === -1) { return ret; }
ret.hash = href.slice(idx + 2);
ret.hashData = parseTypeHash(ret.type, ret.hash);
if (ret.hashData.version === 5) { ret.revocable = true; }
return ret;
}
@ -530,6 +531,7 @@ Version 5: Revocable mailbox
if (idx === -1) { return ret; }
ret.hash = href.slice(idx + 2);
ret.hashData = parseTypeHash(ret.type, ret.hash);
if (ret.hashData.version === 5) { ret.revocable = true; }
return ret;
};

View File

@ -883,7 +883,8 @@ define([
href: href,
title: data.title,
owners: optsPut.owners,
path: ['template']
path: ['template'],
revocable: false // XXX REVOCATION
}, function (obj) {
if (obj && obj.error) { return void cb(obj.error); }
cb();

View File

@ -1164,6 +1164,8 @@ 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);
@ -1176,7 +1178,7 @@ define([
return void logError("Missing data for the file", el, data);
}
var href = isRo ? data.roHref : (data.href || data.roHref);
var href = isRo ? (data.roHref || data.href) : (data.href || data.roHref);
var parsed = Hash.parsePadUrl(href);
if (parsed.hashData && parsed.hashData.type === 'file' && !app
@ -1186,6 +1188,12 @@ define([
var obj = { t: APP.team };
if (!data.roHref && parsed.revocable) { // Revocable
if (isRo) { obj.mode = 'view'; } // force view VS use best rights
return void common.openURL(Hash.getNewPadURL(href, obj));
}
var priv = metadataMgr.getPrivateData();
var useUnsafe = Util.find(priv, ['settings', 'security', 'unsafeLinks']);
if (useUnsafe === true || APP.newSharedFolder) {

View File

@ -724,7 +724,7 @@ define([
var secret;
if (!data.roHref) {
var parsed = Hash.parsePadUrl(data.href);
if (parsed.hashData.type === "pad") {
if (parsed.hashData.type === "pad" && !parsed.revocable) {
secret = Hash.getSecrets(parsed.type, parsed.hash, data.password);
data.roHref = '/' + parsed.type + '/#' + Hash.getViewHashFromKeys(secret);
}
@ -735,6 +735,7 @@ define([
if (data.password) { pad.password = data.password; }
if (data.channel || secret) { pad.channel = data.channel || secret.channel; }
if (data.readme) { pad.readme = 1; }
if (data.revocable) { pad.r = 1; }
var s = getStore(data.teamId);
if (!s || !s.manager) { return void cb({ error: 'ENOTFOUND' }); }
@ -1172,7 +1173,7 @@ define([
// team drive. In this case, we just need to check if the pad is already
// stored in this team drive.
// If no team ID is provided, this may be a pad shared with its URL.
// We need to check if the pad is stored in any managers (user or teams).
// We need to check if the pad is stored in any manager (user or teams).
// If it is stored, update its data, otherwise ask the user if they want to store it
var allData = [];
var sendTo = [];
@ -1256,7 +1257,8 @@ define([
owners: owners,
expire: expire,
password: data.password,
path: data.path
path: data.path,
revocable: p.revocable
}, cb);
// Let inner know that dropped files shouldn't trigger the popup
postMessage(clientId, "AUTOSTORE_DISPLAY_POPUP", {

View File

@ -26,8 +26,6 @@ define([
var isValidRotateMessage = function (ctx, log, newSeeds, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
console.warn(newSeeds);
var rotateUid = newSeeds.uid;
var expectedKeys = {};
log.some(function (logMsg) {
@ -88,10 +86,8 @@ console.warn(newSeeds);
var MAILBOX_COMMANDS = {
// Only the INIT message can add a private key AND must be line 0
INIT: function (msg, log, i, waitFor) {
console.error(msg, i);
if (i || !msg.content || !msg.content.doc || !msg.content.edPrivate) { return; }
isValidRotateMessage(ctx, log, msg.content.doc, waitFor(function (valid, password) {
console.warn(valid);
if (!valid) { return; }
data = JSON.parse(JSON.stringify(msg.content));
data.password = password;

View File

@ -814,7 +814,8 @@ define([
}
// If we have an edit link, check the view link
if (decryptedHref && parsed.hashData.type === "pad" && parsed.hashData.version) {
if (decryptedHref && parsed.hashData.type === "pad" && parsed.hashData.version
&& !parsed.revocable) { // Don't force roHref for revocable URLs // XXX XXX REVOCATION
if (parsed.hashData.mode === "view") {
el.roHref = decryptedHref;
delete el.href;

View File

@ -4,8 +4,6 @@ var factory = function (Hash, Nacl) {
// Log
console.log(Hash.createRandomHash());
Revocable.firstLog = function (modEdPublic) {
return ['ADD', undefined, modEdPublic];
};
@ -34,6 +32,8 @@ var factory = function (Hash, Nacl) {
var check = Nacl.sign.detached.verify(msgBytes, sig, key);
if (!check) { return false; }
var checked = msg.slice();
checked.push(signature);
checked.push(edPublic);
return checked;
} catch (e) {
console.error(e);

View File

@ -96,10 +96,9 @@ define([
common.start = function (cfg) {
cfg = cfg || {};
var realtime = !cfg.noRealtime;
var secret; // Containing document keys
var authSecret; // Containing authentication keys (mailbox)
var mailbox;
var secret;
var hashes;
var padOpts = {};
var isNewFile;
var CpNfOuter;
var Cryptpad;
@ -365,6 +364,7 @@ define([
var newPad = Utils.Hash.decodeDataOptions(options.newPadOpts);
Cryptpad.initialTeam = newPad.t;
Cryptpad.initialPath = newPad.p;
padOpts.readOnly = newPad.mode === "view";
if (newPad.pw) {
try {
var uHash = Utils.LocalStore.getUserHash();
@ -505,6 +505,7 @@ define([
console.error(obj.error);
return;
}
console.error(obj);
secret = Utils.secret = Utils.Hash.getRevocableSecret({
channel: obj.channel,
viewerSeedStr: obj.doc.viewer,
@ -650,7 +651,7 @@ define([
}
}).nThen(function () {
//var readOnly = secret.keys && !secret.keys.editKeyStr; // XXX XXX
var readOnly = secret.keys && !secret.keys.signKey;
var readOnly = padOpts.readOnly || (secret.keys && !secret.keys.signKey);
var isNewHash = true;
if (!secret.keys) {
isNewHash = false;
@ -2188,7 +2189,6 @@ define([
access[editor.edPublic] = {
rights: 'rw',
mailbox: crypto.encrypt(editor.channel),
//contact: crypto.encrypt(), // XXX my contact mailbox
notes: crypto.encrypt(JSON.stringify({
url: Utils.Hash.getRevocableHashFromKeys(parsed.type, editor)
}))

View File

@ -234,6 +234,7 @@ define([
if (!isFile(element)) { return false; }
var data = exp.getFileData(element);
// undefined means this pad doesn't support read-only
if (data.r) { return false; } // XXX REVOCATION, we're not sure so consider edit
if (!data.roHref) { return; }
return Boolean(data.roHref && !data.href);
};