Added connection block
This commit is contained in:
parent
fcafd1f736
commit
780eac5aac
9 changed files with 225 additions and 163 deletions
|
|
@ -1,3 +1,10 @@
|
||||||
onmessage = (e) => {
|
const data = {
|
||||||
postMessage(navigator[e.data]);
|
locale: Intl.DateTimeFormat().resolvedOptions().locale,
|
||||||
|
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||||
|
timezoneOffset: new Date().getTimezoneOffset(),
|
||||||
|
date: new Date().toString(),
|
||||||
|
language: navigator.language,
|
||||||
|
languages: navigator.languages,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
postMessage(data);
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,16 @@
|
||||||
import { useState, useEffect } from 'react';
|
|
||||||
import ScanBlock from './ScanBlock';
|
import ScanBlock from './ScanBlock';
|
||||||
import Table from './OldTable';
|
import Table from './Table';
|
||||||
import { fetchAPI, getConnection } from './mainOld';
|
import { getConnection } from '../utils/conenction';
|
||||||
|
|
||||||
const ConnectionBlock = () => {
|
const LocationBlock = ({ connectionData }) => (
|
||||||
const [data, setData] = useState('');
|
|
||||||
const [display, setDisplay] = useState('');
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
fetchAPI(setData, setDisplay);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ScanBlock>
|
<ScanBlock>
|
||||||
<h1>Connection</h1>
|
<h1>Connection</h1>
|
||||||
{display === 1 && <Table data={getConnection(data)} />}
|
<Table data={getConnection(connectionData)} />
|
||||||
{display === 0 && (
|
|
||||||
<div className="boxWrap">
|
|
||||||
Unable to fetch info. Adblock or content filter may have prevented
|
|
||||||
data from loading.
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<p>
|
<p>
|
||||||
<b>Explanation:</b> Your IP address reveals information about your
|
<b>Explanation:</b> Your IP address reveals information about your
|
||||||
connection. Using a VPN or Tor will hide your connection info.
|
connection. Using a VPN or Tor will hide your connection info.
|
||||||
</p>
|
</p>
|
||||||
</ScanBlock>
|
</ScanBlock>
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
export default ConnectionBlock;
|
export default LocationBlock;
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,17 @@
|
||||||
import { useState, useEffect } from 'react';
|
|
||||||
import ScanBlock from './ScanBlock';
|
import ScanBlock from './ScanBlock';
|
||||||
import Table from './OldTable';
|
import Table from './Table';
|
||||||
import { fetchAPI, getLocation, getMap } from './mainOld';
|
import { getMap, getLocation } from '../utils/conenction';
|
||||||
|
|
||||||
const LocationBlock = () => {
|
const LocationBlock = ({ connectionData, workerData }) => (
|
||||||
const [data, setData] = useState([]);
|
|
||||||
const [display, setDisplay] = useState('');
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
fetchAPI(setData, setDisplay);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ScanBlock>
|
<ScanBlock>
|
||||||
<h1>Location</h1>
|
<h1>Location</h1>
|
||||||
{display === 1 && (
|
<img src={getMap(connectionData)} alt="Map of current location" />
|
||||||
<>
|
<Table data={getLocation(connectionData, workerData)} />
|
||||||
<img src={getMap(data)} alt="Map of current location" />
|
|
||||||
<Table data={getLocation(data)} />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{display === 0 && (
|
|
||||||
<div className="boxWrap">
|
|
||||||
Unable to fetch info. Adblock or content filter may have prevented
|
|
||||||
data from loading.
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<p>
|
<p>
|
||||||
<b>Explanation:</b> Your IP address can be used to determine your
|
<b>Explanation:</b> Your IP address can be used to determine your
|
||||||
location. Using a VPN or Tor will hide your true location.
|
location. Using a VPN or Tor will hide your true location.
|
||||||
</p>
|
</p>
|
||||||
</ScanBlock>
|
</ScanBlock>
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
export default LocationBlock;
|
export default LocationBlock;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
/* eslint-disable no-unused-vars */
|
/* eslint-disable no-unused-vars */
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
import UserAgentBlock from './UserAgentBlock';
|
import UserAgentBlock from './UserAgentBlock';
|
||||||
import IntlBlock from './IntlBlock';
|
import IntlBlock from './IntlBlock';
|
||||||
import OtherBlock from './OtherBlock';
|
import OtherBlock from './OtherBlock';
|
||||||
|
|
@ -11,29 +12,48 @@ import SoftwareBlock from './SoftwareBlock';
|
||||||
import ConnectionBlock from './ConnectionBlock';
|
import ConnectionBlock from './ConnectionBlock';
|
||||||
import FiltersBlock from './FiltersBlock';
|
import FiltersBlock from './FiltersBlock';
|
||||||
// import FontsBlock from './FontsBlock';
|
// import FontsBlock from './FontsBlock';
|
||||||
|
import { fetchAPI, getWebWorker } from '../utils/common';
|
||||||
|
|
||||||
const ScanBlocks = () => (
|
const ScanBlocks = () => {
|
||||||
|
const [workerData, setWorkerData] = useState();
|
||||||
|
const [connectionData, setConnectionData] = useState('');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getWebWorker().onmessage = (event) => {
|
||||||
|
setWorkerData(event.data);
|
||||||
|
fetchAPI(setConnectionData);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{connectionData ? (
|
||||||
<>
|
<>
|
||||||
<div className="centerBlockInner">
|
<div className="centerBlockInner">
|
||||||
<FingerprintBlock />
|
{/* <FingerprintBlock />
|
||||||
<NavigatorBlock />
|
<NavigatorBlock />
|
||||||
<UserAgentBlock />
|
<UserAgentBlock />
|
||||||
<IntlBlock />
|
<IntlBlock /> */}
|
||||||
</div>
|
</div>
|
||||||
<div className="centerBlockInner">
|
<div className="centerBlockInner">
|
||||||
<LocationBlock />
|
<LocationBlock
|
||||||
<ConnectionBlock />
|
workerData={workerData}
|
||||||
<ScreenBlock />
|
connectionData={connectionData}
|
||||||
<OtherBlock />
|
/>
|
||||||
|
<ConnectionBlock
|
||||||
|
workerData={workerData}
|
||||||
|
connectionData={connectionData}
|
||||||
|
/>
|
||||||
|
{/* <ScreenBlock />
|
||||||
|
<OtherBlock /> */}
|
||||||
</div>
|
</div>
|
||||||
{/* <FingerprintBlock />
|
|
||||||
<LocationBlock />
|
|
||||||
<ConnectionBlock />
|
|
||||||
<FiltersBlock />
|
|
||||||
<SoftwareBlock />
|
|
||||||
<HardwareBlock /> */}
|
|
||||||
{/* <FontsBlock /> */}
|
|
||||||
</>
|
</>
|
||||||
);
|
) : (
|
||||||
|
<div className="contentBlock">
|
||||||
|
<center>Loading...</center>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default ScanBlocks;
|
export default ScanBlocks;
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,15 @@
|
||||||
/* eslint-disable no-unused-vars */
|
|
||||||
import parse from 'html-react-parser';
|
|
||||||
import { useState, useEffect } from 'react';
|
|
||||||
import TableRow from './TableRow';
|
import TableRow from './TableRow';
|
||||||
|
|
||||||
const Table = ({ data }) => {
|
const Table = ({ data }) => (
|
||||||
const [workerData, setWorkerData] = useState();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="tableWrap">
|
<div className="tableWrap">
|
||||||
<table>
|
<table>
|
||||||
{data.map((item) => (
|
{data.map((item) => (
|
||||||
<tbody key={item.key}>
|
<tbody key={item.key} title={item.code}>
|
||||||
<TableRow item={item} />
|
<TableRow item={item} />
|
||||||
</tbody>
|
</tbody>
|
||||||
))}
|
))}
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
export default Table;
|
export default Table;
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,10 @@
|
||||||
/* eslint-disable react/button-has-type */
|
|
||||||
/* eslint-disable react/jsx-indent-props */
|
|
||||||
/* eslint-disable no-return-assign */
|
|
||||||
/* eslint-disable no-unused-vars */
|
|
||||||
import parse from 'html-react-parser';
|
|
||||||
import { useState, useEffect } from 'react';
|
|
||||||
import Modal from 'react-modal';
|
import Modal from 'react-modal';
|
||||||
import {
|
import { useState } from 'react';
|
||||||
checkNavigatorProperties,
|
|
||||||
checkWebWorker,
|
|
||||||
checkScreenProperties,
|
|
||||||
} from './main';
|
|
||||||
import { ReactComponent as XCircle } from '../images/xCircle.svg';
|
import { ReactComponent as XCircle } from '../images/xCircle.svg';
|
||||||
import { ReactComponent as CheckCircle } from '../images/checkCircle.svg';
|
import { ReactComponent as CheckCircle } from '../images/checkCircle.svg';
|
||||||
|
import { ReactComponent as X } from '../images/x.svg';
|
||||||
|
|
||||||
const customStyles = {
|
const modalStyles = {
|
||||||
content: {
|
content: {
|
||||||
top: '50%',
|
top: '50%',
|
||||||
left: '50%',
|
left: '50%',
|
||||||
|
|
@ -21,74 +12,53 @@ const customStyles = {
|
||||||
bottom: 'auto',
|
bottom: 'auto',
|
||||||
marginRight: '-50%',
|
marginRight: '-50%',
|
||||||
transform: 'translate(-50%, -50%)',
|
transform: 'translate(-50%, -50%)',
|
||||||
|
padding: '18px',
|
||||||
|
border: '1px solid var(--border)',
|
||||||
|
borderRadius: '6px',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Modal.setAppElement('#root');
|
Modal.setAppElement('#root');
|
||||||
|
|
||||||
const TableRow = ({ item }) => {
|
const TableRow = ({ item }) => {
|
||||||
const [workerData, setWorkerData] = useState('');
|
const issues = item.issues.filter(Boolean).length !== 0;
|
||||||
const [issues, setIssues] = useState(false);
|
|
||||||
const [modalIsOpen, setIsOpen] = useState(false);
|
const [modalIsOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
const openModal = () => {
|
const openModal = () => {
|
||||||
if (issues) setIsOpen(true);
|
if (issues) setIsOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const afterOpenModal = () => {};
|
|
||||||
|
|
||||||
const closeModal = () => {
|
const closeModal = () => {
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (item.issues.filter(Boolean).length !== 0) {
|
|
||||||
setIssues(true);
|
|
||||||
}
|
|
||||||
checkWebWorker(item.key, setWorkerData);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (workerData !== '') {
|
|
||||||
setIssues(true);
|
|
||||||
}
|
|
||||||
}, [workerData]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<tr>
|
||||||
<tr className={issues ? 'issue' : ''} onClick={openModal}>
|
|
||||||
<td>{item.key}</td>
|
<td>{item.key}</td>
|
||||||
<td>{item.value}</td>
|
<td>{item.value}</td>
|
||||||
<td>
|
<td>
|
||||||
{issues ? (
|
{issues ? (
|
||||||
<>
|
<XCircle className="circleButton issueButton" onClick={openModal} />
|
||||||
<XCircle className="circleButton" />
|
|
||||||
</>
|
|
||||||
) : (
|
) : (
|
||||||
<CheckCircle className="circleButton" />
|
<CheckCircle className="circleButton" />
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
|
||||||
<Modal
|
<Modal
|
||||||
isOpen={modalIsOpen}
|
isOpen={modalIsOpen}
|
||||||
onAfterOpen={afterOpenModal}
|
|
||||||
onRequestClose={closeModal}
|
onRequestClose={closeModal}
|
||||||
style={customStyles}
|
style={modalStyles}
|
||||||
contentLabel="Example Modal"
|
contentLabel="Issues Modal"
|
||||||
>
|
>
|
||||||
<button onClick={closeModal}>close</button>
|
<div className="modalHeader">
|
||||||
<>
|
<div className="modalTitle">{item.key} issues</div>
|
||||||
{item.issues.map((ele, index) => (
|
<X className="closeButton" onClick={closeModal} />
|
||||||
<div className="newline" key={index}>
|
|
||||||
{ele}
|
|
||||||
</div>
|
</div>
|
||||||
|
<ul>
|
||||||
|
{item.issues.filter(Boolean).map((ele, index) => (
|
||||||
|
<li key={index}>{ele}</li>
|
||||||
))}
|
))}
|
||||||
<div className="newline">
|
</ul>
|
||||||
{workerData && <>{`Did not match web worker (${workerData})`}</>}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
</Modal>
|
</Modal>
|
||||||
</>
|
</tr>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
1
frontend/src/images/x.svg
Normal file
1
frontend/src/images/x.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z"/></svg>
|
||||||
|
After Width: | Height: | Size: 468 B |
18
frontend/src/utils/common.js
Normal file
18
frontend/src/utils/common.js
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
export { fetchAPI, getWebWorker };
|
||||||
|
|
||||||
|
// Gets location values
|
||||||
|
const fetchAPI = (setData) => {
|
||||||
|
fetch('https://api.vytal.io/ip/')
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((json) => {
|
||||||
|
setData(json);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getWebWorker = () => {
|
||||||
|
let w;
|
||||||
|
if (typeof w === 'undefined') {
|
||||||
|
w = new Worker('worker.js');
|
||||||
|
}
|
||||||
|
return w;
|
||||||
|
};
|
||||||
89
frontend/src/utils/conenction.js
Normal file
89
frontend/src/utils/conenction.js
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
export { getMap, getConnection, getLocation };
|
||||||
|
|
||||||
|
const getMap = (data) =>
|
||||||
|
`https://maps.googleapis.com/maps/api/staticmap?center=${data.lat},${data.lon}&markers=color:red%7Clabel:%7C${data.lat},${data.lon}&size=500x200&zoom=10&key=AIzaSyB-YN-X8PGBSPd7NOaQu4csVhgJUnF3ZGk`;
|
||||||
|
|
||||||
|
const compareTimeZone = (locationTimeZone, workerTimeZone) => {
|
||||||
|
if (locationTimeZone !== workerTimeZone) {
|
||||||
|
return "Location data doesn't match system data";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const checkProxy = (proxy) => {
|
||||||
|
if (proxy) {
|
||||||
|
return 'VPN/proxy has been detected';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Returns object with location data
|
||||||
|
const getLocation = (data, workerData) => {
|
||||||
|
const timeZoneIssue = compareTimeZone(data.timezone, workerData.timeZone);
|
||||||
|
const isProxy = checkProxy(data.proxy);
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
key: 'Country',
|
||||||
|
value: data.country,
|
||||||
|
issues: [timeZoneIssue, isProxy],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'Region',
|
||||||
|
value: data.regionName,
|
||||||
|
issues: [timeZoneIssue, isProxy],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'City',
|
||||||
|
value: data.city,
|
||||||
|
issues: [timeZoneIssue, isProxy],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'Time zone',
|
||||||
|
value: data.timezone,
|
||||||
|
issues: [timeZoneIssue, isProxy],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'Zip code',
|
||||||
|
value: data.zip,
|
||||||
|
issues: [timeZoneIssue, isProxy],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'Latitude',
|
||||||
|
value: data.lat,
|
||||||
|
issues: [timeZoneIssue, isProxy],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'Longitude',
|
||||||
|
value: data.lon,
|
||||||
|
issues: [timeZoneIssue, isProxy],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Returns object with location data
|
||||||
|
const getConnection = (data) => {
|
||||||
|
console.log(data);
|
||||||
|
const isProxy = checkProxy(data.proxy);
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
key: 'IP address',
|
||||||
|
value: data.query,
|
||||||
|
issues: [isProxy],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'ISP',
|
||||||
|
value: data.isp,
|
||||||
|
issues: [isProxy],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'Organization',
|
||||||
|
value: data.org,
|
||||||
|
issues: [isProxy],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'ASN',
|
||||||
|
value: data.as,
|
||||||
|
issues: [isProxy],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
};
|
||||||
Loading…
Add table
Reference in a new issue