Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(api): Add endpoint to allow user to resend confirmation email #543

Merged
merged 3 commits into from
Jul 31, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions api/openapi_server/_spec/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,37 @@ paths:
tags:
- auth
x-openapi-router-controller: openapi_server.controllers.auth_controller
/auth/resend_confirmation_code:
post:
description: Resends the registration confirmation code to the specified user (identified by email).
operationId: resend_confirmation_code
requestBody:
content:
application/json:
schema:
type: object
properties:
email:
type: string
required:
- email
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
'400':
description: The email parameter was not sent or the user with the given email was not found.
'429':
description: Too many requests to resend the registration confirmation code were made to this user.
tags:
- auth
x-openapi-router-controller: openapi_server.controllers.auth_controller
security:
- jwt:
- secret
/auth/confirm:
get:
description: Confirm or deny verification of users email
Expand Down
38 changes: 38 additions & 0 deletions api/openapi_server/controllers/auth_controller.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import connexion
import boto3
import botocore
import hmac
import base64
import requests
Expand Down Expand Up @@ -214,6 +215,43 @@ def signin():
}


def resend_confirmation_code():
'''
Resends the registration confirmation code to the specified user (identified by email).
'''

if connexion.request.is_json:
body = connexion.request.get_json()

if "email" not in body:
raise AuthError({"message": "email invalid"}, 400)

secret_hash = get_secret_hash(body['email'])

try:
email = body['email']
response = userClient.resend_confirmation_code(
ClientId=COGNITO_CLIENT_ID,
SecretHash=secret_hash,
Username=email,
)
return response
except botocore.exceptions.ClientError as error:
match error.response['Error']['Code']:
case 'UserNotFoundException':
msg = "User not found. Confirmation not sent."
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like the more specific breakdown of possible errors. Might be worth doing this with the other routes

raise AuthError({"message": msg}, 400)
case 'TooManyRequestsException':
msg = "Too many attempts to resend confirmation in a short amount of time."
raise AuthError({"message": msg}, 429)
case _:
msg = error.response['Error']['Message']
raise AuthError({"message": msg}, 500)
except botocore.exceptions.ParamValidationError as error:
msg = f"The parameters you provided are incorrect: {error}"
raise AuthError({"message": msg}, 500)


def confirm():
# Validate request data
if connexion.request.is_json:
Expand Down
6 changes: 4 additions & 2 deletions api/openapi_server/openapi/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ paths:
/host:
$ref: "./paths/host.yaml"
/auth/signup/host:
$ref: "./paths/auth/authSignupHost.yaml"
$ref: "./paths/auth/authSignUpHost.yaml"
/auth/signup/coordinator:
$ref: "./paths/auth/authSignupCoordinator.yaml"
$ref: "./paths/auth/authSignUpCoordinator.yaml"
/auth/signin:
$ref: "./paths/auth/authSignin.yaml"
/auth/resend_confirmation_code:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this suppose to be snake or camel case

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @ju1es! Thank you for taking a look. This is a good and important question.

Regarding API endpoint (OpenAPI paths):

I checked again. I see there are both ways being used in this file (e.g. /serviceProviders, /auth/initialInvite, and /auth/forgot_password, /auth/forgot_password/confirm).

  • When I searched for guidance in the OpenAPI documentation, I didn't see any explicit convention written, but I did see they used camelCase (this is called mixed case in Python PEP8) in their examples.
  • I then checked https://restfulapi.net/resource-naming/ which only says to be consistent in whatever convention is used and provides "hints" to use hyphen (-) to separate words, avoid underscores, and use lowercase letters.
  • Then, I checked the connexion documentation and saw they had an example using snake case (/hello_world) (doh!).
  • Finally, I tried searching for preferences from the React side but couldn't find anything.

Do you, @erikguntner, @Joshua-Douglas know if there is a preference on the front end side regarding the API endpoint naming convention?

Regarding OpenAPI operationId:

I tend to use snake case to follow PEP8 function and variable name convention because it's implemented in Python and the auth_controller.py is dominantly snake case.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@paulespinosa Yeah I was using snake case since that's what I saw in the Flask and connexion docs, but I defer to you all with more Python experience for what you wanna do moving forward. Camel case is the standard in Javascript land and always appreciated when getting data back from a db, but the endpoints don't necessarily need to be written in it. Hyphens look fairly clean tho

Copy link
Member

@ju1es ju1es Jul 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so many options! thanks for looking into it so thoroughly @paulespinosa

+1 hyphens for me as well. i don't have a strong preference except that we adhere to one convention for consistency.

$ref: "./paths/auth/authResendConfirmationCode.yaml"
/auth/confirm:
$ref: "./paths/auth/authConfirm.yaml"
/auth/signout:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
post:
description: Resends the registration confirmation code to the specified user (identified by email).
operationId: resend_confirmation_code
requestBody:
content:
application/json:
schema:
type: object
properties:
email:
type: string
required:
- email
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '../../openapi.yaml#/components/schemas/ApiResponse'
'400':
description: The email parameter was not sent or the user with the given email was not found.
'429':
description: Too many requests to resend the registration confirmation code were made to this user.
tags:
- auth
x-openapi-router-controller: openapi_server.controllers.auth_controller
security:
paulespinosa marked this conversation as resolved.
Show resolved Hide resolved
- jwt: ["secret"]