Redirect all /auth routes
This commit is contained in:
parent
55c4e3a00b
commit
5731b9b1c7
14 changed files with 82 additions and 26 deletions
|
@ -249,10 +249,12 @@ export function logOut(intl) {
|
|||
const account = getLoggedInAccount(state);
|
||||
const standalone = isStandalone(state);
|
||||
|
||||
if (!account) return dispatch(noOp);
|
||||
|
||||
const params = {
|
||||
client_id: state.getIn(['auth', 'app', 'client_id']),
|
||||
client_secret: state.getIn(['auth', 'app', 'client_secret']),
|
||||
token: state.getIn(['auth', 'users', account.get('url'), 'access_token']),
|
||||
token: state.getIn(['auth', 'users', account.url, 'access_token']),
|
||||
};
|
||||
|
||||
return Promise.all([
|
||||
|
|
|
@ -42,7 +42,7 @@ function createExternalApp(instance, baseURL) {
|
|||
|
||||
const params = {
|
||||
client_name: sourceCode.displayName,
|
||||
redirect_uris: `${window.location.origin}/auth/external`,
|
||||
redirect_uris: `${window.location.origin}/login/external`,
|
||||
website: sourceCode.homepage,
|
||||
scopes,
|
||||
};
|
||||
|
|
|
@ -285,7 +285,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
|||
<hr />
|
||||
|
||||
<SidebarLink
|
||||
to='/auth/sign_out'
|
||||
to='/logout'
|
||||
icon={require('@tabler/icons/icons/logout.svg')}
|
||||
text={intl.formatMessage(messages.logout)}
|
||||
onClick={onClickLogOut}
|
||||
|
|
|
@ -201,10 +201,6 @@ class SoapboxMount extends React.PureComponent {
|
|||
<Route path='/reset-password' component={AuthLayout} />
|
||||
<Route path='/edit-password' component={AuthLayout} />
|
||||
|
||||
<Redirect from='/auth/reset_password' to='/reset-password' />
|
||||
<Redirect from='/auth/edit_password' to='/edit-password' />
|
||||
<Redirect from='/auth/sign_in' to='/login' />
|
||||
|
||||
<Route path='/' component={UI} />
|
||||
</Switch>
|
||||
</ScrollContext>
|
||||
|
|
|
@ -76,7 +76,7 @@ class LoginPage extends ImmutablePureComponent {
|
|||
const { standalone } = this.props;
|
||||
const { isLoading, mfa_auth_needed, mfa_token, shouldRedirect } = this.state;
|
||||
|
||||
if (standalone) return <Redirect to='/auth/external' />;
|
||||
if (standalone) return <Redirect to='/login/external' />;
|
||||
|
||||
if (shouldRedirect) return <Redirect to='/' />;
|
||||
|
||||
|
|
28
app/soapbox/features/auth_login/components/logout.tsx
Normal file
28
app/soapbox/features/auth_login/components/logout.tsx
Normal file
|
@ -0,0 +1,28 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Redirect } from 'react-router-dom';
|
||||
|
||||
import { logOut } from 'soapbox/actions/auth';
|
||||
import { Spinner } from 'soapbox/components/ui';
|
||||
|
||||
/** Component that logs the user out when rendered */
|
||||
const Logout: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useDispatch();
|
||||
const [done, setDone] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
(dispatch(logOut(intl)) as any)
|
||||
.then(() => setDone(true))
|
||||
.catch(console.warn);
|
||||
});
|
||||
|
||||
if (done) {
|
||||
return <Redirect to='/' />;
|
||||
} else {
|
||||
return <Spinner />;
|
||||
}
|
||||
};
|
||||
|
||||
export default Logout;
|
|
@ -30,7 +30,7 @@ class PublicLayout extends ImmutablePureComponent {
|
|||
const { standalone } = this.props;
|
||||
|
||||
if (standalone) {
|
||||
return <Redirect to='/auth/external' />;
|
||||
return <Redirect to='/login/external' />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -21,7 +21,7 @@ import { Button, Card, CardBody, CardHeader, CardTitle, Column, Form, FormAction
|
|||
|
||||
/*
|
||||
Security settings page for user account
|
||||
Routed to /auth/mfa
|
||||
Routed to /settings/mfa
|
||||
Includes following features:
|
||||
- Set up Multi-factor Auth
|
||||
*/
|
||||
|
|
|
@ -33,7 +33,7 @@ const Settings = () => {
|
|||
|
||||
const navigateToChangeEmail = React.useCallback(() => history.push('/settings/email'), [history]);
|
||||
const navigateToChangePassword = React.useCallback(() => history.push('/settings/password'), [history]);
|
||||
const navigateToMfa = React.useCallback(() => history.push('/auth/mfa'), [history]);
|
||||
const navigateToMfa = React.useCallback(() => history.push('/settings/mfa'), [history]);
|
||||
const navigateToEditProfile = React.useCallback(() => history.push('/settings/profile'), [history]);
|
||||
|
||||
const isMfaEnabled = mfa.getIn(['settings', 'totp']);
|
||||
|
|
|
@ -59,7 +59,7 @@ const LinkFooter: React.FC = (): JSX.Element => {
|
|||
{(features.federating && features.accountMoving) && (
|
||||
<FooterLink to='/settings/migration'><FormattedMessage id='navigation_bar.account_migration' defaultMessage='Move account' /></FooterLink>
|
||||
)}
|
||||
<FooterLink to='/auth/sign_out' onClick={onClickLogOut}><FormattedMessage id='navigation_bar.logout' defaultMessage='Logout' /></FooterLink>
|
||||
<FooterLink to='/logout' onClick={onClickLogOut}><FormattedMessage id='navigation_bar.logout' defaultMessage='Logout' /></FooterLink>
|
||||
</>}
|
||||
</div>
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ const ProfileDropdown: React.FC<IProfileDropdown> = ({ account, children }) => {
|
|||
|
||||
menu.push({
|
||||
text: intl.formatMessage(messages.logout, { acct: account.acct }),
|
||||
to: '/auth/sign_out',
|
||||
to: '/logout',
|
||||
action: handleLogOut,
|
||||
icon: require('@tabler/icons/icons/logout.svg'),
|
||||
});
|
||||
|
|
|
@ -120,6 +120,7 @@ import {
|
|||
CreateApp,
|
||||
SettingsStore,
|
||||
TestTimeline,
|
||||
LogoutPage,
|
||||
} from './util/async-components';
|
||||
import { WrappedRoute } from './util/react_router_helpers';
|
||||
|
||||
|
@ -221,11 +222,16 @@ class SwitchingColumnsArea extends React.PureComponent {
|
|||
const authenticatedProfile = soapbox.get('authenticatedProfile');
|
||||
const hasCrypto = soapbox.get('cryptoAddresses').size > 0;
|
||||
|
||||
// NOTE: Mastodon and Pleroma route some basenames to the backend.
|
||||
// When adding new routes, use a basename that does NOT conflict
|
||||
// with a known backend route, but DO redirect the backend route
|
||||
// to the corresponding component as a fallback.
|
||||
// Ex: use /login instead of /auth, but redirect /auth to /login
|
||||
return (
|
||||
<Switch>
|
||||
<WrappedRoute path='/auth/external' component={ExternalLogin} publicRoute exact />
|
||||
<WrappedRoute path='/auth/mfa' page={DefaultPage} component={MfaForm} exact />
|
||||
<WrappedRoute path='/auth/confirmation' page={EmptyPage} component={EmailConfirmation} publicRoute exact />
|
||||
<WrappedRoute path='/login/external' component={ExternalLogin} publicRoute exact />
|
||||
<WrappedRoute path='/email-confirmation' page={EmptyPage} component={EmailConfirmation} publicRoute exact />
|
||||
<WrappedRoute path='/logout' page={EmptyPage} component={LogoutPage} publicRoute exact />
|
||||
|
||||
<WrappedRoute path='/' exact page={HomePage} component={HomeTimeline} content={children} />
|
||||
|
||||
|
@ -240,6 +246,7 @@ class SwitchingColumnsArea extends React.PureComponent {
|
|||
<WrappedRoute path='/conversations' page={DefaultPage} component={Conversations} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||
<WrappedRoute path='/messages' page={DefaultPage} component={features.directTimeline ? DirectTimeline : Conversations} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||
|
||||
{/* Gab groups */}
|
||||
{/*
|
||||
<WrappedRoute path='/groups' exact page={GroupsPage} component={Groups} content={children} componentParams={{ activeTab: 'featured' }} />
|
||||
<WrappedRoute path='/groups/create' page={GroupsPage} component={Groups} content={children} componentParams={{ showCreateForm: true, activeTab: 'featured' }} />
|
||||
|
@ -251,7 +258,7 @@ class SwitchingColumnsArea extends React.PureComponent {
|
|||
<WrappedRoute path='/groups/:id' page={GroupPage} component={GroupTimeline} content={children} />
|
||||
*/}
|
||||
|
||||
{/* Redirects from Mastodon, Pleroma FE, etc. to fix old bookmarks */}
|
||||
{/* Mastodon web routes */}
|
||||
<Redirect from='/web/:path1/:path2/:path3' to='/:path1/:path2/:path3' />
|
||||
<Redirect from='/web/:path1/:path2' to='/:path1/:path2' />
|
||||
<Redirect from='/web/:path' to='/:path' />
|
||||
|
@ -259,6 +266,8 @@ class SwitchingColumnsArea extends React.PureComponent {
|
|||
<Redirect from='/timelines/public/local' to='/timeline/local' />
|
||||
<Redirect from='/timelines/public' to='/timeline/fediverse' />
|
||||
<Redirect from='/timelines/direct' to='/messages' />
|
||||
|
||||
{/* Pleroma FE web routes */}
|
||||
<Redirect from='/main/all' to='/timeline/fediverse' />
|
||||
<Redirect from='/main/public' to='/timeline/local' />
|
||||
<Redirect from='/main/friends' to='/' />
|
||||
|
@ -268,12 +277,35 @@ class SwitchingColumnsArea extends React.PureComponent {
|
|||
<Redirect from='/users/:username/statuses/:statusId' to='/@:username/posts/:statusId' />
|
||||
<Redirect from='/users/:username/chats' to='/chats' />
|
||||
<Redirect from='/users/:username' to='/@:username' />
|
||||
<Redirect from='/terms' to='/about' />
|
||||
<Redirect from='/registration' to='/' exact />
|
||||
|
||||
{/* Gab */}
|
||||
<Redirect from='/home' to='/' />
|
||||
|
||||
{/* Mastodon rendered pages */}
|
||||
<Redirect from='/admin/dashboard' to='/admin' exact />
|
||||
<Redirect from='/terms' to='/about' />
|
||||
<Redirect from='/settings/preferences' to='/settings' />
|
||||
<Redirect from='/settings/two_factor_authentication_methods' to='/settings/mfa' />
|
||||
<Redirect from='/settings/otp_authentication' to='/settings/mfa' />
|
||||
<Redirect from='/settings/applications' to='/developers' />
|
||||
<Redirect from='/auth/edit' to='/settings' />
|
||||
<Redirect from='/auth/confirmation' to={`/email-confirmation${this.props.location.search}`} />
|
||||
<Redirect from='/auth/reset_password' to='/reset-password' />
|
||||
<Redirect from='/auth/edit_password' to='/edit-password' />
|
||||
<Redirect from='/auth/sign_in' to='/login' />
|
||||
<Redirect from='/auth/sign_out' to='/logout' />
|
||||
|
||||
{/* Pleroma hard-coded email URLs */}
|
||||
<Redirect from='/registration/:token' to='/invite/:token' />
|
||||
|
||||
{/* Soapbox Legacy redirects */}
|
||||
<Redirect from='/canary' to='/about/canary' />
|
||||
<Redirect from='/canary.txt' to='/about/canary' />
|
||||
<Redirect from='/auth/external' to='/login/external' />
|
||||
<Redirect from='/auth/mfa' to='/settings/mfa' />
|
||||
<Redirect from='/auth/password/new' to='/reset-password' />
|
||||
<Redirect from='/auth/password/edit' to='/edit-password' />
|
||||
|
||||
<WrappedRoute path='/tags/:id' publicRoute page={DefaultPage} component={HashtagTimeline} content={children} />
|
||||
|
||||
|
@ -310,14 +342,8 @@ class SwitchingColumnsArea extends React.PureComponent {
|
|||
<WrappedRoute path='/statuses/:statusId' exact component={Status} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
|
||||
{features.scheduledStatuses && <WrappedRoute path='/scheduled_statuses' page={DefaultPage} component={ScheduledStatuses} content={children} />}
|
||||
|
||||
<Redirect from='/registration/:token' to='/invite/:token' />
|
||||
<Redirect from='/registration' to='/' />
|
||||
<WrappedRoute path='/invite/:token' component={RegisterInvite} content={children} publicRoute />
|
||||
|
||||
<Redirect from='/auth/edit' to='/settings' />
|
||||
<Redirect from='/settings/preferences' to='/settings' />
|
||||
<Redirect from='/auth/password/new' to='/reset-password' />
|
||||
<Redirect from='/auth/password/edit' to='/edit-password' />
|
||||
<WrappedRoute path='/settings/profile' page={DefaultPage} component={EditProfile} content={children} />
|
||||
<WrappedRoute path='/settings/export' page={DefaultPage} component={ExportData} content={children} />
|
||||
<WrappedRoute path='/settings/import' page={DefaultPage} component={ImportData} content={children} />
|
||||
|
@ -327,11 +353,11 @@ class SwitchingColumnsArea extends React.PureComponent {
|
|||
<WrappedRoute path='/settings/password' page={DefaultPage} component={EditPassword} content={children} />
|
||||
<WrappedRoute path='/settings/account' page={DefaultPage} component={DeleteAccount} content={children} />
|
||||
<WrappedRoute path='/settings/media_display' page={DefaultPage} component={MediaDisplay} content={children} />
|
||||
<WrappedRoute path='/settings/mfa' page={DefaultPage} component={MfaForm} exact />
|
||||
<WrappedRoute path='/settings' page={DefaultPage} component={Settings} content={children} />
|
||||
{/* <WrappedRoute path='/backups' page={DefaultPage} component={Backups} content={children} /> */}
|
||||
<WrappedRoute path='/soapbox/config' adminOnly page={DefaultPage} component={SoapboxConfig} content={children} />
|
||||
|
||||
<Redirect from='/admin/dashboard' to='/admin' exact />
|
||||
<WrappedRoute path='/admin' staffOnly page={AdminPage} component={Dashboard} content={children} exact />
|
||||
<WrappedRoute path='/admin/approval' staffOnly page={AdminPage} component={AwaitingApproval} content={children} exact />
|
||||
<WrappedRoute path='/admin/reports' staffOnly page={AdminPage} component={Reports} content={children} exact />
|
||||
|
|
|
@ -250,6 +250,10 @@ export function ExternalLogin() {
|
|||
return import(/* webpackChunkName: "features/external_login" */'../../external_login');
|
||||
}
|
||||
|
||||
export function LogoutPage() {
|
||||
return import(/* webpackChunkName: "features/auth_login" */'../../auth_login/components/logout');
|
||||
}
|
||||
|
||||
export function Settings() {
|
||||
return import(/* webpackChunkName: "features/settings" */'../../settings');
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ const WaitlistPage = ({ account }) => {
|
|||
</Link>
|
||||
|
||||
<div className='absolute inset-y-0 right-0 flex items-center pr-2 space-x-3'>
|
||||
<Button onClick={onClickLogOut} theme='primary' to='/auth/sign_out'>
|
||||
<Button onClick={onClickLogOut} theme='primary' to='/logout'>
|
||||
Sign out
|
||||
</Button>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue