Skip to content

Commit

Permalink
fix: validate soil id urls before allowing users to navigate to them (#…
Browse files Browse the repository at this point in the history
…1722)

Validate information URLs returned by the soil ID algorithm before displaying them to the user.
  • Loading branch information
tm-ruxandra authored Jul 5, 2024
1 parent 2ea683d commit e048e51
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 33 deletions.
45 changes: 25 additions & 20 deletions dev-client/src/components/links/ExternalLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* along with this program. If not, see https://www.gnu.org/licenses/.
*/

import React from 'react';
import React, {useCallback, useMemo} from 'react';
import {Linking, Pressable, StyleSheet, View} from 'react-native';

import {IconButton as NativeIconButton} from 'native-base';
Expand All @@ -26,6 +26,7 @@ import {
Row,
Text,
} from 'terraso-mobile-client/components/NativeBaseAdapters';
import {validateUrl} from 'terraso-mobile-client/util';

export type ExternalLinkProps = {
label: string;
Expand All @@ -34,27 +35,31 @@ export type ExternalLinkProps = {

export const ExternalLink = React.forwardRef(
({label, url}: ExternalLinkProps, ref: React.Ref<unknown>) => {
const icon = (
<NativeIconButton ref={ref} icon={<Icon name="open-in-new" />} />
);
const isValidUrl = useMemo(() => validateUrl(url), [url]);
const openUrl = useCallback(() => Linking.openURL(url), [url]);

return (
<View style={styles.container}>
<Pressable onPress={() => Linking.openURL(url)}>
<Box>
<Row alignItems="center">
<Text
color="primary.main"
fontSize="md"
textTransform="uppercase"
style={styles.label}>
{label}
</Text>
{icon}
</Row>
</Box>
</Pressable>
</View>
isValidUrl && (
<View style={styles.container}>
<Pressable onPress={openUrl}>
<Box>
<Row alignItems="center">
<Text
color="primary.main"
fontSize="md"
textTransform="uppercase"
style={styles.label}>
{label}
</Text>
<NativeIconButton
ref={ref}
icon={<Icon name="open-in-new" />}
/>
</Row>
</Box>
</Pressable>
</View>
)
);
},
);
Expand Down
27 changes: 14 additions & 13 deletions dev-client/src/components/links/InternalLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,32 @@
* along with this program. If not, see https://www.gnu.org/licenses/.
*/

import {useCallback} from 'react';
import {useCallback, useMemo} from 'react';
import {Linking} from 'react-native';

import {Link} from 'native-base';
import {InterfaceLinkProps} from 'native-base/lib/typescript/components/primitives/Link/types';

import {validateUrl} from 'terraso-mobile-client/util';

type InternalLinkProps = {
label: string;
onPress?: InterfaceLinkProps['onPress'];
url?: string;
url: string;
};

export default function InternalLink({label, onPress, url}: InternalLinkProps) {
const openUrl = useCallback(() => {
if (url !== undefined) {
Linking.openURL(url);
}
}, [url]);
const isValidUrl = useMemo(() => validateUrl(url), [url]);
const openUrl = useCallback(() => Linking.openURL(url), [url]);

return (
<Link
_text={{color: 'primary.main'}}
isUnderlined={true}
onPress={onPress ? onPress : openUrl}>
{label}
</Link>
isValidUrl && (
<Link
_text={{color: 'primary.main'}}
isUnderlined={true}
onPress={onPress ? onPress : openUrl}>
{label}
</Link>
)
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type SoilInfoDisplayProps = {

export function SoilInfoDisplay({dataSource, soilInfo}: SoilInfoDisplayProps) {
const {t} = useTranslation();

return (
<Column space={3}>
<Heading variant="h6" fontStyle="italic" pb="10px">
Expand Down
8 changes: 8 additions & 0 deletions dev-client/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,11 @@ export const isSiteManager = matchesRole([
export const getSoilWebUrl = (coords: Coords) => {
return `https://casoilresource.lawr.ucdavis.edu/gmap/?loc=${coords.latitude},${coords.longitude}`;
};

export const validateUrl = (url?: string): URL | false => {
try {
return url ? new URL(url) : false;
} catch {
return false;
}
};

0 comments on commit e048e51

Please sign in to comment.