Closed gregorylegarec closed 7 years ago
What do you mean by "authenticate user as soon as his password is recorded"? Did you expect to have the login page just after the password saving in order to authenticate the user? If yes, I don't have this behaviour on my own so maybe I did something wrong...
If not, actually the password step currently redirect to the next step (Infos/Accounts) without asking user authentication, but I suggest that should redirect to login?next=/register
after password saving. That will automatically require authentication before continue to the next onboarding steps.
To handle this way, we need some changes but here are my suggestions that I tested and which seem to work in my environment: These changes is maybe out of the scope here but will also complete your todo point.
First, we need an helper to know if the user "authenticatable":
server/models/user.coffee
# Returns true if the user data contains enough informations fotr cozy authentication
User.isAuthenticatable = (userData) ->
if not userData?.onboardedSteps or userData.onboardedSteps.length < 3
return false
hasCompletedWelcome = userData.onboardedSteps[0] is 'welcome'
hasCompletedAgreement = userData.onboardedSteps[1] is 'agreement'
hasCompletedPassword = userData.onboardedSteps[2] is 'password'
hasCompletedFirstThreeSteps = hasCompletedWelcome and \
hasCompletedAgreement and hasCompletedPassword
hasPassword = userData and userData.password and userData.salt
return hasCompletedFirstThreeSteps and hasPassword
Then, if the user is authenticatable, we have to ask the authentication before continue the register steps by using the next
argument of the login feature in the onboarding function. This next
argument is used to specify the next redirection after the authentication:
server/controllers/authentication.coffee At Line 44
# If authenticatable but not registered yet
# -> need authentication to continue next registration steps
if not req.isAuthenticated() and \
User.isAuthenticatable(userData) and \
not User.isRegistered(userData)
res.redirect '/login?next=/register'
# if already registered -> login to cozy home
else if User.isRegistered userData
res.redirect '/login'
# access onboarding, here the user is not register and:
# - either he is authenticatable and will be authenticated
# - either he is not authenticatable (first three steps)
else
if userData
...
And we have to redirect the login (if the user is authenticatable but not registered) with the correct next
argument if it's not already the case:
server/controllers/authentication.coffee At Line 187
if not User.isRegistered(userData)
if not User.isAuthenticatable(userData)
return res.redirect '/register'
# avoid looping between register and login redirection
else if req.url isnt '/login?next=/register'
return res.redirect '/login?next=/register'
/login?next=/register
to require authentication before continue the registration steps.It's just an idea here, maybe there could be a better solution. What do you think about?
Thanks @CPatchane for your great feedback, I updated the PR with your additionnal code dedicated to login screen when session has expired. Please notice that I updated the code in User.isAuthenticatable
to deal with only one "last unauthenticated step" to avoid dealing with too much step information in the method. What do you think about this refactoring ?
@gregorylegarec That's great, I totally agree with this way to keep the code as maintainable as possible 👍
Thanks @gregorylegarec !
This PR :
isRegistered
andisNotRegistered
to detect if user has completed onboarding.Important
To send credentials to server, our
fetch
call need to have thecredentials
option set totrue
. Otherwise the result of the call is a401 Unauthorized
. It has been pretty long to understand this part and Passport mechanisms.To do
There is still a case to deal with : when user stops registration in accounts step and come back a later. If he is not authenticated anymore, the onboarding will go in a infinite redirection. We'll just have to be able to redirect to login page if user has completed password step, and then redirect to last steps of onboarding once user has logged in.