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: Mark recovery email address verified #1665

Merged
merged 13 commits into from
Sep 22, 2021

Conversation

dadrus
Copy link
Contributor

@dadrus dadrus commented Aug 19, 2021

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.

@dadrus
Copy link
Contributor Author

dadrus commented Aug 20, 2021

@aeneasr: if this is the way to go, I'll add the required tests and extend the documentation. Please take a look.

@aeneasr
Copy link
Member

aeneasr commented Aug 23, 2021

Yeah that looks good! :)

@aeneasr aeneasr marked this pull request as draft August 24, 2021 12:45
@dadrus
Copy link
Contributor Author

dadrus commented Sep 1, 2021

@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
Copy link

codecov bot commented Sep 1, 2021

Codecov Report

Merging #1665 (c201dae) into master (5b456b3) will increase coverage by 0.00%.
The diff coverage is 69.23%.

Impacted file tree graph

@@           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     
Impacted Files Coverage Δ
selfservice/strategy/link/strategy_recovery.go 67.92% <69.23%> (+0.91%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5b456b3...c201dae. Read the comment docs.

@dadrus dadrus marked this pull request as ready for review September 3, 2021 11:51
Copy link
Member

@aeneasr aeneasr left a 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
Copy link
Member

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?

Copy link
Contributor Author

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.

Copy link
Contributor Author

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? ;)

Copy link
Member

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 😉

Copy link
Contributor Author

@dadrus dadrus Sep 10, 2021

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

  1. 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 the Stateattribute.
  2. of a potential developer. You discover the VerifiableAddress, which has the fields State and Verified. Both seems to be kind of redundant, as Verified=true could be considered to correspond to State=identity.VerifiableAddressStatusVerified. But this actually not the case, Verified could be true even the State would still be identity.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.

Copy link
Member

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!

Copy link
Member

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 😅

selfservice/strategy/link/strategy_recovery.go Outdated Show resolved Hide resolved
selfservice/strategy/link/strategy_recovery_test.go Outdated Show resolved Hide resolved
@dadrus
Copy link
Contributor Author

dadrus commented Sep 7, 2021

@aeneasr: Could you please restart the test job? There is some issue with the db not related to the latest commits at all.

@zepatrik
Copy link
Member

zepatrik commented Sep 7, 2021

Done ✔️

@dadrus
Copy link
Contributor Author

dadrus commented Sep 7, 2021

Looks much better now ;) Thank you. Please let me know if you would like to have something more changed/enhanced.

@dadrus
Copy link
Contributor Author

dadrus commented Sep 22, 2021

@aeneasr: The 41ce12c commit removes the status update as you've asked for. The other commits just ensure everything is working with the current master state.

@aeneasr
Copy link
Member

aeneasr commented Sep 22, 2021

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 :)

@aeneasr aeneasr merged commit e3efc5d into ory:master Sep 22, 2021
@dadrus dadrus deleted the feature/mark_recovery_address_verified branch September 22, 2021 16:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants