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) { console.log('initialize 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) { console.log('handle file'); var file = zone.querySelector('input[type="file"]').files[0], reader = new FileReader() ; reader.onload = e => { transmitArrayBuffer(zone, e.target.result); }; 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) => { 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 => { console.log('key', key); console.log('iv', iv); console.log('iv to string', iv.join(',')); jsKey = key; // we register the key somwhere return window.crypto.subtle.exportKey('jwk', key); }).then(exportedKey => { rawKey = exportedKey; console.log('rawkey', rawKey); console.log('data', data); // we start encryption return window.crypto.subtle.encrypt({ name: algo, iv: iv}, jsKey, data); }) .then(encrypted => { console.log('encrypted', encrypted); encryptedData = encrypted; // we get the url and parameters to upload document return window.fetch(generateTempUrlPost); }) .then(response => response.json()) .then(data => { console.log(encryptedData); console.log(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); console.log('filename', suffix); console.log('formData', formData); return window.fetch(data.url, { method: 'POST', mode: 'cors', body: formData }); }) .then(response => { if (response.ok) { console.log('sent'); storeDataInForm(zone, suffix, rawKey, iv, uploadData); } else { console.log('response', response); throw new Error("error while sending data"); } }) .catch(error => { console.log(error); }) // return window.crypto.subtle.importKey('jwk', rawKey, { name: algo, iv: iv }, false, [ "decrypt"]); // // .then(key => { // console.log('decrypt'); // console.log(key); // // return window.crypto.subtle.decrypt({ name: algo, iv: iv }, key, encryptedData); // }) // .then(decrypted => { // console.log('decrypted'); // decrypt(zone, decrypted, 'decrypted'); // }) ; }; var storeDataInForm = (zone, suffix, jskey, iv, uploaddata) => { 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]') ; inputKey.value = JSON.stringify(jskey); inputIv.value = JSON.stringify(iv); inputObject.value = uploaddata.prefix + suffix; }; var decrypt = (zone, arraybuffer, name) => { console.log('arraybuffer', arraybuffer); var link = document.createElement('a'), data = new Blob([ arraybuffer ]) ; link.innerHTML = name; link.href = window.URL.createObjectURL(data); link.download = 'file'; zone.appendChild(link); }; window.addEventListener('load', function(e) { searchForZones(document); });