Removed unused files
This commit is contained in:
parent
59d9128afe
commit
5691f9ed97
29 changed files with 45242 additions and 9370 deletions
|
|
@ -20,7 +20,10 @@ module.exports = {
|
|||
'operator-linebreak': 'off',
|
||||
'no-use-before-define': 'off',
|
||||
'linebreak-style': 'off',
|
||||
'react/jsx-filename-extension': [1, { extensions: ['.jsx', '.js'] }],
|
||||
'react/jsx-filename-extension': [
|
||||
1,
|
||||
{ extensions: ['.jsx', '.js', '.ts', 'tsx'] },
|
||||
],
|
||||
'jsx-a11y/label-has-associated-control': 'off',
|
||||
'one-var': 'off',
|
||||
'one-var-declaration-per-line': 'off',
|
||||
|
|
|
|||
35698
package-lock.json
generated
Normal file
35698
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -5,6 +5,8 @@
|
|||
"private": true,
|
||||
"dependencies": {
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"@emotion/react": "^11.9.0",
|
||||
"@mdx-js/react": "^2.1.1",
|
||||
"@testing-library/jest-dom": "^5.11.4",
|
||||
"@testing-library/react": "^11.1.0",
|
||||
"@testing-library/user-event": "^12.1.10",
|
||||
|
|
@ -16,6 +18,8 @@
|
|||
"react-github-btn": "^1.2.1",
|
||||
"react-modal": "^3.14.3",
|
||||
"react-scripts": "4.0.3",
|
||||
"theme-ui": "^0.14.5",
|
||||
"typescript": "^4.6.4",
|
||||
"web-vitals": "^1.0.1"
|
||||
},
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
import { ThemeProvider } from 'theme-ui';
|
||||
import theme from './theme.ts';
|
||||
import './App.css';
|
||||
import MainColumn from './MainColumn';
|
||||
|
||||
const App = () => (
|
||||
<div className="App">
|
||||
<div className="background" />
|
||||
<MainColumn />
|
||||
</div>
|
||||
<ThemeProvider theme={theme}>
|
||||
<div className="App">
|
||||
<div className="background" />
|
||||
<MainColumn />
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
|
||||
export default App;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import './Blocks.css';
|
||||
import { useState, useEffect } from 'react';
|
||||
import DataContext from './Context';
|
||||
import InfoBlock from './InfoBlock';
|
||||
import DataBlock from './DataBlock';
|
||||
import GeolocationBlock from './GeolocationBlock';
|
||||
import delayedData from '../utils/data';
|
||||
|
|
@ -52,6 +53,7 @@ const Blocks = () => {
|
|||
}}
|
||||
>
|
||||
<div className="centerBlockInner">
|
||||
<InfoBlock />
|
||||
<DataBlock
|
||||
title="Intl.DateTimeFormat().resolvedOptions().timeZone"
|
||||
type="timeZone"
|
||||
|
|
@ -72,6 +74,7 @@ const Blocks = () => {
|
|||
<GeolocationBlock />
|
||||
</div>
|
||||
<div className="centerBlockMobile">
|
||||
<InfoBlock />
|
||||
<DataBlock
|
||||
title="Intl.DateTimeFormat().resolvedOptions().timeZone"
|
||||
type="timeZone"
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
import { useContext } from 'react';
|
||||
import DataContext from './Context';
|
||||
import Block from './Block';
|
||||
import { getConnection } from '../utils/connection';
|
||||
import TableRow from './TableRow';
|
||||
|
||||
const ConnectionBlock = () => {
|
||||
const { connectionData } = useContext(DataContext);
|
||||
return (
|
||||
<Block>
|
||||
<h1>Connection</h1>
|
||||
<div className="tableWrap">
|
||||
<table>
|
||||
<tbody>
|
||||
{getConnection(connectionData).map((item) => (
|
||||
<TableRow key={item.key} title={item.key} value={item.value} issues={item.issues} />
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p>
|
||||
Your IP address reveals information about your
|
||||
connection. Using a VPN or Tor will hide your connection info.
|
||||
</p>
|
||||
</Block>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConnectionBlock;
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
.gitHubButton {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 900px) {
|
||||
.gitHubButton {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 575px) {
|
||||
.gitHubButton {
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
import './GitHub.css';
|
||||
import GitHubButton from 'react-github-btn';
|
||||
|
||||
const GitHub = () => (
|
||||
<div className="gitHubButton">
|
||||
<GitHubButton
|
||||
href="https://github.com/z0ccc/LocateJS"
|
||||
data-color-scheme="no-preference: light; light: light; dark: light;"
|
||||
aria-label="Star z0ccc/LocateJS on GitHub"
|
||||
>
|
||||
Star
|
||||
</GitHubButton>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default GitHub;
|
||||
0
src/components/HeaderBar.css
Normal file
0
src/components/HeaderBar.css
Normal file
|
|
@ -1,12 +1,15 @@
|
|||
// import './HeaderBar.css';
|
||||
/** @jsxImportSource theme-ui */
|
||||
|
||||
import './HeaderBar.css';
|
||||
import { ReactComponent as LogoImg } from '../images/logo.svg';
|
||||
import HeaderButton from './HeaderButton';
|
||||
import chromeImage from '../images/chrome.png';
|
||||
import githubImage from '../images/github.png';
|
||||
|
||||
const HeaderBar = () => (
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
sx={{
|
||||
display: ['block', 'block', 'flex'],
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
width: '1024px',
|
||||
|
|
@ -17,6 +20,7 @@ const HeaderBar = () => (
|
|||
href="."
|
||||
style={{
|
||||
width: '206px',
|
||||
height: '50px',
|
||||
}}
|
||||
alt="LocateJS logo"
|
||||
>
|
||||
|
|
@ -28,55 +32,21 @@ const HeaderBar = () => (
|
|||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
height: '50px',
|
||||
gap: '24px',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#fff',
|
||||
height: '50px',
|
||||
borderRadius: '4px',
|
||||
padding: '0 18px',
|
||||
boxShadow: 'rgb(0 0 0 / 10%) 0px 4px 12px',
|
||||
margin: '0 24px 0 0',
|
||||
fontSize: '15px',
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={chromeImage}
|
||||
alt="Chrome logo"
|
||||
height="28"
|
||||
width="28"
|
||||
style={{
|
||||
marginRight: '8px',
|
||||
}}
|
||||
/>
|
||||
Download Extension
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#fff',
|
||||
height: '50px',
|
||||
borderRadius: '4px',
|
||||
padding: '0 18px',
|
||||
boxShadow: 'rgb(0 0 0 / 10%) 0px 4px 12px',
|
||||
fontSize: '15px',
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={githubImage}
|
||||
alt="Github logo"
|
||||
height="28"
|
||||
width="28"
|
||||
style={{
|
||||
marginRight: '8px',
|
||||
}}
|
||||
/>
|
||||
Source Code
|
||||
</div>
|
||||
<HeaderButton
|
||||
url="/"
|
||||
image={chromeImage}
|
||||
text="Download Extension"
|
||||
alt="Chrome logo"
|
||||
/>
|
||||
<HeaderButton
|
||||
url="https://github.com/z0ccc/Vytal"
|
||||
image={githubImage}
|
||||
text="Source Code"
|
||||
alt="Github logo"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
38
src/components/HeaderButton.js
Normal file
38
src/components/HeaderButton.js
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/** @jsxImportSource theme-ui */
|
||||
|
||||
const HeaderButton = ({ url, image, text, alt }) => (
|
||||
<a
|
||||
href={url}
|
||||
className="headerButton"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#fff',
|
||||
height: '50px',
|
||||
borderRadius: '4px',
|
||||
padding: '0 18px',
|
||||
boxShadow: 'rgb(0 0 0 / 10%) 0px 4px 12px',
|
||||
fontSize: '15px',
|
||||
textDecoration: 'none',
|
||||
color: '#000',
|
||||
':hover': {
|
||||
backgroundColor: 'white90',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={image}
|
||||
alt={alt}
|
||||
height="28"
|
||||
width="28"
|
||||
style={{
|
||||
marginRight: '8px',
|
||||
}}
|
||||
/>
|
||||
{text}
|
||||
</a>
|
||||
);
|
||||
|
||||
export default HeaderButton;
|
||||
13
src/components/InfoBlock.js
Normal file
13
src/components/InfoBlock.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import Block from './Block';
|
||||
|
||||
const InfoBlock = () => (
|
||||
<Block>
|
||||
Vytal is a browser extension that utilizes the chrome.debugger API to mock
|
||||
device data that could otherwise reveal information about you. This website
|
||||
scans your browser for such data. A red x signifies that the scanner has
|
||||
detected tampered data that is inaccurate. A green check means that no
|
||||
tampering has been detected. To read more visit the Github.
|
||||
</Block>
|
||||
);
|
||||
|
||||
export default InfoBlock;
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
.logoWrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 575px) {
|
||||
.logo {
|
||||
width: 160px;
|
||||
margin: 18px 0 12px 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
.mapImg {
|
||||
width: 100%;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--border);
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
margin: 0 0 10px 0;
|
||||
background-color: var(--lightGrey);
|
||||
aspect-ratio: 2 / 1;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 575px) {
|
||||
.mapImg {
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
import { useContext } from 'react';
|
||||
import DataContext from './Context';
|
||||
import './PredictionBlock.css';
|
||||
import Block from './Block';
|
||||
import PredictionTableRow from './PredictionTableRow';
|
||||
|
||||
const PredictionBlock = () => {
|
||||
const { prediction, mapUrl } = useContext(DataContext);
|
||||
|
||||
return (
|
||||
<Block>
|
||||
<h1>Location Prediction</h1>
|
||||
<img
|
||||
className="mapImg"
|
||||
src={mapUrl}
|
||||
alt="Map of location prediction"
|
||||
/>
|
||||
<div className="tableWrap">
|
||||
<table>
|
||||
<tbody>
|
||||
<PredictionTableRow title="Country" value={prediction.country} percent={prediction.countryPercent} />
|
||||
<PredictionTableRow title="City" value={prediction.city} percent={prediction.cityPercent} />
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p>
|
||||
Accuracy of the location prediction is dependant on how much
|
||||
authentic info you're exposing. To learn about how to hide your location visit the{' '}
|
||||
<a
|
||||
className="link"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
alt="Link to GitHub repo"
|
||||
href="https://github.com/z0ccc/LocateJS#locatejs"
|
||||
>
|
||||
GitHub repo
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
</Block>
|
||||
);
|
||||
};
|
||||
|
||||
export default PredictionBlock;
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
const PredictionTableRow = ({ title, value, percent }) => (
|
||||
<tr>
|
||||
<td>{title}</td>
|
||||
<td>{value || 'N/A'}</td>
|
||||
<td>{percent}%</td>
|
||||
</tr>
|
||||
);
|
||||
|
||||
export default PredictionTableRow;
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
import Block from './Block';
|
||||
import TableRow from './TableRow';
|
||||
|
||||
const TorBlock = ({ isTor }) => (
|
||||
<Block>
|
||||
<h1>Tor Browser</h1>
|
||||
<div className="tableWrap">
|
||||
<table>
|
||||
<tbody>
|
||||
<TableRow
|
||||
title="Detected"
|
||||
value={isTor ? 'True' : 'False'}
|
||||
issues={[]}
|
||||
/>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p>
|
||||
Tor Browser is a web browser that hides your location info,
|
||||
causing the location prediction to be inaccurate.
|
||||
</p>
|
||||
</Block>
|
||||
);
|
||||
|
||||
export default TorBlock;
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
import Block from './Block';
|
||||
import TableRow from './TableRow';
|
||||
import { getConnection } from '../utils/connection';
|
||||
|
||||
const WebRTCBlock = ({ data }) => (
|
||||
<Block>
|
||||
<h1>WebRTC Leaks</h1>
|
||||
{data.length === 0 ? (
|
||||
<div className="boxWrap">
|
||||
<div className="hash">No WebRTC leaks found</div>
|
||||
</div>
|
||||
)
|
||||
: (
|
||||
<div style={{ display: 'grid', gap: '24px' }}>
|
||||
{data.map((ipData) => (
|
||||
<div className="tableWrap" key={ipData.query}>
|
||||
<table>
|
||||
<tbody>
|
||||
{getConnection(ipData).map((item) => (
|
||||
<TableRow
|
||||
key={item.key}
|
||||
title={item.key}
|
||||
value={item.value}
|
||||
issues={item.issues}
|
||||
/>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<p>
|
||||
WebRTC leaks are a vulnerability that can expose your real IP address.
|
||||
Using a quality VPN or disabling WebRTC will stop the leaks.
|
||||
</p>
|
||||
</Block>
|
||||
);
|
||||
|
||||
export default WebRTCBlock;
|
||||
10
src/components/theme.ts
Normal file
10
src/components/theme.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import type { Theme } from 'theme-ui';
|
||||
|
||||
const theme: Theme = {
|
||||
breakpoints: ['575px', '1100px'],
|
||||
colors: {
|
||||
white90: 'rgb(255, 255, 255, 0.90)',
|
||||
},
|
||||
};
|
||||
|
||||
export default theme;
|
||||
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M320 320c-44.18 0-80 35.82-80 80 0 44.19 35.83 80 80 80 44.19 0 80-35.84 80-80 0-44.18-35.82-80-80-80zm0 128c-26.47 0-48-21.53-48-48s21.53-48 48-48 48 21.53 48 48-21.53 48-48 48zm316.21-290.05C459.22-9.9 180.95-10.06 3.79 157.95c-4.94 4.69-5.08 12.51-.26 17.32l5.69 5.69c4.61 4.61 12.07 4.74 16.8.25 164.99-156.39 423.64-155.76 587.97 0 4.73 4.48 12.19 4.35 16.8-.25l5.69-5.69c4.81-4.81 4.67-12.63-.27-17.32zM526.02 270.31c-117.34-104.48-294.86-104.34-412.04 0-5.05 4.5-5.32 12.31-.65 17.2l5.53 5.79c4.46 4.67 11.82 4.96 16.66.67 105.17-93.38 264-93.21 368.98 0 4.83 4.29 12.19 4.01 16.66-.67l5.53-5.79c4.65-4.89 4.38-12.7-.67-17.2z"/></svg>
|
||||
|
Before Width: | Height: | Size: 712 B |
|
|
@ -1,5 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512">
|
||||
<g fill="#fff">
|
||||
<path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!-- Font Awesome Pro 5.15.3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M266.34 277.65l11.31-11.31c3.12-3.12 3.12-8.19 0-11.31L230.62 208l47.03-47.03c3.12-3.12 3.12-8.19 0-11.31l-11.31-11.31c-3.12-3.12-8.19-3.12-11.31 0l-64 64c-3.12 3.12-3.12 8.19 0 11.31l64 64c3.13 3.12 8.19 3.12 11.31-.01zm96-11.31l11.31 11.31c3.12 3.12 8.19 3.12 11.31 0l64-64c3.12-3.12 3.12-8.19 0-11.31l-64-64c-3.12-3.12-8.19-3.12-11.31 0l-11.31 11.31c-3.12 3.12-3.12 8.19 0 11.31L409.38 208l-47.03 47.03a7.994 7.994 0 0 0-.01 11.31zM624 368h-48V96c0-35.3-28.72-64-64-64H128c-35.28 0-64 28.7-64 64v272H16c-8.84 0-16 7.16-16 16v48c0 44.11 35.88 80 80 80h480c44.12 0 80-35.89 80-80v-48c0-8.84-7.16-16-16-16zM96 96c0-17.67 14.33-32 32-32h384c17.67 0 32 14.33 32 32v272H391.13c-4.06 0-7.02 3.13-7.92 7.09C379.98 389.35 367.23 400 352 400h-64c-15.23 0-27.98-10.65-31.21-24.91-.9-3.96-3.86-7.09-7.92-7.09H96V96zm512 336c0 26.47-21.53 48-48 48H80c-26.47 0-48-21.53-48-48v-32h194.75c6.59 18.62 24.38 32 45.25 32h96c20.88 0 38.66-13.38 45.25-32H608v32z"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!-- Font Awesome Pro 5.15.3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M528 0H48C21.5 0 0 21.5 0 48v288c0 26.5 21.5 48 48 48h192l-24 96h-72c-8.8 0-16 7.2-16 16s7.2 16 16 16h288c8.8 0 16-7.2 16-16s-7.2-16-16-16h-72l-24-96h192c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zM249 480l16-64h46l16 64h-78zm295-144c0 8.8-7.2 16-16 16H48c-8.8 0-16-7.2-16-16V48c0-8.8 7.2-16 16-16h480c8.8 0 16 7.2 16 16v288z"/></svg>
|
||||
|
Before Width: | Height: | Size: 544 B |
1
src/react-app-env.d.ts
vendored
Normal file
1
src/react-app-env.d.ts
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/// <reference types="react-scripts" />
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
export { fetchAPI, getConnection };
|
||||
|
||||
// Gets connection values
|
||||
const fetchAPI = (setData) => {
|
||||
fetch('https://api.locatejs.com/')
|
||||
.then((response) => response.json())
|
||||
.then((json) => {
|
||||
setData(json);
|
||||
});
|
||||
};
|
||||
|
||||
// Returns object with connection data
|
||||
const getConnection = (connectionData) => {
|
||||
const isProxy = checkProxy(connectionData);
|
||||
return [
|
||||
{
|
||||
key: 'IP address',
|
||||
value: connectionData.query,
|
||||
issues: isProxy,
|
||||
},
|
||||
{
|
||||
key: 'Country',
|
||||
value: connectionData.country,
|
||||
issues: isProxy,
|
||||
},
|
||||
{
|
||||
key: 'Region',
|
||||
value: connectionData.regionName,
|
||||
issues: isProxy,
|
||||
},
|
||||
{
|
||||
key: 'City',
|
||||
value: connectionData.city,
|
||||
issues: isProxy,
|
||||
},
|
||||
{
|
||||
key: 'Time zone',
|
||||
value: connectionData.timezone,
|
||||
issues: isProxy,
|
||||
},
|
||||
{
|
||||
key: 'Latitude',
|
||||
value: connectionData.lat,
|
||||
issues: isProxy,
|
||||
},
|
||||
{
|
||||
key: 'Longitude',
|
||||
value: connectionData.lon,
|
||||
issues: isProxy,
|
||||
},
|
||||
{
|
||||
key: 'ISP',
|
||||
value: connectionData.isp,
|
||||
issues: isProxy,
|
||||
},
|
||||
{
|
||||
key: 'Org',
|
||||
value: connectionData.org,
|
||||
issues: isProxy,
|
||||
},
|
||||
{
|
||||
key: 'ASN',
|
||||
value: connectionData.as,
|
||||
issues: isProxy,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
const checkProxy = (data) => {
|
||||
const issues = [];
|
||||
if (data.security.vpn) {
|
||||
issues.push('VPN has been detected');
|
||||
}
|
||||
if (data.security.proxy) {
|
||||
issues.push('Proxy has been detected');
|
||||
}
|
||||
if (data.security.tor) {
|
||||
issues.push('Tor node has been detected');
|
||||
}
|
||||
if (data.security.relay) {
|
||||
issues.push('Private relay has been detected');
|
||||
}
|
||||
if (issues.length === 0 && data.proxy) {
|
||||
issues.push('VPN/proxy has been detected');
|
||||
}
|
||||
return issues;
|
||||
};
|
||||
|
|
@ -1,198 +0,0 @@
|
|||
export { getMapUrl, getPrediction };
|
||||
const ct = require('countries-and-timezones');
|
||||
|
||||
const getPrediction = (
|
||||
initialData, delayedData, frameData, workerData, connectionData, webRTCData, isTor
|
||||
) => {
|
||||
let country, countryPercent, city, cityPercent, timeZone;
|
||||
|
||||
const getAccurateData = (type) => {
|
||||
if (window.Worker.length && !workerData[type].issues.length) return workerData[type].value;
|
||||
if (!frameData[type].issues.length) return frameData[type].value;
|
||||
if (!delayedData[type].issues.length) return delayedData[type].value;
|
||||
return initialData[type].value;
|
||||
};
|
||||
|
||||
const accurateData = {
|
||||
locale: getAccurateData('locale'),
|
||||
timeZone: getAccurateData('timeZone'),
|
||||
timezoneOffset: getAccurateData('timezoneOffset'),
|
||||
dateString: getAccurateData('dateString'),
|
||||
dateLocale: getAccurateData('dateLocale'),
|
||||
language: getAccurateData('language'),
|
||||
languages: getAccurateData('languages'),
|
||||
};
|
||||
|
||||
const webRTCIP = checkWebRTC(webRTCData);
|
||||
|
||||
const systemCountry = checkCountry(accurateData);
|
||||
|
||||
const systemCity = checkCity(accurateData.timeZone, country);
|
||||
|
||||
if (!connectionData.isProxy) {
|
||||
if (webRTCIP && !webRTCIP.isProxy) {
|
||||
if (webRTCIP.query === connectionData.query) {
|
||||
countryPercent = 90;
|
||||
cityPercent = 90;
|
||||
} else {
|
||||
countryPercent = 80;
|
||||
cityPercent = 80;
|
||||
}
|
||||
country = webRTCIP.countryCode;
|
||||
city = webRTCIP.city;
|
||||
timeZone = webRTCIP.timeZone;
|
||||
} else {
|
||||
country = connectionData.countryCode;
|
||||
city = connectionData.city;
|
||||
timeZone = connectionData.timeZone;
|
||||
|
||||
countryPercent = 80;
|
||||
cityPercent = 80;
|
||||
}
|
||||
} else if (webRTCIP && !webRTCIP.isProxy) {
|
||||
countryPercent = 85;
|
||||
cityPercent = 85;
|
||||
country = webRTCIP.countryCode;
|
||||
city = webRTCIP.city;
|
||||
timeZone = webRTCIP.timeZone;
|
||||
}
|
||||
|
||||
if (country && systemCountry === country) {
|
||||
countryPercent = 95;
|
||||
} else if (country && systemCountry !== country) {
|
||||
countryPercent -= 40;
|
||||
} else {
|
||||
countryPercent = 40;
|
||||
country = systemCountry;
|
||||
}
|
||||
|
||||
if (city && systemCity === city) {
|
||||
cityPercent = 95;
|
||||
} else if (city && systemCity !== city) {
|
||||
cityPercent -= 20;
|
||||
} else {
|
||||
cityPercent = 20;
|
||||
city = systemCity;
|
||||
}
|
||||
|
||||
if (timeZone && timeZone !== accurateData.timeZone) {
|
||||
countryPercent -= 20;
|
||||
}
|
||||
|
||||
if (cityPercent > countryPercent) {
|
||||
cityPercent = countryPercent - 5;
|
||||
}
|
||||
|
||||
if (isTor) {
|
||||
countryPercent = 5;
|
||||
cityPercent = 5;
|
||||
}
|
||||
|
||||
if (!city) cityPercent = 0;
|
||||
|
||||
const regionNames = new Intl.DisplayNames(['en'], { type: 'region' });
|
||||
country = regionNames.of(country);
|
||||
|
||||
return { country, countryPercent, city, cityPercent };
|
||||
};
|
||||
|
||||
const checkWebRTC = (webRTCData) => {
|
||||
let localIP, ipv6, publicIP;
|
||||
for (let i = 0; i < webRTCData.length; i++) {
|
||||
if (webRTCData[i].proxy === false) {
|
||||
if (webRTCData[i].query.match(/^(192\.168\.|169\.254\.|10\.|172\.(1[6-9]|2\d|3[01]))/)) {
|
||||
localIP = webRTCData[i];
|
||||
} else if (webRTCData[i].query.match(/^[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7}$/)) {
|
||||
ipv6 = webRTCData[i];
|
||||
} else {
|
||||
publicIP = webRTCData[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (publicIP) return publicIP;
|
||||
if (ipv6) return ipv6;
|
||||
if (localIP) return localIP;
|
||||
return null;
|
||||
};
|
||||
|
||||
const checkCountry = (data) => {
|
||||
const countryArr =
|
||||
checkLocale(data.locale).concat(checkTimezone(data.timeZone), checkLanguages(data));
|
||||
|
||||
const countryObj = handleCountryArr(countryArr);
|
||||
|
||||
const topCountry =
|
||||
Object.keys(countryObj).reduce((a, b) => (countryObj[a] > countryObj[b] ? a : b));
|
||||
|
||||
return topCountry;
|
||||
};
|
||||
|
||||
// Get country from locale
|
||||
const checkLocale = (locale) => {
|
||||
const IntlLocale = new Intl.Locale(locale);
|
||||
// const regionNames = new Intl.DisplayNames(['en'], { type: 'region' });
|
||||
return [IntlLocale.region];
|
||||
};
|
||||
|
||||
// Get countries of timezone
|
||||
const checkTimezone = (timeZone) => {
|
||||
if (timeZone) {
|
||||
const countryArr = ct.getTimezone(timeZone).countries;
|
||||
return countryArr.concat(countryArr, countryArr);
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
const checkLanguages = (data) => {
|
||||
const countryArr = [];
|
||||
// loop thru system data languages
|
||||
data.languages.forEach((language) => {
|
||||
if (language.length > 2) {
|
||||
countryArr.push(language.slice(-2));
|
||||
}
|
||||
});
|
||||
|
||||
// Checks if main language has country code
|
||||
// if (data.language.length > 2) {
|
||||
// countryArr.push(data.language.slice(-2));
|
||||
// }
|
||||
|
||||
return countryArr;
|
||||
};
|
||||
|
||||
// converts array to object of value/frequency
|
||||
const handleCountryArr = (countryArr) =>
|
||||
countryArr.reduce((obj, val) => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
obj[val] = (obj[val] || 0) + 1;
|
||||
return obj;
|
||||
}, {});
|
||||
|
||||
const checkCity = (timeZone) => {
|
||||
let city = null;
|
||||
|
||||
// Check if timezone contains city info
|
||||
if (
|
||||
timeZone.includes('/') &&
|
||||
timeZone.match(/universal|GMT|UCT|UTC/g) === null &&
|
||||
!/\d/.test(timeZone)
|
||||
) {
|
||||
city = timeZone.split('/');
|
||||
city = city[city.length - 1].replace('_', ' ');
|
||||
}
|
||||
|
||||
return city;
|
||||
};
|
||||
|
||||
// Return url for static map image
|
||||
const getMapUrl = (prediction) => {
|
||||
let location, zoom;
|
||||
if (!prediction.city) {
|
||||
location = prediction.country;
|
||||
zoom = 3;
|
||||
} else {
|
||||
location = `${prediction.city},${prediction.country}`;
|
||||
zoom = 7;
|
||||
}
|
||||
return `https://maps.googleapis.com/maps/api/staticmap?${location}&markers=color:red%7Clabel:%7C${location}&size=460x230&zoom=${zoom}&key=AIzaSyB-YN-X8PGBSPd7NOaQu4csVhgJUnF3ZGk`;
|
||||
};
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
const getWebRTC = (setWebRTCData) => {
|
||||
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
|
||||
|| window.mozRTCPeerConnection
|
||||
|| window.webkitRTCPeerConnection;
|
||||
|
||||
// bypass naive webrtc blocking using an iframe
|
||||
if (!RTCPeerConnection) {
|
||||
const frame = document.createElement('iframe');
|
||||
document.body.appendChild(frame);
|
||||
frame.style.display = 'none';
|
||||
const win = frame.contentWindow;
|
||||
RTCPeerConnection = win.RTCPeerConnection
|
||||
|| win.mozRTCPeerConnection
|
||||
|| win.webkitRTCPeerConnection;
|
||||
}
|
||||
|
||||
// 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 = [];
|
||||
const ipsData = [];
|
||||
|
||||
// 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)];
|
||||
for (let i = 0; i < ips.length; i++) {
|
||||
ipsData.push(fetch(`https://api.locatejs.com/ip/${ips[i]}`)
|
||||
.then((response) => response.json())
|
||||
.then((json) => json));
|
||||
}
|
||||
setWebRTCData(await Promise.all(ipsData));
|
||||
} else {
|
||||
setTimeout(waitForElement, 1000);
|
||||
}
|
||||
};
|
||||
|
||||
waitForElement();
|
||||
} else {
|
||||
setWebRTCData([]);
|
||||
}
|
||||
};
|
||||
|
||||
export default getWebRTC;
|
||||
26
tsconfig.json
Normal file
26
tsconfig.json
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx",
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue