137 lines
4.0 KiB
JavaScript

var algo = 'AES-CBC';
var keyDefinition = {
name: algo,
length: 256
};
var searchForZones = function(root) {
var zones = root.querySelectorAll('div[data-stored-object]');
for(let i=0; i < zones.length; i++) {
initialize(zones[i]);
}
};
var initialize = function(zone) {
var
dropZone = document.createElement('div'),
input = document.createElement('input')
;
input.type = 'file';
input.addEventListener('change', function(e) {
handleInputFile(zone);
});
dropZone.classList.add('chill-doc__dropzone__drop');
zone.insertBefore(input, zone.firstChild);
zone.insertBefore(dropZone, zone.firstChild);
};
var handleInputFile = function (zone) {
var
file = zone.querySelector('input[type="file"]').files[0],
type = file.type,
reader = new FileReader()
;
reader.onload = e => {
transmitArrayBuffer(zone, e.target.result, type);
};
reader.readAsArrayBuffer(file);
};
var createFilename = () => {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (let i = 0; i < 7; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
};
var transmitArrayBuffer = (zone, data, type) => {
var
iv = crypto.getRandomValues(new Uint8Array(16)),
generateTempUrlPost = zone.querySelector('input[data-async-file-upload]').dataset.generateTempUrlPost,
suffix = createFilename(),
jsKey, rawKey, encryptedData, uploadData
;
window.crypto.subtle.generateKey(keyDefinition, true, [ "encrypt", "decrypt" ])
.then(key => {
jsKey = key;
// we register the key somwhere
return window.crypto.subtle.exportKey('jwk', key);
}).then(exportedKey => {
rawKey = exportedKey;
// we start encryption
return window.crypto.subtle.encrypt({ name: algo, iv: iv}, jsKey, data);
})
.then(encrypted => {
encryptedData = encrypted;
// we get the url and parameters to upload document
return window.fetch(generateTempUrlPost);
})
.then(response => response.json())
.then(data => {
var
formData = new FormData();
uploadData = data;
formData.append("redirect", data.redirect);
formData.append("max_file_size", data.max_file_size);
formData.append("max_file_count", data.max_file_count);
formData.append("expires", data.expires);
formData.append("signature", data.signature);
formData.append("file", new Blob([ encryptedData ]), suffix);
return window.fetch(data.url, {
method: 'POST',
mode: 'cors',
body: formData
});
})
.then(response => {
if (response.ok) {
storeDataInForm(zone, suffix, rawKey, iv, uploadData, type);
} else {
throw new Error("error while sending data");
}
})
.catch(error => {
window.alert("Error while sending document.");
console.log(error);
})
;
};
var storeDataInForm = (zone, suffix, jskey, iv, uploaddata, type) => {
var
inputKey = zone.querySelector('input[data-stored-object-key]'),
inputIv = zone.querySelector('input[data-stored-object-iv]'),
inputObject = zone.querySelector('input[data-async-file-upload]'),
inputType = zone.querySelector('input[data-async-file-type]')
;
inputKey.value = JSON.stringify(jskey);
inputIv.value = JSON.stringify(iv);
inputType.value = type;
inputObject.value = uploaddata.prefix + suffix;
};
window.addEventListener('load', function(e) {
searchForZones(document);
});