Skip to content

UX: better error message when social login fails #32772

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions app/controllers/users/omniauth_callbacks_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,19 @@ def valid_origin?(uri)
end

def failure
error_key = params[:message].to_s.gsub(/[^\w-]/, "")
error_key = "generic" if error_key.blank?
if provider = params[:provider].presence || params[:strategy].presence
if authenticator = Discourse.enabled_authenticators.find { _1.name == provider }
provider = authenticator.display_name
end
end

if provider.blank? && Discourse.enabled_authenticators.size == 1
provider = Discourse.enabled_authenticators.first.display_name
end

flash[:error] = I18n.t(
"login.omniauth_error.#{error_key}",
default: I18n.t("login.omniauth_error.generic"),
).html_safe
key = params[:message].to_s.gsub(/[^\w-]/, "").presence || "generic"
default = I18n.t("login.omniauth_error.generic", provider:)
flash[:error] = I18n.t("login.omniauth_error.#{key}", provider:, default:).html_safe

render "failure"
end
Expand Down
10 changes: 6 additions & 4 deletions app/views/application/_header.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@
<div class="panel clearfix">
<%- unless current_user || local_assigns[:hide_auth_buttons] %>
<span class='header-buttons'>
<%- if can_sign_up? %>
<a href="<%= path "/signup"%>" class='btn btn-primary btn-small sign-up-button'><%= I18n.t('sign_up') %></a>
<%- end %>
<a href="<%= path "/login"%>" class='btn btn-primary btn-small login-button btn-icon-text'><%= SvgSprite.raw_svg('user') %><%= I18n.t('log_in') %></a>
<span class='auth-buttons'>
<%- if can_sign_up? %>
<a href="<%= path "/signup" %>" class='btn btn-text btn-primary btn-small sign-up-button'><%= I18n.t('sign_up') %></a>
<%- end %>
<a href="<%= path "/login" %>" class='btn btn-icon-text btn-primary btn-small login-button'><%= SvgSprite.raw_svg('user') %><%= I18n.t('log_in') %></a>
</span>
</span>
<%- end %>
</div>
Expand Down
4 changes: 4 additions & 0 deletions config/initializers/009-omniauth.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
OmniAuth.config.logger = Rails.logger
OmniAuth.config.silence_get_warning = true

# uncomment this line to force the redirect to /auth/failure in development mode
# (by default, omniauth raises an exception in development mode)
# OmniAuth.config.failure_raise_out_environments = []

OmniAuth.config.request_validation_phase = nil # We handle CSRF checks in before_request_phase
OmniAuth.config.before_request_phase do |env|
request = ActionDispatch::Request.new(env)
Expand Down
8 changes: 4 additions & 4 deletions config/locales/server.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3000,10 +3000,10 @@ en:
not_available: "Not available. Try %{suggestion}?"
something_already_taken: "Something went wrong, perhaps the username or email is already registered. Try the forgot password link."
omniauth_error:
generic: "Sorry, there was an error authorizing your account. Please try again."
csrf_detected: "Authorization timed out, or you have switched browsers. Please try again."
request_error: "An error occurred when starting authorization. Please try again."
invalid_iat: "Unable to verify authorization token due to server clock differences. Please try again."
generic: "Sorry, there was an error while trying to authorize your account with %{provider}. Please try again."
csrf_detected: "Sorry, the authorization timed out, or you have switched browsers. Please try again."
request_error: "Sorry, an error occurred when starting the authorization. Please try again."
invalid_iat: "Sorry, we are unable to verify the authorization token due to server clock differences. Please try again."
omniauth_error_unknown: "Something went wrong processing your login, please try again."
omniauth_confirm_title: "Log in using %{provider}"
omniauth_confirm_button: "Continue"
Expand Down
5 changes: 5 additions & 0 deletions lib/auth/authenticator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ def name
raise NotImplementedError
end

# Used in error messages and for display purposes
def display_name
name
end

def enabled?
raise NotImplementedError
end
Expand Down
4 changes: 4 additions & 0 deletions lib/auth/discord_authenticator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ def name
"discord"
end

def display_name
"Discord"
end

def enabled?
SiteSetting.enable_discord_logins?
end
Expand Down
4 changes: 4 additions & 0 deletions lib/auth/facebook_authenticator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ def name
"facebook"
end

def display_name
"Facebook"
end

def enabled?
SiteSetting.enable_facebook_logins
end
Expand Down
4 changes: 4 additions & 0 deletions lib/auth/github_authenticator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ def name
"github"
end

def display_name
"GitHub"
end

def enabled?
SiteSetting.enable_github_logins
end
Expand Down
4 changes: 4 additions & 0 deletions lib/auth/google_oauth2_authenticator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ def name
"google_oauth2"
end

def display_name
"Google"
end

def enabled?
SiteSetting.enable_google_oauth2_logins
end
Expand Down
4 changes: 4 additions & 0 deletions lib/auth/linkedin_oidc_authenticator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ def name
"linkedin_oidc"
end

def display_name
"LinkedIn"
end

def enabled?
SiteSetting.enable_linkedin_oidc_logins
end
Expand Down
4 changes: 4 additions & 0 deletions lib/auth/twitter_authenticator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ def name
"twitter"
end

def display_name
"X / Twitter"
end

def enabled?
SiteSetting.enable_twitter_logins
end
Expand Down
2 changes: 1 addition & 1 deletion lib/discourse.rb
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ def self.authenticators
end

def self.enabled_authenticators
authenticators.select { |authenticator| authenticator.enabled? }
authenticators.select(&:enabled?)
end

def self.cache
Expand Down
2 changes: 1 addition & 1 deletion spec/requests/omniauth_callbacks_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def enabled?
it "should display the failure message if needed" do
get "/auth/failure"
expect(response.status).to eq(200)
expect(response.body).to include(I18n.t("login.omniauth_error.generic"))
expect(response.body).to include(I18n.t("login.omniauth_error.generic", provider: "Google"))
end

describe "request" do
Expand Down
4 changes: 2 additions & 2 deletions spec/views/omniauth_callbacks/failure.html.erb_spec.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# frozen_string_literal: true

RSpec.describe "users/omniauth_callbacks/failure.html.erb" do
before { flash[:error] = I18n.t("login.omniauth_error", strategy: "test") }
before { flash[:error] = I18n.t("login.omniauth_error.generic", provider: "test") }

it "renders the failure page" do
render template: "users/omniauth_callbacks/failure"

expect(rendered).to match I18n.t("login.omniauth_error.generic", strategy: "test")
expect(rendered).to match I18n.t("login.omniauth_error.generic", provider: "test")
end
end
Loading