mirror of
https://github.com/astuto/astuto.git
synced 2025-12-16 03:37:56 +01:00
Fix OAuth login on custom domains (#320)
This commit is contained in:
committed by
GitHub
parent
b63956a173
commit
e887bca9cf
@@ -22,7 +22,7 @@ class OAuthsController < ApplicationController
|
|||||||
# Generate random state + other query params
|
# Generate random state + other query params
|
||||||
tenant_domain = Current.tenant ? Current.tenant_or_raise!.subdomain : "null"
|
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)}"
|
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
|
@o_auth.state = token_state
|
||||||
|
|
||||||
redirect_to @o_auth.authorize_url_with_query_params
|
redirect_to @o_auth.authorize_url_with_query_params
|
||||||
@@ -33,8 +33,10 @@ class OAuthsController < ApplicationController
|
|||||||
def callback
|
def callback
|
||||||
reason, tenant_domain, token_state = params[:state].split(TOKEN_STATE_SEPARATOR, 3)
|
reason, tenant_domain, token_state = params[:state].split(TOKEN_STATE_SEPARATOR, 3)
|
||||||
|
|
||||||
|
unless reason == "test"
|
||||||
return unless cookies[:token_state] == params[:state]
|
return unless cookies[:token_state] == params[:state]
|
||||||
cookies.delete(:token_state, domain: ".#{request.domain}")
|
cookies.delete(:token_state, domain: ".#{request.domain}")
|
||||||
|
end
|
||||||
|
|
||||||
# if it is a default oauth, tenant is not yet set
|
# if it is a default oauth, tenant is not yet set
|
||||||
Current.tenant ||= Tenant.find_by(subdomain: tenant_domain)
|
Current.tenant ||= Tenant.find_by(subdomain: tenant_domain)
|
||||||
@@ -71,7 +73,7 @@ class OAuthsController < ApplicationController
|
|||||||
|
|
||||||
unless user_signed_in? and current_user.admin?
|
unless user_signed_in? and current_user.admin?
|
||||||
flash[:alert] = I18n.t('errors.unauthorized')
|
flash[:alert] = I18n.t('errors.unauthorized')
|
||||||
redirect_to root_url
|
redirect_to get_url_for(method(:root_url))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ module ApplicationHelper
|
|||||||
end
|
end
|
||||||
|
|
||||||
def get_url_for(url_helper, resource: nil, disallow_custom_domain: false, options: {})
|
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
|
options[:subdomain] = Current.tenant.subdomain
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ export interface ISiteSettingsGeneralForm {
|
|||||||
interface Props {
|
interface Props {
|
||||||
originForm: ISiteSettingsGeneralForm;
|
originForm: ISiteSettingsGeneralForm;
|
||||||
boards: IBoardJSON[];
|
boards: IBoardJSON[];
|
||||||
|
isMultiTenant: boolean;
|
||||||
authenticityToken: string;
|
authenticityToken: string;
|
||||||
|
|
||||||
areUpdating: boolean;
|
areUpdating: boolean;
|
||||||
@@ -61,6 +62,7 @@ interface Props {
|
|||||||
const GeneralSiteSettingsP = ({
|
const GeneralSiteSettingsP = ({
|
||||||
originForm,
|
originForm,
|
||||||
boards,
|
boards,
|
||||||
|
isMultiTenant,
|
||||||
authenticityToken,
|
authenticityToken,
|
||||||
|
|
||||||
areUpdating,
|
areUpdating,
|
||||||
@@ -195,6 +197,7 @@ const GeneralSiteSettingsP = ({
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{ isMultiTenant &&
|
||||||
<div className="formGroup">
|
<div className="formGroup">
|
||||||
<label htmlFor="customDomain">{ getLabel('tenant', 'custom_domain') }</label>
|
<label htmlFor="customDomain">{ getLabel('tenant', 'custom_domain') }</label>
|
||||||
<input
|
<input
|
||||||
@@ -208,6 +211,9 @@ const GeneralSiteSettingsP = ({
|
|||||||
<SmallMutedText>
|
<SmallMutedText>
|
||||||
{ I18n.t('site_settings.general.custom_domain_help', { domain: customDomain }) }
|
{ I18n.t('site_settings.general.custom_domain_help', { domain: customDomain }) }
|
||||||
</SmallMutedText>
|
</SmallMutedText>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<div style={{marginTop: 8}}>
|
||||||
<ActionLink
|
<ActionLink
|
||||||
onClick={() => window.open('https://docs.astuto.io/custom-domain', '_blank')}
|
onClick={() => window.open('https://docs.astuto.io/custom-domain', '_blank')}
|
||||||
icon={<LearnMoreIcon />}
|
icon={<LearnMoreIcon />}
|
||||||
@@ -215,8 +221,8 @@ const GeneralSiteSettingsP = ({
|
|||||||
{I18n.t('site_settings.general.custom_domain_learn_more')}
|
{I18n.t('site_settings.general.custom_domain_learn_more')}
|
||||||
</ActionLink>
|
</ActionLink>
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<h4>{ I18n.t('site_settings.general.subtitle_header') }</h4>
|
<h4>{ I18n.t('site_settings.general.subtitle_header') }</h4>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { ISiteSettingsGeneralForm } from './GeneralSiteSettingsP';
|
|||||||
interface Props {
|
interface Props {
|
||||||
originForm: ISiteSettingsGeneralForm;
|
originForm: ISiteSettingsGeneralForm;
|
||||||
boards: IBoardJSON[];
|
boards: IBoardJSON[];
|
||||||
|
isMultiTenant: boolean;
|
||||||
authenticityToken: string;
|
authenticityToken: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,6 +30,7 @@ class GeneralSiteSettingsRoot extends React.Component<Props> {
|
|||||||
<GeneralSiteSettings
|
<GeneralSiteSettings
|
||||||
originForm={this.props.originForm}
|
originForm={this.props.originForm}
|
||||||
boards={this.props.boards}
|
boards={this.props.boards}
|
||||||
|
isMultiTenant={this.props.isMultiTenant}
|
||||||
authenticityToken={this.props.authenticityToken}
|
authenticityToken={this.props.authenticityToken}
|
||||||
/>
|
/>
|
||||||
</Provider>
|
</Provider>
|
||||||
|
|||||||
@@ -7,11 +7,15 @@ interface Props {
|
|||||||
oAuthLogo?: string;
|
oAuthLogo?: string;
|
||||||
oAuthReason: string;
|
oAuthReason: string;
|
||||||
isSignUp?: boolean;
|
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
|
<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(' ', '')}`}
|
className={`oauthProviderBtn oauthProvider${oAuthName.replace(' ', '')}`}
|
||||||
>
|
>
|
||||||
{ oAuthLogo && oAuthLogo.length > 0 && <img src={oAuthLogo} alt={oAuthName} width={28} height={28} /> }
|
{ oAuthLogo && oAuthLogo.length > 0 && <img src={oAuthLogo} alt={oAuthName} width={28} height={28} /> }
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
oAuthLogo: o_auth.logo,
|
oAuthLogo: o_auth.logo,
|
||||||
oAuthReason: "login",
|
oAuthReason: "login",
|
||||||
isSignUp: defined?(is_sign_up) ? is_sign_up : false,
|
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" }),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
%>
|
%>
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
locale: @tenant.locale
|
locale: @tenant.locale
|
||||||
},
|
},
|
||||||
boards: @tenant.boards.order(order: :asc),
|
boards: @tenant.boards.order(order: :asc),
|
||||||
|
isMultiTenant: Rails.application.multi_tenancy?,
|
||||||
authenticityToken: form_authenticity_token
|
authenticityToken: form_authenticity_token
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,5 +10,6 @@ RESERVED_SUBDOMAINS = [
|
|||||||
'logs',
|
'logs',
|
||||||
'dashboard',
|
'dashboard',
|
||||||
'analytics',
|
'analytics',
|
||||||
'cname'
|
'cname',
|
||||||
|
'whatever'
|
||||||
]
|
]
|
||||||
@@ -158,7 +158,7 @@ en:
|
|||||||
collapse_boards_in_header_no_collapse: 'Never'
|
collapse_boards_in_header_no_collapse: 'Never'
|
||||||
collapse_boards_in_header_always_collapse: 'Always'
|
collapse_boards_in_header_always_collapse: 'Always'
|
||||||
subtitle_visibility: 'Visibility'
|
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'
|
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_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.'
|
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.'
|
||||||
|
|||||||
Reference in New Issue
Block a user