mirror of https://github.com/xwiki-labs/cryptpad
Change blob password
This commit is contained in:
parent
da3df964dd
commit
c64eabc33a
2
rpc.js
2
rpc.js
|
@ -857,6 +857,7 @@ var removeOwnedChannel = function (Env, channelId, unsafeKey, cb) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return void cb("E_PROOF_REMOVAL");
|
return void cb("E_PROOF_REMOVAL");
|
||||||
}
|
}
|
||||||
|
cb();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -869,6 +870,7 @@ var removeOwnedChannel = function (Env, channelId, unsafeKey, cb) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return void cb("E_PROOF_REMOVAL");
|
return void cb("E_PROOF_REMOVAL");
|
||||||
}
|
}
|
||||||
|
cb();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,8 +79,10 @@ define([
|
||||||
waitFor.abort();
|
waitFor.abort();
|
||||||
return void cb(err || 'EEMPTY');
|
return void cb(err || 'EEMPTY');
|
||||||
}
|
}
|
||||||
delete val.owners;
|
if (!val.fileType) {
|
||||||
delete val.expire;
|
delete val.owners;
|
||||||
|
delete val.expire;
|
||||||
|
}
|
||||||
Util.extend(data, val);
|
Util.extend(data, val);
|
||||||
if (data.href) { data.href = base + data.href; }
|
if (data.href) { data.href = base + data.href; }
|
||||||
if (data.roHref) { data.roHref = base + data.roHref; }
|
if (data.roHref) { data.roHref = base + data.roHref; }
|
||||||
|
@ -549,11 +551,12 @@ define([
|
||||||
$d.append(password);
|
$d.append(password);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data.noEditPassword && owned && parsed.hashData.type === 'pad' && parsed.type !== "sheet") { // FIXME SHEET fix password change for sheets
|
if (!data.noEditPassword && owned && parsed.type !== "sheet") { // FIXME SHEET fix password change for sheets
|
||||||
var sframeChan = common.getSframeChannel();
|
var sframeChan = common.getSframeChannel();
|
||||||
var changePwTitle = Messages.properties_changePassword;
|
var changePwTitle = Messages.properties_changePassword;
|
||||||
var changePwConfirm = Messages.properties_confirmChange;
|
var changePwConfirm = Messages.properties_confirmChange;
|
||||||
var isSharedFolder = parsed.type === 'drive';
|
var isSharedFolder = parsed.type === 'drive';
|
||||||
|
var isFile = parsed.hashData.type === 'file';
|
||||||
if (!hasPassword) {
|
if (!hasPassword) {
|
||||||
changePwTitle = Messages.properties_addPassword;
|
changePwTitle = Messages.properties_addPassword;
|
||||||
changePwConfirm = Messages.properties_confirmNew;
|
changePwConfirm = Messages.properties_confirmNew;
|
||||||
|
@ -581,7 +584,8 @@ define([
|
||||||
UI.confirm(changePwConfirm, function (yes) {
|
UI.confirm(changePwConfirm, function (yes) {
|
||||||
if (!yes) { pLocked = false; return; }
|
if (!yes) { pLocked = false; return; }
|
||||||
$(passwordOk).html('').append(h('span.fa.fa-spinner.fa-spin', {style: 'margin-left: 0'}));
|
$(passwordOk).html('').append(h('span.fa.fa-spinner.fa-spin', {style: 'margin-left: 0'}));
|
||||||
sframeChan.query("Q_PAD_PASSWORD_CHANGE", {
|
var q = isFile ? 'Q_BLOB_PASSWORD_CHANGE' : 'Q_PAD_PASSWORD_CHANGE';
|
||||||
|
sframeChan.query(q, {
|
||||||
teamId: typeof(owned) !== "boolean" ? owned : undefined,
|
teamId: typeof(owned) !== "boolean" ? owned : undefined,
|
||||||
href: data.href || data.roHref,
|
href: data.href || data.roHref,
|
||||||
password: newPass
|
password: newPass
|
||||||
|
@ -593,6 +597,9 @@ define([
|
||||||
return void UI.alert(Messages.properties_passwordError);
|
return void UI.alert(Messages.properties_passwordError);
|
||||||
}
|
}
|
||||||
UI.findOKButton().click();
|
UI.findOKButton().click();
|
||||||
|
if (isFile) {
|
||||||
|
return void UI.alert(Messages.properties_passwordSuccess);
|
||||||
|
}
|
||||||
// If we didn't have a password, we have to add the /p/
|
// If we didn't have a password, we have to add the /p/
|
||||||
// If we had a password and we changed it to a new one, we just have to reload
|
// If we had a password and we changed it to a new one, we just have to reload
|
||||||
// If we had a password and we removed it, we have to remove the /p/
|
// If we had a password and we removed it, we have to remove the /p/
|
||||||
|
|
|
@ -1023,7 +1023,7 @@ define([
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
common.changeBlobPassword = function (Crypt, Crypto, data, cb) {
|
common.changeBlobPassword = function (data, handlers, cb) {
|
||||||
var href = data.href;
|
var href = data.href;
|
||||||
var newPassword = data.password;
|
var newPassword = data.password;
|
||||||
var teamId = data.teamId;
|
var teamId = data.teamId;
|
||||||
|
@ -1032,26 +1032,34 @@ define([
|
||||||
if (!parsed.hash) { return void cb({ error: 'EINVAL_HREF' }); }
|
if (!parsed.hash) { return void cb({ error: 'EINVAL_HREF' }); }
|
||||||
if (parsed.hashData.type !== 'file') { return void cb({ error: 'EINVAL_TYPE' }); }
|
if (parsed.hashData.type !== 'file') { return void cb({ error: 'EINVAL_TYPE' }); }
|
||||||
|
|
||||||
|
var newSecret;
|
||||||
|
var newHash;
|
||||||
|
|
||||||
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);
|
||||||
if (!(newSecret.keys && newSecret.keys.editKeyStr)) {
|
if (!(newSecret.keys && newSecret.keys.fileKeyStr)) {
|
||||||
return void cb({error: 'EAUTH'});
|
return void cb({error: 'EAUTH'});
|
||||||
}
|
}
|
||||||
newHash = Hash.getEditHashFromKeys(newSecret);
|
newHash = Hash.getFileHashFromKeys(newSecret);
|
||||||
} else {
|
} else {
|
||||||
newHash = Hash.createRandomHash(parsed.type, newPassword);
|
newHash = Hash.createRandomHash(parsed.type, newPassword);
|
||||||
newSecret = Hash.getSecrets(parsed.type, newHash, newPassword);
|
newSecret = Hash.getSecrets(parsed.type, newHash, newPassword);
|
||||||
}
|
}
|
||||||
var newHref = '/' + parsed.type + '/#' + newHash;
|
var newHref = '/' + parsed.type + '/#' + newHash;
|
||||||
|
var fileHost = Config.fileHost || window.location.origin || '';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
1. get old password
|
1. get old password
|
||||||
2. get owners
|
2. get owners
|
||||||
*/
|
*/
|
||||||
var oldPassword;
|
var oldPassword;
|
||||||
var oldSecret;
|
var decrypted;
|
||||||
var oldChannel;
|
var oldChannel;
|
||||||
var oldMetadata;
|
var warning;
|
||||||
|
|
||||||
|
var FileCrypto;
|
||||||
|
var MediaTag;
|
||||||
|
var Upload;
|
||||||
Nthen(function (waitFor) {
|
Nthen(function (waitFor) {
|
||||||
if (parsed.hashData && parsed.hashData.password) {
|
if (parsed.hashData && parsed.hashData.password) {
|
||||||
common.getPadAttribute('password', waitFor(function (err, password) {
|
common.getPadAttribute('password', waitFor(function (err, password) {
|
||||||
|
@ -1059,12 +1067,91 @@ define([
|
||||||
}), href);
|
}), href);
|
||||||
}
|
}
|
||||||
}).nThen(function (waitFor) {
|
}).nThen(function (waitFor) {
|
||||||
oldSecret = Hash.getSecrets(parsed.type, parsed.hash, optsGet.password);
|
require([
|
||||||
oldChannel = oldSecret.channel;
|
'/file/file-crypto.js',
|
||||||
common.getPadMetadata({channel: oldChannel}, waitFor(function (metadata) {
|
'/common/media-tag.js',
|
||||||
oldMetadata = metadata;
|
'/common/outer/upload.js',
|
||||||
|
'/bower_components/tweetnacl/nacl-fast.min.js'
|
||||||
|
], waitFor(function (_FileCrypto, _MT, _Upload) {
|
||||||
|
FileCrypto = _FileCrypto;
|
||||||
|
MediaTag = _MT;
|
||||||
|
Upload = _Upload;
|
||||||
}));
|
}));
|
||||||
}).nThen(function (waitFor) {
|
}).nThen(function (waitFor) {
|
||||||
|
var oldSecret = Hash.getSecrets(parsed.type, parsed.hash, oldPassword);
|
||||||
|
oldChannel = oldSecret.channel;
|
||||||
|
var src = fileHost + Hash.getBlobPathFromHex(oldChannel);
|
||||||
|
var key = oldSecret.keys && oldSecret.keys.cryptKey;
|
||||||
|
var cryptKey = window.nacl.util.encodeBase64(key);
|
||||||
|
|
||||||
|
var mt = document.createElement('media-tag');
|
||||||
|
mt.setAttribute('src', src);
|
||||||
|
mt.setAttribute('data-crypto-key', 'cryptpad:'+cryptKey);
|
||||||
|
|
||||||
|
MediaTag(mt).on('complete', waitFor(function (_decrypted) {
|
||||||
|
decrypted = _decrypted;
|
||||||
|
})).on('error', function (err) {
|
||||||
|
waitFor.abort();
|
||||||
|
cb({error: err});
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
}).nThen(function (waitFor) {
|
||||||
|
var reader = new FileReader();
|
||||||
|
reader.readAsArrayBuffer(decrypted.content);
|
||||||
|
reader.onloadend = waitFor(function() {
|
||||||
|
decrypted.u8 = new Uint8Array(reader.result);
|
||||||
|
});
|
||||||
|
}).nThen(function (waitFor) {
|
||||||
|
var key = newSecret.keys && newSecret.keys.cryptKey;
|
||||||
|
|
||||||
|
var onError = function (err) {
|
||||||
|
waitFor.abort();
|
||||||
|
cb({error: err});
|
||||||
|
};
|
||||||
|
Upload.uploadU8(common, {
|
||||||
|
teamId: teamId,
|
||||||
|
u8: decrypted.u8,
|
||||||
|
metadata: decrypted.metadata,
|
||||||
|
key: key,
|
||||||
|
id: newSecret.channel,
|
||||||
|
owned: true,
|
||||||
|
onError: onError,
|
||||||
|
onPending: handlers.onPending,
|
||||||
|
updateProgress: handlers.updateProgress,
|
||||||
|
}, waitFor());
|
||||||
|
}).nThen(function (waitFor) {
|
||||||
|
// Set the new password to our pad data
|
||||||
|
common.setPadAttribute('password', newPassword, waitFor(function (err) {
|
||||||
|
if (err) { warning = true; }
|
||||||
|
}), href);
|
||||||
|
common.setPadAttribute('channel', newSecret.channel, waitFor(function (err) {
|
||||||
|
if (err) { warning = true; }
|
||||||
|
}), href);
|
||||||
|
if (parsed.hashData.password && newPassword) { return; } // same hash
|
||||||
|
common.setPadAttribute('href', newHref, waitFor(function (err) {
|
||||||
|
if (err) { warning = true; }
|
||||||
|
}), href);
|
||||||
|
}).nThen(function (waitFor) {
|
||||||
|
// delete the old pad
|
||||||
|
common.removeOwnedChannel({
|
||||||
|
channel: oldChannel,
|
||||||
|
teamId: teamId
|
||||||
|
}, waitFor(function (obj) {
|
||||||
|
if (obj && obj.error) {
|
||||||
|
waitFor.abort();
|
||||||
|
return void cb(obj);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
postMessage("CHANGE_PAD_PASSWORD_PIN", {
|
||||||
|
oldChannel: oldChannel,
|
||||||
|
channel: newSecret.channel
|
||||||
|
}, waitFor());
|
||||||
|
}).nThen(function () {
|
||||||
|
cb({
|
||||||
|
warning: warning,
|
||||||
|
hash: newHash,
|
||||||
|
href: newHref,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,82 @@ define([
|
||||||
var Nacl = window.nacl;
|
var Nacl = window.nacl;
|
||||||
var module = {};
|
var module = {};
|
||||||
|
|
||||||
|
module.uploadU8 =function (common, data, cb) {
|
||||||
|
var teamId = data.teamId;
|
||||||
|
var u8 = data.u8;
|
||||||
|
var metadata = data.metadata;
|
||||||
|
var key = data.key;
|
||||||
|
|
||||||
|
var onError = data.onError || function () {};
|
||||||
|
var onPending = data.onPending || function () {};
|
||||||
|
var updateProgress = data.updateProgress || function () {};
|
||||||
|
var owned = data.owned;
|
||||||
|
var id = data.id;
|
||||||
|
|
||||||
|
var next = FileCrypto.encrypt(u8, metadata, key);
|
||||||
|
|
||||||
|
var estimate = FileCrypto.computeEncryptedSize(u8.length, metadata);
|
||||||
|
|
||||||
|
var sendChunk = function (box, cb) {
|
||||||
|
var enc = Nacl.util.encodeBase64(box);
|
||||||
|
common.uploadChunk(teamId, enc, function (e, msg) {
|
||||||
|
cb(e, msg);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var actual = 0;
|
||||||
|
var again = function (err, box) {
|
||||||
|
if (err) { onError(err); }
|
||||||
|
if (box) {
|
||||||
|
actual += box.length;
|
||||||
|
var progressValue = (actual / estimate * 100);
|
||||||
|
progressValue = Math.min(progressValue, 100);
|
||||||
|
updateProgress(progressValue);
|
||||||
|
|
||||||
|
return void sendChunk(box, function (e) {
|
||||||
|
if (e) { return console.error(e); }
|
||||||
|
next(again);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actual !== estimate) {
|
||||||
|
console.error('Estimated size does not match actual size');
|
||||||
|
}
|
||||||
|
|
||||||
|
// if not box then done
|
||||||
|
common.uploadComplete(teamId, id, owned, function (e) {
|
||||||
|
if (e) { return void console.error(e); }
|
||||||
|
var uri = ['', 'blob', id.slice(0,2), id].join('/');
|
||||||
|
console.log("encrypted blob is now available as %s", uri);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cb();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
common.uploadStatus(teamId, estimate, function (e, pending) {
|
||||||
|
if (e) {
|
||||||
|
console.error(e);
|
||||||
|
onError(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pending) {
|
||||||
|
return void onPending(function () {
|
||||||
|
// if the user wants to cancel the pending upload to execute that one
|
||||||
|
common.uploadCancel(teamId, estimate, function (e) {
|
||||||
|
if (e) {
|
||||||
|
return void console.error(e);
|
||||||
|
}
|
||||||
|
next(again);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
next(again);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
module.upload = function (file, noStore, common, updateProgress, onComplete, onError, onPending) {
|
module.upload = function (file, noStore, common, updateProgress, onComplete, onError, onPending) {
|
||||||
var u8 = file.blob; // This is not a blob but a uint8array
|
var u8 = file.blob; // This is not a blob but a uint8array
|
||||||
var metadata = file.metadata;
|
var metadata = file.metadata;
|
||||||
|
@ -50,85 +126,36 @@ define([
|
||||||
metadata.owners = [edPublic];
|
metadata.owners = [edPublic];
|
||||||
}));
|
}));
|
||||||
}).nThen(function () {
|
}).nThen(function () {
|
||||||
var next = FileCrypto.encrypt(u8, metadata, key);
|
module.uploadU8(common, {
|
||||||
|
teamId: teamId,
|
||||||
|
u8: u8,
|
||||||
|
metadata: metadata,
|
||||||
|
key: key,
|
||||||
|
id: id,
|
||||||
|
owned: owned,
|
||||||
|
onError: onError,
|
||||||
|
onPending: onPending,
|
||||||
|
updateProgress: updateProgress,
|
||||||
|
}, function () {
|
||||||
|
if (noStore) { return void onComplete(href); }
|
||||||
|
|
||||||
var estimate = FileCrypto.computeEncryptedSize(u8.length, metadata);
|
var title = metadata.name;
|
||||||
|
var data = {
|
||||||
var sendChunk = function (box, cb) {
|
teamId: teamId,
|
||||||
var enc = Nacl.util.encodeBase64(box);
|
title: title || "",
|
||||||
common.uploadChunk(teamId, enc, function (e, msg) {
|
href: href,
|
||||||
cb(e, msg);
|
path: path,
|
||||||
|
password: password,
|
||||||
|
channel: id,
|
||||||
|
owners: metadata.owners,
|
||||||
|
forceSave: forceSave
|
||||||
|
};
|
||||||
|
common.setPadTitle(data, function (err) {
|
||||||
|
if (err) { return void console.error(err); }
|
||||||
|
onComplete(href);
|
||||||
|
common.setPadAttribute('fileType', metadata.type, null, href);
|
||||||
|
common.setPadAttribute('owners', metadata.owners, null, href);
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
var actual = 0;
|
|
||||||
var again = function (err, box) {
|
|
||||||
if (err) { throw new Error(err); }
|
|
||||||
if (box) {
|
|
||||||
actual += box.length;
|
|
||||||
var progressValue = (actual / estimate * 100);
|
|
||||||
progressValue = Math.min(progressValue, 100);
|
|
||||||
updateProgress(progressValue);
|
|
||||||
|
|
||||||
return void sendChunk(box, function (e) {
|
|
||||||
if (e) { return console.error(e); }
|
|
||||||
next(again);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (actual !== estimate) {
|
|
||||||
console.error('Estimated size does not match actual size');
|
|
||||||
}
|
|
||||||
|
|
||||||
// if not box then done
|
|
||||||
common.uploadComplete(teamId, id, owned, function (e) {
|
|
||||||
if (e) { return void console.error(e); }
|
|
||||||
var uri = ['', 'blob', id.slice(0,2), id].join('/');
|
|
||||||
console.log("encrypted blob is now available as %s", uri);
|
|
||||||
|
|
||||||
|
|
||||||
var title = metadata.name;
|
|
||||||
|
|
||||||
if (noStore) { return void onComplete(href); }
|
|
||||||
|
|
||||||
var data = {
|
|
||||||
teamId: teamId,
|
|
||||||
title: title || "",
|
|
||||||
href: href,
|
|
||||||
path: path,
|
|
||||||
password: password,
|
|
||||||
channel: id,
|
|
||||||
owners: metadata.owners,
|
|
||||||
forceSave: forceSave
|
|
||||||
};
|
|
||||||
common.setPadTitle(data, function (err) {
|
|
||||||
if (err) { return void console.error(err); }
|
|
||||||
onComplete(href);
|
|
||||||
common.setPadAttribute('fileType', metadata.type, null, href);
|
|
||||||
common.setPadAttribute('owners', metadata.owners, null, href);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
common.uploadStatus(teamId, estimate, function (e, pending) {
|
|
||||||
if (e) {
|
|
||||||
console.error(e);
|
|
||||||
onError(e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pending) {
|
|
||||||
return void onPending(function () {
|
|
||||||
// if the user wants to cancel the pending upload to execute that one
|
|
||||||
common.uploadCancel(teamId, estimate, function (e) {
|
|
||||||
if (e) {
|
|
||||||
return void console.error(e);
|
|
||||||
}
|
|
||||||
next(again);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
next(again);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -991,6 +991,21 @@ define([
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
sframeChan.on('Q_BLOB_PASSWORD_CHANGE', function (data, cb) {
|
||||||
|
data.href = data.href || window.location.href;
|
||||||
|
var onPending = function () {
|
||||||
|
// XXX
|
||||||
|
};
|
||||||
|
var updateProgress = function (p) {
|
||||||
|
// XXX
|
||||||
|
console.log(p);
|
||||||
|
};
|
||||||
|
Cryptpad.changeBlobPassword(data, {
|
||||||
|
onPending: onPending,
|
||||||
|
updateProgress: updateProgress
|
||||||
|
}, cb);
|
||||||
|
});
|
||||||
|
|
||||||
sframeChan.on('Q_PAD_PASSWORD_CHANGE', function (data, cb) {
|
sframeChan.on('Q_PAD_PASSWORD_CHANGE', function (data, cb) {
|
||||||
data.href = data.href || window.location.href;
|
data.href = data.href || window.location.href;
|
||||||
Cryptpad.changePadPassword(Cryptget, Crypto, data, cb);
|
Cryptpad.changePadPassword(Cryptget, Crypto, data, cb);
|
||||||
|
|
Loading…
Reference in New Issue