Files
discourse/lib/auth/authenticator.rb
Régis Hanol 0de08e780b UX: better error message when social login fails (#32772)
This improves the error message(s) displayed when an error happens while
using a social login to log in / sign up into a Discourse community.

Unfortunately, we can't be super precise in the reason behind the error
(it can be the user clicked "cancel" during the authorization phase, or
any of the plethora of other possible errors) because the reason isn't
provided (either for security reasons, or because it's just hard to do
so in a reliable & consistent way accross all social logins).

The best I could do was to

- add the name of the "social login" provider in the error message
- tweak the copy a bit for the different cases handle
- fix the CSS/HTML to match the one used by the main application

In order to show the name of the provider, we use either the "provider"
or the "strategy" query parameter, or use the name of the authenticator
(if it's the only one enabled).

Internal ref - t/153662

---

**BEFORE**


![before](https://github.com/user-attachments/assets/67579a3e-5a61-4e8f-aa72-4dc375547e39)

**AFTER**


![after](https://github.com/user-attachments/assets/954f9c8a-e865-44ff-b1e3-841393a26edf)
2025-05-20 16:22:38 +02:00

79 lines
2.2 KiB
Ruby

# frozen_string_literal: true
# this class is used by the user and omniauth controllers, it controls how
# an authentication system interacts with our database and middleware
class Auth::Authenticator
def name
raise NotImplementedError
end
# Used in error messages and for display purposes
def display_name
name
end
def enabled?
raise NotImplementedError
end
# run once the user has completed authentication on the third party system. Should return an instance of Auth::Result.
# If the user has requested to connect an existing account then `existing_account` will be set
def after_authenticate(auth_options, existing_account: nil)
raise NotImplementedError
end
# can be used to hook in after the authentication process
# to ensure records exist for the provider in the db
# this MUST be implemented for authenticators that do not
# trust email
def after_create_account(user, auth)
# not required
end
# hook used for registering omniauth middleware,
# without this we can not authenticate
def register_middleware(omniauth)
raise NotImplementedError
end
# return a string describing the connected account
# for a given user (typically email address). Used to list
# connected accounts under the user's preferences. Empty string
# indicates not connected
def description_for_user(user)
""
end
# return a string describing the connected account
# for a given OmniAuth::AuthHash. Used in the confirmation screen
# when connecting accounts
def description_for_auth_hash(user)
""
end
# can authorisation for this provider be revoked?
def can_revoke?
false
end
# can existing discourse users connect this provider to their accounts
def can_connect_existing_user?
false
end
# optionally implement the ability for users to revoke
# their link with this authenticator.
# should ideally contact the third party to fully revoke
# permissions. If this fails, return :remote_failed.
# skip remote if skip_remote == true
def revoke(user, skip_remote: false)
raise NotImplementedError
end
# provider has implemented user group membership (or equivalent) request
def provides_groups?
false
end
end