We're working with community non-profits who have a Host Home or empty bedrooms initiative to develop a workflow management tool to make the process scalable (across all providers), reduce institutional bias, and effectively capture data.
This PR allows us to collect the first and last names of users who sign up with Google. While implementing this I found some bugs while working in a "staging" environment using the real AWS user pool. Some fixes are included.
What changes did you make?
Updated the /token endpoint to only add a user to the database if they don't already exist.
Updated the get_user_attr function to get the first and last name from the user object returned from Cognito.
The /confirm route had been changed to a POST request which broke the flow we had in place, so I added back the yaml configuration and handler for the GET request. This is necessary because at the moment users confirm their profiles by clicking a link in an email that takes them to /api/auth/confirm?email=email&code=code which is done as a GET request. From what I've seen we can make this a POST request by using a form tag and hidden fields, but that will require refactors to the current email template. I do think this makes more sense as a POST or PUT so I left the POST implementation and just changed the name to confirm_sign_up_v2.
I also noticed session refresh wasn't working when I was getting this error:
Turns out you have to use the user's username/uuid to create the secret hash when using the "REFRESH_TOKEN" auth flow instead of the email. This problem is outlined in this GitHub issue on the boto3 issues page, and the solution came from this stack overflow issue.
To get that username/uuid I added the IdToken to the session object on sign in and then decoded it in the refresh controller using the pyjwt library.
Updated the /session endpoint to get token instead of the refresh_token property from the call to the refresh function. I noticed the object returned from refresh didn't have a refresh_token property on it. This makes sense since we are refreshing the access token and returning the new one to the user instead of the refresh token.
Updated the /user and /session endpoints to return the full user object.
Rationale behind the changes?
Since we've made the change to requiring the user's first, middle, and last name, we didn't have the functionality in place to do so using google authentication.
Testing done for these changes
I manually went through the sign up and sign in flows multiple times for both google auth and email/password auth using the development and staging environments.
What did you learn or can share that is new?(optional)
Something that still needs to be figured out is how to differentiate between signing in with Google and signing up with Google. Right now if a user sign's in with Google from our sign in page, and that user doesn't exist in AWS, a user will be created. That is an issue for us since we can't assign a user role to them. One solution I am looking into is using a pre-sign up lambda function to check if a user with that Google account already exists, and if not, throwing an error. Open to suggestions on this.
Screenshots of Proposed Changes Of The Website (if any, please do not screen shot code changes)
Visuals before changes are applied
![image](Paste_Your_Image_Link_Here_After_Attaching_Files)
Visuals after changes are applied
![image](Paste_Your_Image_Link_Here_After_Attaching_Files)
Closes #680
This PR allows us to collect the first and last names of users who sign up with Google. While implementing this I found some bugs while working in a "staging" environment using the real AWS user pool. Some fixes are included.
What changes did you make?
/token
endpoint to only add a user to the database if they don't already exist.get_user_attr
function to get the first and last name from the user object returned from Cognito./confirm
route had been changed to a POST request which broke the flow we had in place, so I added back the yaml configuration and handler for the GET request. This is necessary because at the moment users confirm their profiles by clicking a link in an email that takes them to/api/auth/confirm?email=email&code=code
which is done as a GET request. From what I've seen we can make this a POST request by using a form tag and hidden fields, but that will require refactors to the current email template. I do think this makes more sense as a POST or PUT so I left the POST implementation and just changed the name toconfirm_sign_up_v2
.Turns out you have to use the user's username/uuid to create the secret hash when using the "REFRESH_TOKEN" auth flow instead of the email. This problem is outlined in this GitHub issue on the boto3 issues page, and the solution came from this stack overflow issue.
IdToken
to the session object on sign in and then decoded it in therefresh
controller using thepyjwt
library./session
endpoint to gettoken
instead of therefresh_token
property from the call to the refresh function. I noticed the object returned from refresh didn't have arefresh_token
property on it. This makes sense since we are refreshing the access token and returning the new one to the user instead of the refresh token./user
and/session
endpoints to return the full user object.Rationale behind the changes?
Testing done for these changes
What did you learn or can share that is new?(optional)
Screenshots of Proposed Changes Of The Website (if any, please do not screen shot code changes)
Visuals before changes are applied
![image](Paste_Your_Image_Link_Here_After_Attaching_Files)Visuals after changes are applied
![image](Paste_Your_Image_Link_Here_After_Attaching_Files)