-
-
Notifications
You must be signed in to change notification settings - Fork 931
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: Mark recovery email address verified #1665
feat: Mark recovery email address verified #1665
Conversation
@aeneasr: if this is the way to go, I'll add the required tests and extend the documentation. Please take a look. |
Yeah that looks good! :) |
…ed for recovery, the status of it is set to StatusSent
@aeneasr : Functionality wise I consider this PR to be complete. So please take a look. After taking a closer look at already existing documentation, it already states, that the verification is initiated by the registration and verification flows. This way there is no need for documentation update. |
Codecov Report
@@ Coverage Diff @@
## master #1665 +/- ##
=======================================
Coverage 74.10% 74.11%
=======================================
Files 260 260
Lines 12715 12733 +18
=======================================
+ Hits 9423 9437 +14
- Misses 2667 2669 +2
- Partials 625 627 +2
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, this looks pretty much mergeable! I’ve got some follow up questions and some ideas for improvement!
if err := s.d.RecoveryFlowPersister().UpdateRecoveryFlow(r.Context(), req); err != nil { | ||
return s.HandleRecoveryError(w, r, req, body, err) | ||
if address != nil && !address.Verified { | ||
address.Status = identity.VerifiableAddressStatusSent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I think it makes sense to mark the verified address as verified if we perform recovery with it, I think that it should stay untouched otherwise. For example, we are not marking the recovery email as status sent if we verify it. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The recovery address is actually a separate struct. As such it does even not have such fields. But if the recovery eMail address is the same, as the eMail address used for verification purposes. In such case, IMHO the verifiable address object should receive the same updates as it receives in a regular verification flow. In both cases an eMail verification is done by sending an email to the user and letting it click the corresponding link. This is also why there is a check for address != nil
. So I would not change the current implementation on this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you not conviced with my answer? ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, the 🏝 got in the way of me reading it 😅
Half half, I still see them as separate things. I agree that the flows work the same way (OOB TOTP over email) implying that solving one challenge is line solving the other. But then again they have different behaviors, lifespans, timeouts, and might have different security guards in the future.
At the same time, the link strategy is on the way out due to it’s many issues so to me it’s not that important!
If I was a dev and would do a recovery flow, and then see „hhmm now verification was also impacted“, I would probably open a bug report about it 😉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything is fine. I'm not pushing ;)
But then again they have different behaviors, lifespans, timeouts, and might have different security guards in the future.
They definitely do and still have. But we're talking about the end effect. And that can be the same, which is also stated by the current account-activation-email-verification documentation. The verify-email-account-activation document does not differentiate recovery and verification flows effects for email verification as well.
Actually, I fully agree with you if the email address used for recovery purposes differs from the email for account identification purposes (thus for login). And this situation is taken into account by the given PR. If they are however the same, I personally would expect the same state changes. And this is IMHO not related to lifespans, timeouts etc. They can for sure differ.
Btw: This is not the single place where the state is updated. The lines 423ff do this as well.
Anyhow, I can change the implementation as you're asking for (even I'm not convinced, you can see a couple of line below why exactly), but then there is a need for documentation update to make the differences obvious and clear. In addition there is a need then to find a solution for the following:
When a new VerifiableAddress is created, its status is set to identity.VerifiableAddressStatusPending
. When no recovery address is configured, the recovery address is set to the value of the email used for VerifiableAddress. When a recovery flow is executed the VerifiableAddress' state will still be in the identity.VerifiableAddressStatusPending
status, even the same email address has been used and this way the VerifiableAddress was actually verified. And now take please the position of
- a potential user of such a system (which requires the password_identifier to be a verified email for login purposes): You register and do not follow the link in the verification email (for whatever reasons, say you just forgot it). Some time later you come back and would like to login. Since the email is still not verified, you most probably will start the "password forgotten" (recovery flow). You change the password and are logged in. Some time later you come back and try to login again - but it doesn't work (as the system handles the same email address differently for different flows). - Ok, to be honest, I'm lying here, as the given PR makes use of the
Verified
attribute and not theState
attribute. - of a potential developer. You discover the VerifiableAddress, which has the fields
State
andVerified
. Both seems to be kind of redundant, asVerified=true
could be considered to correspond toState=identity.VerifiableAddressStatusVerified
. But this actually not the case,Verified
could betrue
even theState
would still beidentity.VerifiableAddressStatusPending
. This is actually my answer to your comment:
If I was a dev and would do a recovery flow, and then see „hhmm now verification was also impacted“, I would probably open a bug report about it.
So I were this dev I would rather open a bug report about that mismatch 😄 . How would you react?
Actually, since we have this discussion, I would rather remove the Verified
attribute and rely on the State
attribute. This would make the implementation much simpler (see point 2 above) and without redundancy, but still be open for having different behavior for the recovery and verification flows as well as open for potential enhancements, like security guards in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The verify-email-account-activation document does not differentiate recovery and verification flows effects for email verification as well.
That is definitely a copy/paste error :D
I agree with you here - if the address is verified the state should reflect that! And yes it’s definitely redundant. I thought it might be useful to have a simple bool flag reflecting the true/false status rather than the state, which is used internally.
By the way, I believe that unless you do not have the verify hook, the state here will almost always be „sent“! We use it internally to decide if a verification mail should be sent or not, for example when you update your email.
Regarding your recovery use case - it makes sense. It would be confusing to the user if they do recovery and still can‘t sign in because they should have done verification. I don’t really know how other sites are handling this. In general I think the problem is that we issue a session here, without doing any hook checks. This logic in general is still pretty akward IMO.
For the emails themselves I think there is a difference - you would e.g. want to send a double consent email (email verify) rather than mingle that with recovery.
In the end both approaches look acceptable to me here. I still feel that we are tricking the system here a bit - we are sending a recovery email and say that we sent the verification email too. Then again most people have this status set to sent already if the hook is used.
One thing is for sure though, if the status is verified already, this shouldn’t be touched!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ps: thank you for taking the input seriously even if the change is minimal 😅
@aeneasr: Could you please restart the test job? There is some issue with the db not related to the latest commits at all. |
Done ✔️ |
Looks much better now ;) Thank you. Please let me know if you would like to have something more changed/enhanced. |
…atusSent when an email for recovery purposes was sent
Awesome, thanks! Could you please add a note to the docs in the recovery part saying that we will mark the address as verified also if they match? Then this is mergable :) |
Related issue(s)
@aeneasr: This PR is for #1662
Checklist
Further Comments
The implementation idea is still the same as described in #1662. This PR does however introduce a separate function for marking the address as verified instead of misusing the
recoveryIssueSession
method.