fix folder name

This commit is contained in:
2021-03-18 13:37:13 +01:00
parent a2f6773f5a
commit eaa0ad925f
1578 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,114 @@
var mime = require('mime-types');
var algo = 'AES-CBC';
var initializeButtons = (root) => {
var
buttons = root.querySelectorAll('a[data-download-button]');
for (let i = 0; i < buttons.length; i ++) {
initialize(buttons[i]);
}
};
var initialize = (button) => {
button.addEventListener('click', onClick);
};
var onClick = e => download(e.target);
var download = (button) => {
var
keyData = JSON.parse(button.dataset.key),
ivData = JSON.parse(button.dataset.iv),
iv = new Uint8Array(ivData),
urlGenerator = button.dataset.tempUrlGetGenerator,
hasFilename = 'filename' in button.dataset,
filename = button.dataset.filename,
labelPreparing = button.dataset.labelPreparing,
labelReady = button.dataset.labelReady,
mimeType = button.dataset.mimeType,
extension = mime.extension(mimeType),
decryptError = "Error while decrypting file",
fetchError = "Error while fetching file",
key, url
;
button.textContent = labelPreparing;
window.fetch(urlGenerator)
.then((r) => {
if (r.ok) {
return r.json();
} else {
throw new Error("error while downloading url " + r.status + " " + r.statusText);
}
})
.then(data => {
url = data.url;
return window.crypto.subtle.importKey('jwk', keyData, { name: algo, iv: iv}, false, ['decrypt']);
})
.catch(e => {
console.error("error while importing key");
console.error(e);
button.appendChild(document.createTextNode(decryptError));
})
.then(nKey => {
key = nKey;
return window.fetch(url);
})
.catch(e => {
console.error("error while fetching data");
console.error(e);
button.textContent = "";
button.appendChild(document.createTextNode(fetchError));
})
.then(r => {
if (r.ok) {
return r.arrayBuffer();
} else {
throw new Error(r.status + r.statusText);
}
})
.then(buffer => {
return window.crypto.subtle.decrypt({ name: algo, iv: iv }, key, buffer);
})
.catch(e => {
console.error("error while importing key");
console.error(e);
button.textContent = "";
button.appendChild(document.createTextNode(decryptError));
})
.then(decrypted => {
var
blob = new Blob([decrypted], { type: mimeType }),
url = window.URL.createObjectURL(blob)
;
button.href = url;
button.target = '_blank';
button.type = mimeType;
button.textContent = labelReady;
if (hasFilename) {
button.download = filename;
if (extension !== false) {
button.download = button.download + '.' + extension;
}
}
button.removeEventListener('click', onClick);
button.click();
})
.catch(error => {
console.log(error);
button.textContent = "";
button.appendChild(document.createTextNode("error while handling decrypted file"));
})
;
};
window.addEventListener('load', function(e) {
initializeButtons(e.target);
});
module.exports = initializeButtons;

View File

@@ -0,0 +1,2 @@
require('./uploader.js');
require('./downloader.js');

View File

@@ -0,0 +1,34 @@
// override dropzone from dropzoneJS
.dropzone {
margin-bottom: 0.5rem;
.dz-preview {
display: initial;
margin-left: auto;
margin-right: auto;
.dz-image {
margin-left: auto;
margin-right: auto;
}
.dz-details, .dz-progress, .dz-success-mark, .dz-error-mark {
position: initial;
margin-left: auto;
margin-right: auto;
}
}
}
.chill-dropzone__below-zone {
display: flex;
& > *:not(:last-child) {
margin-right: 1rem;
}
.sc-button.dz-bt-below-dropzone {
width: 100%;
}
}

View File

@@ -0,0 +1,372 @@
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 addBelowButton = (btn, zone, zoneData) => {
let
belowZone = zone.querySelector('.chill-dropzone__below-zone');
if (belowZone === null) {
belowZone = document.createElement('div');
belowZone.classList.add('chill-dropzone__below-zone');
zone.appendChild(belowZone);
}
belowZone.appendChild(btn);
};
var createZone = (zone, zoneData) => {
var
created = document.createElement('div'),
initMessage = document.createElement('div'),
initContent = zone.dataset.labelInitMessage,
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);
let event = new CustomEvent("chill_dropzone_initialized", {
detail: {
dropzone: dropzoneI,
zoneData: zoneData
}
});
window.dispatchEvent(event);
};
var initialize = function(zone) {
var
allowRemove = zone.dataset.allowRemove,
zoneData = { zone: zone, suffix: createFilename(), allowRemove: allowRemove, old: null }
;
if (hasDataInForm(zone, zoneData)) {
insertRemoveButton(zone, zoneData);
insertDownloadButton(zone, zoneData);
} else {
createZone(zone, zoneData);
}
};
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);
};
const restoreDataInForm = (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]')
;
if (zoneData.old === null) {
console.log('should not have restored data');
return;
}
inputKey.value = zoneData.old.key;
inputIv.value = zoneData.old.iv;
inputType.value = zoneData.old.type;
inputObject.value = zoneData.old.obj;
insertDownloadButton(zone);
};
const hasDataInForm = (zone, zoneData) => {
var
inputObject = zone.querySelector('input[data-async-file-upload]')
;
return inputObject.value.length > 0;
};
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]')
;
// store data for future usage
zoneData.old = {
key: inputKey.value,
iv: inputIv.value,
obj: inputObject.value,
type: inputType.value
};
// set blank values
inputKey.value = "";
inputIv.value = "";
inputType.value = "";
inputObject.value = "";
insertDownloadButton(zone);
};
var insertRemoveButton = (zone, zoneData) => {
var
removeButton = document.createElement('a'),
cancelButton = document.createElement('a'),
labelRemove = zone.dataset.dictRemove,
labelCancel = 'Restaurer'
;
removeButton.classList.add('sc-button', 'bt-delete');
removeButton.textContent = labelRemove;
cancelButton.classList.add('sc-button');
cancelButton.textContent = labelCancel;
removeButton.addEventListener('click', (e) => {
e.preventDefault();
if (zoneData.allowRemove === 'true') {
removeDataInForm(zone, zoneData);
cancelButton.addEventListener('click', (e) => {
e.preventDefault();
restoreDataInForm(zone, zoneData);
cancelButton.remove();
zone.querySelector('.dropzone').remove();
initialize(zone);
});
}
addBelowButton(cancelButton, zone, zoneData);
//zone.appendChild(cancelButton);
removeButton.remove();
createZone(zone, zoneData);
});
addBelowButton(removeButton, zone, zoneData);
// zone.appendChild(removeButton);
};
const removeDownloadButton = (zone, zoneData) => {
var
existingButtons = zone.querySelectorAll('a[data-download-button]')
;
// remove existing
existingButtons.forEach(function(b) {
b.remove();
});
};
var insertDownloadButton = (zone, zoneData) => {
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;
addBelowButton(newButton, zone, zoneData);
//zone.appendChild(newButton);
initializeDownload(zone);
};
window.addEventListener('load', function(e) {
searchForZones(document);
});
window.addEventListener('collection-add-entry', function(e) {
searchForZones(e.detail.entry);
});