WIP support encrypted file upload via base64 chunks
This commit is contained in:
parent
ca7b76a812
commit
f644dc6c0b
@ -122,15 +122,7 @@ define([
|
|||||||
|
|
||||||
// metadata
|
// metadata
|
||||||
/* { filename: 'raccoon.jpg', type: 'image/jpeg' } */
|
/* { filename: 'raccoon.jpg', type: 'image/jpeg' } */
|
||||||
|
var encrypt = function (u8, metadata, key) {
|
||||||
|
|
||||||
/* TODO
|
|
||||||
in your callback, return an object which you can iterate...
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
var encrypt = function (u8, metadata, key, cb) {
|
|
||||||
var nonce = createNonce();
|
var nonce = createNonce();
|
||||||
|
|
||||||
// encode metadata
|
// encode metadata
|
||||||
@ -139,44 +131,62 @@ define([
|
|||||||
|
|
||||||
var plaintext = new Uint8Array(padChunk(metaBuffer));
|
var plaintext = new Uint8Array(padChunk(metaBuffer));
|
||||||
|
|
||||||
var chunks = [];
|
|
||||||
var j = 0;
|
var j = 0;
|
||||||
|
|
||||||
var start;
|
|
||||||
var end;
|
|
||||||
|
|
||||||
var part;
|
|
||||||
var box;
|
|
||||||
|
|
||||||
// prepend some metadata
|
|
||||||
for (;j * plainChunkLength < plaintext.length; j++) {
|
|
||||||
start = j * plainChunkLength;
|
|
||||||
end = start + plainChunkLength;
|
|
||||||
|
|
||||||
part = plaintext.subarray(start, end);
|
|
||||||
box = Nacl.secretbox(part, nonce, key);
|
|
||||||
chunks.push(box);
|
|
||||||
increment(nonce);
|
|
||||||
}
|
|
||||||
|
|
||||||
// append the encrypted file chunks
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
for (;i * plainChunkLength < u8.length; i++) {
|
|
||||||
|
/*
|
||||||
|
0: metadata
|
||||||
|
1: u8
|
||||||
|
2: done
|
||||||
|
*/
|
||||||
|
|
||||||
|
var state = 0;
|
||||||
|
|
||||||
|
var next = function (cb) {
|
||||||
|
var start;
|
||||||
|
var end;
|
||||||
|
var part;
|
||||||
|
var box;
|
||||||
|
|
||||||
|
if (state === 0) { // metadata...
|
||||||
|
start = j * plainChunkLength;
|
||||||
|
end = start + plainChunkLength;
|
||||||
|
|
||||||
|
part = plaintext.subarray(start, end);
|
||||||
|
box = Nacl.secretbox(part, nonce, key);
|
||||||
|
increment(nonce);
|
||||||
|
|
||||||
|
j++;
|
||||||
|
|
||||||
|
// metadata is done
|
||||||
|
if (j * plainChunkLength >= plaintext.length) {
|
||||||
|
return void cb(state++, box);
|
||||||
|
}
|
||||||
|
|
||||||
|
return void cb(state, box);
|
||||||
|
}
|
||||||
|
|
||||||
|
// encrypt the rest of the file...
|
||||||
start = i * plainChunkLength;
|
start = i * plainChunkLength;
|
||||||
end = start + plainChunkLength;
|
end = start + plainChunkLength;
|
||||||
|
|
||||||
part = new Uint8Array(u8.subarray(start, end));
|
part = u8.subarray(start, end);
|
||||||
box = Nacl.secretbox(part, nonce, key);
|
box = Nacl.secretbox(part, nonce, key);
|
||||||
chunks.push(box);
|
|
||||||
increment(nonce);
|
increment(nonce);
|
||||||
}
|
i++;
|
||||||
|
|
||||||
|
// regular data is done
|
||||||
|
if (i * plainChunkLength >= u8.length) { state = 2; }
|
||||||
|
|
||||||
// TODO do something with the chunks...
|
return void cb(state, box);
|
||||||
|
};
|
||||||
|
|
||||||
|
return next;
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
decrypt: decrypt,
|
decrypt: decrypt,
|
||||||
encrypt: encrypt,
|
encrypt: encrypt,
|
||||||
|
joinChunks: joinChunks,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
110
www/file/main.js
110
www/file/main.js
@ -14,6 +14,8 @@ define([
|
|||||||
var saveAs = window.saveAs;
|
var saveAs = window.saveAs;
|
||||||
var Nacl = window.nacl;
|
var Nacl = window.nacl;
|
||||||
|
|
||||||
|
var APP = {};
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
|
|
||||||
var ifrw = $('#pad-iframe')[0].contentWindow;
|
var ifrw = $('#pad-iframe')[0].contentWindow;
|
||||||
@ -31,12 +33,93 @@ define([
|
|||||||
xhr.send(null);
|
xhr.send(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
var upload = function (blob, id, key) {
|
|
||||||
Cryptpad.alert("UPLOAD IS NOT IMPLEMENTED YET");
|
|
||||||
};
|
|
||||||
|
|
||||||
var myFile;
|
var myFile;
|
||||||
var myDataType;
|
var myDataType;
|
||||||
|
|
||||||
|
var upload = function (blob, metadata) {
|
||||||
|
console.log(metadata);
|
||||||
|
var u8 = new Uint8Array(blob);
|
||||||
|
|
||||||
|
var key = Nacl.randomBytes(32);
|
||||||
|
var next = FileCrypto.encrypt(u8, metadata, key);
|
||||||
|
|
||||||
|
var chunks = [];
|
||||||
|
|
||||||
|
var sendChunk = function (box, cb) {
|
||||||
|
var enc = Nacl.util.encodeBase64(box);
|
||||||
|
|
||||||
|
chunks.push(box);
|
||||||
|
Cryptpad.rpc.send('UPLOAD', enc, function (e, msg) {
|
||||||
|
cb(e, msg);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var again = function (state, box) {
|
||||||
|
switch (state) {
|
||||||
|
case 0:
|
||||||
|
sendChunk(box, function (e, msg) {
|
||||||
|
if (e) { return console.error(e); }
|
||||||
|
next(again);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
sendChunk(box, function (e, msg) {
|
||||||
|
if (e) { return console.error(e); }
|
||||||
|
next(again);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
sendChunk(box, function (e, msg) {
|
||||||
|
if (e) { return console.error(e); }
|
||||||
|
Cryptpad.rpc.send('UPLOAD_COMPLETE', '', function (e, res) {
|
||||||
|
if (e) { return void console.error(e); }
|
||||||
|
var id = res[0];
|
||||||
|
var uri = ['', 'blob', id.slice(0,2), id].join('/');
|
||||||
|
console.log("encrypted blob is now available as %s", uri);
|
||||||
|
|
||||||
|
window.location.hash = [
|
||||||
|
'',
|
||||||
|
2,
|
||||||
|
Cryptpad.hexToBase64(id).replace(/\//g, '-'),
|
||||||
|
Nacl.util.encodeBase64(key).replace(/\//g, '-'),
|
||||||
|
''
|
||||||
|
].join('/');
|
||||||
|
|
||||||
|
APP.$form.hide();
|
||||||
|
|
||||||
|
var newU8 = FileCrypto.joinChunks(chunks);
|
||||||
|
FileCrypto.decrypt(newU8, key, function (e, res) {
|
||||||
|
var title = document.title = res.metadata.filename;
|
||||||
|
myFile = res.content;
|
||||||
|
myDataType = res.metadata.type;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error("E_INVAL_STATE");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Cryptpad.rpc.send('UPLOAD_STATUS', '', function (e, pending) {
|
||||||
|
if (e) {
|
||||||
|
console.error(e);
|
||||||
|
return void Cryptpad.alert("something went wrong");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pending[0]) {
|
||||||
|
return void Cryptpad.confirm('upload pending, abort?', function (yes) {
|
||||||
|
if (!yes) { return; }
|
||||||
|
Cryptpad.rpc.send('UPLOAD_CANCEL', '', function (e, res) {
|
||||||
|
if (e) { return void console.error(e); }
|
||||||
|
console.log(res);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
next(again);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
var uploadMode = false;
|
var uploadMode = false;
|
||||||
|
|
||||||
var andThen = function () {
|
var andThen = function () {
|
||||||
@ -54,8 +137,6 @@ define([
|
|||||||
uploadMode = true;
|
uploadMode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//window.location.hash = '/2/K6xWU-LT9BJHCQcDCT-DcQ/VLIgpQOgmSaW3AQcUCCoJnYvCbMSO0MKBqaICSly9fo=';
|
|
||||||
|
|
||||||
var parsed = Cryptpad.parsePadUrl(window.location.href);
|
var parsed = Cryptpad.parsePadUrl(window.location.href);
|
||||||
var defaultName = Cryptpad.getDefaultName(parsed);
|
var defaultName = Cryptpad.getDefaultName(parsed);
|
||||||
|
|
||||||
@ -136,7 +217,7 @@ define([
|
|||||||
|
|
||||||
FileCrypto.decrypt(u8, key, function (e, data) {
|
FileCrypto.decrypt(u8, key, function (e, data) {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
var title = document.title = data.metadata.filename;
|
var title = document.title = data.metadata.name;
|
||||||
myFile = data.content;
|
myFile = data.content;
|
||||||
myDataType = data.metadata.type;
|
myDataType = data.metadata.type;
|
||||||
updateTitle(title || defaultName);
|
updateTitle(title || defaultName);
|
||||||
@ -146,7 +227,11 @@ define([
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var $form = $iframe.find('#upload-form');
|
if (!Cryptpad.isLoggedIn()) {
|
||||||
|
return Cryptpad.alert("You must be logged in to upload files");
|
||||||
|
}
|
||||||
|
|
||||||
|
var $form = APP.$form = $iframe.find('#upload-form');
|
||||||
$form.css({
|
$form.css({
|
||||||
display: 'block',
|
display: 'block',
|
||||||
});
|
});
|
||||||
@ -154,10 +239,13 @@ define([
|
|||||||
var $file = $form.find("#file").on('change', function (e) {
|
var $file = $form.find("#file").on('change', function (e) {
|
||||||
var file = e.target.files[0];
|
var file = e.target.files[0];
|
||||||
var reader = new FileReader();
|
var reader = new FileReader();
|
||||||
reader.onload = function (e) {
|
reader.onloadend = function (e) {
|
||||||
upload(e.target.result);
|
upload(this.result, {
|
||||||
|
name: file.name,
|
||||||
|
type: file.type,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
reader.readAsText(file);
|
reader.readAsArrayBuffer(file);
|
||||||
});
|
});
|
||||||
|
|
||||||
// we're in upload mode
|
// we're in upload mode
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user