Compare commits
No commits in common. "e2465e2874089561df2b8683ab0d5de412a65a5a" and "967b4bf4f55004b0e6c57bec8f0e02b26e2087f7" have entirely different histories.
e2465e2874
...
967b4bf4f5
@ -74,14 +74,6 @@ function jeanCloudContactFormIntercept (formId, notifier) {
|
|||||||
loadingText.classList.add("contact-mailer-sending");
|
loadingText.classList.add("contact-mailer-sending");
|
||||||
loadingText.textContent = 'Envoi en cours…'
|
loadingText.textContent = 'Envoi en cours…'
|
||||||
submitButton.after(loadingText)
|
submitButton.after(loadingText)
|
||||||
|
|
||||||
/* Add the filling timer in seconds */
|
|
||||||
const timerField = document.createElement('input')
|
|
||||||
timerField.value = Math.round((Date.now() - contactMailerPageLoadedTime) / 1000)
|
|
||||||
timerField.name = 'timerfield'
|
|
||||||
timerField.hidden = 'hidden'
|
|
||||||
formElem.appendChild(timerField)
|
|
||||||
|
|
||||||
/* XHR */
|
/* XHR */
|
||||||
fetch(formElem.action, {
|
fetch(formElem.action, {
|
||||||
method: formElem.method,
|
method: formElem.method,
|
||||||
@ -106,9 +98,6 @@ function jeanCloudContactFormIntercept (formId, notifier) {
|
|||||||
loadingText.parentNode.removeChild(loadingText)
|
loadingText.parentNode.removeChild(loadingText)
|
||||||
notifier.error('Impossible d’envoyer le formulaire. Vérifiez votre connexion internet ou réessayez plus tard.')
|
notifier.error('Impossible d’envoyer le formulaire. Vérifiez votre connexion internet ou réessayez plus tard.')
|
||||||
})
|
})
|
||||||
|
|
||||||
/* Remove timer field after xhr. So we can try again. */
|
|
||||||
formElem.removeChild(timerField)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,5 +115,3 @@ function jeanCloudContactFormIntercept (formId, notifier) {
|
|||||||
// cat style.css | openssl dgst -sha384 -binary | openssl base64 -A
|
// cat style.css | openssl dgst -sha384 -binary | openssl base64 -A
|
||||||
document.head.appendChild(link);
|
document.head.appendChild(link);
|
||||||
})()
|
})()
|
||||||
|
|
||||||
var contactMailerPageLoadedTime = Date.now()
|
|
||||||
|
41
main.py
41
main.py
@ -46,6 +46,7 @@ class EnableCors(object):
|
|||||||
return _enable_cors
|
return _enable_cors
|
||||||
|
|
||||||
app = application = bottle.Bottle(catchall=False)
|
app = application = bottle.Bottle(catchall=False)
|
||||||
|
#app.install(EnableCors())
|
||||||
|
|
||||||
##################################################### Configuration ############################################
|
##################################################### Configuration ############################################
|
||||||
|
|
||||||
@ -133,24 +134,16 @@ def submission ():
|
|||||||
response.status = 500
|
response.status = 500
|
||||||
return resp('error', 'La base de donnée n’est pas accessible.')
|
return resp('error', 'La base de donnée n’est pas accessible.')
|
||||||
|
|
||||||
# Did the bot filled the honeypot field?
|
|
||||||
if 'honeypotfield' in form and form['honeypotfield'] in request.forms and request.forms.get(form['honeypotfield']) != '':
|
|
||||||
response.status = 400
|
|
||||||
print('honeypotfield')
|
|
||||||
return resp('error', 'We identified you as a bot. If this is an error, try to contact us via another way.')
|
|
||||||
# Is the js timer enabled?
|
|
||||||
if 'timerdelay' in form:
|
|
||||||
# Did it work?
|
|
||||||
if 'timerfield' not in request.forms or int(request.forms.get('timerfield')) < int(form['timerdelay']):
|
|
||||||
print('timer : {}/{}'.format(request.forms.get('timerfield'), form['timerdelay']))
|
|
||||||
response.status = 400
|
|
||||||
return resp('error', 'We identified you as a bot. If this is an error, try to contact us via another way.')
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
subject_fields = fill_fields(request, get_fields(form['subject']))
|
subject_fields = fill_fields(request, get_fields(form['subject']))
|
||||||
content_fields = fill_fields(request, get_fields(form['content']))
|
content_fields = fill_fields(request, get_fields(form['content']))
|
||||||
except MissingParameterException as e:
|
# Did the bot filled the honeypot field?
|
||||||
|
if 'honeypotfield' in form and form['honeypotfield'] in request.forms and request.forms.get(form['honeypotfield']) != '':
|
||||||
response.status = 400
|
response.status = 400
|
||||||
|
return resp('error', 'We identified you as a bot. If this is an error, try to contact us via another way.')
|
||||||
|
|
||||||
|
except MissingParameterException as e:
|
||||||
|
response.status = 404
|
||||||
return resp('error', str(e))
|
return resp('error', str(e))
|
||||||
|
|
||||||
subject = re.sub(form_regex, r'{\1}', form['subject']).format(**subject_fields)
|
subject = re.sub(form_regex, r'{\1}', form['subject']).format(**subject_fields)
|
||||||
@ -191,13 +184,9 @@ def fill_fields(request, fields):
|
|||||||
"""Look for fields in request and fill fields dict with values or let default ones. If the value is required, throw exception."""
|
"""Look for fields in request and fill fields dict with values or let default ones. If the value is required, throw exception."""
|
||||||
for field in fields:
|
for field in fields:
|
||||||
if field in request.forms:
|
if field in request.forms:
|
||||||
if request.forms.get(field).strip() == '' and fields[field] is None: # If empty and mandatory
|
|
||||||
raise MissingParameterException("Le champs {} doit être rempli".format(field))
|
|
||||||
fields[field] = request.forms.getunicode(field)
|
fields[field] = request.forms.getunicode(field)
|
||||||
if fields[field] is None: # if unicode failed
|
if fields[field] is None: # if unicode failed
|
||||||
fields[field] = request.forms.get(field)
|
fields[field] = request.forms.get(field)
|
||||||
if fields[field] is None: # if get failed too
|
|
||||||
raise Exception("Error, field '{}' not gettable".format(field))
|
|
||||||
elif fields[field] is None:
|
elif fields[field] is None:
|
||||||
raise MissingParameterException("Le champs {} est obligatoire".format(field))
|
raise MissingParameterException("Le champs {} est obligatoire".format(field))
|
||||||
return fields
|
return fields
|
||||||
@ -275,6 +264,10 @@ def create_form ():
|
|||||||
response.status = 400
|
response.status = 400
|
||||||
return resp('error', 'Le champs « contenu » est requis')
|
return resp('error', 'Le champs « contenu » est requis')
|
||||||
|
|
||||||
|
if 'honeypotfield' in request.forms:
|
||||||
|
honeypotfield = request.forms.getunicode('honeypotfield')
|
||||||
|
else:
|
||||||
|
honeypotfield = None
|
||||||
|
|
||||||
# Getting from address
|
# Getting from address
|
||||||
if 'mail' in request.forms:
|
if 'mail' in request.forms:
|
||||||
@ -291,19 +284,14 @@ def create_form ():
|
|||||||
# TODO limit the insertion rate
|
# TODO limit the insertion rate
|
||||||
token = ''.join(random.sample(token_chars, token_len))
|
token = ''.join(random.sample(token_chars, token_len))
|
||||||
try:
|
try:
|
||||||
newEntry = {
|
inserted = mongodb_database['forms'].insert_one({
|
||||||
'mail': mail,
|
'mail': mail,
|
||||||
'content': content,
|
'content': content,
|
||||||
'subject': subject,
|
'subject': subject,
|
||||||
'user_id': user['_id'],
|
'user_id': user['_id'],
|
||||||
'token': token,
|
'token': token,
|
||||||
}
|
'honeypotfield': honeypotfield,
|
||||||
if 'honeypotfield' in request.forms:
|
})
|
||||||
newEntry['honeypotfield'] = request.forms.getunicode('honeypotfield')
|
|
||||||
if 'timerdelay' in request.forms:
|
|
||||||
newEntry['timerdelay'] = request.forms.getunicode('timerdelay')
|
|
||||||
|
|
||||||
inserted = mongodb_database['forms'].insert_one(newEntry)
|
|
||||||
except pymongo.errors.ServerSelectionTimeoutError as e:
|
except pymongo.errors.ServerSelectionTimeoutError as e:
|
||||||
response.status = 500
|
response.status = 500
|
||||||
return resp('error', 'La base de donnée n’est pas accessible')
|
return resp('error', 'La base de donnée n’est pas accessible')
|
||||||
@ -423,7 +411,6 @@ def delete_user (username):
|
|||||||
|
|
||||||
##################################################### app startup ############################################
|
##################################################### app startup ############################################
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.install(EnableCors())
|
|
||||||
bottle.run(app=StripPathMiddleware(app), host=listen_address, port=listen_port, debug=True)
|
bottle.run(app=StripPathMiddleware(app), host=listen_address, port=listen_port, debug=True)
|
||||||
else:
|
else:
|
||||||
prod_app = StripPathMiddleware(app)
|
prod_app = StripPathMiddleware(app)
|
||||||
|
@ -7,8 +7,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<div id="contact-mailer-message"></div>
|
<div id="contact-mailer-message"></div>
|
||||||
<form action="http://localhost:8080/submit" method="POST" id="contact-mailer-form">
|
<form action="http://localhost:8080/submit" method="POST" id="contact-mailer-form">
|
||||||
<noscript>Les protections anti-spam, nécéssitent l’utilisation de javascript. Rien d’intrusif normalement.</noscript>
|
<input type="hidden" name="token" value="sYMXDz5UKuRF38LbQl20ikrmp7nhHcxTCgGZodqAaBtSvPOV4f" />
|
||||||
<input type="hidden" name="token" value="PK8gQHDx9VoJ7yuEhbj5iCZkcUOAqTYlRSN14XFtdfr3LBs0zn" />
|
|
||||||
<div>
|
<div>
|
||||||
<label for="nom">Votre nom :</label>
|
<label for="nom">Votre nom :</label>
|
||||||
<input type="text" name="nom" required="required"/>
|
<input type="text" name="nom" required="required"/>
|
||||||
|
Loading…
Reference in New Issue
Block a user