Removed geolocation permission
This commit is contained in:
parent
4f663f8868
commit
c4d68df3d0
21 changed files with 170 additions and 618 deletions
BIN
promo/logo-300.png
Normal file
BIN
promo/logo-300.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
promo/logo-64.png
Normal file
BIN
promo/logo-64.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.7 KiB |
BIN
promo/opera-promo.png
Normal file
BIN
promo/opera-promo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
|
|
@ -1,14 +1,24 @@
|
|||
import { Link } from 'theme-ui'
|
||||
import { Box, Link } from 'theme-ui'
|
||||
|
||||
const FooterLink = () => {
|
||||
return (
|
||||
<Link
|
||||
variant="footer"
|
||||
href={`https://go.nordvpn.net/aff_c?offer_id=15&aff_id=79520&url_id=902`}
|
||||
target="_blank"
|
||||
<Box
|
||||
sx={{
|
||||
color: 'text',
|
||||
mb: '8px',
|
||||
fontSize: '11px',
|
||||
position: 'fixed',
|
||||
bottom: '0',
|
||||
}}
|
||||
>
|
||||
Vytal does not change your IP address. To change your IP you will need to
|
||||
use a VPN such as{' '}
|
||||
<Link
|
||||
variant="footer"
|
||||
href={`https://go.nordvpn.net/aff_c?offer_id=15&aff_id=79520&url_id=902`}
|
||||
target="_blank"
|
||||
>
|
||||
Vytal does not change your IP address. To change your IP you will need a
|
||||
VPN such as{' '}
|
||||
</Link>
|
||||
<Link
|
||||
variant="hover"
|
||||
href={`https://go.nordvpn.net/aff_c?offer_id=15&aff_id=79520&url_id=902`}
|
||||
|
|
@ -24,7 +34,8 @@ const FooterLink = () => {
|
|||
>
|
||||
ProtonVPN
|
||||
</Link>
|
||||
</Link>
|
||||
.
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
const handleAutofillAddress = (value: boolean) => {
|
||||
console.log(!value)
|
||||
chrome.privacy.services.autofillAddressEnabled.clear({}, () => {
|
||||
chrome.privacy.services.autofillAddressEnabled.set(
|
||||
{
|
||||
value: !value,
|
||||
},
|
||||
() => {
|
||||
chrome.storage.local.set({
|
||||
autofillAddress: value,
|
||||
})
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
export default handleAutofillAddress
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
import { Text } from 'theme-ui'
|
||||
import { useState, useEffect, ChangeEvent } from 'react'
|
||||
import Page from '../../Components/Page'
|
||||
import CheckBox from '../../Components/CheckBox'
|
||||
// import { autofillData } from '../../../types'
|
||||
import Table from '../../Components/Table'
|
||||
import TableRow from '../../Components/TableRow'
|
||||
import { Button } from 'theme-ui'
|
||||
import addresses from '../../../utils/addresses'
|
||||
import FooterLink from '../../Components/FooterLink'
|
||||
import handleAutofillAddress from './handleAutofillAddress'
|
||||
|
||||
interface AutofillPageProps {
|
||||
tab: string
|
||||
autofillData?: any
|
||||
// reverseGeocoding: any
|
||||
}
|
||||
|
||||
const AutofillPage = ({ tab, autofillData }: AutofillPageProps) => {
|
||||
const [autofillAddress, setAutofillAddress] = useState(false)
|
||||
const [country, setCountry] = useState('')
|
||||
const [city, setCity] = useState('')
|
||||
const [region, setRegion] = useState('')
|
||||
const [postCode, setPostCode] = useState('')
|
||||
const [address, setAddress] = useState('')
|
||||
const [phone, setPhone] = useState('9057814565')
|
||||
// const [configuration, setConfiguration] = useState('default')
|
||||
|
||||
useEffect(() => {
|
||||
chrome.storage.local.get(['autofillAddress'], (storage) => {
|
||||
storage.autofillAddress && setAutofillAddress(storage.autofillAddress)
|
||||
})
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
// chrome.storage.local.get(['configuration', 'autofillData'], (storage) => {
|
||||
// storage.configuration && setConfiguration(storage.configuration)
|
||||
// if (storage.autofillData) {
|
||||
// setIP(storage.autofillData)
|
||||
// } else {
|
||||
// Promise.resolve(getIP()).then((autofillData) => setIP(autofillData))
|
||||
// }
|
||||
// })
|
||||
if (autofillData?.country) {
|
||||
setCountry(autofillData.country)
|
||||
// chrome.storage.local.set({
|
||||
// country: autofillData.country,
|
||||
// })
|
||||
}
|
||||
if (autofillData?.locality) {
|
||||
setCity(autofillData.locality)
|
||||
// chrome.storage.local.set({
|
||||
// city: autofillData.city,
|
||||
// })
|
||||
}
|
||||
if (autofillData?.administrative_area_level_1) {
|
||||
setRegion(autofillData.administrative_area_level_1)
|
||||
// chrome.storage.local.set({
|
||||
// region: autofillData.regionName,
|
||||
// })
|
||||
}
|
||||
if (autofillData?.postal_code) {
|
||||
setPostCode(autofillData.postal_code)
|
||||
// chrome.storage.local.set({
|
||||
// postCode: autofillData.zip,
|
||||
// })
|
||||
}
|
||||
if (autofillData?.street_number && autofillData?.route) {
|
||||
setAddress(`${autofillData.street_number} ${autofillData.route}`)
|
||||
// chrome.storage.local.set({
|
||||
// postCode: autofillData.zip,
|
||||
// })
|
||||
}
|
||||
// autofillData?.city && setCity(autofillData.city)
|
||||
// autofillData?.regionName && setRegion(autofillData.regionName)
|
||||
// autofillData?.zip && setPostCode()
|
||||
// chrome.storage.local.set({
|
||||
// country: autofillData.country,
|
||||
// city: autofillData.city,
|
||||
// regionName: autofillData.regionName,
|
||||
// zip: autofillData.zip,
|
||||
// })
|
||||
}, [autofillData, setCity, setPostCode, setRegion])
|
||||
|
||||
// useEffect(() => {
|
||||
// if (!postCode && reverseGeocoding?.postcode) {
|
||||
// setPostCode(reverseGeocoding?.postcode)
|
||||
// chrome.storage.local.set({
|
||||
// postCode: reverseGeocoding?.postcode,
|
||||
// })
|
||||
// }
|
||||
// if (reverseGeocoding?.house_number && reverseGeocoding?.road) {
|
||||
// setAddress(`${reverseGeocoding.house_number} ${reverseGeocoding.road}`)
|
||||
// chrome.storage.local.set({
|
||||
// address: `${reverseGeocoding.house_number} ${reverseGeocoding.road}`,
|
||||
// })
|
||||
// } else if (reverseGeocoding?.road) {
|
||||
// setAddress(reverseGeocoding.road)
|
||||
// chrome.storage.local.set({
|
||||
// address: reverseGeocoding.road,
|
||||
// })
|
||||
// }
|
||||
// }, [postCode, reverseGeocoding, setAddress])
|
||||
|
||||
// const changeUserAgent = () => {
|
||||
// // if (userAgentType !== 'custom') {
|
||||
// // setUserAgentType('custom')
|
||||
// // chrome.storage.local.set({
|
||||
// // userAgentType: 'custom',
|
||||
// // })
|
||||
// // }
|
||||
// }
|
||||
|
||||
const changeCheckBoxValue = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
console.log(e.target.checked)
|
||||
handleAutofillAddress(e.target.checked)
|
||||
setAutofillAddress(e.target.checked)
|
||||
}
|
||||
|
||||
return (
|
||||
<Page isCurrentTab={tab === 'autofill'} title={'Autofill'}>
|
||||
<CheckBox
|
||||
title={'Disable Built-In Address Autofill'}
|
||||
onChange={changeCheckBoxValue}
|
||||
checked={autofillAddress}
|
||||
/>
|
||||
{/* <CheckBox title={'Automatically Autofill'} /> */}
|
||||
<Table>
|
||||
<TableRow title="Country" value={country} />
|
||||
<TableRow title="Region" value={region} />
|
||||
<TableRow title="City" value={city} />
|
||||
<TableRow title="Postal Code" value={postCode} />
|
||||
<TableRow title="Address" value={address} />
|
||||
<TableRow title="Phone" value={phone} noBorder />
|
||||
</Table>
|
||||
<Button
|
||||
variant="primary"
|
||||
sx={{ borderRadius: '4px' }}
|
||||
onClick={() => console.log('click')}
|
||||
>
|
||||
Autofill Current Page
|
||||
</Button>
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
|
||||
export default AutofillPage
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
import { ipData } from '../../../types'
|
||||
import FooterLink from '../../Components/FooterLink'
|
||||
import Page from '../../Components/Page'
|
||||
import Table from '../../Components/Table'
|
||||
import TableRow from '../../Components/TableRow'
|
||||
|
||||
interface ConnectionPageProps {
|
||||
tab: string
|
||||
ipData?: ipData
|
||||
}
|
||||
|
||||
const ConnectionPage = ({ tab, ipData }: ConnectionPageProps) => {
|
||||
// let options: any
|
||||
|
||||
// function success(pos: any) {
|
||||
// var crd = pos.coords
|
||||
// console.log('Your connection position is:')
|
||||
// console.log(`Latitude : ${crd.latitude}`)
|
||||
// console.log(`Longitude: ${crd.longitude}`)
|
||||
// console.log(`More or less ${crd.accuracy} meters.`)
|
||||
// }
|
||||
|
||||
// function error(err: any) {
|
||||
// console.error(`ERROR(${err.code}): ${err.message}`)
|
||||
// }
|
||||
// options = {
|
||||
// enableHighAccuracy: false,
|
||||
// timeout: 5000,
|
||||
// maximumAge: 0,
|
||||
// }
|
||||
|
||||
// navigator.geolocation.watchPosition(success, error)
|
||||
|
||||
return (
|
||||
<Page isCurrentTab={tab === 'connection'} title={'Connection Info'}>
|
||||
<Table>
|
||||
<TableRow title="IP Address" value={ipData?.query} />
|
||||
<TableRow title="Country" value={ipData?.country} />
|
||||
<TableRow title="Region" value={ipData?.regionName} />
|
||||
<TableRow title="City" value={ipData?.city} />
|
||||
<TableRow title="Latitude" value={`${ipData?.lat}`} />
|
||||
<TableRow title="Longitude" value={`${ipData?.lon}`} />
|
||||
<TableRow title="ISP" value={ipData?.isp} />
|
||||
<TableRow title="Organization" value={ipData?.org} />
|
||||
<TableRow
|
||||
title="Proxy/VPN"
|
||||
value={ipData?.proxy ? 'True' : 'False'}
|
||||
noBorder
|
||||
/>
|
||||
</Table>
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
|
||||
export default ConnectionPage
|
||||
|
|
@ -1,22 +1,21 @@
|
|||
import { useState, useEffect, ChangeEvent } from 'react'
|
||||
import { Flex, Label, Radio, Select } from 'theme-ui'
|
||||
import { Box, Flex, Label, Radio, Select } from 'theme-ui'
|
||||
import Page from '../../Components/Page'
|
||||
import DebouncedInput from '../../Components/DebouncedInput'
|
||||
import detachDebugger from '../../../utils/detachDebugger'
|
||||
import countryLocales from '../../../utils/countryLocales'
|
||||
import { ipData } from '../../../types'
|
||||
import configurations from '../../../utils/configurations'
|
||||
import FooterLink from '../../Components/FooterLink'
|
||||
import Table from '../../Components/Table'
|
||||
import TableRow from '../../Components/TableRow'
|
||||
import { ipData } from '../../../types'
|
||||
import getIp from '../../../utils/getIp'
|
||||
import { RotateCw } from 'react-feather'
|
||||
|
||||
interface LocationPageProps {
|
||||
tab: string
|
||||
ipData?: ipData
|
||||
geolocation?: GeolocationCoordinates
|
||||
}
|
||||
|
||||
const LocationPage = ({ tab, ipData, geolocation }: LocationPageProps) => {
|
||||
const LocationPage = ({ tab }: LocationPageProps) => {
|
||||
const [ipData, setIpData] = useState<ipData>()
|
||||
const [locationType, setLocationType] = useState('')
|
||||
const [timezone, setTimezone] = useState('')
|
||||
const [locale, setLocale] = useState('')
|
||||
|
|
@ -24,20 +23,16 @@ const LocationPage = ({ tab, ipData, geolocation }: LocationPageProps) => {
|
|||
const [lon, setLongitude] = useState('')
|
||||
const [configuration, setConfiguration] = useState('custom')
|
||||
|
||||
// console.log(geolocation)
|
||||
useEffect(() => {
|
||||
getIp().then((ipDataRes) => {
|
||||
setIpData(ipDataRes)
|
||||
})
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
chrome.storage.local.get(
|
||||
['locationType', 'configuration', 'timezone', 'locale', 'lat', 'lon'],
|
||||
(storage) => {
|
||||
if (!storage.locationType || storage.locationType === 'default') {
|
||||
setTimezone(Intl.DateTimeFormat().resolvedOptions().timeZone)
|
||||
setLocale(Intl.DateTimeFormat().resolvedOptions().locale)
|
||||
if (geolocation) {
|
||||
setLatitude(`${geolocation.latitude}`)
|
||||
setLongitude(`${geolocation.longitude}`)
|
||||
}
|
||||
}
|
||||
if (storage.locationType === 'matchIp' && ipData) {
|
||||
setTimezone(ipData.timezone)
|
||||
setLocale(countryLocales[ipData.countryCode].locale)
|
||||
|
|
@ -61,7 +56,7 @@ const LocationPage = ({ tab, ipData, geolocation }: LocationPageProps) => {
|
|||
: setLocationType('default')
|
||||
}
|
||||
)
|
||||
}, [geolocation, ipData])
|
||||
}, [ipData])
|
||||
|
||||
const changeType = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
detachDebugger()
|
||||
|
|
@ -69,12 +64,10 @@ const LocationPage = ({ tab, ipData, geolocation }: LocationPageProps) => {
|
|||
chrome.storage.local.set({ locationType: e.target.value })
|
||||
|
||||
if (e.target.value === 'default') {
|
||||
setTimezone(Intl.DateTimeFormat().resolvedOptions().timeZone)
|
||||
setLocale(Intl.DateTimeFormat().resolvedOptions().locale)
|
||||
if (geolocation) {
|
||||
setLatitude(`${geolocation.latitude}`)
|
||||
setLongitude(`${geolocation.longitude}`)
|
||||
}
|
||||
setTimezone('')
|
||||
setLocale('')
|
||||
setLatitude('')
|
||||
setLongitude('')
|
||||
chrome.storage.local.set({
|
||||
timezone: '',
|
||||
locale: '',
|
||||
|
|
@ -94,7 +87,7 @@ const LocationPage = ({ tab, ipData, geolocation }: LocationPageProps) => {
|
|||
lon: ipData.lon,
|
||||
})
|
||||
}
|
||||
} else if (e.target.value === 'custom')
|
||||
} else if (e.target.value === 'custom') {
|
||||
if (configuration !== 'custom') {
|
||||
setTimezone(configurations[configuration].timezone)
|
||||
setLocale(configurations[configuration].locale)
|
||||
|
|
@ -107,6 +100,7 @@ const LocationPage = ({ tab, ipData, geolocation }: LocationPageProps) => {
|
|||
lon: configurations[configuration].lon,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const changeConfiguration = (e: ChangeEvent<HTMLSelectElement>) => {
|
||||
|
|
@ -185,17 +179,46 @@ const LocationPage = ({ tab, ipData, geolocation }: LocationPageProps) => {
|
|||
</Label>
|
||||
</Flex>
|
||||
{locationType === 'matchIp' && (
|
||||
<Table>
|
||||
<TableRow
|
||||
title="IP Address"
|
||||
value={
|
||||
ipData
|
||||
? `${getFlagEmoji(ipData.countryCode)} ${ipData?.query}`
|
||||
: 'loading...'
|
||||
}
|
||||
noBorder
|
||||
<Flex
|
||||
sx={{
|
||||
border: '1px solid',
|
||||
mt: '12px',
|
||||
mb: '8px',
|
||||
borderRadius: '4px',
|
||||
borderColor: 'grey',
|
||||
alignItems: 'center',
|
||||
p: '4px 8px',
|
||||
}}
|
||||
>
|
||||
<Box sx={{ fontWeight: '700', width: '100px', pr: '8px' }}>
|
||||
IP Address
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
width: '188px',
|
||||
whiteSpace: 'nowrap',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
}}
|
||||
title={ipData?.query}
|
||||
>
|
||||
{ipData
|
||||
? `${getFlagEmoji(ipData.countryCode)} ${ipData?.query}`
|
||||
: 'loading...'}
|
||||
</Box>
|
||||
<RotateCw
|
||||
size={20}
|
||||
sx={{
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
onClick={() => {
|
||||
setIpData(undefined)
|
||||
getIp().then((ipDataRes) => {
|
||||
setIpData(ipDataRes)
|
||||
})
|
||||
}}
|
||||
/>
|
||||
</Table>
|
||||
</Flex>
|
||||
)}
|
||||
{locationType === 'custom' && (
|
||||
<>
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
import CheckBox from '../../Components/CheckBox'
|
||||
import Page from '../../Components/Page'
|
||||
|
||||
interface OtherOptionsPageProps {
|
||||
tab: string
|
||||
}
|
||||
|
||||
const OtherOptionsPage = ({ tab }: OtherOptionsPageProps) => {
|
||||
return (
|
||||
<Page isCurrentTab={tab === 'otherOptions'} title={'Other Options'}>
|
||||
<CheckBox title={'Network Prediction Enabled'} />
|
||||
<CheckBox title={'Alternate Error Pages Enabled'} />
|
||||
<CheckBox title={'Safe Browsing Reporting Enabled'} />
|
||||
<CheckBox title={'Search Suggest Enabled'} />
|
||||
<CheckBox title={'Spelling Service Enabled'} />
|
||||
<CheckBox title={'Translation Service Enabled'} />
|
||||
<CheckBox title={'Hyperlink Auditing Enabled'} />
|
||||
<CheckBox title={'Referrers Enabled'} />
|
||||
<CheckBox title={'Third Party Cookies Allowed'} />
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
|
||||
export default OtherOptionsPage
|
||||
17
src/Popup/Pages/SettingsPage/InfoItem.tsx
Normal file
17
src/Popup/Pages/SettingsPage/InfoItem.tsx
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { Box, Flex } from 'theme-ui'
|
||||
|
||||
interface InfoItemProps {
|
||||
title: string
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
const SettingsPage = ({ title, children }: InfoItemProps) => {
|
||||
return (
|
||||
<Box sx={{ mb: '12px' }}>
|
||||
<Flex sx={{ fontWeight: '700', mb: '2px' }}>{title}</Flex>
|
||||
{children}
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
export default SettingsPage
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { Label, Select } from 'theme-ui'
|
||||
import { Link, Text } from 'theme-ui'
|
||||
import Page from '../../Components/Page'
|
||||
import CheckBox from '../../Components/CheckBox'
|
||||
import InfoItem from './InfoItem'
|
||||
|
||||
interface SystemPageProps {
|
||||
tab: string
|
||||
|
|
@ -8,30 +8,62 @@ interface SystemPageProps {
|
|||
|
||||
const SettingsPage = ({ tab }: SystemPageProps) => {
|
||||
return (
|
||||
<Page isCurrentTab={tab === 'settings'} title={'Settings'}>
|
||||
<CheckBox title={'Disable Address Autofill'} />
|
||||
<CheckBox title={'Dark Mode'} />
|
||||
<Label htmlFor="configuration">Language</Label>
|
||||
<Select name="Language" id="Language">
|
||||
<option>Arabic</option>
|
||||
<option>Bengali</option>
|
||||
<option>English</option>
|
||||
<option>French</option>
|
||||
<option>Hindi</option>
|
||||
<option>Mandarin Chinese</option>
|
||||
<option>Persian</option>
|
||||
<option>Portuguese</option>
|
||||
<option>Russian</option>
|
||||
<option>Spanish</option>
|
||||
<option>Turkish</option>
|
||||
<option>Ukrainian</option>
|
||||
<option>Urdu</option>
|
||||
{/* {Object.keys(configurations).map((key) => (
|
||||
<option value={key} key={key}>
|
||||
{configurations[key].name}
|
||||
</option>
|
||||
))} */}
|
||||
</Select>
|
||||
<Page isCurrentTab={tab === 'settings'} title={'Info'}>
|
||||
<InfoItem title={'Hide Debugging Notification Bar'}>
|
||||
While spoofing data a notification bar becomes visible. Hiding the bar
|
||||
can be done by using the{' '}
|
||||
<Text sx={{ fontStyle: 'italic', mr: '2px' }}>
|
||||
--silent-debugger-extension-api
|
||||
</Text>{' '}
|
||||
flag.{' '}
|
||||
<Link
|
||||
variant="hover"
|
||||
href={`https://www.chromium.org/developers/how-tos/run-chromium-with-flags`}
|
||||
target="_blank"
|
||||
>
|
||||
Instructions on how to run chrome with flags
|
||||
</Link>
|
||||
.
|
||||
</InfoItem>
|
||||
<InfoItem title={'Change IP Address'}>
|
||||
Vytal does not change your IP address. To change your IP you will need a
|
||||
VPN such as{' '}
|
||||
<Link
|
||||
variant="hover"
|
||||
href={`https://go.nordvpn.net/aff_c?offer_id=15&aff_id=79520&url_id=902`}
|
||||
target="_blank"
|
||||
>
|
||||
NordVPN
|
||||
</Link>{' '}
|
||||
or{' '}
|
||||
<Link
|
||||
variant="hover"
|
||||
href={`https://go.getproton.me/aff_c?offer_id=26&aff_id=3825`}
|
||||
target="_blank"
|
||||
>
|
||||
ProtonVPN
|
||||
</Link>
|
||||
.
|
||||
</InfoItem>
|
||||
<InfoItem title={'Vytal vs Similar Extensions'}>
|
||||
Vytal utilizes the debugger API to spoof data which is completely
|
||||
undetectable. Other similar extensions rely on{' '}
|
||||
<Link
|
||||
variant="hover"
|
||||
href={`https://palant.info/2020/12/10/how-anti-fingerprinting-extensions-tend-to-make-fingerprinting-easier/`}
|
||||
target="_blank"
|
||||
>
|
||||
inferior script tag injections
|
||||
</Link>
|
||||
.
|
||||
</InfoItem>
|
||||
<InfoItem title={'Test Extension'}>
|
||||
You can test and compare Vytal and other spoofing extensions on{' '}
|
||||
<Link variant="hover" href={`https://vytal.io`} target="_blank">
|
||||
vytal.io
|
||||
</Link>
|
||||
.
|
||||
</InfoItem>
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ const UserAgentPage = ({ tab }: UserAgentPageProps) => {
|
|||
const [userAgentType, setUserAgentType] = useState('default')
|
||||
const [operatingSystem, setOperatingSystem] = useState('Windows')
|
||||
const [browser, setBrowser] = useState('Chrome')
|
||||
const [userAgent, setUserAgent] = useState(navigator.userAgent)
|
||||
const [platform, setPlatform] = useState(navigator.platform)
|
||||
const [userAgent, setUserAgent] = useState('')
|
||||
const [platform, setPlatform] = useState('')
|
||||
|
||||
useEffect(() => {
|
||||
chrome.storage.local.get(
|
||||
|
|
@ -36,8 +36,8 @@ const UserAgentPage = ({ tab }: UserAgentPageProps) => {
|
|||
chrome.storage.local.set({ userAgentType: e.target.value })
|
||||
|
||||
if (e.target.value === 'default') {
|
||||
setUserAgent(navigator.userAgent)
|
||||
setPlatform(navigator.platform)
|
||||
setUserAgent('')
|
||||
setPlatform('')
|
||||
chrome.storage.local.set({
|
||||
userAgent: '',
|
||||
platform: '',
|
||||
|
|
@ -55,14 +55,18 @@ const UserAgentPage = ({ tab }: UserAgentPageProps) => {
|
|||
const changeOperatingSystem = async (e: ChangeEvent<HTMLSelectElement>) => {
|
||||
detachDebugger()
|
||||
setOperatingSystem(e.target.value)
|
||||
setUserAgent(userAgents[e.target.value]['userAgents'][browser])
|
||||
let browserValue = browser
|
||||
if (!userAgents[e.target.value]['userAgents'][browser]) {
|
||||
browserValue = Object.keys(userAgents[e.target.value]['userAgents'])[0]
|
||||
setBrowser(browserValue)
|
||||
}
|
||||
setUserAgent(userAgents[e.target.value]['userAgents'][browserValue])
|
||||
setPlatform(userAgents[e.target.value]['platform'])
|
||||
chrome.storage.local.set({
|
||||
userAgent: userAgents[e.target.value]['userAgents'][browser],
|
||||
userAgent: userAgents[e.target.value]['userAgents'][browserValue],
|
||||
platform: userAgents[e.target.value]['platform'],
|
||||
operatingSystem: e.target.value,
|
||||
})
|
||||
// await attachCurrentTab()
|
||||
}
|
||||
|
||||
const changeBrowser = (e: ChangeEvent<HTMLSelectElement>) => {
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
import { ChangeEvent } from 'react'
|
||||
import { Box, Label, Radio, Text } from 'theme-ui'
|
||||
|
||||
interface RadioButtonProps {
|
||||
value: string
|
||||
name: string
|
||||
description: string
|
||||
webRtcPolicy: string
|
||||
onChange: (e: ChangeEvent<HTMLInputElement>) => void
|
||||
}
|
||||
|
||||
const RadioButton = ({
|
||||
value,
|
||||
name,
|
||||
description,
|
||||
webRtcPolicy,
|
||||
onChange,
|
||||
}: RadioButtonProps) => {
|
||||
return (
|
||||
<>
|
||||
<Label sx={{ cursor: 'pointer' }}>
|
||||
<Radio
|
||||
name="webRtcPolicy"
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
checked={webRtcPolicy === value}
|
||||
/>
|
||||
<Text sx={{ fontWeight: '700' }}>{name}</Text>
|
||||
</Label>
|
||||
<Box sx={{ ml: '32px', mb: '12px', fontSize: '12px' }}>{description}</Box>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default RadioButton
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
const getWebRTC = (setWebRtcIp: any) => {
|
||||
// if (navigator.getUserMedia) {
|
||||
const ipRegex =
|
||||
/([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/
|
||||
|
||||
// compatibility for firefox and chrome
|
||||
let RTCPeerConnection = window.RTCPeerConnection
|
||||
|
||||
// minimal requirements for data connection
|
||||
const mediaConstraints = {
|
||||
optional: [{ RtpDataChannels: true }],
|
||||
}
|
||||
|
||||
const servers = { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] }
|
||||
|
||||
// construct a new RTCPeerConnection
|
||||
const pc = new RTCPeerConnection(servers, mediaConstraints)
|
||||
|
||||
let ips: any = []
|
||||
|
||||
// listen for candidate events
|
||||
pc.onicecandidate = (ice) => {
|
||||
// skip non-candidate events
|
||||
if (ice.candidate) {
|
||||
const ip = ipRegex.exec(ice.candidate.candidate)
|
||||
if (ip !== null && ip.length > 1) {
|
||||
ips.push(ip[1])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create a bogus data channel
|
||||
pc.createDataChannel('')
|
||||
|
||||
// create an offer sdp
|
||||
pc.createOffer(
|
||||
(result) => {
|
||||
// trigger the stun server request
|
||||
pc.setLocalDescription(
|
||||
result,
|
||||
() => {},
|
||||
() => {}
|
||||
)
|
||||
},
|
||||
() => {}
|
||||
)
|
||||
|
||||
const waitForElement = async () => {
|
||||
if (pc.localDescription) {
|
||||
const lines = pc.localDescription.sdp.split('\n')
|
||||
lines.forEach((line) => {
|
||||
if (line.indexOf('a=candidate:') === 0) {
|
||||
const ip = ipRegex.exec(line)
|
||||
if (ip !== null && ip.length > 1) {
|
||||
ips.push(ip[1])
|
||||
}
|
||||
}
|
||||
})
|
||||
ips = [...new Set(ips)]
|
||||
console.log(ips)
|
||||
setWebRtcIp(await Promise.all(ips))
|
||||
} else {
|
||||
setTimeout(waitForElement, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
waitForElement()
|
||||
// } else {
|
||||
// setWebRTCData([])
|
||||
// }
|
||||
}
|
||||
|
||||
export default getWebRTC
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
const handleWebRtcPolicy = (value: string) => {
|
||||
console.log(value)
|
||||
chrome.privacy.network.webRTCIPHandlingPolicy.clear({}, () => {
|
||||
chrome.privacy.network.webRTCIPHandlingPolicy.set(
|
||||
{
|
||||
value,
|
||||
},
|
||||
() => {
|
||||
chrome.storage.local.set({
|
||||
webRtcPolicy: value,
|
||||
})
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
export default handleWebRtcPolicy
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
import { useState, useEffect, ChangeEvent } from 'react'
|
||||
import Page from '../../Components/Page'
|
||||
import handleWebRtcPolicy from './handleWebRtcPolicy'
|
||||
import RadioButton from './RadioButton'
|
||||
import FooterLink from '../../Components/FooterLink'
|
||||
|
||||
interface SystemPageProps {
|
||||
tab: string
|
||||
}
|
||||
|
||||
const WebRtcPage = ({ tab }: SystemPageProps) => {
|
||||
const [webRtcPolicy, setWebRtcPolicy] = useState('default')
|
||||
|
||||
useEffect(() => {
|
||||
chrome.storage.local.get(['webRtcPolicy'], (storage) => {
|
||||
storage.webRtcPolicy && setWebRtcPolicy(storage.webRtcPolicy)
|
||||
})
|
||||
}, [])
|
||||
|
||||
const changeRadioValue = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
handleWebRtcPolicy(e.target.value)
|
||||
setWebRtcPolicy(e.target.value)
|
||||
}
|
||||
|
||||
return (
|
||||
<Page isCurrentTab={tab === 'webRtc'} title={'WebRTC Policy'}>
|
||||
<RadioButton
|
||||
value={'default'}
|
||||
name={'Default'}
|
||||
description={
|
||||
'Will use all available interfaces when searching for the best path.'
|
||||
}
|
||||
webRtcPolicy={webRtcPolicy}
|
||||
onChange={changeRadioValue}
|
||||
/>
|
||||
<RadioButton
|
||||
value={'default_public_and_private_interfaces'}
|
||||
name={'Default Public And Private Interfaces'}
|
||||
description={
|
||||
'Will only use interface connecting to the public Internet, but may connect using private IP.'
|
||||
}
|
||||
webRtcPolicy={webRtcPolicy}
|
||||
onChange={changeRadioValue}
|
||||
/>
|
||||
<RadioButton
|
||||
value={'default_public_interface_only'}
|
||||
name={'Default Public Interface Only'}
|
||||
description={
|
||||
'Will only use interface connecting to the public Internet, and will not connect using private IP.'
|
||||
}
|
||||
webRtcPolicy={webRtcPolicy}
|
||||
onChange={changeRadioValue}
|
||||
/>
|
||||
<RadioButton
|
||||
value={'disable_non_proxied_udp'}
|
||||
name={'Disable Non-Proxied UDP (Force Proxy)'}
|
||||
description={
|
||||
'Will use TCP on the public-facing interface, and will only use UDP if supported by a configured proxy.'
|
||||
}
|
||||
webRtcPolicy={webRtcPolicy}
|
||||
onChange={changeRadioValue}
|
||||
/>
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
|
||||
export default WebRtcPage
|
||||
|
|
@ -1,64 +1,22 @@
|
|||
import { useState, useEffect } from 'react'
|
||||
import { useState } from 'react'
|
||||
import { ThemeProvider, Flex, Box } from 'theme-ui'
|
||||
import { theme } from '../theme'
|
||||
import {
|
||||
Wifi,
|
||||
MapPin,
|
||||
FileText,
|
||||
MessageSquare,
|
||||
Globe,
|
||||
Settings,
|
||||
} from 'react-feather'
|
||||
import { MapPin, Globe, Info } from 'react-feather'
|
||||
import TabItem from './TabItem'
|
||||
import LocationPage from './Pages/LocationPage'
|
||||
import UserAgentPage from './Pages/UserAgentPage'
|
||||
import SettingsPage from './Pages/SettingsPage'
|
||||
import AutofillPage from './Pages/AutofillPage'
|
||||
import WebRtcPage from './Pages/WebRtcPage'
|
||||
import ConnectionPage from './Pages/ConnectionPage'
|
||||
import { ipData } from '../types'
|
||||
import getIp from '../utils/getIp'
|
||||
// import getReverseGeocoding from '../utils/getReverseGeocoding'
|
||||
import '../assets/global.css'
|
||||
import OtherOptionsPage from './Pages/OtherOptionsPage'
|
||||
import addresses from '../utils/addresses'
|
||||
|
||||
const Popup = () => {
|
||||
const [tab, setTab] = useState('location')
|
||||
const [ipData, setIpData] = useState<ipData>()
|
||||
// const [reverseGeocoding, setReverseGeocoding] = useState<any>(undefined)
|
||||
const [geolocation, setGeolocation] = useState<GeolocationCoordinates>()
|
||||
const [autofillData, setAutofillData] = useState<any>()
|
||||
|
||||
useEffect(() => {
|
||||
getIp().then((ipDataRes) => {
|
||||
setIpData(ipDataRes)
|
||||
let geoIndex = (ipDataRes.lat + 90) * 180 + ipDataRes.lon
|
||||
console.log(geoIndex)
|
||||
let closest = addresses.reduce((prev: any, curr: any) => {
|
||||
return Math.abs(curr.geoIndex - geoIndex) <
|
||||
Math.abs(prev.geoIndex - geoIndex)
|
||||
? curr
|
||||
: prev
|
||||
})
|
||||
setAutofillData(closest)
|
||||
})
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
(pos) => setGeolocation(pos.coords),
|
||||
(err) => console.warn(`ERROR(${err.code}): ${err.message}`),
|
||||
{
|
||||
enableHighAccuracy: true,
|
||||
timeout: 5000,
|
||||
}
|
||||
)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={theme}>
|
||||
<Flex
|
||||
sx={{
|
||||
width: '350px',
|
||||
height: '455px',
|
||||
height: '460px',
|
||||
}}
|
||||
>
|
||||
<Flex
|
||||
|
|
@ -69,68 +27,26 @@ const Popup = () => {
|
|||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
{/* <TabItem
|
||||
Icon={Wifi}
|
||||
active={tab === 'connection'}
|
||||
onClick={() => setTab('connection')}
|
||||
/> */}
|
||||
<TabItem
|
||||
Icon={MapPin}
|
||||
active={tab === 'location'}
|
||||
onClick={() => setTab('location')}
|
||||
/>
|
||||
{/* <TabItem
|
||||
Icon={FileText}
|
||||
active={tab === 'autofill'}
|
||||
onClick={() => setTab('autofill')}
|
||||
/>
|
||||
<TabItem
|
||||
Icon={MessageSquare}
|
||||
active={tab === 'webRtc'}
|
||||
onClick={() => setTab('webRtc')}
|
||||
/> */}
|
||||
<TabItem
|
||||
Icon={Globe}
|
||||
active={tab === 'userAgent'}
|
||||
onClick={() => setTab('userAgent')}
|
||||
/>
|
||||
{/* <TabItem
|
||||
Icon={Sliders}
|
||||
active={tab === 'otherOptions'}
|
||||
onClick={() => setTab('otherOptions')}
|
||||
/> */}
|
||||
<TabItem
|
||||
Icon={Settings}
|
||||
Icon={Info}
|
||||
active={tab === 'settings'}
|
||||
onClick={() => setTab('settings')}
|
||||
/>
|
||||
{/* <TabItem
|
||||
Icon={ExternalLink}
|
||||
onClick={() => window.open('https://vytal.io')}
|
||||
/> */}
|
||||
</Flex>
|
||||
<Box sx={{ m: '12px', width: '100%' }}>
|
||||
<ConnectionPage tab={tab} ipData={ipData} />
|
||||
<LocationPage tab={tab} ipData={ipData} geolocation={geolocation} />
|
||||
<AutofillPage
|
||||
tab={tab}
|
||||
autofillData={autofillData}
|
||||
// reverseGeocoding={reverseGeocoding}
|
||||
/>
|
||||
<WebRtcPage tab={tab} />
|
||||
<LocationPage tab={tab} />
|
||||
<UserAgentPage tab={tab} />
|
||||
<OtherOptionsPage tab={tab} />
|
||||
<SettingsPage tab={tab} />
|
||||
{/* <Text
|
||||
sx={{
|
||||
mb: '8px',
|
||||
fontSize: '10px',
|
||||
position: 'fixed',
|
||||
bottom: '0',
|
||||
}}
|
||||
>
|
||||
Connection tab won't be fully spoofed until after 1st or 2nd reload.
|
||||
</Text> */}
|
||||
</Box>
|
||||
</Flex>
|
||||
</ThemeProvider>
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@
|
|||
}
|
||||
|
||||
body {
|
||||
font-family: 'Nunito';
|
||||
font-family: 'Nunito', Arial, Helvetica, sans-serif;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
input {
|
||||
font-family: 'Nunito';
|
||||
font-family: 'Nunito', Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
"name": "Vytal - Spoof timezone, location & user agent",
|
||||
"version": "2.1.0",
|
||||
"description": "Spoof Timezone, Geolocation, Locale and User Agent.",
|
||||
"permissions": ["storage", "debugger", "privacy", "geolocation"],
|
||||
"permissions": ["storage", "debugger"],
|
||||
"background": { "service_worker": "background.bundle.js" },
|
||||
"action": {
|
||||
"default_popup": "popup.html",
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@ export const theme: Theme = {
|
|||
colors: {
|
||||
text: '#333333',
|
||||
background: '#FDFDFD',
|
||||
// primary: '#B77EEE',
|
||||
// primaryDark: '#a55eea',
|
||||
primary: '#a55eea',
|
||||
primaryDark: '#9454d2',
|
||||
red: '#fc5c65',
|
||||
|
|
@ -73,10 +71,6 @@ export const theme: Theme = {
|
|||
links: {
|
||||
footer: {
|
||||
color: 'text',
|
||||
mb: '8px',
|
||||
fontSize: '11px',
|
||||
position: 'fixed',
|
||||
bottom: '0',
|
||||
textDecoration: 'none',
|
||||
},
|
||||
hover: {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ const attachDebugger = (tabId: number) => {
|
|||
'platform',
|
||||
],
|
||||
(storage) => {
|
||||
console.log(storage)
|
||||
if (
|
||||
storage.timezone ||
|
||||
storage.lat ||
|
||||
|
|
@ -24,15 +23,6 @@ const attachDebugger = (tabId: number) => {
|
|||
) {
|
||||
chrome.debugger.attach({ tabId: tabId }, '1.3', () => {
|
||||
if (!chrome.runtime.lastError) {
|
||||
// chrome.debugger.sendCommand(
|
||||
// { tabId: tabId },
|
||||
// 'Target.autoAttachRelated',
|
||||
// { targetId: tabId, waitForDebuggerOnStart: false },
|
||||
// (res) => {
|
||||
// console.log(res)
|
||||
// }
|
||||
// )
|
||||
|
||||
if (storage.timezone) {
|
||||
chrome.debugger.sendCommand(
|
||||
{ tabId: tabId },
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue