Skip to content

Commit

Permalink
Merge pull request #5555 from Expensify/marcaaron-cleanUpPusherSubscr…
Browse files Browse the repository at this point in the history
…iptions

Cleanup Pusher subscriptions when signing out in another tab
  • Loading branch information
aldo-expensify committed Sep 28, 2021
2 parents 2036c3f + ccef3d9 commit d54f307
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 27 deletions.
3 changes: 3 additions & 0 deletions src/ONYXKEYS.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,7 @@ export default {

// Stores Workspace ID that will be tied to reimbursement account during setup
REIMBURSEMENT_ACCOUNT_WORKSPACE_ID: 'reimbursementAccountWorkspaceID',

// Notifies all tabs that they should sign out and clear storage.
SHOULD_SIGN_OUT: 'shouldSignOut',
};
3 changes: 2 additions & 1 deletion src/libs/Navigation/AppNavigator/AuthScreens.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import CardOverlay from '../../../components/CardOverlay';
import defaultScreenOptions from './defaultScreenOptions';
import * as API from '../../API';
import {setLocale} from '../../actions/App';
import {cleanupSession} from '../../actions/Session';
import WorkspaceNew from '../../../pages/workspace/WorkspaceNew';

Onyx.connect({
Expand Down Expand Up @@ -249,7 +250,7 @@ class AuthScreens extends React.Component {
if (this.unsubscribeGroupShortcut) {
this.unsubscribeGroupShortcut();
}
NetworkConnection.stopListeningForReconnect();
cleanupSession();
clearInterval(this.interval);
this.interval = null;
hasLoadedPolicies = false;
Expand Down
38 changes: 38 additions & 0 deletions src/libs/SignoutManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import Onyx from 'react-native-onyx';
import ONYXKEYS from '../ONYXKEYS';

let signoutCallback = () => {};
let errorMessage = '';
let shouldSignOut = false;
Onyx.connect({
key: ONYXKEYS.SHOULD_SIGN_OUT,
callback: (val) => {
if (!shouldSignOut && val) {
signoutCallback(errorMessage);
errorMessage = '';
Onyx.set(ONYXKEYS.SHOULD_SIGN_OUT, false);
}

shouldSignOut = val;
},
});

/**
* @param {Function} callback
*/
function registerSignoutCallback(callback) {
signoutCallback = callback;
}

/**
* @param {String} message
*/
function signOut(message) {
errorMessage = message;
Onyx.set(ONYXKEYS.SHOULD_SIGN_OUT, true);
}

export default {
signOut,
registerSignoutCallback,
};
19 changes: 18 additions & 1 deletion src/libs/actions/Session.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ import Navigation from '../Navigation/Navigation';
import ROUTES from '../../ROUTES';
import {translateLocal} from '../translate';
import * as Network from '../Network';
import UnreadIndicatorUpdater from '../UnreadIndicatorUpdater';
import Timers from '../Timers';
import * as Pusher from '../Pusher/pusher';
import NetworkConnection from '../NetworkConnection';
import {getUserDetails} from './User';


let credentials = {};
Onyx.connect({
key: ONYXKEYS.CREDENTIALS,
Expand Down Expand Up @@ -339,6 +342,19 @@ function continueSessionFromECom(accountID, validateCode, twoFactorAuthCode) {
});
}

/**
* Put any logic that needs to run when we are signed out here. This can be triggered when the current tab or another tab signs out.
*/
function cleanupSession() {
// We got signed out in this tab or another so clean up any subscriptions and timers
NetworkConnection.stopListeningForReconnect();
UnreadIndicatorUpdater.stopListeningForReportChanges();
PushNotification.deregister();
PushNotification.clearNotifications();
Pusher.disconnect();
Timers.clearAll();
}

export {
continueSessionFromECom,
fetchAccountDetails,
Expand All @@ -349,4 +365,5 @@ export {
reopenAccount,
resendValidationLink,
resetPassword,
cleanupSession,
};
41 changes: 16 additions & 25 deletions src/libs/actions/SignInRedirect.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import Onyx from 'react-native-onyx';
import SignoutManager from '../SignoutManager';
import ONYXKEYS from '../../ONYXKEYS';
import * as Pusher from '../Pusher/pusher';
import UnreadIndicatorUpdater from '../UnreadIndicatorUpdater';
import PushNotification from '../Notification/PushNotification';
import Timers from '../Timers';

let currentActiveClients;
Onyx.connect({
Expand All @@ -20,18 +17,9 @@ Onyx.connect({
});

/**
* Clears the Onyx store and redirects to the sign in page.
* Normally this method would live in Session.js, but that would cause a circular dependency with Network.js.
*
* @param {String} [errorMessage] error message to be displayed on the sign in page
* @param {String} errorMessage
*/
function redirectToSignIn(errorMessage) {
UnreadIndicatorUpdater.stopListeningForReportChanges();
PushNotification.deregister();
PushNotification.clearNotifications();
Pusher.disconnect();
Timers.clearAll();

function clearStorageAndRedirect(errorMessage) {
const activeClients = currentActiveClients;
const preferredLocale = currentPreferredLocale;

Expand All @@ -45,18 +33,21 @@ function redirectToSignIn(errorMessage) {
Onyx.set(ONYXKEYS.ACTIVE_CLIENTS, activeClients);
}

const session = {
// We must set the authToken to null so that signOut action is triggered across other clients
authToken: null,
};

if (errorMessage) {
session.error = errorMessage;
}

// `Onyx.clear` reinitialize the Onyx instance with initial values so use `Onyx.merge` instead of `Onyx.set`.
Onyx.merge(ONYXKEYS.SESSION, session);
Onyx.merge(ONYXKEYS.SESSION, {error: errorMessage});
});
}

SignoutManager.registerSignoutCallback(clearStorageAndRedirect);

/**
* Clears the Onyx store and redirects to the sign in page.
* Normally this method would live in Session.js, but that would cause a circular dependency with Network.js.
*
* @param {String} [errorMessage] error message to be displayed on the sign in page
*/
function redirectToSignIn(errorMessage) {
SignoutManager.signOut(errorMessage);
}

export default redirectToSignIn;

0 comments on commit d54f307

Please sign in to comment.