Generating screenshots
This commit is contained in:
parent
24da4a34dd
commit
7a2122089e
|
@ -15,7 +15,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&__content {
|
&__content {
|
||||||
height: 75vh;
|
height: 70vh;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
padding: 1rem 2rem;
|
padding: 1rem 2rem;
|
||||||
color: $black-color;
|
color: $black-color;
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { Explainers } from './explainers';
|
||||||
import { ParsedAnswers } from './parse-answers';
|
import { ParsedAnswers } from './parse-answers';
|
||||||
import { v } from './verbs';
|
import { v } from './verbs';
|
||||||
import './email-content.scss';
|
import './email-content.scss';
|
||||||
|
import { Fragment } from 'react';
|
||||||
|
|
||||||
declare var PLUGIN_NAME: string;
|
declare var PLUGIN_NAME: string;
|
||||||
declare var PLUGIN_URL: string;
|
declare var PLUGIN_URL: string;
|
||||||
|
@ -28,6 +29,13 @@ export default function EmailContent({
|
||||||
)
|
)
|
||||||
).map((explainer_key) => Explainers[explainer_key]);
|
).map((explainer_key) => Explainers[explainer_key]);
|
||||||
return (
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<h1>Treść maila</h1>
|
||||||
|
<p>
|
||||||
|
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Iure dolore, pariatur ab
|
||||||
|
eius expedita maxime alias esse quis possimus rem aliquid dicta laudantium rerum
|
||||||
|
libero enim cumque. Aperiam, enim aliquid.
|
||||||
|
</p>
|
||||||
<div className="mail-container">
|
<div className="mail-container">
|
||||||
<div className="mail-container__header">
|
<div className="mail-container__header">
|
||||||
<div className="mail-container__header--control">
|
<div className="mail-container__header--control">
|
||||||
|
@ -39,10 +47,10 @@ export default function EmailContent({
|
||||||
<article className="mail-container__content">
|
<article className="mail-container__content">
|
||||||
<p>Dzień dobry,</p>
|
<p>Dzień dobry,</p>
|
||||||
<p>
|
<p>
|
||||||
w dniu {getDate()} {_('odwiedziłem')} stronę {visited_url}. Po podejrzeniu ruchu
|
w dniu {getDate()} {_('odwiedziłem')} stronę {visited_url}. Po podejrzeniu
|
||||||
sieciowego generowanego przez tę stronę za pomocą wtyczki{' '}
|
ruchu sieciowego generowanego przez tę stronę za pomocą wtyczki{' '}
|
||||||
<a href={PLUGIN_URL}>{PLUGIN_NAME}</a> w przeglądarce Firefox {_('mam')} pytania
|
<a href={PLUGIN_URL}>{PLUGIN_NAME}</a> w przeglądarce Firefox {_('mam')}{' '}
|
||||||
dotyczące przetwarzania {_('moich')} danych osobowych, na które nie{' '}
|
pytania dotyczące przetwarzania {_('moich')} danych osobowych, na które nie{' '}
|
||||||
{_('znalazłem')} odpowiedzi nigdzie na Państwa stronie.
|
{_('znalazłem')} odpowiedzi nigdzie na Państwa stronie.
|
||||||
</p>
|
</p>
|
||||||
{problems.map((problem) => problem.getEmailContent())}
|
{problems.map((problem) => problem.getEmailContent())}
|
||||||
|
@ -54,14 +62,15 @@ export default function EmailContent({
|
||||||
treści wyroku TSUE w sprawie C-40/17
|
treści wyroku TSUE w sprawie C-40/17
|
||||||
</a>{' '}
|
</a>{' '}
|
||||||
poprzez wysyłanie moich danych w wyżej opisanym zakresie stają się Państwo
|
poprzez wysyłanie moich danych w wyżej opisanym zakresie stają się Państwo
|
||||||
współadministratorem moich danych osobowych, dlatego ciąży na Państwu obowiązek
|
współadministratorem moich danych osobowych, dlatego ciąży na Państwu
|
||||||
odpowiedzi na moje pytania na mocy Art. 12 i 13 Rozporządzenia 2016/679
|
obowiązek odpowiedzi na moje pytania na mocy Art. 12 i 13 Rozporządzenia
|
||||||
Parlamentu Europejskiego i Rady (UE) z dnia 27 kwietnia 2016 r. w sprawie
|
2016/679 Parlamentu Europejskiego i Rady (UE) z dnia 27 kwietnia 2016 r. w
|
||||||
ochrony osób fizycznych w związku z przetwarzaniem danych osobowych i w sprawie
|
sprawie ochrony osób fizycznych w związku z przetwarzaniem danych osobowych
|
||||||
swobodnego przepływu takich danych oraz uchylenia dyrektywy 95/46/WE (ogólne
|
i w sprawie swobodnego przepływu takich danych oraz uchylenia dyrektywy
|
||||||
rozporządzenie o ochronie danych, dalej: „RODO”).
|
95/46/WE (ogólne rozporządzenie o ochronie danych, dalej: „RODO”).
|
||||||
</p>
|
</p>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
@import './../../styles/colors.scss';
|
@import './../../styles/colors.scss';
|
||||||
|
|
||||||
* {
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
font-family: 'OpenSans' !important;
|
font-family: 'OpenSans' !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,10 +45,8 @@ h3 {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
max-height: 3.5rem;
|
max-height: 3.5rem;
|
||||||
min-height: 3.5rem;
|
min-height: 3.5rem;
|
||||||
// border-bottom: 1px solid $light-grey;
|
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
// background: #ffffff;
|
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
||||||
.webpage-metadata {
|
.webpage-metadata {
|
||||||
|
@ -75,7 +74,6 @@ h3 {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
.sv_p_root {
|
.sv_p_root {
|
||||||
& > .sv_row:nth-child(2n) {
|
& > .sv_row:nth-child(2n) {
|
||||||
// background-color: hsl(217.5, 7.8%, 96%);
|
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +82,6 @@ h3 {
|
||||||
}
|
}
|
||||||
|
|
||||||
& > .sv_row {
|
& > .sv_row {
|
||||||
// border-bottom: 1px solid #d1d1d1;
|
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
box-shadow: rgba(12, 12, 13, 0.1) 0px 1px 4px 0px;
|
box-shadow: rgba(12, 12, 13, 0.1) 0px 1px 4px 0px;
|
||||||
|
|
|
@ -19,21 +19,6 @@ function Report() {
|
||||||
);
|
);
|
||||||
const [mode, setMode] = React.useState(url.searchParams.get('mode') || 'survey');
|
const [mode, setMode] = React.useState(url.searchParams.get('mode') || 'survey');
|
||||||
const clusters = getMemory().getClustersForOrigin(origin);
|
const clusters = getMemory().getClustersForOrigin(origin);
|
||||||
/* const [entries, setEntries] = React.useState<StolenDataEntry[]>([]); */
|
|
||||||
/* React.useEffect(() => {
|
|
||||||
* setEntries(
|
|
||||||
* Object.values(clusters)
|
|
||||||
* .map((cluster) => {
|
|
||||||
* cluster.calculateRepresentativeStolenData();
|
|
||||||
* return cluster.representativeStolenData;
|
|
||||||
* })
|
|
||||||
* .reduce(reduceConcat, [])
|
|
||||||
* .filter((entry) => entry.isMarked)
|
|
||||||
* );
|
|
||||||
* }, []); */
|
|
||||||
/* if (entries.length == 0) {
|
|
||||||
* return <>Wczytywanie...</>;
|
|
||||||
* } */
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const url = new URL(document.location.toString());
|
const url = new URL(document.location.toString());
|
||||||
|
@ -62,7 +47,9 @@ function Report() {
|
||||||
''
|
''
|
||||||
)}
|
)}
|
||||||
{mode === 'screenshots' ? (
|
{mode === 'screenshots' ? (
|
||||||
<ScreenshotGenerator {...{ visited_url, clusters }} />
|
<ScreenshotGenerator
|
||||||
|
{...{ visited_url, clusters, setReportWindowMode: setMode }}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
''
|
''
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
@import './../../styles/colors.scss';
|
||||||
|
|
||||||
|
.images {
|
||||||
|
display: flex;
|
||||||
|
grid-gap: 1rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin: 2rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.browser {
|
||||||
|
height: 9.667rem;
|
||||||
|
width: 16rem;
|
||||||
|
font-weight: 800 !important;
|
||||||
|
// box-shadow: rgba(12, 12, 13, 0.1) 0px 1px 4px 0px;
|
||||||
|
color: $disabled-grey !important;
|
||||||
|
border: 1px solid $disabled-grey;
|
||||||
|
background-image: linear-gradient(to bottom, $icd-rentgen-color 20%, #fff 20%, #fff 100%);
|
||||||
|
animation: xray 2s cubic-bezier(0, 1.43, 0.39, 1.43) infinite;
|
||||||
|
|
||||||
|
&--filled {
|
||||||
|
background-size: contain;
|
||||||
|
background-position-y: 18px;
|
||||||
|
animation: none;
|
||||||
|
|
||||||
|
.browser__header {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes xray {
|
||||||
|
to {
|
||||||
|
background-position-y: 11.1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__header {
|
||||||
|
height: 1.667rem;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
padding: 0 0.5rem;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
border-bottom: 1px solid $disabled-grey;
|
||||||
|
|
||||||
|
&--address-bar {
|
||||||
|
border: 1px solid $disabled-grey;
|
||||||
|
height: 1rem;
|
||||||
|
width: 10rem;
|
||||||
|
font-size: 0.667rem;
|
||||||
|
font-weight: 400;
|
||||||
|
padding-left: 0.25rem;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--controls {
|
||||||
|
padding-bottom: 0.25rem;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
height: 7.667rem;
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,21 @@ import React, { Fragment } from 'react';
|
||||||
import { RequestCluster } from '../../request-cluster';
|
import { RequestCluster } from '../../request-cluster';
|
||||||
import './screenshot-generator.scss';
|
import './screenshot-generator.scss';
|
||||||
|
|
||||||
|
enum taskState {
|
||||||
|
WAITING = 'waiting',
|
||||||
|
RUNNING = 'running',
|
||||||
|
FINISHED = 'finished',
|
||||||
|
}
|
||||||
|
|
||||||
|
interface screenshotTask {
|
||||||
|
url: string;
|
||||||
|
domains: string[];
|
||||||
|
id: string;
|
||||||
|
status: taskState;
|
||||||
|
output: string;
|
||||||
|
files: string[];
|
||||||
|
}
|
||||||
|
|
||||||
function createTaskEndpoint(visited_url: string, domains: string[]) {
|
function createTaskEndpoint(visited_url: string, domains: string[]) {
|
||||||
return `http://65.108.60.135:3000/api/requests?url=${visited_url}${domains.reduce(
|
return `http://65.108.60.135:3000/api/requests?url=${visited_url}${domains.reduce(
|
||||||
(prev: string, curr: string) => prev + '&domains[]=' + curr,
|
(prev: string, curr: string) => prev + '&domains[]=' + curr,
|
||||||
|
@ -13,39 +28,45 @@ function createTask(visited_url: string, domains: string[]) {
|
||||||
return fetch(createTaskEndpoint(visited_url, domains), { method: 'POST' });
|
return fetch(createTaskEndpoint(visited_url, domains), { method: 'POST' });
|
||||||
}
|
}
|
||||||
|
|
||||||
async function subscribe(path: string) {
|
function pollTask(path: string): Promise<Response> {
|
||||||
let request = await fetch(path, { method: 'GET' });
|
return fetch(path, { method: 'GET' });
|
||||||
const response = await request.json();
|
|
||||||
|
|
||||||
if (response.status === 'running' || response.status === 'waiting') {
|
|
||||||
console.debug(response.status);
|
|
||||||
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
||||||
await subscribe(path);
|
|
||||||
} else if (response.status === 'finished') {
|
|
||||||
console.log('response', response);
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ScreenshotGenerator({
|
export default function ScreenshotGenerator({
|
||||||
visited_url,
|
visited_url,
|
||||||
clusters,
|
clusters,
|
||||||
|
setReportWindowMode,
|
||||||
}: {
|
}: {
|
||||||
visited_url: string;
|
visited_url: string;
|
||||||
clusters: Record<string, RequestCluster>;
|
clusters: Record<string, RequestCluster>;
|
||||||
|
setReportWindowMode: Function;
|
||||||
}) {
|
}) {
|
||||||
const [isLoading, setLoading] = React.useState<boolean>(false);
|
const [mode, setMode] = React.useState<string>('idle');
|
||||||
const [output, setOutput] = React.useState<string[]>([]);
|
const [images, setImages] = React.useState<string[]>([]);
|
||||||
|
const [taskId, setTaskId] = React.useState<string>(null);
|
||||||
|
|
||||||
|
async function subscribeTask(path: string): Promise<screenshotTask> {
|
||||||
|
let response = { status: taskState.WAITING };
|
||||||
|
while (response.status === taskState.WAITING || response.status === taskState.RUNNING) {
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||||
|
response = await (await pollTask(path)).json();
|
||||||
|
setImages((response as screenshotTask)?.files);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.status === taskState.FINISHED) {
|
||||||
|
setMode('finished');
|
||||||
|
}
|
||||||
|
return response as screenshotTask;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="generator-container">
|
<div className="generator-container">
|
||||||
{!isLoading ? (
|
{mode === 'idle' ? (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<h1>Przygotowanie zrzutów ekranów</h1>
|
<h1>Przygotowanie zrzutów ekranów</h1>
|
||||||
<p>
|
<p>
|
||||||
Dla potwierdzenia przechwyconych danych, warto załączyć zrzuty ekranów
|
Dla potwierdzenia przechwyconych danych, warto załączyć zrzuty ekranów
|
||||||
narzędzi deweloperskich do maila dla administratora oraz Urzędzu Ochrony
|
narzędzi deweloperskich do maila dla administratora oraz Urzędu Ochrony
|
||||||
Danych Osobowych.
|
Danych Osobowych.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
|
@ -54,30 +75,70 @@ export default function ScreenshotGenerator({
|
||||||
Ciebie.
|
Ciebie.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<button>Pomiń</button>
|
|
||||||
<button
|
<button
|
||||||
|
className="sv_prev_btn"
|
||||||
|
onClick={() => {
|
||||||
|
setReportWindowMode('preview');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Pomiń
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="sv_next_btn"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
setLoading(true);
|
setMode('in_progress');
|
||||||
const task = await createTask(visited_url, Object.keys(clusters));
|
const task = await createTask(visited_url, Object.keys(clusters));
|
||||||
const response = await subscribe(task.url);
|
const urlArr = task.url.split('/');
|
||||||
|
setTaskId(urlArr[urlArr.length - 1]);
|
||||||
setOutput(response.files);
|
const response = await subscribeTask(task.url);
|
||||||
|
setImages(response.files);
|
||||||
console.log('output', response);
|
console.log('output', response);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Wygeneruj
|
Wygeneruj
|
||||||
</button>
|
</button>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
) : (
|
) : null}
|
||||||
|
|
||||||
|
{mode === 'in_progress' || mode === 'finished' ? (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<h1>Przygotowujemy zrzuty ekranów</h1>
|
<h1>Przygotowujemy zrzuty ekranów</h1>
|
||||||
|
|
||||||
<pre>{createTaskEndpoint(visited_url, Object.keys(clusters))}</pre>
|
<div className="images">
|
||||||
|
{images.map((filename: string) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="browser browser--filled"
|
||||||
|
style={{
|
||||||
|
backgroundImage: `url(http://65.108.60.135:3000/static/${taskId}/${filename})`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="browser__header">
|
||||||
|
<div className="browser__header--address-bar">
|
||||||
|
{filename}
|
||||||
|
</div>
|
||||||
|
<div className="browser__header--controls">· · ·</div>
|
||||||
|
</div>
|
||||||
|
<div className="browser__content"></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
{JSON.stringify(output)}
|
{mode === 'in_progress' ? (
|
||||||
<button>In progress</button>
|
<div className="browser">
|
||||||
|
<div className="browser__header">
|
||||||
|
<div className="browser__header--address-bar"></div>
|
||||||
|
<div className="browser__header--controls">· · ·</div>
|
||||||
|
</div>
|
||||||
|
<div className="browser__content"></div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
{mode === 'finished' ? (
|
||||||
|
<button className="sv_next_btn">Pobierz zrzuty ekranów</button>
|
||||||
|
) : null}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user