mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-13 13:54:23 +00:00
261 lines
8.1 KiB
JavaScript
261 lines
8.1 KiB
JavaScript
var algo = 'AES-CBC';
|
|
var Dropzone = require('dropzone');
|
|
var initializeDownload = require('./downloader.js');
|
|
|
|
|
|
/**
|
|
*
|
|
* define a dropzone for chill usage
|
|
*
|
|
* An event is launched when dropzone is initialize, allowing to customize events
|
|
* on dropzone :
|
|
*
|
|
* ```
|
|
* window.addEventListener("chill_dropzone_initialized", (e) => {
|
|
* // do something with dropzone:
|
|
* e.detail.dropzone.on("success", (e) => {
|
|
* // see https://www.dropzonejs.com/#event-success
|
|
* });
|
|
* });
|
|
* ```
|
|
*
|
|
*/
|
|
|
|
// load css
|
|
//require('dropzone/dist/basic.css');
|
|
require('dropzone/dist/dropzone.css');
|
|
require('./index.scss');
|
|
//
|
|
|
|
// disable dropzone autodiscover
|
|
Dropzone.autoDiscover = false;
|
|
|
|
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 getUploadUrl = function(zoneData, files) {
|
|
var
|
|
generateTempUrlPost = zoneData.zone.querySelector('input[data-async-file-upload]').dataset.generateTempUrlPost,
|
|
oReq = new XMLHttpRequest()
|
|
;
|
|
|
|
// arg, dropzone, you cannot handle async upload...
|
|
oReq.open("GET", generateTempUrlPost, false);
|
|
oReq.send();
|
|
|
|
if (oReq.readyState !== XMLHttpRequest.DONE) {
|
|
throw new Error("Error while fetching url to upload");
|
|
}
|
|
|
|
zoneData.params = JSON.parse(oReq.responseText);
|
|
|
|
return zoneData.params.url;
|
|
};
|
|
|
|
var encryptFile = function(originalFile, zoneData, done) {
|
|
var
|
|
iv = crypto.getRandomValues(new Uint8Array(16)),
|
|
reader = new FileReader(),
|
|
jsKey, rawKey
|
|
;
|
|
|
|
zoneData.originalType = originalFile.type;
|
|
|
|
reader.onload = e => {
|
|
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, e.target.result);
|
|
})
|
|
.then(encrypted => {
|
|
zoneData.crypto = {
|
|
jsKey: jsKey,
|
|
rawKey: rawKey,
|
|
iv: iv
|
|
};
|
|
|
|
done(new File( [ encrypted ], zoneData.suffix));
|
|
});
|
|
};
|
|
|
|
reader.readAsArrayBuffer(originalFile);
|
|
};
|
|
|
|
|
|
var initialize = function(zone) {
|
|
var
|
|
created = document.createElement('div'),
|
|
initMessage = document.createElement('div'),
|
|
initContent = zone.dataset.labelInitMessage,
|
|
zoneData = { zone: zone, suffix: createFilename() },
|
|
dropzoneI;
|
|
|
|
created.classList.add('dropzone');
|
|
initMessage.classList.add('dz-message');
|
|
initMessage.appendChild(document.createTextNode(initContent));
|
|
|
|
dropzoneI = new Dropzone(created, {
|
|
url: function(files) {
|
|
return getUploadUrl(zoneData, files);
|
|
},
|
|
dictDefaultMessage: zone.dataset.dictDefaultMessage,
|
|
dictFileTooBig: zone.dataset.dictFileTooBig,
|
|
dictRemoveFile: zone.dataset.dictRemoveFile,
|
|
dictMaxFilesExceeded: zone.dataset.dictMaxFilesExceeded,
|
|
dictCancelUpload: zone.dataset.dictCancelUpload,
|
|
dictCancelUploadConfirm: zone.dataset.dictCancelUploadConfirm,
|
|
dictUploadCanceled: zone.dataset.dictUploadCanceled,
|
|
maxFiles: 1,
|
|
addRemoveLinks: true,
|
|
transformFile: function(file, done) {
|
|
encryptFile(file, zoneData, done);
|
|
},
|
|
renameFile: function(file) {
|
|
return zoneData.suffix;
|
|
}
|
|
});
|
|
|
|
dropzoneI.on("sending", function(file, xhr, formData) {
|
|
formData.append("redirect", zoneData.params.redirect);
|
|
formData.append("max_file_size", zoneData.params.max_file_size);
|
|
formData.append("max_file_count", zoneData.params.max_file_count);
|
|
formData.append("expires", zoneData.params.expires);
|
|
formData.append("signature", zoneData.params.signature);
|
|
});
|
|
|
|
dropzoneI.on("success", function(file, response) {
|
|
zoneData.currentFile = file;
|
|
storeDataInForm(zone, zoneData);
|
|
});
|
|
|
|
dropzoneI.on("addedfile", function(file) {
|
|
if (zoneData.hasOwnProperty('currentFile')) {
|
|
dropzoneI.removeFile(zoneData.currentFile);
|
|
}
|
|
});
|
|
|
|
dropzoneI.on("removedfile", function(file) {
|
|
removeDataInForm(zone, zoneData);
|
|
});
|
|
|
|
zone.insertBefore(created, zone.firstChild);
|
|
|
|
insertDownloadButton(zone, zoneData);
|
|
|
|
let event = new CustomEvent("chill_dropzone_initialized", {
|
|
detail: {
|
|
dropzone: dropzoneI,
|
|
zoneData: zoneData
|
|
}
|
|
});
|
|
window.dispatchEvent(event);
|
|
};
|
|
|
|
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 storeDataInForm = (zone, zoneData) => {
|
|
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(zoneData.crypto.rawKey);
|
|
inputIv.value = JSON.stringify(Array.from(zoneData.crypto.iv));
|
|
inputType.value = zoneData.originalType;
|
|
inputObject.value = zoneData.params.prefix + zoneData.suffix;
|
|
|
|
insertDownloadButton(zone);
|
|
};
|
|
|
|
var removeDataInForm = (zone, zoneData) => {
|
|
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 = "";
|
|
inputIv.value = "";
|
|
inputType.value = "";
|
|
inputObject.value = "";
|
|
|
|
insertDownloadButton(zone);
|
|
};
|
|
|
|
var insertDownloadButton = (zone) => {
|
|
var
|
|
existingButtons = zone.querySelectorAll('a[data-download-button]'),
|
|
newButton = document.createElement('a'),
|
|
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]'),
|
|
labelPreparing = zone.dataset.labelPreparing,
|
|
labelQuietButton = zone.dataset.labelQuietButton,
|
|
labelReady = zone.dataset.labelReady,
|
|
tempUrlGenerator = zone.dataset.tempUrlGenerator,
|
|
tempUrlGeneratorParams = new URLSearchParams()
|
|
;
|
|
|
|
// remove existing
|
|
existingButtons.forEach(function(b) {
|
|
b.remove();
|
|
});
|
|
|
|
if (inputObject.value === '') {
|
|
return;
|
|
}
|
|
|
|
tempUrlGeneratorParams.append('object_name', inputObject.value);
|
|
|
|
newButton.dataset.downloadButton = true;
|
|
newButton.dataset.key = inputKey.value;
|
|
newButton.dataset.iv = inputIv.value;
|
|
newButton.dataset.mimeType = inputType.value;
|
|
newButton.dataset.labelPreparing = labelPreparing;
|
|
newButton.dataset.labelReady = labelReady;
|
|
newButton.dataset.tempUrlGetGenerator = tempUrlGenerator + '?' + tempUrlGeneratorParams.toString();
|
|
newButton.classList.add('sc-button', 'bt-download', 'dz-bt-below-dropzone');
|
|
newButton.textContent = labelQuietButton;
|
|
|
|
zone.appendChild(newButton);
|
|
initializeDownload(zone);
|
|
};
|
|
|
|
window.addEventListener('load', function(e) {
|
|
searchForZones(document);
|
|
});
|
|
|
|
window.addEventListener('collection-add-entry', function(e) {
|
|
searchForZones(e.detail.entry);
|
|
});
|