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
- New Google user → confirmed_at set once → no further confirmation emails.
- Existing Google user → skip confirmation entirely.
confirm_new_userconfirm_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)
endauthentication 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)
endExpected 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_actionsauto_confirm_actions of the confirmation strategy list