parent
5fb603f6c9
commit
d0d98ba762
|
@ -5,7 +5,9 @@ import map from 'lodash/map';
|
||||||
|
|
||||||
import Card from '../ui/Card';
|
import Card from '../ui/Card';
|
||||||
import Cell from '../ui/Cell';
|
import Cell from '../ui/Cell';
|
||||||
|
import Popover from '../ui/Popover';
|
||||||
|
|
||||||
|
import { getTrackerData } from '../../helpers/whotracksme';
|
||||||
import { getPercent } from '../../helpers/helpers';
|
import { getPercent } from '../../helpers/helpers';
|
||||||
import { STATUS_COLORS } from '../../helpers/constants';
|
import { STATUS_COLORS } from '../../helpers/constants';
|
||||||
|
|
||||||
|
@ -13,7 +15,19 @@ class BlockedDomains extends Component {
|
||||||
columns = [{
|
columns = [{
|
||||||
Header: 'IP',
|
Header: 'IP',
|
||||||
accessor: 'ip',
|
accessor: 'ip',
|
||||||
Cell: ({ value }) => (<div className="logs__row logs__row--overflow"><span className="logs__text" title={value}>{value}</span></div>),
|
Cell: (row) => {
|
||||||
|
const { value } = row;
|
||||||
|
const trackerData = getTrackerData(value);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="logs__row" title={value}>
|
||||||
|
<div className="logs__text">
|
||||||
|
{value}
|
||||||
|
</div>
|
||||||
|
{trackerData && <Popover data={trackerData} />}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
}, {
|
}, {
|
||||||
Header: 'Requests count',
|
Header: 'Requests count',
|
||||||
accessor: 'domain',
|
accessor: 'domain',
|
||||||
|
@ -43,7 +57,7 @@ class BlockedDomains extends Component {
|
||||||
showPagination={false}
|
showPagination={false}
|
||||||
noDataText="No domains found"
|
noDataText="No domains found"
|
||||||
minRows={6}
|
minRows={6}
|
||||||
className="-striped -highlight card-table-overflow"
|
className="-striped -highlight card-table-overflow stats__table"
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
.stats__table .popover__body {
|
||||||
|
left: 0;
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats__table .popover__body:after {
|
||||||
|
left: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats__table .rt-tr-group:first-child .popover__body,
|
||||||
|
.stats__table .rt-tr-group:nth-child(2) .popover__body {
|
||||||
|
top: calc(100% + 5px);
|
||||||
|
bottom: initial;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats__table .rt-tr-group:first-child .popover__body:after,
|
||||||
|
.stats__table .rt-tr-group:nth-child(2) .popover__body:after {
|
||||||
|
top: -11px;
|
||||||
|
border-top: 6px solid transparent;
|
||||||
|
border-bottom: 6px solid #585965;
|
||||||
|
}
|
|
@ -5,7 +5,9 @@ import map from 'lodash/map';
|
||||||
|
|
||||||
import Card from '../ui/Card';
|
import Card from '../ui/Card';
|
||||||
import Cell from '../ui/Cell';
|
import Cell from '../ui/Cell';
|
||||||
|
import Popover from '../ui/Popover';
|
||||||
|
|
||||||
|
import { getTrackerData } from '../../helpers/whotracksme';
|
||||||
import { getPercent } from '../../helpers/helpers';
|
import { getPercent } from '../../helpers/helpers';
|
||||||
import { STATUS_COLORS } from '../../helpers/constants';
|
import { STATUS_COLORS } from '../../helpers/constants';
|
||||||
|
|
||||||
|
@ -22,7 +24,19 @@ class QueriedDomains extends Component {
|
||||||
columns = [{
|
columns = [{
|
||||||
Header: 'IP',
|
Header: 'IP',
|
||||||
accessor: 'ip',
|
accessor: 'ip',
|
||||||
Cell: ({ value }) => (<div className="logs__row logs__row--overflow"><span className="logs__text" title={value}>{value}</span></div>),
|
Cell: (row) => {
|
||||||
|
const { value } = row;
|
||||||
|
const trackerData = getTrackerData(value);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="logs__row" title={value}>
|
||||||
|
<div className="logs__text">
|
||||||
|
{value}
|
||||||
|
</div>
|
||||||
|
{trackerData && <Popover data={trackerData} />}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
}, {
|
}, {
|
||||||
Header: 'Requests count',
|
Header: 'Requests count',
|
||||||
accessor: 'count',
|
accessor: 'count',
|
||||||
|
@ -47,7 +61,7 @@ class QueriedDomains extends Component {
|
||||||
showPagination={false}
|
showPagination={false}
|
||||||
noDataText="No domains found"
|
noDataText="No domains found"
|
||||||
minRows={6}
|
minRows={6}
|
||||||
className="-striped -highlight card-table-overflow"
|
className="-striped -highlight card-table-overflow stats__table"
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|
|
@ -10,6 +10,7 @@ import BlockedDomains from './BlockedDomains';
|
||||||
|
|
||||||
import PageTitle from '../ui/PageTitle';
|
import PageTitle from '../ui/PageTitle';
|
||||||
import Loading from '../ui/Loading';
|
import Loading from '../ui/Loading';
|
||||||
|
import './Dashboard.css';
|
||||||
|
|
||||||
class Dashboard extends Component {
|
class Dashboard extends Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
|
|
@ -60,6 +60,18 @@
|
||||||
border-bottom: 6px solid #585965;
|
border-bottom: 6px solid #585965;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.logs__table .rt-tr-group:first-child .popover__body {
|
||||||
|
top: calc(100% + 5px);
|
||||||
|
bottom: initial;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logs__table .rt-tr-group:first-child .popover__body:after {
|
||||||
|
top: -11px;
|
||||||
|
border-top: 6px solid transparent;
|
||||||
|
border-bottom: 6px solid #585965;
|
||||||
|
}
|
||||||
|
|
||||||
.logs__table .rt-thead.-filters input,
|
.logs__table .rt-thead.-filters input,
|
||||||
.logs__table .rt-thead.-filters select {
|
.logs__table .rt-thead.-filters select {
|
||||||
padding: 6px 7px;
|
padding: 6px 7px;
|
||||||
|
|
|
@ -6,10 +6,12 @@ import escapeRegExp from 'lodash/escapeRegExp';
|
||||||
import endsWith from 'lodash/endsWith';
|
import endsWith from 'lodash/endsWith';
|
||||||
|
|
||||||
import { formatTime } from '../../helpers/helpers';
|
import { formatTime } from '../../helpers/helpers';
|
||||||
|
import { getTrackerData } from '../../helpers/whotracksme';
|
||||||
import PageTitle from '../ui/PageTitle';
|
import PageTitle from '../ui/PageTitle';
|
||||||
import Card from '../ui/Card';
|
import Card from '../ui/Card';
|
||||||
import Loading from '../ui/Loading';
|
import Loading from '../ui/Loading';
|
||||||
import Tooltip from '../ui/Tooltip';
|
import Tooltip from '../ui/Tooltip';
|
||||||
|
import Popover from '../ui/Popover';
|
||||||
import './Logs.css';
|
import './Logs.css';
|
||||||
|
|
||||||
const DOWNLOAD_LOG_FILENAME = 'dns-logs.txt';
|
const DOWNLOAD_LOG_FILENAME = 'dns-logs.txt';
|
||||||
|
@ -91,12 +93,14 @@ class Logs extends Component {
|
||||||
accessor: 'domain',
|
accessor: 'domain',
|
||||||
Cell: (row) => {
|
Cell: (row) => {
|
||||||
const response = row.value;
|
const response = row.value;
|
||||||
|
const trackerData = getTrackerData(response);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="logs__row logs__row--overflow" title={response}>
|
<div className="logs__row" title={response}>
|
||||||
<div className="logs__text">
|
<div className="logs__text">
|
||||||
{response}
|
{response}
|
||||||
</div>
|
</div>
|
||||||
|
{trackerData && <Popover data={trackerData}/>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
.popover-wrap {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover__trigger {
|
||||||
|
position: relative;
|
||||||
|
top: 3px;
|
||||||
|
margin: 0 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover__trigger:after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: -6px;
|
||||||
|
left: -3px;
|
||||||
|
width: 26px;
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover__body {
|
||||||
|
content: "";
|
||||||
|
display: flex;
|
||||||
|
position: absolute;
|
||||||
|
min-width: 275px;
|
||||||
|
bottom: calc(100% + 3px);
|
||||||
|
left: 50%;
|
||||||
|
padding: 10px 15px;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
white-space: normal;
|
||||||
|
color: #fff;
|
||||||
|
background-color: #585965;
|
||||||
|
border-radius: 3px;
|
||||||
|
transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
visibility: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover__body:after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
bottom: -5px;
|
||||||
|
left: calc(50% - 6px);
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-left: 6px solid transparent;
|
||||||
|
border-right: 6px solid transparent;
|
||||||
|
border-top: 6px solid #585965;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover__trigger:hover + .popover__body,
|
||||||
|
.popover__body:hover {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover__icon {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
stroke: #9aa0ac;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover__list-title {
|
||||||
|
margin-bottom: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover__list-item {
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover__list-item:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover__link {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
color: #66b586;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover__link:hover,
|
||||||
|
.popover__link:focus {
|
||||||
|
color: #66b586;
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import './Popover.css';
|
||||||
|
|
||||||
|
class Popover extends Component {
|
||||||
|
render() {
|
||||||
|
const { data } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="popover-wrap">
|
||||||
|
<div className="popover__trigger">
|
||||||
|
<svg className="popover__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg>
|
||||||
|
</div>
|
||||||
|
<div className="popover__body">
|
||||||
|
<div className="popover__list">
|
||||||
|
<div className="popover__list-title">
|
||||||
|
This domain belongs to a known tracker.
|
||||||
|
</div>
|
||||||
|
<div className="popover__list-item">
|
||||||
|
Name: <strong>{data.name}</strong>
|
||||||
|
</div>
|
||||||
|
<div className="popover__list-item">
|
||||||
|
Category: <strong>{data.category}</strong>
|
||||||
|
</div>
|
||||||
|
<div className="popover__list-item">
|
||||||
|
<a href={`https://whotracks.me/trackers/${data.id}.html`} className="popover__link" target="_blank" rel="noopener noreferrer">More information on Whotracksme</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Popover.propTypes = {
|
||||||
|
data: PropTypes.object.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Popover;
|
|
@ -4,6 +4,10 @@
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ReactTable .rt-tbody {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
.rt-tr-group .red {
|
.rt-tr-group .red {
|
||||||
background-color: #fff4f2;
|
background-color: #fff4f2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
content: attr(data-tooltip);
|
content: attr(data-tooltip);
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: calc(100% + 12px);
|
bottom: calc(100% + 10px);
|
||||||
left: 50%;
|
left: 50%;
|
||||||
padding: 10px 15px;
|
padding: 10px 15px;
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
.tooltip-custom:after {
|
.tooltip-custom:after {
|
||||||
content: "";
|
content: "";
|
||||||
position: relative;
|
position: relative;
|
||||||
top: -9px;
|
top: -7px;
|
||||||
left: calc(50% - 6px);
|
left: calc(50% - 6px);
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|
|
@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
|
||||||
import './Tooltip.css';
|
import './Tooltip.css';
|
||||||
|
|
||||||
const Tooltip = props => (
|
const Tooltip = props => (
|
||||||
<div data-tooltip={props.text} className={`tooltip-custom ${props.type}`}></div>
|
<div data-tooltip={props.text} className={`tooltip-custom ${props.type || ''}`}></div>
|
||||||
);
|
);
|
||||||
|
|
||||||
Tooltip.propTypes = {
|
Tooltip.propTypes = {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import trackersDb from './whotracksmedb.json';
|
||||||
@type {object}
|
@type {object}
|
||||||
@property {string} id - tracker ID.
|
@property {string} id - tracker ID.
|
||||||
@property {string} name - tracker name.
|
@property {string} name - tracker name.
|
||||||
@property {number} age - tracker category.
|
@property {number} category - tracker category.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,9 +22,9 @@ export const getTrackerData = (domainName) => {
|
||||||
const parts = domainName.split(/\./g).reverse();
|
const parts = domainName.split(/\./g).reverse();
|
||||||
let hostToCheck = '';
|
let hostToCheck = '';
|
||||||
|
|
||||||
// Check every subdomain except the TLD
|
// Check every subdomain
|
||||||
for (let i = 1; i < parts.length; i += 1) {
|
for (let i = 0; i < parts.length; i += 1) {
|
||||||
hostToCheck = hostToCheck + (i > 0 ? '.' : '') + parts[i];
|
hostToCheck = parts[i] + (i > 0 ? '.' : '') + hostToCheck;
|
||||||
const trackerId = trackersDb.trackerDomains[hostToCheck];
|
const trackerId = trackersDb.trackerDomains[hostToCheck];
|
||||||
|
|
||||||
if (trackerId) {
|
if (trackerId) {
|
||||||
|
|
Loading…
Reference in New Issue