Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix MM-61975 #8459

Merged
merged 11 commits into from
Feb 17, 2025
2 changes: 1 addition & 1 deletion app/actions/remote/session.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ describe('sessions', () => {
});

it('logout - base case', async () => {
const result = await logout(serverUrl, true, true, true);
const result = await logout(serverUrl, undefined, {skipServerLogout: true, removeServer: true, skipEvents: true});
expect(result).toBeDefined();
expect(result.data).toBeDefined();
});
Expand Down
55 changes: 51 additions & 4 deletions app/actions/remote/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// See LICENSE.txt for license information.

import NetInfo from '@react-native-community/netinfo';
import {DeviceEventEmitter, Platform} from 'react-native';
import {Alert, DeviceEventEmitter, Platform, type AlertButton} from 'react-native';

import {Database, Events} from '@constants';
import {SYSTEM_IDENTIFIERS} from '@constants/database';
Expand All @@ -22,6 +22,7 @@ import {getCSRFFromCookie} from '@utils/security';
import {loginEntry} from './entry';

import type {LoginArgs} from '@typings/database/database';
import type {IntlShape} from 'react-intl';

const HTTP_UNAUTHORIZED = 401;

Expand Down Expand Up @@ -56,7 +57,7 @@ export const forceLogoutIfNecessary = async (serverUrl: string, err: unknown) =>
const currentUserId = await getCurrentUserId(database);

if (isErrorWithStatusCode(err) && err.status_code === HTTP_UNAUTHORIZED && isErrorWithUrl(err) && err.url?.indexOf('/login') === -1 && currentUserId) {
await logout(serverUrl);
await logout(serverUrl, undefined, {skipServerLogout: true});
return {error: null, logout: true};
}

Expand Down Expand Up @@ -135,15 +136,61 @@ export const login = async (serverUrl: string, {ldapOnly = false, loginId, mfaTo
}
};

export const logout = async (serverUrl: string, skipServerLogout = false, removeServer = false, skipEvents = false) => {
type LogoutOptions = {
skipServerLogout?: boolean;
removeServer?: boolean;
skipEvents?: boolean;
logoutOnAlert?: boolean;
};

export const logout = async (
serverUrl: string,
intl: IntlShape | undefined,
{
skipServerLogout = false,
removeServer = false,
skipEvents = false,
logoutOnAlert = false,
}: LogoutOptions = {}) => {
if (!skipServerLogout) {
let loggedOut = false;
try {
const client = NetworkManager.getClient(serverUrl);
await client.logout();
const response = await client.logout();
if (response.status === 200) {
loggedOut = true;
}
} catch (error) {
// We want to log the user even if logging out from the server failed
logWarning('An error occurred logging out from the server', serverUrl, getFullErrorMessage(error));
}

if (!loggedOut) {
const title = intl?.formatMessage({id: 'logout.fail.title', defaultMessage: 'Logout Failed'}) || 'Logout Failed';

const body = logoutOnAlert ?
intl?.formatMessage({id: 'logout.fail.message.forced', defaultMessage: 'We could not log you out of the server. Data may continue to be accessible to this device once the device goes back online.'}) || 'We could not log you out of the server. Data may continue to be accessible to this device once the device goes back online.' :
intl?.formatMessage({id: 'logout.fail.message', defaultMessage: 'We could not log you out of the server. If you log out now, data may continue to be accessible to this device once the device goes back online. Do you still want to continue?'}) || 'We could not log you out of the server. If you log out now, data may continue to be accessible to this device once the device goes back online. Do you still want to continue?';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could potentially add to a variable so that you don't have to repeat twice?

const cancel = intl?.formatMessage({id: 'logout.fail.cancel', defaultMessage: 'Cancel'}) || 'Cancel';
const confirm = intl?.formatMessage({id: 'logout.fail.confirm', defaultMessage: 'Confirm'}) || 'Confirm';

const buttons: AlertButton[] = logoutOnAlert ? [] : [{text: cancel, style: 'cancel'}];
buttons.push({
text: confirm,
onPress: logoutOnAlert ? undefined : async () => {
logout(serverUrl, intl, {skipServerLogout: true});
},
});
Alert.alert(
title,
body,
buttons,
);

if (!logoutOnAlert) {
return {data: false};
}
}
}

if (!skipEvents) {
Expand Down
3 changes: 3 additions & 0 deletions app/client/rest/tracking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {t} from '@i18n';
import {setServerCredentials} from '@init/credentials';
import PerformanceMetricsManager from '@managers/performance_metrics_manager';
import {NetworkRequestMetrics} from '@managers/performance_metrics_manager/constant';
import {isErrorWithStatusCode} from '@utils/errors';
import {getFormattedFileSize} from '@utils/file';
import {logDebug, logInfo} from '@utils/log';
import {semverFromServerVersion} from '@utils/server';
Expand Down Expand Up @@ -405,6 +406,7 @@ export default class ClientTracking {
url,
});
} catch (error) {
const status_code = isErrorWithStatusCode(error) ? error.status_code : undefined;
throw new ClientError(this.apiClient.baseUrl, {
message: 'Received invalid response from the server.',
intl: {
Expand All @@ -413,6 +415,7 @@ export default class ClientTracking {
},
url,
details: error,
status_code,
});
} finally {
if (groupLabel && CollectNetworkMetrics) {
Expand Down
2 changes: 1 addition & 1 deletion app/managers/session_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ class SessionManager {

private onSessionExpired = async (serverUrl: string) => {
this.terminatingSessionUrl.add(serverUrl);
await logout(serverUrl, false, false, true);
await logout(serverUrl, undefined, {skipServerLogout: true, skipEvents: true});
await this.terminateSession(serverUrl, false);

const activeServerUrl = await DatabaseManager.getActiveServerUrl();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const LogOut = () => {

const onLogout = useCallback(preventDoubleTap(() => {
Navigation.updateProps(Screens.HOME, {extra: undefined});
alertServerLogout(serverDisplayName, () => logout(serverUrl), intl);
alertServerLogout(serverDisplayName, () => logout(serverUrl, intl), intl);
}), [serverDisplayName, serverUrl, intl]);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,8 @@ const ChannelListHeader = ({
}, [pushProxyStatus, intl]);

const onLogoutPress = useCallback(() => {
alertServerLogout(serverDisplayName, () => logout(serverUrl), intl);
}, []);
alertServerLogout(serverDisplayName, () => logout(serverUrl, intl), intl);
}, [intl, serverDisplayName, serverUrl]);

let header;
if (displayName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,21 +181,21 @@ const ServerItem = ({

const logoutServer = useCallback(async () => {
Navigation.updateProps(Screens.HOME, {extra: undefined});
await logout(server.url);
await logout(server.url, intl);

if (isActive) {
dismissBottomSheet();
} else {
DeviceEventEmitter.emit(Events.SWIPEABLE, '');
}
}, [isActive, server.url]);
}, [intl, isActive, server.url]);

const removeServer = useCallback(async () => {
const skipLogoutFromServer = server.lastActiveAt === 0;
const skipServerLogout = server.lastActiveAt === 0;
await dismissBottomSheet();
Navigation.updateProps(Screens.HOME, {extra: undefined});
await logout(server.url, skipLogoutFromServer, true);
}, [server.lastActiveAt, server.url]);
await logout(server.url, intl, {skipServerLogout, removeServer: true});
}, [intl, server.lastActiveAt, server.url]);

const startTutorial = () => {
viewRef.current?.measureInWindow((x, y, w, h) => {
Expand Down
4 changes: 2 additions & 2 deletions app/screens/select_team/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ function Header() {

const headerStyle = useMemo(() => ({...styles.header, marginLeft: canAddOtherServers ? MARGIN_WITH_SERVER_ICON : undefined}), [canAddOtherServers]);
const onLogoutPress = useCallback(() => {
alertServerLogout(serverDisplayName, () => logout(serverUrl), intl);
}, [serverUrl, serverDisplayName]);
alertServerLogout(serverDisplayName, () => logout(serverUrl, intl), intl);
}, [serverDisplayName, intl, serverUrl]);

const onLabelPress = useCallback(() => {
serverButtonRef.current?.openServers();
Expand Down
4 changes: 2 additions & 2 deletions app/screens/terms_of_service/terms_of_service.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ const TermsOfService = ({

const closeTermsAndLogout = useCallback(() => {
dismissOverlay(componentId);
logout(serverUrl);
}, [serverUrl, componentId]);
logout(serverUrl, intl, {logoutOnAlert: true});
}, [serverUrl, componentId, intl]);

const alertError = useCallback((retry: () => void) => {
Alert.alert(
Expand Down
4 changes: 4 additions & 0 deletions assets/base/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,10 @@
"login.signIn": "Log In",
"login.signingIn": "Logging In",
"login.username": "Username",
"logout.fail.cancel": "Cancel",
"logout.fail.confirm": "Confirm",
"logout.fail.message": "We could not log you out of the server. If you log out now, data may continue to be accessible to this device once the device goes back online. Do you still want to continue?",
"logout.fail.title": "Logout Failed",
"markdown.latex.error": "Latex render error",
"markdown.max_nodes.error": "This message is too long to by shown fully on a mobile device. Please view it on desktop or contact an admin to increase this limit.",
"markdown.parse_error": "An error occurred while parsing this text",
Expand Down
Loading