react-native-splash-screen
react-native-splash-screen copied to clipboard
React Navigation deep linking - async getInitialURL(). Method [RNSplashScreen show]; breaks deep linking flow.
Hi all. I would like to report you about a serious issue that breaks the safety flow when dealing with deep links. My React-Native version 0.71.8
Flow to reproduce.
-
Setup React Navigation - https://reactnavigation.org
-
Setup Deep links
- https://reactnavigation.org/docs/deep-linking/
- https://itsitdude.medium.com/react-native-navigation-flow-deep-linking-b91d3237baf7
When an unauthorized user tries to call a deep link for a private screen, the app should automatically redirect the user to the login screen. The getInitialURL
method in the snippet below is responsible for preventing unauthorized users from visiting private screens.
import {Linking} from 'react-native';
import {restoreSession} from 'services/session';
import config from './config';
import {isPrivateRoute} from './utils';
const linking = {
prefixes: ['reactnavigation://app', 'https://reactnavigation.org'],
async getInitialURL() {
try {
const url = await Linking.getInitialURL();
// check if URL is for private screen (screen for authorized users)
if (isPrivateRoute(url || '')) {
await restoreSession(); // restore user session before show private screen
}
return url;
} catch (error) {
return 'reactnavigation://app/onboarding'; // This is fallback address in a case when url is not registered for deep linking.
}
},
subscribe(listener: any) {
const linkingSubscription = Linking.addEventListener('url', async ({url}) => {
try {
// check if URL is for private screen (screen for authorized users)
if (isPrivateRoute(url || '')) {
await restoreSession(); // restore user session before show private screen
}
return listener(url);
} catch (error) {
return 'reactnavigation://app/onboarding'; // This is fallback address in a case when url is not registered for deep linking.
}
});
return () => {
linkingSubscription.remove();
};
},
config,
};
export default linking;
This code works pretty good before injecting library react-native-splash-screen into ios/AppDelegeta.mm file.
Deep linking flow breaks once add a line [RNSplashScreen show]
into AppDelegate.mm file.
BOOL didFinishLaunchingSuccess = [super application:application didFinishLaunchingWithOptions:launchOptions];
// Call [RNSplashScreen show] only after [super application:didFinishLaunchingWithOptions:]
[RNSplashScreen show];
return didFinishLaunchingSuccess;
Next line of code [RNSplashScreen show] breaks navigation mechanism inside of method async getInitialURL() {...}. Unauthorized users able to land to private screens.
By removing a line [RNSplashScreen show]
from the ios/AppDelegate.mm file, the getInitialURL()
method will prevent unauthorized users from visiting private screens.
The issue was reproduced in different projects with different React Native versions (0.70+) I was unable to test this issue with React Native versions below 0.70.