From e887bca9cfda04d0fe6b77efd69b184ff6464fef Mon Sep 17 00:00:00 2001 From: Riccardo Graziosi <31478034+riggraz@users.noreply.github.com> Date: Thu, 28 Mar 2024 12:29:54 +0100 Subject: [PATCH] Fix OAuth login on custom domains (#320) --- app/controllers/o_auths_controller.rb | 10 +++--- app/helpers/application_helper.rb | 4 +-- .../General/GeneralSiteSettingsP.tsx | 36 +++++++++++-------- .../components/SiteSettings/General/index.tsx | 2 ++ .../components/common/OAuthProviderLink.tsx | 8 +++-- app/views/devise/shared/_o_auths.html.erb | 1 + app/views/site_settings/general.html.erb | 1 + config/initializers/reserved_subdomains.rb | 3 +- config/locales/en.yml | 2 +- 9 files changed, 42 insertions(+), 25 deletions(-) diff --git a/app/controllers/o_auths_controller.rb b/app/controllers/o_auths_controller.rb index 160189d1..3c1c3a0a 100644 --- a/app/controllers/o_auths_controller.rb +++ b/app/controllers/o_auths_controller.rb @@ -22,7 +22,7 @@ class OAuthsController < ApplicationController # Generate random state + other query params tenant_domain = Current.tenant ? Current.tenant_or_raise!.subdomain : "null" token_state = "#{params[:reason]}#{TOKEN_STATE_SEPARATOR}#{tenant_domain}#{TOKEN_STATE_SEPARATOR}#{Devise.friendly_token(30)}" - cookies[:token_state] = { value: token_state, domain: ".#{request.domain}", httponly: true } + cookies[:token_state] = { value: token_state, domain: ".#{request.domain}", httponly: true } unless params[:reason] == 'test' @o_auth.state = token_state redirect_to @o_auth.authorize_url_with_query_params @@ -33,8 +33,10 @@ class OAuthsController < ApplicationController def callback reason, tenant_domain, token_state = params[:state].split(TOKEN_STATE_SEPARATOR, 3) - return unless cookies[:token_state] == params[:state] - cookies.delete(:token_state, domain: ".#{request.domain}") + unless reason == "test" + return unless cookies[:token_state] == params[:state] + cookies.delete(:token_state, domain: ".#{request.domain}") + end # if it is a default oauth, tenant is not yet set Current.tenant ||= Tenant.find_by(subdomain: tenant_domain) @@ -71,7 +73,7 @@ class OAuthsController < ApplicationController unless user_signed_in? and current_user.admin? flash[:alert] = I18n.t('errors.unauthorized') - redirect_to root_url + redirect_to get_url_for(method(:root_url)) return end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 72f56fac..d8d8977c 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -29,9 +29,9 @@ module ApplicationHelper end def get_url_for(url_helper, resource: nil, disallow_custom_domain: false, options: {}) - custom_domain = Current.tenant.custom_domain + custom_domain = Current.tenant.custom_domain if not disallow_custom_domain and Current.tenant - if Rails.application.multi_tenancy? && (custom_domain.blank? || disallow_custom_domain) + if options[:subdomain].blank? && Rails.application.multi_tenancy? && (custom_domain.blank? || disallow_custom_domain) options[:subdomain] = Current.tenant.subdomain end diff --git a/app/javascript/components/SiteSettings/General/GeneralSiteSettingsP.tsx b/app/javascript/components/SiteSettings/General/GeneralSiteSettingsP.tsx index 2459005f..20aafa5f 100644 --- a/app/javascript/components/SiteSettings/General/GeneralSiteSettingsP.tsx +++ b/app/javascript/components/SiteSettings/General/GeneralSiteSettingsP.tsx @@ -37,6 +37,7 @@ export interface ISiteSettingsGeneralForm { interface Props { originForm: ISiteSettingsGeneralForm; boards: IBoardJSON[]; + isMultiTenant: boolean; authenticityToken: string; areUpdating: boolean; @@ -61,6 +62,7 @@ interface Props { const GeneralSiteSettingsP = ({ originForm, boards, + isMultiTenant, authenticityToken, areUpdating, @@ -195,19 +197,23 @@ const GeneralSiteSettingsP = ({ -
- - - { - originForm.customDomain !== customDomain && customDomain !== '' && -
- - { I18n.t('site_settings.general.custom_domain_help', { domain: customDomain }) } - + { isMultiTenant && +
+ + + { + originForm.customDomain !== customDomain && customDomain !== '' && +
+ + { I18n.t('site_settings.general.custom_domain_help', { domain: customDomain }) } + +
+ } +
window.open('https://docs.astuto.io/custom-domain', '_blank')} icon={} @@ -215,8 +221,8 @@ const GeneralSiteSettingsP = ({ {I18n.t('site_settings.general.custom_domain_learn_more')}
- } -
+
+ }

{ I18n.t('site_settings.general.subtitle_header') }

diff --git a/app/javascript/components/SiteSettings/General/index.tsx b/app/javascript/components/SiteSettings/General/index.tsx index 94cd11d7..c31d9dfe 100644 --- a/app/javascript/components/SiteSettings/General/index.tsx +++ b/app/javascript/components/SiteSettings/General/index.tsx @@ -11,6 +11,7 @@ import { ISiteSettingsGeneralForm } from './GeneralSiteSettingsP'; interface Props { originForm: ISiteSettingsGeneralForm; boards: IBoardJSON[]; + isMultiTenant: boolean; authenticityToken: string; } @@ -29,6 +30,7 @@ class GeneralSiteSettingsRoot extends React.Component { diff --git a/app/javascript/components/common/OAuthProviderLink.tsx b/app/javascript/components/common/OAuthProviderLink.tsx index bef01945..1fd43d85 100644 --- a/app/javascript/components/common/OAuthProviderLink.tsx +++ b/app/javascript/components/common/OAuthProviderLink.tsx @@ -7,11 +7,15 @@ interface Props { oAuthLogo?: string; oAuthReason: string; isSignUp?: boolean; + + href?: string; } -const OAuthProviderLink = ({ oAuthId, oAuthName, oAuthLogo, oAuthReason, isSignUp = false }: Props) => ( +const OAuthProviderLink = ({ oAuthId, oAuthName, oAuthLogo, oAuthReason, isSignUp = false, href = undefined }: Props) => (