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

Unable to get verification flow id after registration when using code method. #2975

Closed
4 of 6 tasks
bhdurak opened this issue Dec 21, 2022 · 12 comments · Fixed by #3144
Closed
4 of 6 tasks

Unable to get verification flow id after registration when using code method. #2975

bhdurak opened this issue Dec 21, 2022 · 12 comments · Fixed by #3144
Assignees
Labels
bug Something is not working.

Comments

@bhdurak
Copy link

bhdurak commented Dec 21, 2022

Preflight checklist

Describe the bug

Greetings,

We are using ory Kratos (v.0.11.0) with the FrontendApi in our React Native app. We were previously using link as verification method and now we have migrated to code. And after calling the updateRegistrationFlow function, the verification code is sent automatically, without us creating a Native Verification Flow manually by calling createNativeVerificationFlow. Hence, since we don't know the id of the verification flow which was just created, we can't really call the updateVerificationFlow function when the code is entered. We tried to use the id from the Registration flow, thinking that since it creates the Verification Flow the id's might be the same. But obviously that was not the case.

Here the question is, how to access the id of the Verification flow so that we can call the update function and do the verification?

In the relevant fields of kratos.yml we have :

methods:
    password:
      enabled: true
    link:
      enabled: true
    code:
      enabled: true
    ...
flows:
    ...
    verification:
      enabled: true
      use: code
      ...
      

We call the registration flow as follows:

const flow = (await kratosApi().createNativeRegistrationFlow()).data;
      const data = await kratosApi().updateRegistrationFlow({
        flow: flow.id,
        updateRegistrationFlowBody: {
          csrf_token: "",
          method: "password",
          password: state.password,
          traits: {
            email,
            ...
          },
        },
      });

With kratosApi being

    new Configuration({
      basePath,
      apiKey: token,
      baseOptions: {
        withCredentials: false,
      },
    }),
    "",
    axios
  );

When we call the flow like this, we do get an email with the code inside to the email address that's specified in the traits.email field. Alongside, we also get the id of the verification flow which was created by the registration flow. But we need to get the id in the code somehow in order to use it in verification for the flow field which can be seen in the next code block.

And finally, we are trying to get the verification as follows:

updateVerificationFlow({
      flow: <id of the Registration Flow (to be changed with the actual id of verification flow)>,
      updateVerificationFlowBody: { code, email }
    })

Thank you and best regards,

Reproducing the bug

Adding kratos v0.11.0 to the application and specifying the kratos version in docker-compose.yml & kube-kratos-values.yml

Enabling and adding code as verification method in kratos.yml

Creating a Native Registration flow with FrontendApi and updating the flow with the account parameters needed.

The verification flow will have been automatically created, mail will be sent to the email address stated in traits with the id, but the id of verification flow is unreachable to the code to call updateVerificationFlow with it.

Relevant log output

No response

Relevant configuration

No response

Version

0.11.0

On which operating system are you observing this issue?

Linux

In which environment are you deploying?

Docker Compose

Additional Context

No response

@bhdurak bhdurak added the bug Something is not working. label Dec 21, 2022
@prajaybasu
Copy link

Facing the same issue.

@aeneasr
Copy link
Member

aeneasr commented Dec 22, 2022

Assigning jonas, he is however on vacation until the new year

@jonas-jonas
Copy link
Contributor

Hi all! Sorry for the confusion on this topic, and thanks for your reports. In truth, this feature is not completely done, and so the current "ergonomics" of the flow are not perfect. The ultimate goal is to show the form right after the registration is done, the verification flow is created, and the code is sent to the user. However, there currently are multiple issues with this idea, preventing us from shipping this straight away:

  1. We do not have a standardized way of redirecting from one flow "type" to another (e.g. registration -> verification) on all client types (SPA, browser and native) we support. Browsers can deal with redirects, but API clients typically cannot. This is, however, on our immediate roadmap, as it is needed for other flows as well. (See Design Doc: Common framework for state transitions on native/spa/web clients #2884 and feel free to provide your perspective on this.)
  2. There are cases where the verification is not needed and showing the form there would be undesirable. The best way to deal with this is to somehow figure out when verification is required (e.g. for login via the require_verified_address hook) and show the form in that case. But this needs to be well-thought-out. Alternatively, we could add a new config value (either after registration hooks or a key). Ideas on this are welcome!

@akkie
Copy link

akkie commented Jan 3, 2023

It would also be great if the SDK's could return the ID of the verification flow with the JSON response, after the registration or settings flow was successful, so that an app can redirect the user to the correct flow.

@Akkarine
Copy link

Akkarine commented Jan 20, 2023

I have another use-case. I want to make verification with code part of registration flow. And make smooth UX with AJAX requests. It would possible, if I could disable autosend code at registration by kratos config. And initiate verification flow by frontend. But when customer recieve code on email, I just don't have id and csrf_token for verification flow on registration page. So user just need to click link. And I can't create new verification flow and send second email - that is bad UX - which code user should use?

Also, in such case there is no difference with magic link. I have code in query parameters, email not needed (it already in flow) and csrf_token I can get by AJAX GET verification flow - I can just make AJAX POST request and show, thal all done.

@staklau
Copy link

staklau commented Feb 2, 2023

@Akkarine +1
It seems like this would be a non-issue if they allow us to disable the autosending of the initial verification email which contains the code.. Really frustrating issue, I must say.

@aeneasr
Copy link
Member

aeneasr commented Feb 2, 2023

We're prioritizing this issue. If you're encountering this problem, for now fall back to magic links :)

@jonas-jonas would it not be possible to add the link URL for the code with the flow ID (similar to magic links) to the email template?

@w0aw
Copy link

w0aw commented Feb 19, 2023

can we send current active verification flow id inside session object. eg -

session: {
                identity: {
                     verifiable_addresses: [
                              {
                                   .........id,value, etc...,
                                   active_flows: [ "HERE COLLECTION OF ALL ACTIVE FLOWS"]
  
}
]
}

}

SORRY for bad syntax

@jonas-jonas
Copy link
Contributor

My first thought was, that we can use the new page/state transition (error) schema here (see #2884). However, it's quite hard to figure out when to actually respond with that response, as not everyone wants to show the verification flow directly after the registration flow. This makes the API pretty weird and quite unpredictable, IMO. Kratos also supports multiple verifiable addresses, and picking which flow to redirect to here is also non-trivial, further adding to the complexity of the API.

Which leaves @maipal-oscoy's proposal, which could work, as the implementor of the UI probably knows which verifiable address to use, as they control the schema. However, from an API consumer standpoint, I don't think returning a list of flows is optimal here. Which flow do you pick here?

IMO, we should just return a single flow_id here, which would be the latest flow that is active for this verifiable address.

        "id": "3d34d7e6-c7ca-436f-8f83-85f2e5274d03",
        ...
        "verifiable_addresses": [
          {
            "id": "fea22b48-a8ff-4cb7-878e-cdf7acd8485d",
            "value": "foo@ory.sh",
            "verified": false,
            "via": "email",
            "status": "sent",
            "created_at": "2023-03-03T18:28:52.874827+01:00",
            "updated_at": "2023-03-03T18:28:52.874827+01:00",
            "verification_flow_id": "7de0fe6f-781a-412f-8fa8-6c4ee584be0d"
          }
        ],
        ...

Now, the dev implementing a UI, can choose to show the verification UI, or ignore it and let the user click on the link in the email. We should probably add a check, that removes the ID if the flow expired. Alternatively, we can keep the ID and if the flow expired, but is fetched, re-issue a new verification flow (the current behavior).

LMKWYT, and if I missed anything.

@w0aw
Copy link

w0aw commented Mar 4, 2023

Thanks @jonas-jonas , i thought verification link/code usually takes 10-15 minutes to expire. However we can customize verification flow expiration time but it doesn't make sense if code/link expires before flow. That's why i thought we will have a few active flows. And sending them in array will not be a big deal.

But sending single latest active flow will work for me.
Thanks again

@w0aw
Copy link

w0aw commented Mar 4, 2023

Another flexibility will be , create a new route that will allow us to fetch all current active flows for a particular user. So we will fetch the flow ourself.

There are few suggestions from my side.

  1. Verification is always done after user's registration. So when user initiate Verification flow, ask for them to send a proper valid session, and a valid verifiable address eg. (Phone/email) from verifiable_address Array. Then only generate a flow if both session and a verifiable_address are valid then only generate a Verification flow and send code/link in same request. And then return this Verification flow. So user can submit code/link with that flow id.
  2. Why i am talking about this approach, because right now i can create a ton of Verification flows, then submit them with verifiable_address. I can repeat same again create flow submit same address again, but not link /code.By using approach above we can put some checks - if address is already verified then we won't generate flow we will send error or something like success already verified. Another check will be if any ongoing flow is active for a particular address we will send the same flow again if expiration time is more than 1/2 minutes. Another benefit will be it reduces calling one route. (First get flow then post then post again to simply post address then post code ). And now get will send all active flows for all verifiable_address for a user. Send empty array if none active. CONS of this approach - it is different for all other flows. But at the end registration, login, recovery are not same as Verification.

Correct me if i am wrong. Because i don't know too much about security. Take it as a feedback from user. That's all

@Akkarine
Copy link

Akkarine commented Mar 4, 2023

Please don't overthink about it. Just give us verification flow id in registration response or provide option to disable auto-creation verification flow at registration.
Speak in use-cases, if this is not enough for someone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something is not working.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants