[MM-66711] Verify push notifications on magic link login (#9322)

* [MM-66711] Verify push notifications on magic link login

* Address copilot suggestion

* Add missing await

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
Daniel Espino García 2025-12-18 13:31:18 +01:00 committed by GitHub
parent c42ebca8d3
commit 4934920e10
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 32 additions and 6 deletions

View file

@ -5,6 +5,7 @@ import {defineMessages, type IntlShape} from 'react-intl';
import {Alert, DeviceEventEmitter, type AlertButton} from 'react-native';
import {cancelSessionNotification, findSession} from '@actions/local/session';
import {doPing} from '@actions/remote/general';
import {Database, Events} from '@constants';
import {SYSTEM_IDENTIFIERS} from '@constants/database';
import DatabaseManager from '@database/manager';
@ -18,8 +19,10 @@ import {getCurrentUser} from '@queries/servers/user';
import {resetToHome} from '@screens/navigation';
import EphemeralStore from '@store/ephemeral_store';
import {getFullErrorMessage, isErrorWithStatusCode, isErrorWithUrl} from '@utils/errors';
import {getIntlShape} from '@utils/general';
import {logWarning, logError, logDebug} from '@utils/log';
import {scheduleExpiredNotification} from '@utils/notification';
import {canReceiveNotifications} from '@utils/push_proxy';
import {type SAMLChallenge} from '@utils/saml_challenge';
import {getCSRFFromCookie} from '@utils/security';
import {getServerUrlAfterRedirect} from '@utils/url';
@ -468,6 +471,19 @@ export const magicLinkLogin = async (serverUrl: string, token: string): Promise<
});
const csrfToken = await getCSRFFromCookie(serverUrlToUse);
client.setCSRFToken(csrfToken);
// Check push notification capability (similar to normal login flow)
const pingResult = await doPing(
serverUrlToUse,
true, // verifyPushProxy
undefined, // timeoutInterval
undefined, // preauthSecret
client, // client
);
if (!pingResult.error && pingResult.canReceiveNotifications) {
const intl = getIntlShape(user.locale);
await canReceiveNotifications(serverUrlToUse, pingResult.canReceiveNotifications as string, intl);
}
} catch (error) {
return {error, failed: true};
}

View file

@ -110,7 +110,12 @@ const EditServer = ({closeButtonId, componentId, server, theme}: ServerProps) =>
}
// Then try ping request - use doPing without client to avoid client pollution
const result = await doPing(headRequest.url, true, undefined, secretForValidation);
const result = await doPing(
headRequest.url, // serverUrl
true, // verifyPushProxy
undefined, // timeoutInterval
secretForValidation, // preauthSecret
);
if (result.error) {
if (result.isPreauthError) {
setPreauthSecretError(formatMessage({

View file

@ -146,8 +146,8 @@ const Server = ({
handleConnect(managedConfig?.serverUrl || LocalConfig.DefaultServerUrl);
}
// functions do not need memoization
// eslint-disable-next-line react-hooks/exhaustive-deps
// We only want to handle connect when a smaller set of variables change
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [managedConfig?.allowOtherServers, managedConfig?.serverUrl, managedConfig?.serverName, defaultServerUrl]);
useEffect(() => {
@ -189,8 +189,8 @@ const Server = ({
return () => backHandler.remove();
// only needed on mount
// eslint-disable-next-line react-hooks/exhaustive-deps
// We register the back handler and the push notifications only on mount
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useNavButtonPressed(closeButtonId || '', componentId, dismiss, []);
@ -329,7 +329,12 @@ const Server = ({
}
return;
}
const result = await doPing(headRequest.url, true, managedConfig?.timeout ? parseInt(managedConfig?.timeout, 10) : undefined, preauthSecret.trim() || undefined);
const result = await doPing(
headRequest.url,
true, // verifyPushProxy
managedConfig?.timeout ? parseInt(managedConfig?.timeout, 10) : undefined, // timeoutInterval
preauthSecret.trim() || undefined, // preauthSecret
);
if (canceled) {
return;