Ash FrameworkAF
Ash Framework8mo ago
17 replies
Joan Gavelán

Confirmation Token Generated on Every Google Login

I'm using Ash Authentication + Google OAuth2 and I've noticed that every time I sign in with Google - even if I've already confirmed my account - a new confirm_new_user token/email is generated. Here is my setup:
authentication do
  add_ons do
    log_out_everywhere do
      apply_on_password_change? true
    end

    confirmation :confirm_new_user do
      monitor_fields [:email]
      confirm_on_create? true
      confirm_on_update? false
      require_interaction? true
      confirmed_at_field :confirmed_at
      auto_confirm_actions [:sign_in_with_magic_link, :reset_password_with_token]
      sender Noted.Accounts.User.Senders.SendNewUserConfirmationEmail
    end
  end

  tokens do
    enabled? true
    token_resource Noted.Accounts.Token
    signing_secret Noted.Secrets
    store_all_tokens? true
    require_token_presence_for_authentication? true
  end

  strategies do
    password :password do
      identity_field :email
      sign_in_tokens_enabled? false

      resettable do
        sender Noted.Accounts.User.Senders.SendPasswordResetEmail
        # these configurations will be the default in a future release
        password_reset_action_name :reset_password_with_token
        request_password_reset_action_name :request_password_reset_token
      end
    end

    google do
      client_id Noted.Secrets
      client_secret Noted.Secrets
      redirect_uri Noted.Secrets
    end
  end
end

# ... 

create :register_with_google do
  argument :user_info, :map, allow_nil?: false
  argument :oauth_tokens, :map, allow_nil?: false
  upsert? true
  upsert_identity :unique_email

  change AshAuthentication.GenerateTokenChange

  # Required if you have the `identity_resource` configuration enabled.
  # change AshAuthentication.Strategy.OAuth2.IdentityChange

  change fn changeset, _ ->
    user_info = Ash.Changeset.get_argument(changeset, :user_info)

    Ash.Changeset.change_attributes(
      changeset,
      Map.take(user_info, ["email", "name", "picture"])
    )
  end

  # Required if you're using the password & confirmation strategies
  upsert_fields []
  change set_attribute(:confirmed_at, &DateTime.utc_now/0)

  change after_action(fn _changeset, user, _context ->
           case user.confirmed_at do
             nil -> {:error, "Unconfirmed user exists already"}
             _ -> {:ok, user}
           end
         end)
end


Expected vs. Actual

Expected:


- New Google user → confirmed_at set once → no further confirmation emails.

- Existing Google user → skip confirmation entirely.

Actual:

- Every Google login—new or existing—triggers a new confirm_new_user token and email.
Solution
which you can do by configuring it in the auto_confirm_actions of the confirmation strategy list
Was this page helpful?