Password change ticket URL results(ed) in different UI although New UL is activated – redirect doesn't work reliably

Hey, first time on the Forum. I’ll give my best :slightly_smiling_face:

What we want to achieve is, that

  • we create an account for a user using the management API
    • verify_email = false
    • email_verified = false
  • we issue a password change ticket
    • user_id = {USER_ID}
    • client_id = {CLIENT_ID} (in order to enable redirect)
    • mark_email_as_verified = true
  • we send user the ticket URL via our own mail service
  • the user
    • opens the password change ticket URL,
    • sets a new password
    • and will be redirected to the applications login URL (or to some URL)

According to the management API docs, the redirect should work, if we set the client_id:

BUT, it does not work … respectively until yesterday evening DID NOT work … now it somehow works.

Our setup:

  • Node.js
  • Management API calls via npm package auth0
  • New Universal Login experience is activated

I tested three scenarios:


1st test:

const passwordChangeTicketResponse = await auth0.createPasswordChangeTicket({
    mark_email_as_verified: true,
    user_id: createdUser.user_id,
    client_id: auth0ClientId
})

Today:
Ticket URL: https://SUBDOMAIN.auth0.com/lo/reset?ticket=A76e2...
Setting password works: YES
User is redirected after setting password: NO

Until yesterday:
Ticket URL was something like this: https://SUBDOMAIN.auth0.com/u/reset-password?ticket=asd87...
And the UI was different compared to today??


2nd test:

const passwordChangeTicketResponse = await auth0.createPasswordChangeTicket({
    mark_email_as_verified: true,
    user_id: createdUser.user_id,
    result_url: "https://google.de" // respectively our URLs
})

Today:
Ticket URL: https://SUBDOMAIN.auth0.com/lo/reset?ticket=asd987...
Setting password works: YES
User is redirected after setting password: YES

Until yesterday:
Ticket URL was something like this: https://SUBDOMAIN.auth0.com/u/reset-password?ticket=765asd7...
And the UI was different too!

What wonders me here:

According to the API docs the user should be redirect to the Classic Universal Login … but it looks exactly the same like in the 1st approach:


3rd test (The only one which worked until yesterday!)

const passwordChangeTicketResponse = await auth0.createPasswordChangeTicket({
    mark_email_as_verified: true,
    user_id: createdUser.user_id,
    includeEmailInRedirect: true,
    result_url: "https://google.de"
})

Here includeEmailInRedirect: true was somehow the trigger to now generate URLs with a pathname like /lo/reset?... instead of /u/reset-password?...

Here everything worked yesterday (but I mean, the flag includeEmailInRedirect should not be the one enabling redirects…).


So following questions:

  • Have there been any changes to the Management API which caused the different behavour between yesterday and today?
  • How was it possible to generate (I assume) Classic Universal Login password change tickets by passing client_id?
  • What’s the correct way to redirect a user after resetting the password?

I hope I could clearly demonstrate my problems. Hopefully someone can help me out to better understand what’s going on :slightly_smiling_face:

Peter

Hi @peter-valuecase,

Welcome to the Auth0 Community!

Great first topic btw! Very thorough :smile:

Looking at the screenshot you shared, it looks like you are using Classic Universal Login. You can choose classic or new, but you cannot use both, and how your users are redirected after password reset will depend on which one you chose.

Classic login will redirect to the link you provide.

New login will redirect to the default login route of the app or tenant.

You must use New Universal Login to have this flow.

To confirm you have New Universal Login configured, in the dashboard navigate to Branding and confirm that New Universal Login is selected.

Here is an example of what you should see:

Important: If you seeing the following warning, you are using Classic UL:

Thanks for your reply!

The tip with the warning was helpful: Now the API returns a New Universal Login password change ticket URL.

But the user is never redirected. The screen stays exactly like that:

What did I do?

const passwordChangeTicketResponse = await auth0.createPasswordChangeTicket({
    mark_email_as_verified: true,
    user_id: createdUser.user_id,
    client_id: auth0ClientId
})

According to the API docs, passing client_id AND having the application’s login URI set should trigger a redirect, right?

Login URI is set:

What else could be missing or or improperly configured?

Thanks for you help!

Peter

Looks like we are narrowing it down.

Which client ID are you sending? Make sure you are sending the client ID of the app that has the associated Login URI, and not the client ID of the backend app (if these are separate apps).

I think I figured it out! So as always, the problem was sitting in front of the PC :innocent:

In order to use the Management API we added the corresponding M2M-Applications to the granted applications of the Management API in the API section - along with the needed rights in order to perform the password change ticket request.

But this M2M-Application did not have an Application Login URI – after setting it, I finally saw the “Back to …”-Button after setting the password:

This works for us like expected!

Thanks for guiding me to the right direction. I really appreciate the help/support here :slightly_smiling_face:!

Peter

Glad you figured it out.

A word of advice on this; you should be using the client ID of the application that you would like your use to log into after the successful password reset.

It looks like you had a SPA configured, and I would suspect that is the client ID you should be sending with the password ticket request.

Due to our application being a SPA and with Token Endpoint Auth Method set to None I am not able to enable the Client Credentials grant type, which would allow to get a token using client id and secret for the Management API.

Is there a better way to obtain a token for the backend service? Or can you recommend an other setup?

Thanks in advance!

Peter

You will still need two apps, an M2M backend app, and a SPA client app.

You should request the token with the credentials for you M2M app, and will request the ticket with the client ID for the SPA.

For example:

const ManagementClient = require('auth0').ManagementClient;
const auth0 = new ManagementClient({
  domain: '{YOUR_DOMAIN}',
  clientId: '{YOUR_M2M_CLIENT_ID}',
  clientSecret: '{YOUR_M2M_CLIENT_SECRET}',
  scope: '{SCOPES}',
})

const passwordChangeTicketResponse = await auth0.createPasswordChangeTicket({
    mark_email_as_verified: true,
    user_id: createdUser.user_id,
    client_id: '{YOUR_SPA_CLIENT_ID}'
})

The reason you are using your SPA client id in the ticket request is that you want to redirect your user back to your SPA after a password reset (if I understand your desired flow correctly). The default login route from that client is then attached to the ticket.

Hope that helps to clarify things!

Oh I got it. Use the M2M-Application to obtain the token, but pass the actual Application’s client_id in order to use the correct login URI.

Thanks, got it :slightly_smiling_face:

Peter

1 Like

You got it! Let me know if you have other questions.