From 5bdbe9b85035a4d8f758a2fc0e2ed3df63f86254 Mon Sep 17 00:00:00 2001 From: Marty Bode Date: Wed, 20 Mar 2024 16:55:01 -0400 Subject: [PATCH 1/6] add reset token validation --- app.py | 6 ++++++ regular_api_checks.py | 17 ++++++++++++++++ resources/RequestResetPassword.py | 2 +- resources/ResetPassword.py | 3 +-- resources/ResetTokenValidation.py | 33 +++++++++++++++++++++++++++++++ 5 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 resources/ResetTokenValidation.py diff --git a/app.py b/app.py index d62a6c44..dd52009b 100644 --- a/app.py +++ b/app.py @@ -7,6 +7,7 @@ from resources.ApiKey import ApiKey from resources.RequestResetPassword import RequestResetPassword from resources.ResetPassword import ResetPassword +from resources.ResetTokenValidation import ResetTokenValidation from resources.QuickSearch import QuickSearch from resources.DataSources import ( DataSources, @@ -50,6 +51,11 @@ "/reset-password", resource_class_kwargs={"psycopg2_connection": psycopg2_connection}, ) +api.add_resource( + ResetTokenValidation, + "/reset-token-validation", + resource_class_kwargs={"psycopg2_connection": psycopg2_connection}, +) api.add_resource( QuickSearch, "/quick-search//", diff --git a/regular_api_checks.py b/regular_api_checks.py index 6f28cee2..5d74ca40 100644 --- a/regular_api_checks.py +++ b/regular_api_checks.py @@ -200,6 +200,23 @@ def test_request_reset_password(): return response.json()["message"] == "Successfully updated password" +def test_reset_token_validation(): + reset_token = requests.post( + f"{BASE_URL}/request-reset-password", + headers=HEADERS, + json={"email": "test2"}, + ) + + response = requests.post( + f"{BASE_URL}/reset-token-validation", + headers=HEADERS, + json={"token": reset_token.json()["token"], "password": "test"}, + ) + + return response.json()["message"] == "Token is valid" + + + # api-key def test_get_api_key(): response = requests.get( diff --git a/resources/RequestResetPassword.py b/resources/RequestResetPassword.py index d411a5de..8dbd50d7 100644 --- a/resources/RequestResetPassword.py +++ b/resources/RequestResetPassword.py @@ -36,7 +36,7 @@ def post(self): ) return { - "message": "An email has been sent to your email address with a link to reset your password.", + "message": "An email has been sent to your email address with a link to reset your password. It will be valid for 15 minutes.", "token": token, } diff --git a/resources/ResetPassword.py b/resources/ResetPassword.py index 28d6623a..88e6657d 100644 --- a/resources/ResetPassword.py +++ b/resources/ResetPassword.py @@ -3,7 +3,6 @@ from flask import request from middleware.reset_token_queries import ( check_reset_token, - add_reset_token, delete_reset_token, ) from datetime import datetime as dt @@ -25,7 +24,7 @@ def post(self): return {"message": "The submitted token is invalid"}, 400 token_create_date = token_data["create_date"] - token_expired = (dt.utcnow() - token_create_date).total_seconds() > 300 + token_expired = (dt.utcnow() - token_create_date).total_seconds() > 900 delete_reset_token(cursor, token_data["email"], token) if token_expired: return {"message": "The submitted token is invalid"}, 400 diff --git a/resources/ResetTokenValidation.py b/resources/ResetTokenValidation.py new file mode 100644 index 00000000..50e3ea91 --- /dev/null +++ b/resources/ResetTokenValidation.py @@ -0,0 +1,33 @@ +from flask_restful import Resource +from flask import request +from middleware.reset_token_queries import ( + check_reset_token, +) +from datetime import datetime as dt + + +class ResetTokenValidation(Resource): + def __init__(self, **kwargs): + self.psycopg2_connection = kwargs["psycopg2_connection"] + + def post(self): + try: + data = request.get_json() + token = data.get("token") + cursor = self.psycopg2_connection.cursor() + token_data = check_reset_token(cursor, token) + if "create_date" not in token_data: + return {"message": "The submitted token is invalid"}, 400 + + token_create_date = token_data["create_date"] + token_expired = (dt.utcnow() - token_create_date).total_seconds() > 900 + + if token_expired: + return {"message": "The submitted token is invalid"}, 400 + + return {"message": "Token is valid"} + + except Exception as e: + self.psycopg2_connection.rollback() + print(str(e)) + return {"message": str(e)}, 500 From 158c9f9280bc6e5f5f4063eb59b65f6564814f5c Mon Sep 17 00:00:00 2001 From: Marty Bode Date: Wed, 20 Mar 2024 17:02:43 -0400 Subject: [PATCH 2/6] formatting --- regular_api_checks.py | 1 - 1 file changed, 1 deletion(-) diff --git a/regular_api_checks.py b/regular_api_checks.py index 5d74ca40..1c32eee2 100644 --- a/regular_api_checks.py +++ b/regular_api_checks.py @@ -216,7 +216,6 @@ def test_reset_token_validation(): return response.json()["message"] == "Token is valid" - # api-key def test_get_api_key(): response = requests.get( From c519c55a4ce91adcf23230ad56be91194bd4b07d Mon Sep 17 00:00:00 2001 From: Marty Bode Date: Wed, 20 Mar 2024 17:07:17 -0400 Subject: [PATCH 3/6] merge fix --- client/src/pages/SearchResultPage.vue | 36 ++++++++++++++------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/client/src/pages/SearchResultPage.vue b/client/src/pages/SearchResultPage.vue index 004929e5..2eca36e7 100644 --- a/client/src/pages/SearchResultPage.vue +++ b/client/src/pages/SearchResultPage.vue @@ -42,15 +42,18 @@
-
-

+ {{ section.header }} -

+ + + + From 4eeb994d0a4fb7cc45ddc6884ae621065cb83302 Mon Sep 17 00:00:00 2001 From: Joshua Graber Date: Thu, 21 Mar 2024 11:24:43 -0400 Subject: [PATCH 4/6] refactor(pages): ResetPassword Check token validity on page load --- client/src/pages/ResetPassword.vue | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/client/src/pages/ResetPassword.vue b/client/src/pages/ResetPassword.vue index 5ff65daf..83094266 100644 --- a/client/src/pages/ResetPassword.vue +++ b/client/src/pages/ResetPassword.vue @@ -15,8 +15,11 @@ class="pdap-flex-container mx-auto max-w-2xl" >

Change your password

+

+ Loading... +

@@ -72,7 +75,7 @@