FusionAuth
    • Home
    • Categories
    • Recent
    • Popular
    • Pricing
    • Contact us
    • Docs
    • Login
    1. Home
    2. stephen
    S
    • Profile
    • Following 0
    • Followers 0
    • Topics 4
    • Posts 13
    • Best 5
    • Controversial 0
    • Groups 0

    stephen

    @stephen

    5
    Reputation
    3
    Profile views
    13
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    stephen Unfollow Follow

    Best posts made by stephen

    • Is it possible to disable two-factor without providing the two-factor code?

      Hello,

      We're implementing two-factor authentication in our application and want to provide a path for a user if they are no longer able to generate a two-factor code. This would happen if they lost their device or the device was destroyed by being thrown into a volcano like the One Ring.

      The two ways I've seen this handled in other systems are:

      • Provide an API endpoint that requires API Key Authentication and doesn't require a two-factor code so that we can develop an API endpoint that a Global Administrator can use to allow the affected user to bypass two-factor.
      • Provide one or more recovery codes that a user can enter to bypass entering the two-factor code

      I'm not sure if I'm missing a way to do either of these or there are any other recommended solutions to handle this use case.

      Thanks for helping out,
      Stephen

      posted in Q&A
      S
      stephen
    • RE: Is it possible to disable two-factor without providing the two-factor code?

      Thanks for the reply!

      I didn't realize you could turn off the two-factor by patching the user. Thanks for pointing me in the correct direction.

      posted in Q&A
      S
      stephen
    • RE: Is it possible to disable two-factor without providing the two-factor code?

      Thanks for adding an issue for this

      posted in Q&A
      S
      stephen
    • How long does the email template changePasswordId id last before it expires? How can invitation expiration be implemented?

      Hello,

      For future users that land on this topic, I've figured out an answer for the first question—"How long does the email template changePasswordId id last before it expires?". The Account Created email has a variable in it called changePasswordId in it that you can use it to the reset the users password by passing it to the Change a User’s Password API. The expiration time setting for this changePasswordId is called Setup Password in the FusionAuth settings. There is a different expiration time setting for the changePasswordId that is returned from the Start Forgot Password Workflow. That changePasswordId setting is called Change Password. Both of these expiration time settings can be adjusted in the FusionAuth UI by navigating to the advanced settings of the tenant.

      I've ran into some issues with the invitation flow and providing a good experience to the users of our application. One issue I'm having is that is that there is no way to distinguish an error for the invite user flow from an error on a reset password flow. This means that I can't display "Your invite has expired" to the user, I can only give them a generic, your invite didn't work message with no direction for recourse other than telling them that they can reset their password to get their account back. This is not a desirable behavior for our application. Please let me know if there are any solutions to this that I'm missing.

      The workflow I would like to achieve in our application UI is the following:

      • Invites expire after 7 days
      • In the list of users I can see what users have accepted the invite and which haven't
      • If user's invite has expired, an admin can resend them the invite

      There doesn't seem to be the concept of invites expiring in FusionAuth (Email Verification can expire, but that doesn't prevent change password requests). What I'm thinking I would need to do to achieve this is the following:

      • Set Email Verification in the advanced tenant settings to 7 days (604800 seconds)
      • Store a boolean for if the password has been initially set—this will let us know if the invite has been accepted. We can call this hasInviteBeenAccepted.
      • Intercept the complete reset password API
        • If 7 days have not passed, reset the password and set hasInviteBeenAccepted to true
        • If 7 days have passed and hasInviteBeenAccepted is false, return an error
      • If 7 days have passed
        • Remove application registration to deny login attempts
        • If hasInviteBeenAccepted is false, display a button on the users screen for admins that allow them to resend the invite. The user will also need to be reregistered to the application.
          • I think the only way to resend the initial invite is to remove the user and recreate them
      • Intercept the initiate password reset request
        • If hasInviteBeenAccepted is false, return an error
        • If hasInviteBeenAccepted is true, initiate the password reset request

      Am I missing anything? Are there any suggestions for a better workflow for this?

      Is this something that makes sense to be included as a feature of FusionAuth?

      Thanks,
      Stephen

      posted in Q&A
      S
      stephen
    • RE: How long does the email template changePasswordId id last before it expires? How can invitation expiration be implemented?

      Added a feature request for this issue: https://github.com/FusionAuth/fusionauth-issues/issues/904

      posted in Q&A
      S
      stephen

    Latest posts made by stephen

    • RE: Why does FusionAuth provide 10 recovery codes?

      @Joshua

      Thanks for the explanation.

      In our system, we only present recovery codes as a way to disable two-factor and reset it back up, not as a mechanism to bypass it temporarily.

      This provides a solution for the following use cases:

      • A user loses access to their device that has their authenticator app on it
      • A user has to switch phone numbers or loses access to their phone number
      posted in Q&A
      S
      stephen
    • RE: (FusionAuth 1.33.0. Update) How to Update the Password Reset Functionality for Users that Have Two-Factor On?

      @robotdan Thanks for the response.

      This is not working as I expected. When I didn't provide a trustChallenge to the Two Factor Start API, I couldn't get the Change Password API to work. The message indicated that I needed to provide a trustToken, even though I was passing this into the API.

      The workaround I found is that it worked when I provided a trustChallenge in the Two Factor Start API and the Change Password API.

      posted in Q&A
      S
      stephen
    • RE: (FusionAuth 1.33.0. Update) How to Update the Password Reset Functionality for Users that Have Two-Factor On?

      @robotdan

      If I include a trustChallenge it works.

      posted in Q&A
      S
      stephen
    • RE: (FusionAuth 1.33.0. Update) How to Update the Password Reset Functionality for Users that Have Two-Factor On?

      @robotdan

      Thanks for the reply. This was very helpful!

      This allowed me to get much further, but now I'm running into a separate issue completing the flow. When I provide the trust token to the POST /api/user/change-password it is still giving me the [TrustTokenRequired] error code — the same one you have in your message. I'm not sure what I'm doing wrong. Here is the full flow that I'm doing:

      1. POST /api/two-factor/start
      2. POST /api/two-factor/login
      3. POST /api/user/change-password

      Note: The version I'm updating to is 1.35.0, two versions after the Change Password API changed.


      Two-factor Start
      POST /api/two-factor/start

      Headers

      {
        "Authorization": "API_KEY",
        "Accept": "application/json"
      }
      

      Body

      {
        "loginId": "testemail@test.com"
      }
      

      Response 200

      {
        "code": "CODE",
        "methods": [
          {
            "authenticator": {
              "algorithm": "HmacSHA1",
              "codeLength": 6,
              "timeStep": 30
            },
            "id": "METHOD_ID",
            "method": "authenticator"
          }
        ],
        "twoFactorId": "TWO_FACTOR_ID"
      }
      

      Two-factor Login
      POST /api/two-factor/login

      Headers

      {
        "Authorization": "API_KEY",
        "Accept": "application/json"
      }
      

      Body

      {
        "code": "CODE",
        "twoFactorId": "TWO_FACTOR_ID",
      }
      

      Response 200

      {
        "token": "TOKEN",
        "tokenExpirationInstant": TOKEN_EXPIRATION_INSTANT,
        "trustToken": "TRUST_TOKEN",
        "user": {
          "active": true,
          "connectorId": "CONECTOR_ID",
          "data": {
            "companyId": "COMAPNY_ID"
          },
          "email": "EMAIL",
          "firstName": "FIRST_NAME",
          "id": "ID",
          "insertInstant": INSERT_INSTANCE,
          "lastLoginInstant": LAST_LOGIN_INSTANCE,
          "lastName": "LAST_NAME",
          "lastUpdateInstant": LAST_UPDATE_INSTANCE,
          "passwordChangeRequired": PASSWORD_CHANGE_REQUIRED,
          "passwordLastUpdateInstant": PASSWORD_LAST_UPDATE_INSTANT,
          "registrations": [
            {
              "applicationId": "APPLICATION_ID",
              "id": "ID",
              "insertInstant": INSERT_ID,
              "lastLoginInstant": LAST_LOGIN_INSTANT,
              "lastUpdateInstant": LAST_UPDATE_INSTANT,
              "roles": [
                "ROLE_NAME"
              ],
              "usernameStatus": "ACTIVE",
              "verified": true
            }
          ],
          "tenantId": "TENENT_ID",
          "twoFactor": {
            "methods": [
              {
                "authenticator": {
                  "algorithm": "HmacSHA1",
                  "codeLength": 6,
                  "timeStep": 30
                },
                "id": "ID",
                "method": "authenticator"
              }
            ]
          },
          "usernameStatus": "ACTIVE",
          "verified": true
        }
      }
      

      Change Password
      POST /api/user/change-password

      Headers

      {
        "Authorization": "API_KEY",
        "Accept": "application/json"
      }
      

      Body
      The TRUST_TOKEN supplied is the one returned from the previous POST /api/two-factor/login call

      {
        "loginId": "testemail@test.com",
        "currentPassword": "CURRENT_PASSWORD",
        "password": "NEW_PASSWORD",
        "trustToken": "TRUST_TOKEN"
      }
      

      Response 400

      {
        "generalErrors": [
          {
            "code": "[TrustTokenRequired]",
            "message": "This request requires a Trust Token. Use the Start Two-Factor API to obtain a Trust Token required to complete this request."
          }
        ]
      }
      
      posted in Q&A
      S
      stephen
    • (FusionAuth 1.33.0. Update) How to Update the Password Reset Functionality for Users that Have Two-Factor On?

      Overview

      Password reset functionality has changed for users that have two-factor on in the 1.33.0 release. I am trying to accomplish the two following user flows that were previously possible, and are possible in other systems I've tried:

      1. User is logged in and wants to change their password
      2. User is resetting their password using the reset password email

      The two API's I'm using to achieve these are apart of the Change a User's Password API.

      1. (Logged in flow) POST /api/user/change-password
      2. (Email flow) POST /api/user/change-password/{changePasswordId}

      Each of these API's has a new requirement for a trustToken that was introduced in the 1.33.0 release. The only way that I've seen to obtain a trustToken is during the login flow, even if I'm making the change using API Key Authentication. The trustToken seems to not be available when I need to make a call to the API.

      User flows

      I'm not sure how to obtain my two desired user flows:

      User is logged in and wants to change their password

      The desired flow is that the user logs in and navigates to their account settings and updates their password by entering their old password and a new password. If a user refreshes the page, they will still be logged in but I will no longer have the trust token. Currently I don't have to store any data during the login process, this is all handle through cookies that are added by FusionAuth and inaccessible by client side JavaScript. What is the recommended path for achieving this user flow?

      User is resetting their password using the reset password email

      The desired flow for this is that a user puts in their email into a field and they receive an email with a reset password link. When they click on the link it takes them to a page where they enter a new password, then they can log in with their new password.

      During this flow the user isn't able to log in to the application, so they are unable to retrieve a trustToken. What is the recommended path for achieving this user flow?


      Thanks in advance for any help.

      posted in Q&A
      S
      stephen
    • Why does FusionAuth provide 10 recovery codes?

      Many systems, along with FusionAuth, provide 10 recovery codes. Once one is used, they are all reset, so why provide 10 of them?

      I can see one reason being storing them in multiple places, but you could just store the same one in multiple places. I'm trying to determine if I should show all 10 to the user, or if a single one makes the most sense. Does anyone have any thoughts or opinions on this?

      posted in Q&A
      S
      stephen
    • RE: How long does the email template changePasswordId id last before it expires? How can invitation expiration be implemented?

      Added a feature request for this issue: https://github.com/FusionAuth/fusionauth-issues/issues/904

      posted in Q&A
      S
      stephen
    • RE: How long does the email template changePasswordId id last before it expires? How can invitation expiration be implemented?

      This is great, thanks Dan.

      I have one question though regarding resends:

      Set up a page in your application to send people an invite. Only admin users can do so. (This solves the re-sending problem as well.)

      How does this solve the resend issue? When an admin hits the resend invite button, I would still have to remove the user and readd them, correct? Is that the only way to resend that invite email?

      Thanks for your help.

      posted in Q&A
      S
      stephen
    • How long does the email template changePasswordId id last before it expires? How can invitation expiration be implemented?

      Hello,

      For future users that land on this topic, I've figured out an answer for the first question—"How long does the email template changePasswordId id last before it expires?". The Account Created email has a variable in it called changePasswordId in it that you can use it to the reset the users password by passing it to the Change a User’s Password API. The expiration time setting for this changePasswordId is called Setup Password in the FusionAuth settings. There is a different expiration time setting for the changePasswordId that is returned from the Start Forgot Password Workflow. That changePasswordId setting is called Change Password. Both of these expiration time settings can be adjusted in the FusionAuth UI by navigating to the advanced settings of the tenant.

      I've ran into some issues with the invitation flow and providing a good experience to the users of our application. One issue I'm having is that is that there is no way to distinguish an error for the invite user flow from an error on a reset password flow. This means that I can't display "Your invite has expired" to the user, I can only give them a generic, your invite didn't work message with no direction for recourse other than telling them that they can reset their password to get their account back. This is not a desirable behavior for our application. Please let me know if there are any solutions to this that I'm missing.

      The workflow I would like to achieve in our application UI is the following:

      • Invites expire after 7 days
      • In the list of users I can see what users have accepted the invite and which haven't
      • If user's invite has expired, an admin can resend them the invite

      There doesn't seem to be the concept of invites expiring in FusionAuth (Email Verification can expire, but that doesn't prevent change password requests). What I'm thinking I would need to do to achieve this is the following:

      • Set Email Verification in the advanced tenant settings to 7 days (604800 seconds)
      • Store a boolean for if the password has been initially set—this will let us know if the invite has been accepted. We can call this hasInviteBeenAccepted.
      • Intercept the complete reset password API
        • If 7 days have not passed, reset the password and set hasInviteBeenAccepted to true
        • If 7 days have passed and hasInviteBeenAccepted is false, return an error
      • If 7 days have passed
        • Remove application registration to deny login attempts
        • If hasInviteBeenAccepted is false, display a button on the users screen for admins that allow them to resend the invite. The user will also need to be reregistered to the application.
          • I think the only way to resend the initial invite is to remove the user and recreate them
      • Intercept the initiate password reset request
        • If hasInviteBeenAccepted is false, return an error
        • If hasInviteBeenAccepted is true, initiate the password reset request

      Am I missing anything? Are there any suggestions for a better workflow for this?

      Is this something that makes sense to be included as a feature of FusionAuth?

      Thanks,
      Stephen

      posted in Q&A
      S
      stephen
    • RE: Is it possible to disable two-factor without providing the two-factor code?

      Thanks for adding an issue for this

      posted in Q&A
      S
      stephen