Fix OAuth login on custom domains (#320)

This commit is contained in:
Riccardo Graziosi
2024-03-28 12:29:54 +01:00
committed by GitHub
parent b63956a173
commit e887bca9cf
9 changed files with 42 additions and 25 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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 = ({
</select>
</div>
<div className="formGroup">
<label htmlFor="customDomain">{ getLabel('tenant', 'custom_domain') }</label>
<input
{...register('customDomain')}
id="customDomain"
className="formControl"
/>
{
originForm.customDomain !== customDomain && customDomain !== '' &&
<div style={{marginTop: 16}}>
<SmallMutedText>
{ I18n.t('site_settings.general.custom_domain_help', { domain: customDomain }) }
</SmallMutedText>
{ isMultiTenant &&
<div className="formGroup">
<label htmlFor="customDomain">{ getLabel('tenant', 'custom_domain') }</label>
<input
{...register('customDomain')}
id="customDomain"
className="formControl"
/>
{
originForm.customDomain !== customDomain && customDomain !== '' &&
<div style={{marginTop: 16}}>
<SmallMutedText>
{ I18n.t('site_settings.general.custom_domain_help', { domain: customDomain }) }
</SmallMutedText>
</div>
}
<div style={{marginTop: 8}}>
<ActionLink
onClick={() => window.open('https://docs.astuto.io/custom-domain', '_blank')}
icon={<LearnMoreIcon />}
@@ -215,8 +221,8 @@ const GeneralSiteSettingsP = ({
{I18n.t('site_settings.general.custom_domain_learn_more')}
</ActionLink>
</div>
}
</div>
</div>
}
<br />
<h4>{ I18n.t('site_settings.general.subtitle_header') }</h4>

View File

@@ -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<Props> {
<GeneralSiteSettings
originForm={this.props.originForm}
boards={this.props.boards}
isMultiTenant={this.props.isMultiTenant}
authenticityToken={this.props.authenticityToken}
/>
</Provider>

View File

@@ -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) => (
<button
onClick={() => window.location.href = `/o_auths/${oAuthId}/start?reason=${oAuthReason}`}
onClick={
() => { window.location.href = href ? href : `/o_auths/${oAuthId}/start?reason=${oAuthReason}` }
}
className={`oauthProviderBtn oauthProvider${oAuthName.replace(' ', '')}`}
>
{ oAuthLogo && oAuthLogo.length > 0 && <img src={oAuthLogo} alt={oAuthName} width={28} height={28} /> }

View File

@@ -10,6 +10,7 @@
oAuthLogo: o_auth.logo,
oAuthReason: "login",
isSignUp: defined?(is_sign_up) ? is_sign_up : false,
href: get_url_for(method(:o_auth_start_url), resource: o_auth.id, disallow_custom_domain: true, options: { reason: "login" }),
}
)
%>

View File

@@ -19,6 +19,7 @@
locale: @tenant.locale
},
boards: @tenant.boards.order(order: :asc),
isMultiTenant: Rails.application.multi_tenancy?,
authenticityToken: form_authenticity_token
}
)

View File

@@ -10,5 +10,6 @@ RESERVED_SUBDOMAINS = [
'logs',
'dashboard',
'analytics',
'cname'
'cname',
'whatever'
]

View File

@@ -158,7 +158,7 @@ en:
collapse_boards_in_header_no_collapse: 'Never'
collapse_boards_in_header_always_collapse: 'Always'
subtitle_visibility: 'Visibility'
custom_domain_help: 'In your DNS settings, add a CNAME record pointing "%{domain}" to "cname.astuto.io"'
custom_domain_help: 'First, in your DNS settings, add a CNAME record pointing "%{domain}" to "cname.astuto.io". Then, click the "Save" button below.'
custom_domain_learn_more: 'Learn how to configure a custom domain'
show_vote_count_help: 'If you enable this setting, users will be able to see the vote count of posts. This may incentivize users to vote on already popular posts, leading to a snowball effect.'
show_vote_button_in_board_help: 'If you enable this setting, users will be able to vote posts from the board page. This may incentivize users to vote on more posts, leading to a higher number of votes but of lower significance.'