authentik icon indicating copy to clipboard operation
authentik copied to clipboard

Recovery with email verification is accessible without email link (but does not work)

Open SebastianRzk opened this issue 3 years ago • 4 comments

Describe the bug

When the user clicks on "reset password", he is directly navigated to the "enter new password" page.

Flow from: https://goauthentik.io/docs/flow/examples/flows

Verified on existing installation aswell as clean demo installtion.

pwreset

But gladly, you can not change it 😅

pwreset2

To Reproduce Steps to reproduce the behavior:

Initial setup:

  1. Do download the docker-compose.yml
  2. Start the stack
  3. Add your initial admin account

The bug: 4. Add the "Recovery with email verification" flow from https://goauthentik.io/docs/flow/examples/flows 5. Try to recover your account

Expected behavior

The page should show "check your email inbox" instead of the password prompt.

Screenshots If applicable, add screenshots to help explain your problem.

pwreset

pwreset2

Logs Output of docker-compose logs or kubectl logs respectively

Version and Deployment (please complete the following information):

  • authentik version: 2022.7.2, 2022.7.3 at least. BUT on 2022.2.X everything worked as expected.
  • Deployment: [e.g. docker-compose, helm]

Additional context

I had not the time to diff the akflow json from the website. I think the ordering in the json in the docs is wrong and the authentik itself works fine.

If i am doing it by hand, everything works as expected.

Thanks for all of your work, authentik is really great.

SebastianRzk avatar Jul 21 '22 14:07 SebastianRzk

interesting, can you check the server container logs to see what the unknown error actually is? I'm assuming it's failing with something email related and just continuing

BeryJu avatar Jul 21 '22 14:07 BeryJu

Of course. here you go (full log attached):

{"event": "/if/flow/default-recovery-flow/", "host": "localhost:9000", "level": "info", "logger": "authentik.asgi", "method": "GET", "pid": 28, "remote": "172.27.0.1", "request_id": "1765d78bbba04584aecc60328aae76da", "runtime": 27, "scheme": "http", "status": 200, "timestamp": "2022-07-27T08:05:08.730358", "user": "", "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"}

{"event": "f(exec): Found existing plan for other flow, deleting plan", "flow_slug": "default-recovery-fl
ow", "host": "localhost:9000", "level": "warning", "logger": "authentik.flows.views.executor", "other_flow": "174d1dfd3eb24e03a9ebeb2508de2adc", "pid": 27, "request_id": "fc95058e65814f1a95bc56cc7a336170", "timestamp": "2022-07-27T08:05:08.831329"}

{"event": "/api/v3/core/tenants/current/", "host": "localhost:9000", "level": "info", "logger": "authentik.asgi", "method": "GET", "pid": 28, "remote": "172.27.0.1", "request_id": "3ac3a30efdf5414f9a7d6f6f3439a53c", "runtime": 52, "scheme": "http", "status": 200, "timestamp": "2022-07-27T08:05:08.849656", "user": "", "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"}

{"event": "/api/v3/root/config/", "host": "localhost:9000", "level": "info", "logger": "authentik.asgi", "method": "GET", "pid": 28, "remote": "172.27.0.1", "request_id": "593610867b324f8dac7a065636f77d90", "runtime": 72, "scheme": "http", "status": 200, "timestamp": "2022-07-27T08:05:08.876617", "user": "", "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"}

{"event": "/api/v3/flows/executor/default-recovery-flow/?query=", "host": "localhost:9000", "level": "info", "logger": "authentik.asgi", "method": "GET", "pid": 27, "remote": "172.27.0.1", "request_id": "fc95058e65814f1a95bc56cc7a336170", "runtime": 266, "scheme": "http", "status": 200, "timestamp": "2022-07-27T08:05:09.068998", "user": "", "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"}

{"event":"/static/dist/flow/PromptStage-300f86cb.js","host":"localhost:9000","level":"info","logger":"authentik.router","method":"GET","remote":"172.27.0.1:47650","runtime":"0.133","scheme":"","size":0,"status":304,"timestamp":"2022-07-27T08:05:09Z","upstream":"","user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"}

Full log authentik_log.txt

SebastianRzk avatar Jul 27 '22 08:07 SebastianRzk

I am able to reproduce this issue with latest version.

vineethmn avatar Aug 02 '22 10:08 vineethmn

I am also facing this issue with fresh installation of Authentik.

hatiac avatar Sep 14 '22 09:09 hatiac

same here, please fix

MartinVerges avatar Sep 30 '22 06:09 MartinVerges

same issue with fresh installation of Authentik.

iakovlevk avatar Oct 20 '22 21:10 iakovlevk

Same issue here (with 2022.11.1/2/3). Unlike OP, I don't know how to do this manually.

rmvh avatar Dec 06 '22 14:12 rmvh

I'm also currently trying to get recovery to work.

The problem with the example recovery flow from the docs seems to be the default-recovery-skip-if-restored expression policy attached to the first stages. If I remove that, the flow starts from the beginning as expected, and works all the way through. At least in my tests.

It seems that the policy leads to the first steps up to the password prompt being skipped by default. Maybe it was supposed to be negated or something like that?

This makes me wonder what that policy actually was meant to do. Its expression is:

return request.context.get('is_restored', False)

I'm not really sure what that does and the docs don't help. My only guess is it has something to do with starting a recovery manually with the "Reset password" button in the user directory, because it'd make sense to skip ahead to entering a new password in that case.

Also, coincidentally, with my current recovery flow without the aforementioned policy I get a "To create a recovery link, the current tenant needs to have a recovery flow configured." error message when trying to use that button to reset a user's password. Even though I've configured my only recovery flow as default recovery flow in my only and default tenant. I have no idea whether that has anything to do with this, but I thought I might as well mention it.

I hope some of this info might be helpful.

Eisfunke avatar Dec 08 '22 16:12 Eisfunke

Yeah, setting this to True makes it work. Is that how it was intended to be?

If this is the intended behaviour, I'd just change it.

erebion avatar Dec 24 '22 17:12 erebion

Just came across this issue after having experienced the same behavior with a fresh install of authentik (2023.1.0, although the admin interface is stubborn about telling me I'm still running 2022.12.2 … :roll_eyes:)

If I understand the documentation correctly, is_restored is True when the user arrives at a stage by clicking the link in their recovery email:

context['is_restored']: Set to True when the flow plan has been restored from a flow token, for example the user clicked a link to a flow which was sent by an email stage. (Optional)

As the policy is called default-recovery-skip-if-restored, it should skip (and not allow) the stages it is bound to when is_restored is True (so the user does not get asked their username again after clicking the link in the mail). So probably there is a not missing in the expression:

return not request.context.get('is_restored', False)

At least this works for me, and it sort of makes sense (although I do not claim to really understand what I am doing there … :laughing:).

drpetersen avatar Jan 19 '23 11:01 drpetersen

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Mar 21 '23 05:03 stale[bot]

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

AFAIK, this bug is not fixed, yet.

maxkratz avatar Mar 21 '23 06:03 maxkratz

I just imported the current example from the website, and the policy expression has changed to:

return bool(request.context.get('is_restored', True))

It seems to indeed have been fixed!

typedrat avatar Mar 30 '23 22:03 typedrat

I just imported the current example from the website, and the policy expression has changed to:

return bool(request.context.get('is_restored', True))

It seems to indeed have been fixed!

I confirm this as well! Importing the new flow fixed it! @BeryJu is there any chance those flows could be added by default to authentik instead of having to download them manually?

fuomag9 avatar Apr 21 '23 16:04 fuomag9

@BeryJu is there any chance those flows could be added by default to authentik instead of having to download them manually?

Yes, please. That way we get updates if anything is terribly broken and impacting security instead of just being mildly annoying, so that'd definitely be a useful feature to have.

edit: typo

erebion avatar Apr 21 '23 16:04 erebion

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

AFAIK this issue still exists. Bad bot.

erebion avatar Nov 08 '23 01:11 erebion