From bb4123a34934e76203d45d75ac3c4d928ff31189 Mon Sep 17 00:00:00 2001 From: Grey Li Date: Tue, 17 Sep 2024 16:09:27 +0800 Subject: [PATCH 01/12] Update Flask-Mail version --- pdm.lock | 10 ++++++---- requirements.txt | 22 +++++++++++++++++++--- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/pdm.lock b/pdm.lock index b0b3eb1..fd33524 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,7 +5,7 @@ groups = ["default", "dev", "test"] strategy = ["cross_platform"] lock_version = "4.4.1" -content_hash = "sha256:9b57f5731de651ff102a0281c852de6a90dce75d4cb109b9f94c21e5820ede7f" +content_hash = "sha256:5a42527a683460ebd49d450fb587270a6b0024513577b89f1e4dde34643e4fe2" [[package]] name = "attrs" @@ -253,14 +253,16 @@ files = [ [[package]] name = "flask-mail" -version = "0.9.1" +version = "0.10.0" +requires_python = ">=3.8" summary = "Flask extension for sending email" dependencies = [ - "Flask", "blinker", + "flask", ] files = [ - {file = "Flask-Mail-0.9.1.tar.gz", hash = "sha256:22e5eb9a940bf407bcf30410ecc3708f3c56cc44b29c34e1726fe85006935f41"}, + {file = "flask_mail-0.10.0-py3-none-any.whl", hash = "sha256:a451e490931bb3441d9b11ebab6812a16bfa81855792ae1bf9c1e1e22c4e51e7"}, + {file = "flask_mail-0.10.0.tar.gz", hash = "sha256:44083e7b02bbcce792209c06252f8569dd5a325a7aaa76afe7330422bd97881d"}, ] [[package]] diff --git a/requirements.txt b/requirements.txt index d082ad2..98b5737 100644 --- a/requirements.txt +++ b/requirements.txt @@ -53,7 +53,7 @@ cfgv==3.4.0 \ click==8.1.7 \ --hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \ --hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de -colorama==0.4.6; platform_system == "Windows" \ +colorama==0.4.6; sys_platform == "win32" or platform_system == "Windows" \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 distlib==0.3.8 \ @@ -86,8 +86,9 @@ flask-dropzone==2.0.0 \ flask-login==0.6.3 \ --hash=sha256:5e23d14a607ef12806c699590b89d0f0e0d67baeec599d75947bf9c147330333 \ --hash=sha256:849b25b82a436bf830a054e74214074af59097171562ab10bfa999e6b78aae5d -flask-mail==0.9.1 \ - --hash=sha256:22e5eb9a940bf407bcf30410ecc3708f3c56cc44b29c34e1726fe85006935f41 +flask-mail==0.10.0 \ + --hash=sha256:44083e7b02bbcce792209c06252f8569dd5a325a7aaa76afe7330422bd97881d \ + --hash=sha256:a451e490931bb3441d9b11ebab6812a16bfa81855792ae1bf9c1e1e22c4e51e7 flask-sqlalchemy==3.1.1 \ --hash=sha256:4ba4be7f419dc72f4efd8802d69974803c37259dd42f3913b0dcf75c9447e0a0 \ --hash=sha256:e4b68bb881802dda1a7d878b2fc84c06d1ee57fb40b874d3dc97dabfa36b8312 @@ -138,6 +139,9 @@ idna==3.6 \ importlib-metadata==8.0.0; python_version < "3.10" \ --hash=sha256:15584cf2b1bf449d98ff8a6ff1abef57bf20f3ac6454f431736cd3e660921b2f \ --hash=sha256:188bd24e4c346d3f0a933f275c2fec67050326a856b9a359881d7c2a697e8812 +iniconfig==2.0.0 \ + --hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \ + --hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374 itsdangerous==2.1.2 \ --hash=sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44 \ --hash=sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a @@ -182,6 +186,9 @@ nodeenv==1.9.1 \ outcome==1.3.0.post0 \ --hash=sha256:9dcf02e65f2971b80047b377468e72a268e15c0af3cf1238e6ff14f7f91143b8 \ --hash=sha256:e771c5ce06d1415e356078d3bdd68523f284b4ce5419828922b6871e65eda82b +packaging==23.2 \ + --hash=sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5 \ + --hash=sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7 pillow==10.2.0 \ --hash=sha256:0eae2073305f451d8ecacb5474997c08569fb4eb4ac231ffa4ad7d342fdc25ac \ --hash=sha256:11fa2e5984b949b0dd6d7a94d967743d87c577ff0b83392f17cb3990d0d2fd6e \ @@ -233,6 +240,9 @@ pillow==10.2.0 \ platformdirs==4.2.2 \ --hash=sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee \ --hash=sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3 +pluggy==1.4.0 \ + --hash=sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981 \ + --hash=sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be pre-commit==3.5.0 \ --hash=sha256:5804465c675b659b0862f07907f96295d490822a450c4c40e747d0b1c6ebcb32 \ --hash=sha256:841dc9aef25daba9a0238cd27984041fa0467b4199fc4852e27950664919f660 @@ -245,6 +255,9 @@ pyjwt==2.8.0 \ pysocks==1.7.1 \ --hash=sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5 \ --hash=sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0 +pytest==8.1.1 \ + --hash=sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7 \ + --hash=sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044 python-dateutil==2.8.2 \ --hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \ --hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9 @@ -348,6 +361,9 @@ sqlalchemy==2.0.27 \ --hash=sha256:eb15ef40b833f5b2f19eeae65d65e191f039e71790dd565c2af2a3783f72262f \ --hash=sha256:f9374e270e2553653d710ece397df67db9d19c60d2647bcd35bfc616f1622dcd \ --hash=sha256:fa67d821c1fd268a5a87922ef4940442513b4e6c377553506b9db3b83beebbd8 +tomli==2.0.1; python_version < "3.11" \ + --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \ + --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f trio==0.25.0 \ --hash=sha256:9b41f5993ad2c0e5f62d0acca320ec657fdb6b2a2c22b8c7aed6caf154475c4e \ --hash=sha256:e6458efe29cc543e557a91e614e2b51710eba2961669329ce9c862d50c6e8e81 From 6be2f4f0bf1ef05374a6a31ebdd1f3636f5ca131 Mon Sep 17 00:00:00 2001 From: Grey Li Date: Tue, 17 Sep 2024 16:09:34 +0800 Subject: [PATCH 02/12] Add env example --- .env.example | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..2351de1 --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +DATABASE_URL=sqlite:////home/moments/database/data.db +MAIL_SERVER=smtp.example.com +MAIL_USERNAME=example +MAIL_PASSWORD=example-password From e610b592ff30725e8cb3eb256cf82534ad01c569 Mon Sep 17 00:00:00 2001 From: Grey Li Date: Tue, 17 Sep 2024 16:10:38 +0800 Subject: [PATCH 03/12] Validate URL in profile form --- moments/forms/user.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/moments/forms/user.py b/moments/forms/user.py index e8a4de2..31cdd28 100644 --- a/moments/forms/user.py +++ b/moments/forms/user.py @@ -3,7 +3,7 @@ from flask_wtf.file import FileAllowed, FileField, FileRequired from sqlalchemy import select from wtforms import BooleanField, HiddenField, PasswordField, StringField, SubmitField, TextAreaField, ValidationError -from wtforms.validators import DataRequired, Email, EqualTo, Length, Optional, Regexp +from wtforms.validators import DataRequired, URL, Email, EqualTo, Length, Optional, Regexp from moments.core.extensions import db from moments.models import User @@ -19,7 +19,7 @@ class EditProfileForm(FlaskForm): Regexp('^[a-zA-Z0-9]*$', message='The username should contain only a-z, A-Z and 0-9.'), ], ) - website = StringField('Website', validators=[Optional(), Length(0, 255)]) + website = StringField('Website', validators=[URL(), Optional(), Length(0, 255)]) location = StringField('City', validators=[Optional(), Length(0, 50)]) bio = TextAreaField('Bio', validators=[Optional(), Length(0, 120)]) submit = SubmitField() From 8d10e178b25a1fbf177751801fcd59242d886e90 Mon Sep 17 00:00:00 2001 From: Grey Li Date: Tue, 17 Sep 2024 16:11:01 +0800 Subject: [PATCH 04/12] Improve error handling --- moments/core/errors.py | 25 +++++++++++++------------ moments/templates/errors/403.html | 2 +- moments/templates/errors/404.html | 2 +- moments/templates/errors/413.html | 2 +- moments/templates/errors/500.html | 2 +- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/moments/core/errors.py b/moments/core/errors.py index 5fc1f06..56eb5eb 100644 --- a/moments/core/errors.py +++ b/moments/core/errors.py @@ -4,25 +4,26 @@ def register_error_handlers(app): @app.errorhandler(400) - def bad_request(e): - return render_template('errors/400.html'), 400 + def bad_request(error): + return render_template('errors/400.html', description=error.description), 400 @app.errorhandler(403) - def forbidden(e): - return render_template('errors/403.html'), 403 + def forbidden(error): + return render_template('errors/403.html', description=error.description), 403 @app.errorhandler(404) - def page_not_found(e): - return render_template('errors/404.html'), 404 + def page_not_found(error): + return render_template('errors/404.html', description=error.description), 404 @app.errorhandler(413) - def request_entity_too_large(e): - return render_template('errors/413.html'), 413 + def request_entity_too_large(error): + return render_template('errors/413.html', description=error.description), 413 @app.errorhandler(500) - def internal_server_error(e): - return render_template('errors/500.html'), 500 + def internal_server_error(error): + return render_template('errors/500.html', description=error.description), 500 @app.errorhandler(CSRFError) - def handle_csrf_error(e): - return render_template('errors/400.html', description=e.description), 500 + def handle_csrf_error(error): + description = 'Session expired, return last page and try again.' + return render_template('errors/400.html', description=description), 500 diff --git a/moments/templates/errors/403.html b/moments/templates/errors/403.html index 0b188e5..f1776da 100644 --- a/moments/templates/errors/403.html +++ b/moments/templates/errors/403.html @@ -8,7 +8,7 @@
403 Error
-

Forbidden

+

{{ description|default('Forbidden') }}