From 6c6d6297f95cacbc17165934267cd65e59dfbf03 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 11 Apr 2020 14:41:13 -0500 Subject: [PATCH] LogOut working --- app/gabsocial/actions/auth.js | 12 ++++++++++++ app/gabsocial/components/sidebar_menu.js | 11 ++++++++--- app/gabsocial/features/auth_login/index.js | 2 -- .../features/compose/components/action_bar.js | 13 +++++++++---- app/gabsocial/features/ui/components/link_footer.js | 9 +++++++-- app/gabsocial/features/ui/index.js | 2 +- app/gabsocial/reducers/auth.js | 4 ++++ app/gabsocial/reducers/me.js | 3 +++ 8 files changed, 44 insertions(+), 12 deletions(-) diff --git a/app/gabsocial/actions/auth.js b/app/gabsocial/actions/auth.js index 1ff3648d0..f63d43aaa 100644 --- a/app/gabsocial/actions/auth.js +++ b/app/gabsocial/actions/auth.js @@ -1,8 +1,10 @@ import api from '../api'; +import { showAlert } from 'gabsocial/actions/alerts'; export const AUTH_APP_CREATED = 'AUTH_APP_CREATED'; export const AUTH_APP_AUTHORIZED = 'AUTH_APP_AUTHORIZED'; export const AUTH_LOGGED_IN = 'AUTH_LOGGED_IN'; +export const AUTH_LOGGED_OUT = 'AUTH_LOGGED_OUT'; export function createAuthApp() { return (dispatch, getState) => { @@ -39,10 +41,20 @@ export function logIn(username, password) { password: password }).then(response => { dispatch(authLoggedIn(response.data)); + }).catch((error) => { + dispatch(showAlert('Login failed.', 'Invalid username or password.')); + throw error; }); } } +export function logOut() { + return (dispatch, getState) => { + dispatch({ type: AUTH_LOGGED_OUT }); + dispatch(showAlert('Successfully logged out.', '')); + }; +} + export function authAppCreated(app) { return { type: AUTH_APP_CREATED, diff --git a/app/gabsocial/components/sidebar_menu.js b/app/gabsocial/components/sidebar_menu.js index 70637d312..94517cb4a 100644 --- a/app/gabsocial/components/sidebar_menu.js +++ b/app/gabsocial/components/sidebar_menu.js @@ -13,6 +13,7 @@ import DisplayName from './display_name'; import { closeSidebar } from '../actions/sidebar'; import { shortNumberFormat } from '../utils/numbers'; import { makeGetAccount } from '../selectors'; +import { logOut } from 'gabsocial/actions/auth'; const messages = defineMessages({ followers: { id: 'account.followers', defaultMessage: 'Followers' }, @@ -46,6 +47,10 @@ const mapDispatchToProps = (dispatch) => ({ onClose () { dispatch(closeSidebar()); }, + onClickLogOut(e) { + dispatch(logOut()); + e.preventDefault(); + }, }); export default @connect(mapStateToProps, mapDispatchToProps) @@ -60,7 +65,7 @@ class SidebarMenu extends ImmutablePureComponent { }; render () { - const { sidebarOpen, onClose, intl, account } = this.props; + const { sidebarOpen, onClose, intl, account, onClickLogOut } = this.props; if (!account) return null; const acct = account.get('acct'); @@ -150,9 +155,9 @@ class SidebarMenu extends ImmutablePureComponent {
- + {intl.formatMessage(messages.logout)} - +
diff --git a/app/gabsocial/features/auth_login/index.js b/app/gabsocial/features/auth_login/index.js index 35c60022f..a8a5900c6 100644 --- a/app/gabsocial/features/auth_login/index.js +++ b/app/gabsocial/features/auth_login/index.js @@ -4,7 +4,6 @@ import ImmutablePureComponent from 'react-immutable-pure-component'; import { createAuthApp, logIn } from 'gabsocial/actions/auth'; import { fetchMe } from 'gabsocial/actions/me'; import { Link } from 'react-router-dom'; -import { showAlert } from 'gabsocial/actions/alerts'; export default @connect() class LoginForm extends ImmutablePureComponent { @@ -29,7 +28,6 @@ class LoginForm extends ImmutablePureComponent { dispatch(logIn(username, password)).then(() => { return dispatch(fetchMe()); }).catch((error) => { - dispatch(showAlert('Login failed', 'Invalid username or password.')); this.setState({isLoading: false}); }); this.setState({isLoading: true}); diff --git a/app/gabsocial/features/compose/components/action_bar.js b/app/gabsocial/features/compose/components/action_bar.js index 878a033b0..7f106f62a 100644 --- a/app/gabsocial/features/compose/components/action_bar.js +++ b/app/gabsocial/features/compose/components/action_bar.js @@ -6,6 +6,7 @@ import PropTypes from 'prop-types'; import DropdownMenuContainer from '../../../containers/dropdown_menu_container'; import { defineMessages, injectIntl } from 'react-intl'; import { meUsername } from 'gabsocial/initial_state'; +import { logOut } from 'gabsocial/actions/auth'; const messages = defineMessages({ profile: { id: 'account.profile', defaultMessage: 'Profile' }, @@ -24,6 +25,10 @@ const mapDispatchToProps = (dispatch) => ({ onOpenHotkeys() { dispatch(openModal('HOTKEYS')); }, + onClickLogOut(e) { + dispatch(logOut()); + e.preventDefault(); + }, }); class ActionBar extends React.PureComponent { @@ -38,7 +43,7 @@ class ActionBar extends React.PureComponent { } render () { - const { intl, onOpenHotkeys } = this.props; + const { intl, onOpenHotkeys, onClickLogOut } = this.props; const size = this.props.size || 16; let menu = []; @@ -50,11 +55,11 @@ class ActionBar extends React.PureComponent { menu.push({ text: intl.formatMessage(messages.mutes), to: '/mutes' }); menu.push({ text: intl.formatMessage(messages.blocks), to: '/blocks' }); menu.push({ text: intl.formatMessage(messages.domain_blocks), to: '/domain_blocks' }); - menu.push({ text: intl.formatMessage(messages.filters), href: '/filters' }); + menu.push({ text: intl.formatMessage(messages.filters), to: '/filters' }); menu.push(null); menu.push({ text: intl.formatMessage(messages.keyboard_shortcuts), action: this.handleHotkeyClick }); - menu.push({ text: intl.formatMessage(messages.preferences), href: '/settings/preferences' }); - menu.push({ text: intl.formatMessage(messages.logout), href: '/auth/sign_out', isLogout: true }); + menu.push({ text: intl.formatMessage(messages.preferences), to: '/settings/preferences' }); + menu.push({ text: intl.formatMessage(messages.logout), to: '/auth/sign_out', action: onClickLogOut }); return (
diff --git a/app/gabsocial/features/ui/components/link_footer.js b/app/gabsocial/features/ui/components/link_footer.js index 65b22971b..36ac48552 100644 --- a/app/gabsocial/features/ui/components/link_footer.js +++ b/app/gabsocial/features/ui/components/link_footer.js @@ -5,6 +5,7 @@ import { Link } from 'react-router-dom'; import { invitesEnabled, version, repository, source_url } from 'gabsocial/initial_state'; import { connect } from 'react-redux'; import { openModal } from '../../../actions/modal'; +import { logOut } from 'gabsocial/actions/auth'; const mapStateToProps = state => { const me = state.get('me'); @@ -18,9 +19,13 @@ const mapDispatchToProps = (dispatch) => ({ onOpenHotkeys() { dispatch(openModal('HOTKEYS')); }, + onClickLogOut(e) { + dispatch(logOut()); + e.preventDefault(); + }, }); -const LinkFooter = ({ onOpenHotkeys, account, siteTitle }) => ( +const LinkFooter = ({ onOpenHotkeys, account, siteTitle, onClickLogOut }) => (
    {(invitesEnabled && account) &&
  • ·
  • } @@ -31,7 +36,7 @@ const LinkFooter = ({ onOpenHotkeys, account, siteTitle }) => (
  • ·
  • ·
  • - {account &&
  • · 
  • } + {account &&
  • · 
  • }

diff --git a/app/gabsocial/features/ui/index.js b/app/gabsocial/features/ui/index.js index a6a49b12a..616573862 100644 --- a/app/gabsocial/features/ui/index.js +++ b/app/gabsocial/features/ui/index.js @@ -479,7 +479,7 @@ class UI extends React.PureComponent { const { me } = this.props; this.hotkeys = c; - if (!me) return; + if (!me || !this.hotkeys) return; this.hotkeys.__mousetrap__.stopCallback = (e, element) => { return ['TEXTAREA', 'SELECT', 'INPUT'].includes(element.tagName); }; diff --git a/app/gabsocial/reducers/auth.js b/app/gabsocial/reducers/auth.js index 1738ce64d..241471a08 100644 --- a/app/gabsocial/reducers/auth.js +++ b/app/gabsocial/reducers/auth.js @@ -2,6 +2,7 @@ import { AUTH_APP_CREATED, AUTH_LOGGED_IN, AUTH_APP_AUTHORIZED, + AUTH_LOGGED_OUT, } from '../actions/auth'; import { Map as ImmutableMap, fromJS } from 'immutable'; @@ -22,6 +23,9 @@ export default function auth(state = initialState, action) { case AUTH_LOGGED_IN: localStorage.setItem('soapbox:auth:user', JSON.stringify(action.user)); // TODO: Better persistence return state.set('user', ImmutableMap(action.user)); + case AUTH_LOGGED_OUT: + localStorage.removeItem('soapbox:auth:user'); + return state.setIn(['user'], ImmutableMap()); default: return state; } diff --git a/app/gabsocial/reducers/me.js b/app/gabsocial/reducers/me.js index 649b0db40..6f52a7164 100644 --- a/app/gabsocial/reducers/me.js +++ b/app/gabsocial/reducers/me.js @@ -1,4 +1,5 @@ import { ME_FETCH_SUCCESS, ME_FETCH_FAIL } from '../actions/me'; +import { AUTH_LOGGED_OUT } from '../actions/auth'; import { Map as ImmutableMap, fromJS } from 'immutable'; const initialState = null; @@ -9,6 +10,8 @@ export default function me(state = initialState, action) { return fromJS(action.me.id); case ME_FETCH_FAIL: return false; + case AUTH_LOGGED_OUT: + return false; default: return state; }