Wsparcie dla dwóch podstawowych problemów, more to come
This commit is contained in:
parent
d62c1167ad
commit
5cf640e686
143
report-window/deduce-problems.tsx
Normal file
143
report-window/deduce-problems.tsx
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
import { RequestCluster } from '../request-cluster';
|
||||||
|
import { ExplainerKey } from './explainers';
|
||||||
|
import { ParsedAnswers } from './parse-answers';
|
||||||
|
import { v } from './verbs';
|
||||||
|
|
||||||
|
abstract class Problem {
|
||||||
|
constructor(public answers: ParsedAnswers, public clusters: Record<string, RequestCluster>) {}
|
||||||
|
|
||||||
|
getMarkedClusters() {
|
||||||
|
return Object.values(this.clusters).filter((c) => c.hasMarks());
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract getEmailContent(): JSX.Element;
|
||||||
|
abstract getNecessaryExplainers(): ExplainerKey[];
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatRange(cluster: RequestCluster) {
|
||||||
|
const parts = [] as string[];
|
||||||
|
console.log(cluster);
|
||||||
|
if (cluster.hasMarkedCookies()) {
|
||||||
|
parts.push('mojego identyfikatora internetowego pozyskanego z Cookie');
|
||||||
|
}
|
||||||
|
if (cluster.exposesOrigin()) {
|
||||||
|
parts.push('części mojej historii przeglądania');
|
||||||
|
}
|
||||||
|
return parts.join(' oraz ');
|
||||||
|
}
|
||||||
|
|
||||||
|
class NoInformationAtAllProblem extends Problem {
|
||||||
|
getEmailContent() {
|
||||||
|
const _ = (word: string) => v(word, this.answers.zaimek);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h2>Brak informacji na temat przetwarzania danych osobowych</h2>
|
||||||
|
<p>
|
||||||
|
{_('Moje')} dane osobowe zostały ujawnione podmiotom, które są właścicielami
|
||||||
|
domen:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
{this.getMarkedClusters().map((cluster) => (
|
||||||
|
<li key={cluster.id}>
|
||||||
|
{cluster.id} (w zakresie: {formatRange(cluster)})
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
Na stronie brakuje jednak jakichkolwiek informacji o tym, jakie są cele
|
||||||
|
przetwarzania takich danych oraz jakie są podstawy prawne takiego przetwarzania.
|
||||||
|
</p>
|
||||||
|
<p>Zwracam się zatem do Państwa z następującymi pytaniami:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Jaka jest tożsamość właścicieli tych domen?</li>
|
||||||
|
<li>Jaki jest cel takiego przetwarzania danych przez Państwa stronę?</li>
|
||||||
|
<li>
|
||||||
|
Jaka jest podstawa prawna takiego przetwarzania moich danych osobowych przez
|
||||||
|
Państwa stronę?
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
getNecessaryExplainers() {
|
||||||
|
const explainers = [] as Array<ExplainerKey>;
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.getMarkedClusters().some((cluster) => {
|
||||||
|
console.log(cluster);
|
||||||
|
return cluster.hasMarkedCookies();
|
||||||
|
})
|
||||||
|
) {
|
||||||
|
explainers.push('cookies_are_pii');
|
||||||
|
}
|
||||||
|
return explainers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UnlawfulCookieAccess extends Problem {
|
||||||
|
getNecessaryExplainers(): ExplainerKey[] {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
getEmailContent() {
|
||||||
|
const cookie_clusters = Object.values(this.clusters).filter((c) => c.hasMarkedCookies());
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h2>Dostęp do cookies niezgodny z ustawą Prawo Telekomunikacyjne</h2>
|
||||||
|
<p>
|
||||||
|
Państwa strona dokonała odczytu plików Cookie zapisanych na dysku twardym mojego
|
||||||
|
komputera. Dotyczy to plików cookie przypisanych do domen:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
{cookie_clusters.map((cluster, index) => {
|
||||||
|
const names = cluster
|
||||||
|
.getMarkedEntries()
|
||||||
|
.filter((e) => e.source === 'cookie')
|
||||||
|
.map((e) => e.name);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<li>
|
||||||
|
{cluster.id} ({names.length > 1 ? 'pliki' : 'plik'}{' '}
|
||||||
|
{names.map((name, index) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{index > 0 ? ', ' : ''}
|
||||||
|
{name}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
){index === cookie_clusters.length - 1 ? '.' : ';'}
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
static qualifies(answers: ParsedAnswers, clusters: RequestCluster[]): boolean {
|
||||||
|
// są cookiesy, nie było zgody, nie są konieczne do działania strony
|
||||||
|
const cookie_clusters = Object.values(clusters).filter((c) => c.hasMarkedCookies());
|
||||||
|
return cookie_clusters.some((cluster) => {
|
||||||
|
const hostAnswers = answers.hosts[cluster.id];
|
||||||
|
return (
|
||||||
|
(hostAnswers.present == 'not_mentioned' ||
|
||||||
|
hostAnswers.present == 'not_before_making_a_choice' ||
|
||||||
|
['none', 'closed_popup', 'deny_all'].includes(hostAnswers.popup_action)) &&
|
||||||
|
hostAnswers.was_processing_necessary != 'yes'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function deduceProblems(
|
||||||
|
answers: ParsedAnswers,
|
||||||
|
clusters: Record<string, RequestCluster>
|
||||||
|
): Problem[] {
|
||||||
|
const problems = [];
|
||||||
|
if (answers.popup_type === 'none') {
|
||||||
|
problems.push(new NoInformationAtAllProblem(answers, clusters));
|
||||||
|
}
|
||||||
|
if (UnlawfulCookieAccess.qualifies(answers, Object.values(clusters))) {
|
||||||
|
problems.push(new UnlawfulCookieAccess(answers, clusters));
|
||||||
|
}
|
||||||
|
return problems;
|
||||||
|
}
|
|
@ -1,10 +1,57 @@
|
||||||
|
import { RequestCluster } from '../request-cluster';
|
||||||
|
import { getDate } from '../util';
|
||||||
|
import deduceProblems from './deduce-problems';
|
||||||
|
import { Explainers } from './explainers';
|
||||||
import { ParsedAnswers } from './parse-answers';
|
import { ParsedAnswers } from './parse-answers';
|
||||||
|
import { v } from './verbs';
|
||||||
|
|
||||||
export default function EmailContent({ answers }: { answers: ParsedAnswers }) {
|
declare var PLUGIN_NAME: string;
|
||||||
|
declare var PLUGIN_URL: string;
|
||||||
|
|
||||||
|
export default function EmailContent({
|
||||||
|
answers,
|
||||||
|
visited_url,
|
||||||
|
clusters,
|
||||||
|
}: {
|
||||||
|
answers: ParsedAnswers;
|
||||||
|
visited_url: string;
|
||||||
|
clusters: Record<string, RequestCluster>;
|
||||||
|
}) {
|
||||||
|
const _ = (key: string) => v(key, answers.zaimek);
|
||||||
|
const problems = deduceProblems(answers, clusters);
|
||||||
|
const explainers = Array.from(
|
||||||
|
new Set(
|
||||||
|
problems
|
||||||
|
.map((problem) => problem.getNecessaryExplainers())
|
||||||
|
.reduce((a, b) => a.concat(b), [])
|
||||||
|
)
|
||||||
|
).map((explainer_key) => Explainers[explainer_key]);
|
||||||
return (
|
return (
|
||||||
<div>
|
<div style={{ padding: '1rem' }}>
|
||||||
<h1>Email template</h1>
|
|
||||||
<pre>{JSON.stringify(answers, null, 3)}</pre>
|
<pre>{JSON.stringify(answers, null, 3)}</pre>
|
||||||
|
<p>Dzień dobry,</p>
|
||||||
|
<p>
|
||||||
|
w dniu {getDate()} {_('odwiedziłem')} stronę {visited_url}. Po podejrzeniu ruchu
|
||||||
|
sieciowego generowanego przez tę stronę za pomocą wtyczki{' '}
|
||||||
|
<a href={PLUGIN_URL}>{PLUGIN_NAME}</a> w przeglądarce Firefox {_('mam')} pytania
|
||||||
|
dotyczące przetwarzania {_('moich')} danych osobowych, na które nie {_('znalazłem')}{' '}
|
||||||
|
odpowiedzi nigdzie na Państwa stronie.
|
||||||
|
</p>
|
||||||
|
{problems.map((problem) => problem.getEmailContent())}
|
||||||
|
{explainers.map((explainer) => explainer(answers.zaimek))}
|
||||||
|
<p>
|
||||||
|
{_('Zwracam')} Państwa uwagę na fakt, że w myśl{' '}
|
||||||
|
<a href="https://curia.europa.eu/juris/document/document.jsf?text=&docid=216555&pageIndex=0&doclang=PL&mode=lst&dir=&occ=first&part=1&cid=1254905">
|
||||||
|
treści wyroku TSUE w sprawie C-40/17
|
||||||
|
</a>{' '}
|
||||||
|
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
|
||||||
|
odpowiedzi na moje pytanie na mocy Art. 12 i 13 Rozporządzenia 2016/679 Parlamentu
|
||||||
|
Europejskiego i Rady (UE) z dnia 27 kwietnia 2016 r. w sprawie ochrony osób
|
||||||
|
fizycznych w związku z przetwarzaniem danych osobowych i w sprawie swobodnego
|
||||||
|
przepływu takich danych oraz uchylenia dyrektywy 95/46/WE (ogólne rozporządzenie o
|
||||||
|
ochronie danych, dalej: „RODO”).
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
14
report-window/explainers.tsx
Normal file
14
report-window/explainers.tsx
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
export type ExplainerKey = 'cookies_are_pii';
|
||||||
|
|
||||||
|
export const Explainers: Record<ExplainerKey, (zaimek_index: 0 | 1 | 2 | 3) => JSX.Element> = {
|
||||||
|
cookies_are_pii: () => (
|
||||||
|
<>
|
||||||
|
<h3>Ciasteczka stanowią dane osobowe</h3>
|
||||||
|
<p>
|
||||||
|
Sztucznie wygenerowane identyfikatory przechowywane w plikach Cookies stanowią dane
|
||||||
|
osobowe. Wskazuje na to wprost Art. 4. pkt 1. RODO, wymieniając „identyfikator
|
||||||
|
internetowy” i „numer identyfikacyjny” jako przykłady danych osobowych.
|
||||||
|
</p>
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
};
|
|
@ -2,7 +2,7 @@ function generateHostPage(
|
||||||
host: string,
|
host: string,
|
||||||
index: number,
|
index: number,
|
||||||
all_hosts: string[]
|
all_hosts: string[]
|
||||||
): { title: string; elements: any[] } {
|
): { title: string; elements: any[]; visibleIf: string } {
|
||||||
function f(name: string, h = host) {
|
function f(name: string, h = host) {
|
||||||
return `${h.replace(/\./g, '_')}|${name}`;
|
return `${h.replace(/\./g, '_')}|${name}`;
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ function generateHostPage(
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
title: host,
|
title: host,
|
||||||
|
visibleIf: "{popup_type} != 'none'",
|
||||||
elements: [
|
elements: [
|
||||||
{
|
{
|
||||||
type: 'radiogroup',
|
type: 'radiogroup',
|
||||||
|
@ -70,6 +71,8 @@ function generateHostPage(
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
title: `Jak ma się ta podstawa prawna do stanu faktycznego?`,
|
title: `Jak ma się ta podstawa prawna do stanu faktycznego?`,
|
||||||
visibleIf: `{${f('legal_basis_type')}} = "consent"`,
|
visibleIf: `{${f('legal_basis_type')}} = "consent"`,
|
||||||
|
defaultValueExpression:
|
||||||
|
'iif({popup_action} = "none" or {popup_action} = "closed_popup", "claims_consent_but_sends_before_consent", iif({popup_action} = "accept_all" and {rejection_is_hard} = "yes", "claims_consent_but_there_was_no_easy_refuse", ""))',
|
||||||
choices: [
|
choices: [
|
||||||
{
|
{
|
||||||
value: 'claims_consent_but_sends_before_consent',
|
value: 'claims_consent_but_sends_before_consent',
|
||||||
|
@ -83,7 +86,7 @@ function generateHostPage(
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'dropdown',
|
type: 'radiogroup',
|
||||||
name: f('legitimate_interest_activity_specified'),
|
name: f('legitimate_interest_activity_specified'),
|
||||||
...defaultValue('legitimate_interest_activity_specified'),
|
...defaultValue('legitimate_interest_activity_specified'),
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
|
@ -118,7 +121,7 @@ function generateHostPage(
|
||||||
: `{${f('legitimate_interest_description', previous_host)}}`,
|
: `{${f('legitimate_interest_description', previous_host)}}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'dropdown',
|
type: 'radiogroup',
|
||||||
title: `Czy domena ${host} należy do podmiotu spoza Europy (np. Google, Facebook)?`,
|
title: `Czy domena ${host} należy do podmiotu spoza Europy (np. Google, Facebook)?`,
|
||||||
name: f('outside_eu'),
|
name: f('outside_eu'),
|
||||||
...defaultValue('outside_eu'),
|
...defaultValue('outside_eu'),
|
||||||
|
@ -131,6 +134,20 @@ function generateHostPage(
|
||||||
{ value: 'not_sure', text: 'Nie wiem' },
|
{ value: 'not_sure', text: 'Nie wiem' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'radiogroup',
|
||||||
|
title: `Czy w {Twojej} ocenie wysłanie {Twoich} danych do właściciela domeny ${host} było konieczne do świadczenia zażądanej przez {Ciebie} usługi drogą elektroniczną?`,
|
||||||
|
name: f('was_processing_necessary'),
|
||||||
|
...defaultValue('was_processing_necessary'),
|
||||||
|
visibleIf: `{${f('legal_basis_type')}} = "legitimate_interest" or {${f(
|
||||||
|
'present'
|
||||||
|
)}} = "not_mentioned"`,
|
||||||
|
choices: [
|
||||||
|
{ value: 'yes', text: 'Tak, było konieczne' },
|
||||||
|
{ value: 'no', text: 'Nie, nie było konieczne' },
|
||||||
|
{ value: 'not_sure', text: 'Nie mam zdania' },
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -168,6 +185,10 @@ export default function generateSurveyQuestions(hosts: string[]) {
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
choices: [
|
choices: [
|
||||||
{ value: 'none', text: 'Brak informacji' },
|
{ value: 'none', text: 'Brak informacji' },
|
||||||
|
{
|
||||||
|
value: 'page',
|
||||||
|
text: 'Tylko w postaci tekstu na podstronie np. "prywatność" lub "polityka cookies"',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
value: 'passive_popup',
|
value: 'passive_popup',
|
||||||
text: /* HTML */ `Okienko o cookiesach, bez możliwości podjęcia
|
text: /* HTML */ `Okienko o cookiesach, bez możliwości podjęcia
|
||||||
|
@ -185,7 +206,7 @@ export default function generateSurveyQuestions(hosts: string[]) {
|
||||||
dotyczącymi przetwarzania {Twoich} danych osobowych ukazało się dawno temu w
|
dotyczącymi przetwarzania {Twoich} danych osobowych ukazało się dawno temu w
|
||||||
trakcie {twojej} wcześniejszej wizyty i wtedy je {odkliknąłeś}. {Otwórz} tę
|
trakcie {twojej} wcześniejszej wizyty i wtedy je {odkliknąłeś}. {Otwórz} tę
|
||||||
samą stronę w Trybie Prywatnym (Incognito). Co {widzisz}?`,
|
samą stronę w Trybie Prywatnym (Incognito). Co {widzisz}?`,
|
||||||
visibleIf: "{popup_type} = 'none'",
|
visibleIf: "{popup_type} = 'none' or {popup_type} = 'page'",
|
||||||
name: 'is_incognito_different',
|
name: 'is_incognito_different',
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
choices: [
|
choices: [
|
||||||
|
@ -197,7 +218,8 @@ export default function generateSurveyQuestions(hosts: string[]) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'html',
|
type: 'html',
|
||||||
visibleIf: '{is_incognito_different} != "no" and {popup_type} = "none"',
|
visibleIf:
|
||||||
|
'{is_incognito_different} != "no" and ({popup_type} = "none" or {popup_type} = "page") ',
|
||||||
html: /* HTML */ `Jeżeli w trybie incognito widzisz więcej okienek z
|
html: /* HTML */ `Jeżeli w trybie incognito widzisz więcej okienek z
|
||||||
informacjami o przetwarzaniu danych osobowych, wykonaj analizę w
|
informacjami o przetwarzaniu danych osobowych, wykonaj analizę w
|
||||||
normalnym trybie ponownie - ale najpierw usuń pliki cookies tej strony.
|
normalnym trybie ponownie - ale najpierw usuń pliki cookies tej strony.
|
||||||
|
@ -213,7 +235,7 @@ export default function generateSurveyQuestions(hosts: string[]) {
|
||||||
name: 'mentions_passive_consent',
|
name: 'mentions_passive_consent',
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
visibleIf: '{popup_type} = "passive_popup"',
|
visibleIf: '{popup_type} = "passive_popup"',
|
||||||
title: 'Czy treść okienka wskazuje na zgodę wyrażoną pasywnie, np. „Korzystając z naszej strony wyrażasz zgodę” lub „Brak zmiany ustawień przeglądarki oznacza zgodę”?',
|
title: 'Czy treść okienka wskazuje na zgodę wyrażoną pasywnie, np. „Korzystając z naszej strony wyrażasz zgodę”, „Brak zmiany ustawień przeglądarki oznacza zgodę”, „Klikając przycisk "X" (zamknij) wyrażasz zgodę”?',
|
||||||
choices: [
|
choices: [
|
||||||
{
|
{
|
||||||
value: 'yes',
|
value: 'yes',
|
||||||
|
@ -267,6 +289,35 @@ export default function generateSurveyQuestions(hosts: string[]) {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'radiogroup',
|
||||||
|
name: 'popup_action',
|
||||||
|
isRequired: true,
|
||||||
|
visibleIf: '{popup_type} = "some_choice" or {popup_type} = "passive_popup"',
|
||||||
|
title: 'Jaką akcję {podjąłeś} w ramach wyskakującego okienka?',
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
value: 'none',
|
||||||
|
text: 'Nic nie {kliknąłem}',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'closed_popup',
|
||||||
|
text: '{Zamknąłem} okienko za pomocą przycisku „X” lub „Zamknij”, lub podobnego',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'accept_all',
|
||||||
|
text: '{Kliknąłem} przycisk od akceptacji wszystkich zgód',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'deny_all',
|
||||||
|
text: '{Kliknąłem} przycisk do odmówienia zgody na wszystkie cele',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'other',
|
||||||
|
text: 'Coś innego',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'radiogroup',
|
type: 'radiogroup',
|
||||||
name: 'administrator_identity_available_before_choice',
|
name: 'administrator_identity_available_before_choice',
|
||||||
|
@ -288,6 +339,7 @@ export default function generateSurveyQuestions(hosts: string[]) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Obowiązek informacyjny, polityka prywatności',
|
title: 'Obowiązek informacyjny, polityka prywatności',
|
||||||
|
visibleIf: "{popup_type} != 'none'",
|
||||||
elements: [
|
elements: [
|
||||||
{
|
{
|
||||||
type: 'radiogroup',
|
type: 'radiogroup',
|
||||||
|
|
|
@ -2,42 +2,27 @@ import RawAnswers, { BasicRawAnswers, HostRawAnswers } from './raw-answers';
|
||||||
|
|
||||||
export type RecordValue<T> = T extends Record<any, infer R> ? R : any;
|
export type RecordValue<T> = T extends Record<any, infer R> ? R : any;
|
||||||
|
|
||||||
export type ParsedHostAnswers =
|
export type ParsedHostAnswers = ({
|
||||||
| {
|
present:
|
||||||
present: 'not_mentioned' | 'not_before_making_a_choice';
|
| 'not_mentioned'
|
||||||
}
|
| 'not_before_making_a_choice'
|
||||||
| ({
|
| 'mentioned_in_policy'
|
||||||
present: 'mentioned_in_policy' | 'mentioned_in_popup';
|
| 'mentioned_in_popup';
|
||||||
} & (
|
legal_basis_type: 'consent' | 'legitimate_interes' | 'not_mentioned';
|
||||||
| ({
|
popup_action: 'none' | 'closed_popup' | 'accept_all' | 'deny_all' | 'other';
|
||||||
legal_basis_type: 'consent';
|
was_processing_necessary: 'yes' | 'no' | 'not_sure';
|
||||||
} & (
|
} & (
|
||||||
| {
|
| {
|
||||||
consent_problems:
|
consent_problems:
|
||||||
| 'claims_consent_but_sends_before_consent'
|
| 'claims_consent_but_sends_before_consent'
|
||||||
| 'claims_consent_but_there_was_no_easy_refuse';
|
| 'claims_consent_but_there_was_no_easy_refuse';
|
||||||
}
|
}
|
||||||
| { consent_problems: 'none'; outside_eu: 'yes' | 'no' | 'not_sure' }
|
| { consent_problems: 'none'; outside_eu: 'yes' | 'no' | 'not_sure' }
|
||||||
))
|
)) & {
|
||||||
| ({
|
legitimate_interest_activity_specified: 'no' | 'precise' | 'vague';
|
||||||
legal_basis_type: 'legitimate_interest';
|
|
||||||
} & (
|
|
||||||
| {
|
|
||||||
legitimate_interest_activity_specified: 'no';
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
legitimate_interest_activity_specified: 'precise';
|
|
||||||
outside_eu: 'yes' | 'no' | 'not_sure';
|
outside_eu: 'yes' | 'no' | 'not_sure';
|
||||||
}
|
legitimate_interest_description?: string;
|
||||||
| {
|
};
|
||||||
legitimate_interest_activity_specified: 'vague';
|
|
||||||
legitimate_interest_description: string;
|
|
||||||
}
|
|
||||||
))
|
|
||||||
| {
|
|
||||||
legal_basis_type: 'not_mentioned';
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
export type ParsedAnswers = BasicRawAnswers & { hosts: Record<string, ParsedHostAnswers> };
|
export type ParsedAnswers = BasicRawAnswers & { hosts: Record<string, ParsedHostAnswers> };
|
||||||
|
|
||||||
|
@ -79,5 +64,5 @@ export function parseAnswers({
|
||||||
rejection_is_hard,
|
rejection_is_hard,
|
||||||
administrator_identity_available_before_choice,
|
administrator_identity_available_before_choice,
|
||||||
hosts: parseHostAnswers(rest),
|
hosts: parseHostAnswers(rest),
|
||||||
} as RawAnswers;
|
} as ParsedAnswers;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ export type BasicRawAnswers = {
|
||||||
zaimek: 0 | 1 | 2 | 3;
|
zaimek: 0 | 1 | 2 | 3;
|
||||||
is_incognito_different: [] | ['incognito_is_the_same'];
|
is_incognito_different: [] | ['incognito_is_the_same'];
|
||||||
policy_readable: 'yes' | 'vague' | 'cant_find';
|
policy_readable: 'yes' | 'vague' | 'cant_find';
|
||||||
|
popup_action: 'none' | 'closed_popup' | 'accept_all' | 'deny_all' | 'other';
|
||||||
} & (
|
} & (
|
||||||
| ({
|
| ({
|
||||||
popup_type: 'passive_popup';
|
popup_type: 'passive_popup';
|
||||||
|
@ -37,13 +38,13 @@ export type BasicRawAnswers = {
|
||||||
| {
|
| {
|
||||||
popup_type: 'some_choice';
|
popup_type: 'some_choice';
|
||||||
rejection_is_hard: 'yes' | 'no';
|
rejection_is_hard: 'yes' | 'no';
|
||||||
|
administrator_identity_available_before_choice: 'yes' | 'no';
|
||||||
cookie_wall: undefined;
|
cookie_wall: undefined;
|
||||||
passive_consent_description: undefined;
|
passive_consent_description: undefined;
|
||||||
mentions_passive_consent: undefined;
|
mentions_passive_consent: undefined;
|
||||||
administrator_identity_available_before_choice: 'yes' | 'no';
|
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
popup_type: 'none';
|
popup_type: 'none' | 'page';
|
||||||
cookie_wall: undefined;
|
cookie_wall: undefined;
|
||||||
passive_consent_description: undefined;
|
passive_consent_description: undefined;
|
||||||
mentions_passive_consent: undefined;
|
mentions_passive_consent: undefined;
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
* {
|
* {
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
padding: 0px;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
text-rendering: optimizelegibility;
|
text-rendering: optimizelegibility;
|
||||||
font-smooth: auto;
|
font-smooth: auto;
|
||||||
|
@ -21,13 +20,6 @@ body {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
color: $black-color;
|
|
||||||
font-size: 1.25rem;
|
|
||||||
line-height: 2.1875rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav {
|
nav {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|
|
@ -30,6 +30,10 @@ function Report() {
|
||||||
/* if (entries.length == 0) {
|
/* if (entries.length == 0) {
|
||||||
* return <>Wczytywanie...</>;
|
* return <>Wczytywanie...</>;
|
||||||
* } */
|
* } */
|
||||||
|
const visited_url = Object.values(clusters)
|
||||||
|
.find((cluster) => cluster.getMarkedRequests().length > 0)
|
||||||
|
?.getMarkedRequests()[0].originalURL;
|
||||||
|
|
||||||
const result = (
|
const result = (
|
||||||
<div {...{ 'data-version': counter }}>
|
<div {...{ 'data-version': counter }}>
|
||||||
<nav>
|
<nav>
|
||||||
|
@ -38,7 +42,9 @@ function Report() {
|
||||||
</nav>
|
</nav>
|
||||||
{mode === 'survey' ? (
|
{mode === 'survey' ? (
|
||||||
<Questions
|
<Questions
|
||||||
hosts={Object.keys(clusters)}
|
hosts={Object.values(clusters)
|
||||||
|
.filter((cluster) => cluster.getMarkedRequests().length > 0)
|
||||||
|
.map((cluster) => cluster.id)}
|
||||||
onComplete={(answers) => {
|
onComplete={(answers) => {
|
||||||
setAnswers(parseAnswers(answers));
|
setAnswers(parseAnswers(answers));
|
||||||
setMode('preview');
|
setMode('preview');
|
||||||
|
@ -47,7 +53,7 @@ function Report() {
|
||||||
) : (
|
) : (
|
||||||
''
|
''
|
||||||
)}
|
)}
|
||||||
{mode === 'preview' ? <EmailContent {...{ answers }} /> : ''}
|
{mode === 'preview' ? <EmailContent {...{ answers, visited_url, clusters }} /> : ''}
|
||||||
{/* <HARConverter {...{ entries }} /> */}
|
{/* <HARConverter {...{ entries }} /> */}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -11,6 +11,7 @@ export default function useSurvey(
|
||||||
const [survey, setSurvey] = React.useState<Survey.Model>(null);
|
const [survey, setSurvey] = React.useState<Survey.Model>(null);
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const model = generateSurveyQuestions(hosts);
|
const model = generateSurveyQuestions(hosts);
|
||||||
|
console.log(model);
|
||||||
const survey = new Survey.Model(model);
|
const survey = new Survey.Model(model);
|
||||||
survey.onProcessTextValue.add(function (
|
survey.onProcessTextValue.add(function (
|
||||||
sender: Survey.SurveyModel,
|
sender: Survey.SurveyModel,
|
||||||
|
|
|
@ -16,12 +16,19 @@ const words = {
|
||||||
widzisz: ['widzisz', 'widzisz', 'widzisz', 'widzicie'],
|
widzisz: ['widzisz', 'widzisz', 'widzisz', 'widzicie'],
|
||||||
widzę: ['widzę', 'widzę', 'widzę', 'widzimy'],
|
widzę: ['widzę', 'widzę', 'widzę', 'widzimy'],
|
||||||
widziałem: ['widziałem', 'widziałam', 'widziałom', 'widzieliśmy'],
|
widziałem: ['widziałem', 'widziałam', 'widziałom', 'widzieliśmy'],
|
||||||
|
odwiedziłem: ['odwiedziłem', 'odwiedziłam', 'odwiedziłom', 'odwiedziliśmy'],
|
||||||
|
mam: ['mam', 'mam', 'mam', 'mamy'],
|
||||||
|
podjąłeś: ['podjąłeś', 'podjęłaś', 'podjęłoś', 'podjęliście'],
|
||||||
|
zamknąłem: ['zamknąłem', 'zamknęłaś', 'zamknęłoś', 'zamknęliście'],
|
||||||
|
zwracam: ['zwracam', 'zwracam', 'zwracam', 'zwracamy'],
|
||||||
|
moich: ['moich', 'moich', 'moich', 'naszych'],
|
||||||
|
ciebie: ['ciebie', 'ciebie', 'ciebie', 'was'],
|
||||||
} as { [key: string]: string[] };
|
} as { [key: string]: string[] };
|
||||||
|
|
||||||
export default words;
|
export default words;
|
||||||
|
|
||||||
export function v(key: string, index: number) {
|
export function v(key: string, index: number) {
|
||||||
let result = words[key.toLowerCase()][index] || key;
|
let result = words[key.toLowerCase()]?.[index] || key;
|
||||||
if (key[0] == key[0].toUpperCase()) {
|
if (key[0] == key[0].toUpperCase()) {
|
||||||
result = [result[0].toUpperCase(), ...result.slice(1)].join('');
|
result = [result[0].toUpperCase(), ...result.slice(1)].join('');
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,7 @@ import { Sources, StolenDataEntry } from './stolen-data-entry';
|
||||||
|
|
||||||
import { allSubhosts, isSameURL, reduceConcat, unique } from './util';
|
import { allSubhosts, isSameURL, reduceConcat, unique } from './util';
|
||||||
|
|
||||||
const source_priority: Array<Sources> = [
|
const source_priority: Array<Sources> = ['cookie', 'pathname', 'queryparams', 'header'];
|
||||||
'cookie',
|
|
||||||
'pathname',
|
|
||||||
'queryparams',
|
|
||||||
'header',
|
|
||||||
];
|
|
||||||
|
|
||||||
export class RequestCluster extends EventEmitter {
|
export class RequestCluster extends EventEmitter {
|
||||||
public requests: ExtendedRequest[] = [];
|
public requests: ExtendedRequest[] = [];
|
||||||
|
@ -37,6 +32,10 @@ export class RequestCluster extends EventEmitter {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasMarkedCookies() {
|
||||||
|
return this.getMarkedEntries().some((entry) => entry.source === 'cookie');
|
||||||
|
}
|
||||||
|
|
||||||
calculateRepresentativeStolenData(
|
calculateRepresentativeStolenData(
|
||||||
filter: {
|
filter: {
|
||||||
minValueLength: number;
|
minValueLength: number;
|
||||||
|
@ -93,8 +92,7 @@ export class RequestCluster extends EventEmitter {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
array[index].getValuePreview() ===
|
array[index].getValuePreview() === array[index - 1].getValuePreview() ||
|
||||||
array[index - 1].getValuePreview() ||
|
|
||||||
isSameURL(array[index].value, array[index - 1].value)
|
isSameURL(array[index].value, array[index - 1].value)
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -126,9 +124,7 @@ export class RequestCluster extends EventEmitter {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.sort((entry1, entry2) =>
|
.sort((entry1, entry2) => (entry1.getPriority() > entry2.getPriority() ? -1 : 1));
|
||||||
entry1.getPriority() > entry2.getPriority() ? -1 : 1
|
|
||||||
);
|
|
||||||
return this.representativeStolenData;
|
return this.representativeStolenData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,9 +161,7 @@ export class RequestCluster extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
getMarkedEntries(): StolenDataEntry[] {
|
getMarkedEntries(): StolenDataEntry[] {
|
||||||
return this.requests
|
return this.requests.map((request) => request.getMarkedEntries()).reduce(reduceConcat, []);
|
||||||
.map((request) => request.getMarkedEntries())
|
|
||||||
.reduce(reduceConcat, []);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exposesOrigin() {
|
exposesOrigin() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user