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) => {
|
||||
postMessage(navigator[e.data]);
|
||||
const 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 Table from './OldTable';
|
||||
import { fetchAPI, getConnection } from './mainOld';
|
||||
import Table from './Table';
|
||||
import { getConnection } from '../utils/conenction';
|
||||
|
||||
const ConnectionBlock = () => {
|
||||
const [data, setData] = useState('');
|
||||
const [display, setDisplay] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
fetchAPI(setData, setDisplay);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
const LocationBlock = ({ connectionData }) => (
|
||||
<ScanBlock>
|
||||
<h1>Connection</h1>
|
||||
{display === 1 && <Table data={getConnection(data)} />}
|
||||
{display === 0 && (
|
||||
<div className="boxWrap">
|
||||
Unable to fetch info. Adblock or content filter may have prevented
|
||||
data from loading.
|
||||
</div>
|
||||
)}
|
||||
<Table data={getConnection(connectionData)} />
|
||||
<p>
|
||||
<b>Explanation:</b> Your IP address reveals information about your
|
||||
connection. Using a VPN or Tor will hide your connection info.
|
||||
</p>
|
||||
</ScanBlock>
|
||||
);
|
||||
};
|
||||
);
|
||||
|
||||
export default ConnectionBlock;
|
||||
export default LocationBlock;
|
||||
|
|
|
|||
|
|
@ -1,37 +1,17 @@
|
|||
import { useState, useEffect } from 'react';
|
||||
import ScanBlock from './ScanBlock';
|
||||
import Table from './OldTable';
|
||||
import { fetchAPI, getLocation, getMap } from './mainOld';
|
||||
import Table from './Table';
|
||||
import { getMap, getLocation } from '../utils/conenction';
|
||||
|
||||
const LocationBlock = () => {
|
||||
const [data, setData] = useState([]);
|
||||
const [display, setDisplay] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
fetchAPI(setData, setDisplay);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
const LocationBlock = ({ connectionData, workerData }) => (
|
||||
<ScanBlock>
|
||||
<h1>Location</h1>
|
||||
{display === 1 && (
|
||||
<>
|
||||
<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>
|
||||
)}
|
||||
<img src={getMap(connectionData)} alt="Map of current location" />
|
||||
<Table data={getLocation(connectionData, workerData)} />
|
||||
<p>
|
||||
<b>Explanation:</b> Your IP address can be used to determine your
|
||||
location. Using a VPN or Tor will hide your true location.
|
||||
</p>
|
||||
</ScanBlock>
|
||||
);
|
||||
};
|
||||
);
|
||||
|
||||
export default LocationBlock;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/* eslint-disable no-unused-vars */
|
||||
import { useState, useEffect } from 'react';
|
||||
import UserAgentBlock from './UserAgentBlock';
|
||||
import IntlBlock from './IntlBlock';
|
||||
import OtherBlock from './OtherBlock';
|
||||
|
|
@ -11,29 +12,48 @@ import SoftwareBlock from './SoftwareBlock';
|
|||
import ConnectionBlock from './ConnectionBlock';
|
||||
import FiltersBlock from './FiltersBlock';
|
||||
// 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">
|
||||
<FingerprintBlock />
|
||||
{/* <FingerprintBlock />
|
||||
<NavigatorBlock />
|
||||
<UserAgentBlock />
|
||||
<IntlBlock />
|
||||
<IntlBlock /> */}
|
||||
</div>
|
||||
<div className="centerBlockInner">
|
||||
<LocationBlock />
|
||||
<ConnectionBlock />
|
||||
<ScreenBlock />
|
||||
<OtherBlock />
|
||||
<LocationBlock
|
||||
workerData={workerData}
|
||||
connectionData={connectionData}
|
||||
/>
|
||||
<ConnectionBlock
|
||||
workerData={workerData}
|
||||
connectionData={connectionData}
|
||||
/>
|
||||
{/* <ScreenBlock />
|
||||
<OtherBlock /> */}
|
||||
</div>
|
||||
{/* <FingerprintBlock />
|
||||
<LocationBlock />
|
||||
<ConnectionBlock />
|
||||
<FiltersBlock />
|
||||
<SoftwareBlock />
|
||||
<HardwareBlock /> */}
|
||||
{/* <FontsBlock /> */}
|
||||
</>
|
||||
);
|
||||
) : (
|
||||
<div className="contentBlock">
|
||||
<center>Loading...</center>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
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';
|
||||
|
||||
const Table = ({ data }) => {
|
||||
const [workerData, setWorkerData] = useState();
|
||||
|
||||
return (
|
||||
const Table = ({ data }) => (
|
||||
<div className="tableWrap">
|
||||
<table>
|
||||
{data.map((item) => (
|
||||
<tbody key={item.key}>
|
||||
<tbody key={item.key} title={item.code}>
|
||||
<TableRow item={item} />
|
||||
</tbody>
|
||||
))}
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
);
|
||||
|
||||
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 {
|
||||
checkNavigatorProperties,
|
||||
checkWebWorker,
|
||||
checkScreenProperties,
|
||||
} from './main';
|
||||
import { useState } from 'react';
|
||||
import { ReactComponent as XCircle } from '../images/xCircle.svg';
|
||||
import { ReactComponent as CheckCircle } from '../images/checkCircle.svg';
|
||||
import { ReactComponent as X } from '../images/x.svg';
|
||||
|
||||
const customStyles = {
|
||||
const modalStyles = {
|
||||
content: {
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
|
|
@ -21,74 +12,53 @@ const customStyles = {
|
|||
bottom: 'auto',
|
||||
marginRight: '-50%',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
padding: '18px',
|
||||
border: '1px solid var(--border)',
|
||||
borderRadius: '6px',
|
||||
},
|
||||
};
|
||||
|
||||
Modal.setAppElement('#root');
|
||||
|
||||
const TableRow = ({ item }) => {
|
||||
const [workerData, setWorkerData] = useState('');
|
||||
const [issues, setIssues] = useState(false);
|
||||
const issues = item.issues.filter(Boolean).length !== 0;
|
||||
const [modalIsOpen, setIsOpen] = useState(false);
|
||||
|
||||
const openModal = () => {
|
||||
if (issues) setIsOpen(true);
|
||||
};
|
||||
|
||||
const afterOpenModal = () => {};
|
||||
|
||||
const closeModal = () => {
|
||||
setIsOpen(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (item.issues.filter(Boolean).length !== 0) {
|
||||
setIssues(true);
|
||||
}
|
||||
checkWebWorker(item.key, setWorkerData);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (workerData !== '') {
|
||||
setIssues(true);
|
||||
}
|
||||
}, [workerData]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<tr className={issues ? 'issue' : ''} onClick={openModal}>
|
||||
<tr>
|
||||
<td>{item.key}</td>
|
||||
<td>{item.value}</td>
|
||||
<td>
|
||||
{issues ? (
|
||||
<>
|
||||
<XCircle className="circleButton" />
|
||||
</>
|
||||
<XCircle className="circleButton issueButton" onClick={openModal} />
|
||||
) : (
|
||||
<CheckCircle className="circleButton" />
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
<Modal
|
||||
isOpen={modalIsOpen}
|
||||
onAfterOpen={afterOpenModal}
|
||||
onRequestClose={closeModal}
|
||||
style={customStyles}
|
||||
contentLabel="Example Modal"
|
||||
style={modalStyles}
|
||||
contentLabel="Issues Modal"
|
||||
>
|
||||
<button onClick={closeModal}>close</button>
|
||||
<>
|
||||
{item.issues.map((ele, index) => (
|
||||
<div className="newline" key={index}>
|
||||
{ele}
|
||||
<div className="modalHeader">
|
||||
<div className="modalTitle">{item.key} issues</div>
|
||||
<X className="closeButton" onClick={closeModal} />
|
||||
</div>
|
||||
<ul>
|
||||
{item.issues.filter(Boolean).map((ele, index) => (
|
||||
<li key={index}>{ele}</li>
|
||||
))}
|
||||
<div className="newline">
|
||||
{workerData && <>{`Did not match web worker (${workerData})`}</>}
|
||||
</div>
|
||||
</>
|
||||
</ul>
|
||||
</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