Skip to content

Commit 7697c06

Browse files
added validation for custom search engine url
1 parent 2691306 commit 7697c06

File tree

2 files changed

+44
-20
lines changed

2 files changed

+44
-20
lines changed

src/stores/keystroke.store.ts

+16-8
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {Clipboard, EmitterSubscription, Linking} from 'react-native'
66
import {IRootStore} from 'store'
77
import {ItemType, Widget} from './ui.store'
88
import {EMOJI_ROW_SIZE} from './emoji.store'
9+
import { isValidCustomSearchEngineUrl } from 'widgets/settings/general'
910

1011
let keyDownListener: EmitterSubscription | undefined
1112
let keyUpListener: EmitterSubscription | undefined
@@ -298,17 +299,24 @@ export const createKeystrokeStore = (root: IRootStore) => {
298299
})
299300
break
300301
case 'custom':
301-
Linking.openURL(
302-
root.ui.customSearchUrl.replace(
303-
'%s',
304-
encodeURI(root.ui.query),
305-
),
306-
).catch(e => {
302+
if (isValidCustomSearchEngineUrl(root.ui.customSearchUrl)) {
303+
Linking.openURL(
304+
root.ui.customSearchUrl.replace(
305+
'%s',
306+
encodeURI(root.ui.query),
307+
),
308+
).catch(e => {
309+
solNative.showToast(
310+
`Could not open URL: ${root.ui.query}, error: ${e}`,
311+
'error',
312+
)
313+
})
314+
} else {
307315
solNative.showToast(
308-
`Could not open URL: ${root.ui.query}, error: ${e}`,
316+
`Invalid search URL. Please ensure the URL is a valid search engine URL and includes a query parameter. Example: https://google.com/search?q=%s`,
309317
'error',
310318
)
311-
})
319+
}
312320
break
313321
}
314322

src/widgets/settings/general.tsx

+28-12
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ import {observer} from 'mobx-react-lite'
66
import {ScrollView, Text, TouchableOpacity, View} from 'react-native'
77
import {useStore} from 'store'
88

9+
export const isValidCustomSearchEngineUrl = (url: string) => {
10+
if (url.trim() === '') return false
11+
const searchPatternRegex =
12+
/^https?:\/\/(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?|localhost|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(:\d+)?(\/[^\s?#]*)?\?q=%s$/
13+
return searchPatternRegex.test(url)
14+
}
915
export const General = observer(() => {
1016
const store = useStore()
1117
return (
@@ -65,18 +71,28 @@ export const General = observer(() => {
6571
/>
6672
{value === 'custom' && (
6773
<View className="flex-1">
68-
<Input
69-
className="w-80 text-xs rounded border border-lightBorder dark:border-darkBorder px-1"
70-
inputClassName={
71-
store.ui.searchEngine !== 'custom'
72-
? 'opacity-45 dark:text-white'
73-
: ''
74-
}
75-
readOnly={store.ui.searchEngine !== 'custom'}
76-
value={store.ui.customSearchUrl}
77-
onChangeText={e => store.ui.setCustomSearchUrl(e)}
78-
placeholder="https://google.com/search?q=%s"
79-
/>
74+
<View className="flex-row items-center gap-2">
75+
<Input
76+
className="w-80 text-xs rounded border border-lightBorder dark:border-darkBorder px-1"
77+
inputClassName={
78+
store.ui.searchEngine !== 'custom'
79+
? 'opacity-45 dark:text-white'
80+
: ''
81+
}
82+
readOnly={store.ui.searchEngine !== 'custom'}
83+
value={store.ui.customSearchUrl}
84+
onChangeText={e => store.ui.setCustomSearchUrl(e)}
85+
placeholder="https://google.com/search?q=%s"
86+
/>
87+
{store.ui.searchEngine === 'custom' &&
88+
(isValidCustomSearchEngineUrl(
89+
store.ui.customSearchUrl,
90+
) ? (
91+
<View className="w-2 h-2 rounded-full bg-green-500" />
92+
) : (
93+
<View className="w-2 h-2 rounded-full bg-red-500" />
94+
))}
95+
</View>
8096
<Text className="text-xs text-neutral-500 dark:text-neutral-400 mt-1 ml-1">
8197
Use %s in place of the search term
8298
</Text>

0 commit comments

Comments
 (0)