Closes #19 - dodanie alternatywnych templatek (raport vs email)

This commit is contained in:
Kuba Orlik 2022-07-08 20:53:12 +02:00
parent 69115b9e64
commit 2b763cd7e8
13 changed files with 393 additions and 127 deletions

View File

@ -1,14 +1,12 @@
import { RequestCluster } from '../../request-cluster'; import { RequestCluster } from '../../request-cluster';
import { getDate } from '../../util';
import deduceProblems from './deduce-problems'; import deduceProblems from './deduce-problems';
import { Explainers } from './explainers'; 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, useState } from 'react'; import { Fragment, useState } from 'react';
import emailIntro from './email-intro';
declare var PLUGIN_NAME: string; import { reportIntro } from './report-intro';
declare var PLUGIN_URL: string;
export default function EmailContent({ export default function EmailContent({
answers, answers,
@ -41,41 +39,53 @@ export default function EmailContent({
setCopy(true); setCopy(true);
} }
const mode = answers.user_role === 'user' ? 'email' : 'report';
const email_tone = answers.email_type === 'polite_information' ? 'polite' : 'official';
return ( return (
<Fragment> <Fragment>
<div className="generator-container"> <div className="generator-container">
<h1>Treść maila</h1> <h1>Treść {mode === 'email' ? 'maila' : 'raportu'}</h1>
<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> <div className="mail-container__header--control"></div>
</div> </div>
<article className="mail-container__content"> <article className="mail-container__content">
<p>Dzień dobry,</p> {mode === 'email'
<p> ? emailIntro(email_tone, _, visited_url)
w dniu {getDate()} {_('odwiedziłem')} stronę {visited_url}. Po : reportIntro(visited_url)}
podejrzeniu ruchu sieciowego generowanego przez stronę za pomocą {problems.map((problem) => problem.getEmailContent(mode, email_tone))}
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))} {explainers.map((explainer) => explainer(answers.zaimek))}
<h2>Państwa rola jako współadministratora danych osobowych</h2> <h2>Państwa rola jako współadministratora danych osobowych</h2>
<p> {mode == 'email' ? (
{_('Zwracam')} Państwa uwagę na fakt, że w myśl{' '} <p>
<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"> {_('Zwracam')} Państwa uwagę na fakt, że w myśl{' '}
treści wyroku TSUE w sprawie C-40/17 <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">
</a>{' '} treści wyroku TSUE w sprawie C-40/17
poprzez wysyłanie moich danych w wyżej opisanym zakresie stają się </a>{' '}
Państwo współadministratorem moich danych osobowych, dlatego ciąży na poprzez wysyłanie moich danych w wyżej opisanym zakresie stają się
Państwu obowiązek odpowiedzi na moje pytania na mocy Art. 12 i 13 Państwo współadministratorem {_('moich')} danych osobowych, nawet
Rozporządzenia 2016/679 Parlamentu Europejskiego i Rady (UE) z dnia 27 jeżeli nie Państwo bezpośrednimi autorami osadzonych na Państwa
kwietnia 2016 r. w sprawie ochrony osób fizycznych w związku z stronie skryptów czy innych zasobów ujawniających dane użytkowników
przetwarzaniem danych osobowych i w sprawie swobodnego przepływu takich Państwa strony podmiotom trzecim. Dlatego ciąży na Państwu obowiązek
danych oraz uchylenia dyrektywy 95/46/WE (ogólne rozporządzenie o odpowiedzi na {_('moje')} pytania na mocy Art. 12 i 13
ochronie danych, dalej: RODO). Rozporządzenia 2016/679 Parlamentu Europejskiego i Rady (UE) z dnia
</p> 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) RODO
</p>
) : (
<p>
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>
, ponoszą Państwo współodpowiedzialność za skrypty i inne zasoby
ujawniajace dane osobowe na Państwa stronie, nawet jeżeli nie
Państwo ich bezpośrednimi autorami.
</p>
)}
</article> </article>
</div> </div>
<div className="buttons-container"> <div className="buttons-container">

View File

@ -0,0 +1,32 @@
import { getDate } from '../../util';
declare var PLUGIN_NAME: string;
declare var PLUGIN_URL: string;
export default function emailIntro(
tone: 'polite' | 'official',
_: (verb: string) => string,
visited_url: string
) {
return (
<>
<p>{tone == 'polite' ? 'Szanowni Państwo' : 'Dzień dobry'},</p>
<p>
w dniu {getDate()} {_('odwiedziłem')} stronę {visited_url}. Po podejrzeniu ruchu
sieciowego generowanego przez stronę za pomocą wtyczki{' '}
<a href={PLUGIN_URL}>{PLUGIN_NAME}</a> w przeglądarce Firefox{' '}
{tone == 'polite' ? (
<>
{_('chciałbym')} zwrócić Państwa uwagę na kilka potencjalnych problemów ze
zgodnością RODO na Państwa stronie.
</>
) : (
<>
{_('mam')} pytania dotyczące przetwarzania {_('moich')} danych osobowych, na
które nie {_('znalazłem')} odpowiedzi nigdzie na Państwa stronie.
</>
)}
</p>
</>
);
}

View File

@ -24,7 +24,7 @@ function generateHostPage(
type: 'radiogroup', type: 'radiogroup',
name: f('present'), name: f('present'),
isRequired: true, isRequired: true,
title: `Cel ujawnienia danych (${danych}) właścicielowi domeny ${domain}`, title: `Strona udostępniła właścicielowi domeny ${domain} ${danych}. Cel takiego przetwarzania danych:`,
...defaultValue('present'), ...defaultValue('present'),
visibleIf: '{popup_type} != "none"', visibleIf: '{popup_type} != "none"',
choices: [ choices: [
@ -169,28 +169,53 @@ export default function generateSurveyQuestions(clusters: RequestCluster[]) {
clearInvisibleValues: 'onHidden', clearInvisibleValues: 'onHidden',
pages: [ pages: [
{ {
title: 'Tytuł - co to za ankieta?', title: 'Dodatkowe pytania',
elements: [ elements: [
{ {
type: 'html', type: 'html',
name: 'intro', name: 'intro',
html: /* HTML */ `<p> html: /* HTML */ `<p>
Analiza ruchu strony zakończona. Aby lepiej oszacować, gdzie Analiza ruchu sieciowego generowanego przez stronę została zakończona.
potencjalne obszary robocze pod względem zgodności z RODO, możesz Teraz, aby lepiej oszacować, gdzie potencjalne obszary robocze pod
udzielić odpowiedzi na pytania dotyczące funkcjonowania strony. Wtyczka względem zgodności z RODO, możesz udzielić odpowiedzi na pytania
wtedy wygeneruje raport lub treść maila, którą możesz wysłać do dotyczące funkcjonowania strony. Wtyczka wtedy wygeneruje raport lub
administratora strony. treść maila, którą możesz wysłać do administratora strony.
</p>`, </p>`,
}, },
], ],
}, },
{ {
title: 'Zaimki', title: 'Kontekst analizy',
elements: [ elements: [
{
type: 'radiogroup',
name: 'user_role',
title: 'Jestem:',
choices: [
{ value: 'user', text: 'użytkownikiem strony' },
{ value: 'admin', text: 'administratorem strony' },
],
},
{
type: 'radiogroup',
name: 'email_type',
title: 'Chcę:',
visibleIf: "{user_role} = 'user'",
choices: [
{
value: 'polite_information',
text: 'uprzejmie poinformować administratora strony o potencjalnych problemach ze zgodnością z RODO na jego stronie',
},
{
value: 'official_request',
text: 'wysłać formalne zapytanie do administratora strony, na które ma obowiązek odpowiedzieć. Jeżeli administrator nie odpowie na takie zapytanie, może to być podstawą złożenia skargi do UODO',
},
],
},
{ {
type: 'radiogroup', type: 'radiogroup',
name: 'zaimek', name: 'zaimek',
title: 'Forma czasownika:', title: 'Forma czasownika, jaka będzie użyta w raporcie:',
isRequired: true, isRequired: true,
choices: [ choices: [
{ value: 0, text: 'Wysłałem' }, { value: 0, text: 'Wysłałem' },
@ -312,7 +337,7 @@ export default function generateSurveyQuestions(clusters: RequestCluster[]) {
}, },
{ {
value: 'yes', value: 'yes',
text: 'Nie. {Muszę} wykonać więcej czynności aby odmówić wszystkich zgód, albo opcja niewyrażenia zgody jest mało widoczna.', text: 'Nie. {Muszę} wykonać więcej czynności (np. kliknięć) aby odmówić wszystkich zgód, albo opcja niewyrażenia zgody jest mało widoczna.',
}, },
], ],
}, },

View File

@ -42,6 +42,8 @@ function parseHostAnswers(
export function parseAnswers({ export function parseAnswers({
zaimek, zaimek,
user_role,
email_type,
is_incognito_different, is_incognito_different,
policy_readable, policy_readable,
popup_type, popup_type,
@ -55,6 +57,8 @@ export function parseAnswers({
}: RawAnswers): ParsedAnswers { }: RawAnswers): ParsedAnswers {
return { return {
zaimek, zaimek,
user_role,
email_type,
is_incognito_different, is_incognito_different,
policy_readable, policy_readable,
popup_type, popup_type,

View File

@ -6,27 +6,46 @@ export default class NoInformationAtAllProblem extends Problem {
qualifies() { qualifies() {
return this.answers.popup_type === 'none'; return this.answers.popup_type === 'none';
} }
getEmailContent() { getEmailContent(mode: 'email' | 'report', tone: 'official' | 'polite') {
const _ = (word: string) => v(word, this.answers.zaimek); const _ = (word: string) => v(word, this.answers.zaimek);
return ( return (
<> <>
<h2>Brak informacji na temat przetwarzania danych osobowych</h2> <h2>Brak informacji na temat przetwarzania danych osobowych</h2>
<p> {mode == 'email' ? (
{_('Moje')} dane osobowe zostały ujawnione podmiotom, które właścicielami tone == 'official' ? (
domen: <p>
</p> {_('Moje')} dane osobowe zostały ujawnione podmiotom, które
właścicielami domen:
</p>
) : (
<p>
Państwa strona ujawnia dane użytkowników podmiotom, które
właścicielami następujących domen:
</p>
)
) : (
<p>
Poprzez skrypty osadzone na stronie dane osobowe użytkownika końcowego
przekazywane podmiotom, którzy właścicielami następujacych domen:
</p>
)}
{this.getRangeDescription()} {this.getRangeDescription()}
<p> <p>
Na stronie brakuje jednak jakichkolwiek informacji o tym, jakie cele Na stronie brakuje jednak jakichkolwiek informacji o tym, jakie cele
przetwarzania takich danych oraz jakie podstawy prawne takiego przetwarzania. przetwarzania takich danych oraz jakie podstawy prawne takiego przetwarzania.
</p> </p>
<p>Zwracam się zatem do Państwa z następującymi pytaniami:</p> {mode == 'email' ? (
<p>Zwracam się zatem do Państwa z następującymi pytaniami:</p>
) : (
<p>Na stronie należy zawrzeć odpowiedzi na następujące pytania:</p>
)}
<ul> <ul>
<li>Jaka jest tożsamość właścicieli tych domen?</li> <li>Jaka jest tożsamość właścicieli tych domen?</li>
<li>Jaki jest cel takiego przetwarzania danych przez Państwa stronę?</li> <li>Jaki jest cel takiego przetwarzania danych przez Państwa stronę?</li>
<li> <li>
Jaka jest podstawa prawna takiego przetwarzania moich danych osobowych przez Jaka jest podstawa prawna takiego przetwarzania{' '}
Państwa stronę? {mode == 'email' ? _('moich') : ''} danych osobowych $
{mode == 'report' ? 'użytkowników końcowych' : ''} przez Państwa stronę?
</li> </li>
</ul> </ul>
</> </>

View File

@ -17,7 +17,7 @@ function formatRange(cluster: RequestCluster) {
export abstract class Problem { export abstract class Problem {
constructor(public answers: ParsedAnswers, public clusters: Record<string, RequestCluster>) {} constructor(public answers: ParsedAnswers, public clusters: Record<string, RequestCluster>) {}
abstract getEmailContent(): JSX.Element; abstract getEmailContent(mode: 'email' | 'report', tone: 'polite' | 'official'): JSX.Element;
abstract getNecessaryExplainers(): ExplainerKey[]; abstract getNecessaryExplainers(): ExplainerKey[];
abstract qualifies(): boolean; abstract qualifies(): boolean;

View File

@ -20,43 +20,69 @@ export class TransferOutsideEU extends Problem {
.map(([id]) => this.clusters[id]); .map(([id]) => this.clusters[id]);
} }
getEmailContent() { getEmailContent(mode: 'email' | 'report') {
const clusters = this.getRelatedClusters(); const clusters = this.getRelatedClusters();
const _ = (key: string) => v(key, this.answers.zaimek); const _ = (key: string) => v(key, this.answers.zaimek);
return ( return (
<> <>
<h2>Transfer danych osobowych poza Europejski Obszar Gospodarczy</h2> <h2>Transfer danych osobowych poza Europejski Obszar Gospodarczy</h2>
<p> {mode == 'email' ? (
Państwa strona przetworzyła {_('moje')} dane osobowe poprzez przesłanie danych <p>
do: Państwa strona przetworzyła {_('moje')} dane osobowe poprzez przesłanie
</p> danych do:
</p>
) : (
<p>
Strona przetwarza dane osobowe użytkowników końcowych poprzez przesłanie
przekazanie ich do:
</p>
)}
<ul> <ul>
{clusters.map((cluster) => ( {clusters.map((cluster) => (
<li key={cluster.id}> <li key={cluster.id}>
Właściciela domeny <strong>{cluster.id}</strong>: (w zakresie:{' '} właściciela domeny <strong>{cluster.id}</strong>: (w zakresie:{' '}
{cluster.getDataTypeDescription('mojej')}); {cluster.getDataTypeDescription(mode == 'email' ? 'mojej' : '')});
</li> </li>
))} ))}
</ul> </ul>
<p> {mode == 'email' ? (
Według {_('mojej')} najlepszej wiedzy, każdy z tych podmiotów utrzymuje swoje <p>
serwery poza Europejskim Obszarem Gospodarczym. Zatem Państwa strona przesłała Według {_('mojej')} najlepszej wiedzy, każdy z tych podmiotów utrzymuje
{_('moje')} dane osobowe poza EOG. Jeżeli tak jest, to takie przetwarzanie swoje serwery poza Europejskim Obszarem Gospodarczym. Zatem Państwa strona
danych jest niezgodne z prawem, gdyż dane trafiają do krajów, które nie przesłała
gwarantują ochrony danych w stopniu, jakiego wymaga RODO, a tzw. Tarcza {_('moje')} dane osobowe poza EOG. Jeżeli tak jest, to takie przetwarzanie
Prywatności została unieważniona w 2020r. Zob.{' '} danych jest niezgodne z prawem, gdyż dane trafiają do krajów, które nie
<a href="https://panoptykon.org/noyb-skargi-schrems-ii"> gwarantują ochrony danych w stopniu, jakiego wymaga RODO, a tzw. Tarcza
artykuł Fundacji Panoptykon w tej sprawie Prywatności została unieważniona w 2020r. Zob.{' '}
</a> <a href="https://panoptykon.org/noyb-skargi-schrems-ii">
. artykuł Fundacji Panoptykon w tej sprawie
</p> </a>
<p> .
{_('Zwracam')} się zatem do Państwa z pytaniem:{' '} </p>
<strong> ) : (
czy wyżej wymienione podmioty, którym Państwa strona ujawniła moje dane <p>
osobowe, przechowują moje dane poza EOG? Te podmioty utrzymują swoje centra danych poza Europejskim Obszarem
</strong> Gospodarczym. Jako, że tzw. Tarcza Prywatności zostałą unieważniona w
</p> 2020r., nie można przesyłać danych osobowych obywateli Unii Europejskiej do
krajów, które nie zapewniają ochrony danych o sile odpowiadającej RODO.
Przykłądem kraju, do którego nie można przekazywać danych osobowych
obywateli UE Stany Zjednoczone.
</p>
)}
{mode == 'email' ? (
<p>
{_('Zwracam')} się zatem do Państwa z pytaniem:{' '}
<strong>
czy wyżej wymienione podmioty, którym Państwa strona ujawniła moje dane
osobowe, przechowują moje dane poza EOG?
</strong>
</p>
) : (
<p>
Zaleca się rezygnację z korzystania z usług firm, które przetwarzają dane
osobowe użytkowników, a których centra danych znajdują się poza EOG.
</p>
)}
</> </>
); );
} }

View File

@ -36,37 +36,81 @@ export class UnknownLegalBasis extends Problem {
); );
} }
getEmailContent() { getEmailContent(mode: 'email' | 'report', tone: 'polite' | 'official') {
const clusters = this.getRelatedClusters(); const clusters = this.getRelatedClusters();
const _ = (key: string) => v(key, this.answers.zaimek); const _ = (key: string) => v(key, this.answers.zaimek);
return ( return (
<> <>
<h2>Przetwarzanie danych osobowych bez podania podstawy prawnej</h2> <h2>Przetwarzanie danych osobowych bez podania podstawy prawnej</h2>
<p>Państwa strona przetworzyła {_('moje')} dane osobowe poprzez ujawnienie:</p> {mode == 'email' ? (
<p>Państwa strona przetworzyła {_('moje')} dane osobowe poprzez ujawnienie:</p>
) : (
<p>Państwa strona przetwarza dane osobowe użytkowników poprzez ujawnienie</p>
)}
<ul> <ul>
{clusters.map((cluster) => ( {clusters.map((cluster) => (
<li key={cluster.id}> <li key={cluster.id}>
Właścicielowi domeny <strong>{cluster.id}</strong>:{' '} właścicielowi domeny <strong>{cluster.id}</strong>:{' '}
{cluster.getDataTypeDescription('mojej')} {cluster.getDataTypeDescription(mode == 'email' ? 'mojej' : '')}
</li> </li>
))} ))}
</ul> </ul>
<p> {mode == 'email' ? (
{_('Moja')} historia przeglądania stanowi {_('moje')} dane osobowe. Zgodnie z <p>
treścią Artykułu 13 p. 1 lit. c){' '} {_('Moja')} historia przeglądania stanowi {_('moje')} dane osobowe. Zgodnie
<a href="https://eur-lex.europa.eu/legal-content/PL/TXT/HTML/?uri=CELEX:32016R0679&qid=1632163985520&from=PL#d1e1822-1-1"> z treścią Artykułu 13 p. 1 lit. c){' '}
RODO <a href="https://eur-lex.europa.eu/legal-content/PL/TXT/HTML/?uri=CELEX:32016R0679&qid=1632163985520&from=PL#d1e1822-1-1">
</a> RODO
, aby przetwarzać dane osobowe, trzeba poinformować osobę, której dane dotyczą, </a>
o tym, jaka jest podstawa prawna takiego przetwarzania danych. , aby przetwarzać dane osobowe, trzeba poinformować osobę, której dane
</p> dotyczą, o tym, jaka jest podstawa prawna takiego przetwarzania danych.
<p> </p>
Zwracam się zatem z pytaniem:{' '} ) : (
<strong> <p>
jakie były podstawy prawne ujawnienia moich danych każdemu z wyżej Na stronie nie znajdują się informacje o tym, jaka jest podstawa prawna
wymienionych podmiotów przez Państwa stronę? takiego przetwarzania danych osobowych, jakimi jest część historii
</strong> przeglądania. Zgodnie z treścią Artykułu 13. p. 1 lit. c) RODO, aby
</p> przetwarzać dane osobowe, trzeba poinformować osobę, któ©ej dane dotyczą, o
tym, jak ajest podstaw aprawna takiego przetwarzania danych.
</p>
)}
{mode == 'email' ? (
tone == 'official' ? (
<p>
Zwracam się zatem z pytaniem:{' '}
<strong>
jakie były podstawy prawne ujawnienia moich danych każdemu z wyżej
wymienionych podmiotów przez Państwa stronę?
</strong>
</p>
) : (
<p>
Dodanie do Państwa strony informacji o tym, jakie podstawy prawne (w
znaczeniu Art. 6 pkt. 1 RODO) dla każdego z tych procesów przetwarzania
miałoby pozytywny wpływ na przejrzystość informacji dla użytkowników
końcowych, jak i na zgodność strony z obowiązującymi przepisami.
</p>
)
) : (
<>
<p>Możliwe działania:</p>
<ul>
<li>rezygnacja z niektórych skryptów śledzących;</li>
<li>
przeniesienie assetów z CDN-a na samohostowanie (przy korzystaniu z
HTTP2 to może dać zwiększoną wydajność wzgłędem CDN);
</li>
<li>
konfiguracja nagłówka{' '}
<a href="https://developer.mozilla.org/pl/docs/Web/HTTP/Headers/Referrer-Policy">
Referrer-Policy
</a>{' '}
tak, aby nie ujawniać historii przeglądania właścicielom zasobów z
domen podmiotów trzecich.
</li>
</ul>
</>
)}
</> </>
); );
} }

View File

@ -23,7 +23,7 @@ export class UnlawfulCookieAccess extends Problem {
}); });
} }
getEmailContent() { getEmailContent(mode: 'email' | 'report', tone: 'official' | 'polite') {
const cookie_clusters = Object.values(this.clusters).filter((c) => c.hasMarkedCookies()); const cookie_clusters = Object.values(this.clusters).filter((c) => c.hasMarkedCookies());
const unnecessary_hosts = Object.entries(this.answers.hosts) const unnecessary_hosts = Object.entries(this.answers.hosts)
.filter(([, answers]) => answers.was_processing_necessary === 'no') .filter(([, answers]) => answers.was_processing_necessary === 'no')
@ -36,8 +36,12 @@ export class UnlawfulCookieAccess extends Problem {
<> <>
<h2>Dostęp do cookies niezgodny z ustawą Prawo Telekomunikacyjne</h2> <h2>Dostęp do cookies niezgodny z ustawą Prawo Telekomunikacyjne</h2>
<p> <p>
Państwa strona dokonała odczytu plików Cookie zapisanych na dysku twardym mojego Państwa strona {mode == 'email' ? 'dokonała' : 'dokonuje'} odczytu plików Cookie
komputera. Dotyczy to plików cookie przypisanych do domen: zapisanych na dysku twardym{' '}
{mode === 'email'
? _('mojego') + ' komputera.'
: 'komputerach użytkowników końcowych.'}
. Dotyczy to plików cookie przypisanych do domen:
</p> </p>
<ul> <ul>
{cookie_clusters.map((cluster, index) => { {cookie_clusters.map((cluster, index) => {
@ -75,7 +79,8 @@ export class UnlawfulCookieAccess extends Problem {
Użytkownik wyraził zgodę na takie przetwarzanie danych <em>po</em> tym, jak Użytkownik wyraził zgodę na takie przetwarzanie danych <em>po</em> tym, jak
został poinformowany bezpośrednio o celu uzyskania dostępu do tej został poinformowany bezpośrednio o celu uzyskania dostępu do tej
informacji. Zgodnie z Art. 174 ustawy Prawo Telekomunikacyjne, taka zgoda informacji. Zgodnie z Art. 174 ustawy Prawo Telekomunikacyjne, taka zgoda
musiałaby spełniać warunki zgody ustalone przez RODO; musi spełniać warunki zgody ustalone przez RODO, aby mogła być jako podstawa
prawna uzyskania dostępu do cookies i podobnych technologii w przeglądarce;
</li> </li>
<li> <li>
Dostęp do treści plików cookies jest konieczny do dostarczania usługi Dostęp do treści plików cookies jest konieczny do dostarczania usługi
@ -84,25 +89,47 @@ export class UnlawfulCookieAccess extends Problem {
</ol> </ol>
{(() => { {(() => {
if (this.answers.popup_type == 'none' || this.answers.popup_type == 'page') { if (this.answers.popup_type == 'none' || this.answers.popup_type == 'page') {
return ( return mode === 'email' ? (
<p> <p>
Jako, że strona nie pytała {_('mnie')} nigdy o zgodę, nie jest Jako, że strona nie pytała {_('mnie')} nigdy o zgodę, nie jest
spełniony warunek 1. spełniony warunek 1.
</p> </p>
) : (
<p>
Strona nie ma zaimplementowanego mechanizmu pozyskiwania zgód, zatem
nie spełnia warunku opisanego w punkcie 1.
</p>
); );
} else if (this.answers.popup_type === 'passive_popup') { } else if (this.answers.popup_type === 'passive_popup') {
return ( return (
<p> <p>
Państwa strona nie dała mi nigdy faktycznego wyboru dotyczącego {mode === 'email' ? (
wyrażenia lub odmówienia zgody na takie przetwarzanie danych <>
osobowych, dlatego nie jest spełniony warunek 1.{' '} Państwa strona nie dała mi nigdy faktycznego wyboru
dotyczącego wyrażenia lub odmówienia zgody na takie
przetwarzanie danych osobowych. Aby zgoda była ważna w
świetle RODO, musi być dobrowolna. Brak możliwości
odmówienia zgody sprawia, że tak wyrażona zgoda nie jest
ważna w świetle RODO. Dlatego nie jest spełniony warunek 1.{' '}
</>
) : (
<>
Aktualnie zaimplementowane okienko o przetwarzaniu danych
osobowych nie daje użytkownikom końcowym możliwości odmowy
wyrażenia zgody, przez co tak wyrażona zgoda nie spełnia
warunku dobrowolności opisanego w motywie (32) RODO. Z tego
powodu nie jest spełniony warunek opisany w punkcie 1.
powyżej, zatem tak pozyskana "zgoda" nie może stanowić
podstawy prawnej dostępu do cookiesów użytkownika końcowego.
</>
)}{' '}
{this.answers.mentions_passive_consent ? ( {this.answers.mentions_passive_consent ? (
<> <>
Zgody wyrażonej w sposób bierny lub milczący nie można uznać Należy nadmienić także, że zgody wyrażonej w sposób bierny
za ważną w świetle obowiązujących przepisów rozporządzenia lub milczący nie można uznać za ważną w świetle
2016/679. Dlatego zaniechanie zmiany ustawień przeglądarki obowiązujących przepisów rozporządzenia 2016/679. Dlatego
lub po prostu korzystanie ze strony nie stanowi ważnej zaniechanie zmiany ustawień przeglądarki lub po prostu
zgody. Takie jest{' '} korzystanie ze strony nie stanowi ważnej zgody. Takie jest{' '}
<a href="https://assets.midline.pl/pisma/2021-12-16%20odpowiedz%20UODO%20na%20skarg%C4%99%20i(n)Secure.pdf"> <a href="https://assets.midline.pl/pisma/2021-12-16%20odpowiedz%20UODO%20na%20skarg%C4%99%20i(n)Secure.pdf">
stanowisko polskiego UODO stanowisko polskiego UODO
</a> </a>
@ -115,15 +142,26 @@ export class UnlawfulCookieAccess extends Problem {
); );
} else if (this.answers.popup_type === 'some_choice') { } else if (this.answers.popup_type === 'some_choice') {
if (this.answers.popup_action === 'none') { if (this.answers.popup_action === 'none') {
return ( return mode == 'email' ? (
<p> <p>
Nie {_('wyraziłem')} zgody na takie przetwarzanie {_('moich')}{' '} Nie {_('wyraziłem')} zgody na takie przetwarzanie {_('moich')}{' '}
danych osobowych. W okienku pytającym o zgodę nic nie{' '} danych osobowych. W okienku pytającym o zgodę nic nie{' '}
{_('kliknąłem')}. Nie jest zatem spełniony warunek 1. {_('kliknąłem')}. Nie jest zatem spełniony warunek 1.
</p> </p>
) : (
<p>
Skrypty pozyskujące dostęp do plików cookie uruchamiają się
zanim użytkownik końcowy zdąży wybrać jakąkolwiek opcję w
okienku pytającym o zgodę. Aby zgoda była ważna, musi być
pozyskana <strong>zanim</strong> nastąpi proces przetwarzania
danych, którego ta zgoda dotyczy. Z tego powodu nie jest
spełniony warunek 1. Nie można używać tak pozyskanej zgody
jako podstawy prawnej dostępu do plików cookies na urządzeniu
użytkownika końcowego.
</p>
); );
} else if (this.answers.popup_action === 'closed_popup') { } else if (this.answers.popup_action === 'closed_popup') {
return ( return mode == 'email' ? (
<p> <p>
Nie {_('wyraziłem')} zgody na takie przetwarzanie {_('moich')}{' '} Nie {_('wyraziłem')} zgody na takie przetwarzanie {_('moich')}{' '}
danych osobowych. {this.answers.popup_closed_how.trim()} danych osobowych. {this.answers.popup_closed_how.trim()}
@ -135,9 +173,19 @@ export class UnlawfulCookieAccess extends Problem {
jednoznaczności opisanego w Art. 4, pkt 11 RODO. Nie jest zatem jednoznaczności opisanego w Art. 4, pkt 11 RODO. Nie jest zatem
spełniony warunek 1. spełniony warunek 1.
</p> </p>
) : (
<p>
Gdy użytkownik końcowy strony nie wyrazi jednoznacznej zgody w
wyskakującym okienku, a zamiast tego po prostu zamknie to
okienko, strona nadal pozyskuje dostęp do plików cookies na
urządzeniu użytkownika. Zamknięcia okienka (np. przyciskiem x)
nie można uznać za ważną zgodę, gdyż taka czyność nie spełnia
warunku jednoznaczności opisanego w Art. 4. pkt 11. RODO. Nie
jest zatem spełniony warunek 1.
</p>
); );
} else if (this.answers.popup_action == 'deny_all') { } else if (this.answers.popup_action == 'deny_all') {
return ( return mode == 'email' ? (
<p> <p>
{this.answers.popup_deny_all_how.trim()} {this.answers.popup_deny_all_how.trim()}
{this.answers.popup_closed_how.trim().at(-1) != '.' {this.answers.popup_closed_how.trim().at(-1) != '.'
@ -145,31 +193,78 @@ export class UnlawfulCookieAccess extends Problem {
: ''}{' '} : ''}{' '}
Zatem nie jest spełniony warunek 1. Zatem nie jest spełniony warunek 1.
</p> </p>
) : (
<p>
Gdy użytkownik jednoznacznie odmówi zgód na wszystkie cele
przetwarzania, strona nadal pozyskuje dostęp do plików cookies
na urządzeniu użytkownika. Jeżeli uzytkownik nie odmówił zgody,
to nie powinny załączać się procesy przetwarzania powołujące się
na zgodę jako podstawę prawną.
</p>
); );
} }
} }
})()} })()}
{unnecessary_hosts.length > 0 ? ( {unnecessary_hosts.length > 0 ? (
<p> mode == 'email' ? (
W {_('mojej')} ocenie odczytywanie przez Państwa stronę treści plików <p>
cookies z {wordlist(unnecessary_hosts)} nie jest konieczne do wyświetlenia W {_('mojej')} ocenie odczytywanie przez Państwa stronę treści plików
treści Państwa strony, dlatego nie jest dla nich spełniony warunek 2. Jeżeli cookies z {wordlist(unnecessary_hosts)} nie jest konieczne do
Państwa zdaniem jest inaczej, {_('proszę')} o wskazanie, co jest źródłem tej wyświetlenia treści Państwa strony, dlatego nie jest dla nich spełniony
konieczności i co odróżnia Państwa stronę od wielu innych stron, które warunek 2. Jeżeli według Państwa oceny jest inaczej, {_('proszę')} o
realizują te same funkcjonalności <em>bez</em> korzystania z plików Cookie. wskazanie, co jest źródłem tej konieczności i co odróżnia Państwa stronę
</p> od wielu innych stron, które realizują te same funkcjonalności{' '}
<em>bez</em> korzystania z plików Cookie.
</p>
) : (
<p>
Warto, aby informacje na stronie opisywały w zrozumiały sposob, które z
podmiotów, których skrypty uruchamiają się na stronie (
{wordlist(unnecessary_hosts)}) konieczne do działania strony, jaki
zakres danych przetwarzają i w jakim celu.
</p>
)
) : ( ) : (
'' ''
)} )}
<p> {mode == 'email' ? (
{_('Proszę')} o wskazanie,{' '} tone === 'official' ? (
<strong> <p>
czy być może stosowali Państwo inną podstawę prawną do takiego przetwarzania{' '} {_('Proszę')} o wskazanie,{' '}
{_('moich')} danych osobowych, czy przetwarzali je państwo bez ważnej <strong>
podstawy prawnej? czy być może stosowali Państwo inną podstawę prawną do takiego
</strong> przetwarzania {_('moich')} danych osobowych, czy być może
</p> przetwarzali je Państwo bez ważnej podstawy prawnej?
{maybe_unnecessary_hosts.length > 1 ? ( </strong>
</p>
) : (
<p>
Apeluję o wdrożenie zmian na Państwa stronie tak, aby użytkownik miał
faktyczny wybór dotyczący procesów przetwarzania jego danych osobowych,
jakie zachodzą w trakcie odwiedzin tej strony.
</p>
)
) : (
<p>
Jeżeli zgoda nadal ma być używana jako podstawa prawna do odczytu cookiesów
przez skrypty wyżej wymienionych podmiotów, to należy zmienić mechanizm
zgody tak, aby:{' '}
<ul>
<li>
dawał użytkownikowi końcowemu możliwość odmowy zgody w sposób równie
łatwy i dostępny, jak na wyrażenie zgody;
</li>
<li>
skrypty śledzące uruchamiały się dopiero po uzyskaniu ważnej zgody;
</li>
<li>
skrypty śledzące nie uruchamiały się, jeżeli użytkownik nie wyraził
na nie zgody.
</li>
</ul>
</p>
)}
{maybe_unnecessary_hosts.length > 1 && mode == 'email' && tone == 'official' ? (
<p> <p>
{_('Proszę')} też o wskazanie, czy dostęp do treści plików cookie z {_('Proszę')} też o wskazanie, czy dostęp do treści plików cookie z
{wordlist(maybe_unnecessary_hosts)} jest konieczny do poprawnego działania {wordlist(maybe_unnecessary_hosts)} jest konieczny do poprawnego działania

View File

@ -16,6 +16,8 @@ export type HostRawAnswers = {
export type BasicRawAnswers = { export type BasicRawAnswers = {
zaimek: 0 | 1 | 2 | 3; zaimek: 0 | 1 | 2 | 3;
user_role: 'user' | 'admin';
email_type: 'polite_information' | 'official_request';
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_action: 'none' | 'closed_popup' | 'accept_all' | 'deny_all' | 'other';

View File

@ -0,0 +1,3 @@
export function reportIntro(visited_url: string) {
return <h2>Analiza skryptów śledzących na ${visited_url} - raport</h2>;
}

View File

@ -1,5 +1,6 @@
const words = { const words = {
ciebie: ['ciebie', 'ciebie', 'ciebie', 'was'], ciebie: ['ciebie', 'ciebie', 'ciebie', 'was'],
chciałbym: ['chciałbym', 'chciałabym', 'chciałobym', 'chcielibyśmy'],
dokonałeś: ['dokonałeś', 'dokonałaś', 'dokonałoś', 'dokonaliście'], dokonałeś: ['dokonałeś', 'dokonałaś', 'dokonałoś', 'dokonaliście'],
jesteś: ['jesteś', 'jesteś', 'jesteś', 'jesteście'], jesteś: ['jesteś', 'jesteś', 'jesteś', 'jesteście'],
kliknąłem: ['kliknąłem', 'kliknęłam', 'klinkęłom', 'kliknęliśmy'], kliknąłem: ['kliknąłem', 'kliknęłam', 'klinkęłom', 'kliknęliśmy'],
@ -8,6 +9,7 @@ const words = {
mnie: ['mnie', 'mnie', 'mnie', 'nas'], mnie: ['mnie', 'mnie', 'mnie', 'nas'],
moich: ['moich', 'moich', 'moich', 'naszych'], moich: ['moich', 'moich', 'moich', 'naszych'],
moje: ['moje', 'moje', 'moje', 'nasze'], moje: ['moje', 'moje', 'moje', 'nasze'],
mojego: ['mojefo', 'mojego', 'mojego', 'naszego'],
moja: ['moja', 'moja', 'moja', 'nasza'], moja: ['moja', 'moja', 'moja', 'nasza'],
mojej: ['mojej', 'mojej', 'mojej', 'naszej'], mojej: ['mojej', 'mojej', 'mojej', 'naszej'],
muszę: ['muszę', 'muszę', 'muszę', 'musimy'], muszę: ['muszę', 'muszę', 'muszę', 'musimy'],

View File

@ -191,6 +191,10 @@ export class RequestCluster extends SaferEmitter {
if (this.hasMarkedCookies()) { if (this.hasMarkedCookies()) {
types_of_data.push('unikalne ID z cookies'); types_of_data.push('unikalne ID z cookies');
} }
if (types_of_data.length > 1) {
types_of_data[types_of_data.length - 1] =
'oraz ' + types_of_data[types_of_data.length - 1];
}
return types_of_data.join(', '); return types_of_data.join(', ');
} }
} }