Make uploading over ajax, and ajax flash messages, work

This commit is contained in:
Micah Lee 2019-02-15 14:52:00 -08:00
parent a22d21c222
commit e2c4ec1f6f
No known key found for this signature in database
GPG Key ID: 403C2657CD994F73
4 changed files with 84 additions and 38 deletions

View File

@ -1,5 +1,6 @@
import os import os
import tempfile import tempfile
import json
from datetime import datetime from datetime import datetime
from flask import Request, request, render_template, make_response, flash, redirect from flask import Request, request, render_template, make_response, flash, redirect
from werkzeug.utils import secure_filename from werkzeug.utils import secure_filename
@ -150,6 +151,21 @@ class ReceiveModeWeb(object):
return self.web.error404() return self.web.error404()
return upload_logic() return upload_logic()
@self.web.app.route("/<slug_candidate>/upload-ajax", methods=['POST'])
def upload_ajax(slug_candidate):
if not self.can_upload:
return self.web.error403()
self.web.check_slug_candidate(slug_candidate)
return upload_logic(slug_candidate, ajax=True)
@self.web.app.route("/upload-ajax", methods=['POST'])
def upload_ajax_public():
if not self.can_upload:
return self.web.error403()
if not self.common.settings.get('public_mode'):
return self.web.error404()
return upload_logic(ajax=True)
class ReceiveModeWSGIMiddleware(object): class ReceiveModeWSGIMiddleware(object):
""" """
@ -251,12 +267,12 @@ class ReceiveModeRequest(Request):
# Is this a valid upload request? # Is this a valid upload request?
self.upload_request = False self.upload_request = False
if self.method == 'POST': if self.method == 'POST':
if self.path == '/{}/upload'.format(self.web.slug): if self.web.common.settings.get('public_mode'):
self.upload_request = True if self.path == '/upload' or self.path == '/upload-ajax':
self.upload_request = True
else: else:
if self.web.common.settings.get('public_mode'): if self.path == '/{}/upload'.format(self.web.slug) or self.path == '/{}/upload-ajax'.format(self.web.slug):
if self.path == '/upload': self.upload_request = True
self.upload_request = True
if self.upload_request: if self.upload_request:
# No errors yet # No errors yet

View File

@ -139,30 +139,22 @@ ul.flashes {
} }
ul.flashes li { ul.flashes li {
margin: 0; margin: 0 0 5px 0;
padding: 10px; padding: 10px;
list-style: none;
border: 0;
border-radius: 3px;
text-align: left;
} }
li.error { li.error {
list-style: none;
margin: 0;
padding: 0;
color: #ffffff; color: #ffffff;
background-color: #c90c0c; background-color: #c90c0c;
border: 0;
border-radius: 5px;
text-align: left;
} }
li.info { li.info {
list-style: none;
margin: 0;
padding: 0;
color: #000000; color: #000000;
background-color: #a9e26c; background-color: #a9e26c;
border: 0;
border-radius: 5px;
text-align: left;
} }
.closed-wrapper { .closed-wrapper {

View File

@ -4,6 +4,15 @@ document.getElementById('noscript').style.display = 'none';
var form = document.getElementById('send'); var form = document.getElementById('send');
var fileSelect = document.getElementById('file-select'); var fileSelect = document.getElementById('file-select');
var uploadButton = document.getElementById('send-button'); var uploadButton = document.getElementById('send-button');
var flashes = document.getElementById('flashes');
// Add a flash message
function flash(category, message) {
var el = document.createElement('li');
el.innerText = message;
el.className = category;
flashes.appendChild(el);
}
form.onsubmit = function(event) { form.onsubmit = function(event) {
event.preventDefault(); event.preventDefault();
@ -30,9 +39,37 @@ form.onsubmit = function(event) {
uploadButton.innerHTML = 'Uploading '+percent+'%'; uploadButton.innerHTML = 'Uploading '+percent+'%';
}, false); }, false);
ajax.addEventListener("load", function(event){ ajax.addEventListener('load', function(event){
console.log("upload finished"); console.log('upload finished', ajax.response);
if(ajax.status == 200) { if(ajax.status == 200) {
// Parse response
try {
var response = JSON.parse(ajax.response);
// The 'new_body' response replaces the whole HTML document and ends
if('new_body' in response) {
document.body.innerHTML = response['new_body'];
return;
}
// Show error flashes
if('error_flashes' in response) {
for(var i=0; i<response['error_flashes'].length; i++) {
flash('error', response['error_flashes'][i]);
}
}
// Show info flashes
if('info_flashes' in response) {
for(var i=0; i<response['info_flashes'].length; i++) {
flash('info', response['info_flashes'][i]);
}
}
} catch(e) {
console.log('invalid response', ajax.response);
flash('error', 'Invalid response from server: '+ajax.response);
}
// Re-enable button, and update text // Re-enable button, and update text
uploadButton.innerHTML = 'Send Files'; uploadButton.innerHTML = 'Send Files';
uploadButton.disabled = false; uploadButton.disabled = false;
@ -40,16 +77,18 @@ form.onsubmit = function(event) {
} }
}, false); }, false);
ajax.addEventListener("error", function(event){ ajax.addEventListener('error', function(event){
console.log('error', event); console.log('error', event);
flash('error', 'Error uploading');
}, false); }, false);
ajax.addEventListener("abort", function(event){ ajax.addEventListener('abort', function(event){
console.log('abort', event); console.log('abort', event);
flash('error', 'Upload aborted');
}, false); }, false);
// Send the request // Send the request
ajax.open('POST', window.location.pathname + '/upload', true); ajax.open('POST', window.location.pathname + '/upload-ajax', true);
ajax.send(formData); ajax.send(formData);
console.log("upload started"); console.log('upload started');
} }

View File

@ -21,23 +21,21 @@
<p><input type="file" id="file-select" name="file[]" multiple /></p> <p><input type="file" id="file-select" name="file[]" multiple /></p>
<p><button type="submit" id="send-button" class="button">Send Files</button></p> <p><button type="submit" id="send-button" class="button">Send Files</button></p>
<div> <div>
{% with messages = get_flashed_messages(with_categories=true) %} <ul id="flashes" class="flashes">
{% if messages %} {% with messages = get_flashed_messages(with_categories=true) %}
<ul class=flashes> {% if messages %}
{% for category, message in messages %} {% for category, message in messages %}
<li class="{{ category }}">{{ message }}</li> <li class="{{ category }}">{{ message }}</li>
{% endfor %} {% endfor %}
</ul> {% endif %}
{% endif %} {% endwith %}
{% endwith %} </ul>
</div> </div>
</form> </form>
<!-- We are not using a <noscript> tag because it only works when the security slider <!--
is set to Safest, not Safer. We are not using a <noscript> tag because it only works when the security slider is set to
Safest, not Safer: https://trac.torproject.org/projects/tor/ticket/29506
For more information about the upload issue:
https://github.com/micahflee/onionshare/issues/899
--> -->
<div id="noscript"> <div id="noscript">
<p> <p>
@ -47,6 +45,7 @@
to Standard or to Standard or
<a target="_blank" href="/noscript-xss-instructions">turn off your Tor Browser's NoScript XSS setting</a>.</p> <a target="_blank" href="/noscript-xss-instructions">turn off your Tor Browser's NoScript XSS setting</a>.</p>
</div> </div>
</div> </div>
</div> </div>
<script src="/static/js/receive.js"></script> <script src="/static/js/receive.js"></script>