added filename special character check, and moved replace regex to front end

This commit is contained in:
bill bittner 2017-07-22 15:09:58 -07:00
parent 49f1fb8745
commit e99e8291bd
5 changed files with 126 additions and 163 deletions

View file

@ -24,14 +24,11 @@ module.exports = {
default: default:
throw new Error('The ' + file.Type + ' content type is not supported. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.'); throw new Error('The ' + file.Type + ' content type is not supported. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.');
} }
// validate claim name
// validate name const invalidCharacters = /[^A-Za-z0-9,-]/.exec(name);
const invalidCharacters = /[^A-Za-z0-9,- ]/.exec(name);
if (invalidCharacters) { if (invalidCharacters) {
throw new Error('The name you provided is not allowed. Please use A-Z, a-z, 0-9, and "-" only.'); throw new Error('The claim name you provided is not allowed. Only the following characters are allowed: A-Z, a-z, 0-9, and "-"');
} }
name = str.replace(/\s+/g, '-'); //replace space with dash/hyphen
// validate license // validate license
if ((license.indexOf('Public Domain') === -1) && (license.indexOf('Creative Commons') === -1)) { if ((license.indexOf('Public Domain') === -1) && (license.indexOf('Creative Commons') === -1)) {
throw new Error('Only posts with a license of "Public Domain" or "Creative Commons" are eligible for publishing through spee.ch'); throw new Error('Only posts with a license of "Public Domain" or "Creative Commons" are eligible for publishing through spee.ch');

View file

@ -1,75 +0,0 @@
// define variables
var socket = io();
var uploader = new SocketIOFileUpload(socket);
var stagedFiles = null;
/* configure the submit button */
function publishSelectedImage(event) {
event.preventDefault();
// validate inputs
var name = document.getElementById('publish-name').value;
try {
validateSubmission(stagedFiles, name);
} catch (error) {
if (error.name === 'FileError'){
showError('input-error-file-selection', error.message);
} else if (error.name === 'NameError') {
showError('input-error-claim-name', error.message);
} else {
showError('input-error-publish-submit', error.message);
}
return;
}
// make sure the name is available then start the upload
validateClaimName(name)
.then(function() {
uploader.submitFiles(stagedFiles); //note: must pass the file as part of an array.
})
.catch(function(error) {
showError('input-error-claim-name', error);
})
};
/* socketio-file-upload listeners */
uploader.addEventListener('start', function(event){
var name = document.getElementById('publish-name').value;
var license = document.getElementById('publish-license').value;
var nsfw = document.getElementById('publish-nsfw').checked;
event.file.meta.name = name;
event.file.meta.license = license;
event.file.meta.nsfw = nsfw;
event.file.meta.type = stagedFiles[0].type;
// re-set the html in the publish area
document.getElementById('publish-active-area').innerHTML = '<div id="publish-status"></div><div id="progress-bar"></div>';
// start a progress animation
createProgressBar(document.getElementById('progress-bar'), 12);
// google analytics
ga('send', {
hitType: 'event',
eventCategory: 'publish',
eventAction: name
});
});
uploader.addEventListener('progress', function(event){
var percent = event.bytesLoaded / event.file.size * 100;
updatePublishStatus('File is ' + percent.toFixed(2) + '% loaded to the server');
});
/* socket.io message listeners */
socket.on('publish-status', function(msg){
updatePublishStatus(msg);
});
socket.on('publish-failure', function(msg){
document.getElementById('publish-active-area').innerHTML = '<p> --(✖╭╮✖)→ </p><p>' + JSON.stringify(msg) + '</p><strong>For help, post the above error text in the #speech channel on the <a href="https://lbry.slack.com/" target="_blank">lbry slack</a></strong>';
});
socket.on('publish-complete', function(msg){
var publishResults;
var showUrl = '/show/' + msg.name + '/' + msg.result.claim_id;
// build new publish area
publishResults = '<p>Your publish is complete! You are being redirected to it now.</p>';
publishResults += '<p><a target="_blank" href="' + showUrl + '">If you do not get redirected, click here.</a></p>';
// update publish area
document.getElementById('publish-active-area').innerHTML = publishResults;
window.location.href = showUrl;
});

View file

@ -2,7 +2,7 @@
function updatePublishStatus(msg){ function updatePublishStatus(msg){
document.getElementById('publish-status').innerHTML = msg; document.getElementById('publish-status').innerHTML = msg;
} }
// validation function which checks the proposed file's type and size
function validateFile(file) { function validateFile(file) {
if (!file) { if (!file) {
throw new Error('no file provided'); throw new Error('no file provided');
@ -22,28 +22,28 @@ function validateFile(file) {
} }
break; break;
default: default:
throw new Error('The ' + file.Type + ' content type is not supported. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.') throw new Error(file.type + ' is not supported a supported file type. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.')
} }
// validate the file name (note: different from the lbry claim name)
var invalidCharacter = /[^\w.-\s()]/g.exec(file.name);
if (invalidCharacter) {
throw new Error('Special characters, such as "' + invalidCharacter + '", are not allowed in the file name.');
};
} }
// validation function that checks to make sure the claim name is not already claimed
function validateSubmission(stagedFiles, name){
// make sure only 1 file was selected
if (!stagedFiles) {
throw new FileError("Please select a file");
} else if (stagedFiles.length > 1) {
throw new FileError("Only one file is allowed at a time");
}
// validate 'name' field
var invalidCharacters = /[^A-Za-z0-9,-]/.exec(name);
if (invalidCharacters) {
throw new NameError(invalidCharacters + ' is not allowed. A-Z, a-z, 0-9, and "-" only.');
} else if (name.length < 1) {
throw new NameError("You must enter a name for your claim");
}
}
function validateClaimName (name) { function validateClaimName (name) {
var deferred = new Promise(function(resolve, reject) { var deferred = new Promise(function(resolve, reject) {
// validate the characters in the 'name' field
if (name.length < 1) {
reject(new NameError("You must enter a name for your claim"));
return;
}
var invalidCharacters = /[^A-Za-z0-9,-]/g.exec(name);
if (invalidCharacters) {
reject(new NameError('"' + invalidCharacters + '" is not allowed. Use only the following characters: A-Z, a-z, 0-9, and "-"'));
return;
}
// make sure the claim name is still available
var xhttp; var xhttp;
xhttp = new XMLHttpRequest(); xhttp = new XMLHttpRequest();
xhttp.open('GET', '/api/isClaimAvailable/' + name, true); xhttp.open('GET', '/api/isClaimAvailable/' + name, true);
@ -54,7 +54,7 @@ function validateClaimName (name) {
if (this.response == true) { if (this.response == true) {
resolve(); resolve();
} else { } else {
reject("That name has already been claimed by spee.ch. Please choose a different name."); reject( new NameError("That name has already been claimed by spee.ch. Please choose a different name."));
} }
} else { } else {
reject("request to check claim name failed with status:" + this.status); reject("request to check claim name failed with status:" + this.status);
@ -65,41 +65,88 @@ function validateClaimName (name) {
}); });
return deferred; return deferred;
} }
// validation function which checks all aspects of the publish submission
function validateSubmission(stagedFiles, name){
var deferred = new Promise(function (resolve, reject) {
// make sure only 1 file was selected
if (!stagedFiles) {
reject(new FileError("Please select a file"));
} else if (stagedFiles.length > 1) {
reject(new FileError("Only one file is allowed at a time"));
}
// validate the file's name, type, and size
try {
validateFile(stagedFiles[0]);
} catch (error) {
reject(error);
}
// make sure the claim name has not already been used
validateClaimName(name)
.then(function() {
resolve();
})
.catch(function(error) {
reject(error);
})
});
return deferred;
}
/* regular publish helper functions */ /* publish helper functions */
// When a file is selected for publish, validate that file and
// stage it so it will be ready when the publish button is clicked.
function previewAndStageFile(selectedFile){ function previewAndStageFile(selectedFile){
var previewHolder = document.getElementById('asset-preview-holder'); var previewHolder = document.getElementById('asset-preview-holder');
var dropzone = document.getElementById('drop-zone'); var dropzone = document.getElementById('drop-zone');
var previewReader = new FileReader(); var previewReader = new FileReader();
var nameInput = document.getElementById('publish-name'); var nameInput = document.getElementById('publish-name');
// validate the file // validate the file's name, type, and size
try { try {
validateFile(selectedFile); validateFile(selectedFile);
} catch (error) { } catch (error) {
showError('input-error-file-selection', error.message); showError('input-error-file-selection', error.message);
return; return;
} }
// set the preview // set the image preview, if a preview was provided
if (selectedFile.type === 'video/mp4') { if (selectedFile.type !== 'video/mp4') {
} else {
previewReader.readAsDataURL(selectedFile); previewReader.readAsDataURL(selectedFile);
previewReader.onloadend = function () { previewReader.onloadend = function () {
dropzone.style.display = 'none'; dropzone.style.display = 'none';
previewHolder.style.display = 'block'; previewHolder.style.display = 'block';
previewHolder.innerHTML = '<img width="100%" src="' + previewReader.result + '" alt="image preview"/>'; previewHolder.innerHTML = '<img width="100%" src="' + previewReader.result + '" alt="image preview"/>';
}; };
} }
// set the name input value to the image name if none is set yet // set the name input value to the image name if none is set yet
if (nameInput.value === "") { if (nameInput.value === "") {
nameInput.value = selectedFile.name.substring(0, selectedFile.name.indexOf('.')); var filename = selectedFile.name.substring(0, selectedFile.name.indexOf('.'))
filename = filename.replace(/\s+/g, '-');
nameInput.value = filename;
} }
// store the selected file for upload // store the selected file for upload
stagedFiles = [selectedFile]; stagedFiles = [selectedFile];
} }
// Validate the publish submission and then trigger publishing.
function publishSelectedImage(event) {
event.preventDefault();
var name = document.getElementById('publish-name').value;
validateSubmission(stagedFiles, name)
.then(function() {
uploader.submitFiles(stagedFiles);
})
.catch(function(error) {
if (error.name === 'FileError'){
showError('input-error-file-selection', error.message);
} else if (error.name === 'NameError') {
showError('input-error-claim-name', error.message);
} else {
showError('input-error-publish-submit', error.message);
}
return;
})
};
/* drop zone functions */ /* drop zone functions */
function drop_handler(ev) { function drop_handler(ev) {
@ -128,51 +175,3 @@ function dragend_handler(ev) {
ev.dataTransfer.clearData(); ev.dataTransfer.clearData();
} }
} }
/* meme publish functions */
function startPublish() {
//download the image
var dataUrl = canvas.toDataURL('image/jpeg'); // canvas defined in memeDraw.js
var blob = dataURItoBlob(dataUrl)
var fileName = nameInput.value + ".jpeg"; //note: need to dynamically grab type
var file = new File([blob], fileName, {type: 'image/jpeg', lastModified: Date.now()});
stageAndPublish(file);
};
function stageAndPublish(file) {
var name = nameInput.value;
var invalidCharacters = /[^A-Za-z0-9,-]/.exec(name);
// validate 'name'
if (invalidCharacters) {
showError('input-error-claim-name', invalidCharacters + ' is not allowed. A-Z, a-z, 0-9, "_" and "-" only.');
return;
} else if (name.length < 1) {
showError('input-error-claim-name', 'You must enter a name for your claim');
return;
}
// stage files
stagedFiles = [file]; // stores the selected file for
// make sure a file was selected
if (stagedFiles) {
// make sure only 1 file was selected
if (stagedFiles.length < 1) {
showError('input-error-file-selection', 'A file is needed');
return;
}
// make sure the content type is acceptable
switch (stagedFiles[0].type) {
case "image/png":
case "image/jpeg":
case "image/gif":
case "video/mp4":
uploader.submitFiles(stagedFiles);
break;
default:
showError('input-error-publish-submit', 'Only .png, .jpeg, .gif, and .mp4 files are currently supported');
break;
}
} else {
showError('input-error-file-selection', 'Please select a file');
}
}

View file

@ -10,7 +10,52 @@
<script src="/socket.io/socket.io.js"></script> <script src="/socket.io/socket.io.js"></script>
<script src="/siofu/client.js"></script> <script src="/siofu/client.js"></script>
<script src="/assets/js/generalFunctions.js"></script> <script src="/assets/js/generalFunctions.js"></script>
<script src="/assets/js/publishFunctions.js"></script> <script src="/assets/js/publishFunctions.js"></script>
<script src="/assets/js/index.js"></script> <script typ="text/javascript">
// define variables
var socket = io();
var uploader = new SocketIOFileUpload(socket);
var stagedFiles = null;
/* socketio-file-upload listeners */
uploader.addEventListener('start', function(event){
var name = document.getElementById('publish-name').value;
var license = document.getElementById('publish-license').value;
var nsfw = document.getElementById('publish-nsfw').checked;
event.file.meta.name = name;
event.file.meta.license = license;
event.file.meta.nsfw = nsfw;
event.file.meta.type = stagedFiles[0].type;
// re-set the html in the publish area
document.getElementById('publish-active-area').innerHTML = '<div id="publish-status"></div><div id="progress-bar"></div>';
// start a progress animation
createProgressBar(document.getElementById('progress-bar'), 12);
// google analytics
ga('send', {
hitType: 'event',
eventCategory: 'publish',
eventAction: name
});
});
uploader.addEventListener('progress', function(event){
var percent = event.bytesLoaded / event.file.size * 100;
updatePublishStatus('File is ' + percent.toFixed(2) + '% loaded to the server');
});
/* socket.io message listeners */
socket.on('publish-status', function(msg){
updatePublishStatus(msg);
});
socket.on('publish-failure', function(msg){
document.getElementById('publish-active-area').innerHTML = '<p> --(✖╭╮✖)→ </p><p>' + JSON.stringify(msg) + '</p><strong>For help, post the above error text in the #speech channel on the <a href="https://lbry.slack.com/" target="_blank">lbry slack</a></strong>';
});
socket.on('publish-complete', function(msg){
var publishResults;
var showUrl = '/show/' + msg.name + '/' + msg.result.claim_id;
// build new publish area
publishResults = '<p>Your publish is complete! You are being redirected to it now.</p>';
publishResults += '<p><a target="_blank" href="' + showUrl + '">If you do not get redirected, click here.</a></p>';
// update publish area
document.getElementById('publish-active-area').innerHTML = publishResults;
window.location.href = showUrl;
});
</script>

View file

@ -26,7 +26,6 @@
<script> <script>
var elem = document.querySelector('.grid'); var elem = document.querySelector('.grid');
var trendingImages = document.querySelectorAll('.trending-image'); var trendingImages = document.querySelectorAll('.trending-image');
console.log(trendingImages)
var trendingVideos = document.querySelectorAll('.trending-video'); var trendingVideos = document.querySelectorAll('.trending-video');
var msnry = new Masonry( elem, { var msnry = new Masonry( elem, {
itemSelector: '.grid-item' itemSelector: '.grid-item'
@ -34,14 +33,12 @@
// after images are loaded, reset layout // after images are loaded, reset layout
for (var i = 0; i < trendingVideos.length; i++) { for (var i = 0; i < trendingVideos.length; i++) {
trendingImages[i].addEventListener('load', function(){ trendingImages[i].addEventListener('load', function(){
console.log('image loaded');
msnry.layout(); msnry.layout();
}) })
} }
// after videos are loaded, reset layout // after videos are loaded, reset layout
for (var i = 0; i < trendingVideos.length; i++) { for (var i = 0; i < trendingVideos.length; i++) {
trendingVideos[i].addEventListener('loadeddata', function(){ trendingVideos[i].addEventListener('loadeddata', function(){
console.log('video loaded');
msnry.layout(); msnry.layout();
}) })
} }