Redesign #3

Closed
arek wants to merge 15 commits from redesign into master
13 changed files with 1134 additions and 977 deletions
Showing only changes of commit 268f9a7d06 - Show all commits

3
assets/icons/mail.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20 20H4C2.89543 20 2 19.1046 2 18V5.913C2.04661 4.84255 2.92853 3.99899 4 4H20C21.1046 4 22 4.89543 22 6V18C22 19.1046 21.1046 20 20 20ZM4 7.868V18H20V7.868L12 13.2L4 7.868ZM4.8 6L12 10.8L19.2 6H4.8Z" fill="#2E3A59"/>
</svg>

After

Width:  |  Height:  |  Size: 331 B

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.8199 22H10.1799C9.71003 22 9.30347 21.673 9.20292 21.214L8.79592 19.33C8.25297 19.0921 7.73814 18.7946 7.26092 18.443L5.42392 19.028C4.97592 19.1709 4.48891 18.9823 4.25392 18.575L2.42992 15.424C2.19751 15.0165 2.27758 14.5025 2.62292 14.185L4.04792 12.885C3.98312 12.2961 3.98312 11.7019 4.04792 11.113L2.62292 9.816C2.27707 9.49837 2.19697 8.98372 2.42992 8.576L4.24992 5.423C4.48491 5.0157 4.97192 4.82714 5.41992 4.97L7.25692 5.555C7.50098 5.37416 7.75505 5.20722 8.01792 5.055C8.27026 4.91269 8.52995 4.78385 8.79592 4.669L9.20392 2.787C9.30399 2.32797 9.71011 2.00049 10.1799 2H13.8199C14.2897 2.00049 14.6958 2.32797 14.7959 2.787L15.2079 4.67C15.4887 4.79352 15.7622 4.93308 16.0269 5.088C16.2739 5.23081 16.5126 5.38739 16.7419 5.557L18.5799 4.972C19.0276 4.82967 19.514 5.01816 19.7489 5.425L21.5689 8.578C21.8013 8.98548 21.7213 9.49951 21.3759 9.817L19.9509 11.117C20.0157 11.7059 20.0157 12.3001 19.9509 12.889L21.3759 14.189C21.7213 14.5065 21.8013 15.0205 21.5689 15.428L19.7489 18.581C19.514 18.9878 19.0276 19.1763 18.5799 19.034L16.7419 18.449C16.5093 18.6203 16.2677 18.7789 16.0179 18.924C15.7557 19.0759 15.4853 19.2131 15.2079 19.335L14.7959 21.214C14.6954 21.6726 14.2894 21.9996 13.8199 22ZM7.61992 16.229L8.43992 16.829C8.62477 16.9652 8.81743 17.0904 9.01692 17.204C9.20462 17.3127 9.39788 17.4115 9.59592 17.5L10.5289 17.909L10.9859 20H13.0159L13.4729 17.908L14.4059 17.499C14.8132 17.3194 15.1998 17.0961 15.5589 16.833L16.3799 16.233L18.4209 16.883L19.4359 15.125L17.8529 13.682L17.9649 12.67C18.0141 12.2274 18.0141 11.7806 17.9649 11.338L17.8529 10.326L19.4369 8.88L18.4209 7.121L16.3799 7.771L15.5589 7.171C15.1997 6.90671 14.8132 6.68175 14.4059 6.5L13.4729 6.091L13.0159 4H10.9859L10.5269 6.092L9.59592 6.5C9.39772 6.58704 9.20444 6.68486 9.01692 6.793C8.81866 6.90633 8.62701 7.03086 8.44292 7.166L7.62192 7.766L5.58192 7.116L4.56492 8.88L6.14792 10.321L6.03592 11.334C5.98672 11.7766 5.98672 12.2234 6.03592 12.666L6.14792 13.678L4.56492 15.121L5.57992 16.879L7.61992 16.229ZM11.9959 16C9.78678 16 7.99592 14.2091 7.99592 12C7.99592 9.79086 9.78678 8 11.9959 8C14.2051 8 15.9959 9.79086 15.9959 12C15.9932 14.208 14.2039 15.9972 11.9959 16ZM11.9959 10C10.9033 10.0011 10.0138 10.8788 9.99815 11.9713C9.98249 13.0638 10.8465 13.9667 11.9386 13.9991C13.0307 14.0315 13.9468 13.1815 13.9959 12.09V12.49V12C13.9959 10.8954 13.1005 10 11.9959 10Z" fill="#2E3A59"/>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.83 11L11.41 7.41L10 6L4 12L10 18L11.41 16.59L7.83 13H20V11H7.83Z" fill="#2E3A59"/>
</svg>

After

Width:  |  Height:  |  Size: 198 B

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17 22H7C5.89543 22 5 21.1046 5 20V7H3V5H7V4C7 2.89543 7.89543 2 9 2H15C16.1046 2 17 2.89543 17 4V5H21V7H19V20C19 21.1046 18.1046 22 17 22ZM7 7V20H17V7H7ZM9 4V5H15V4H9ZM15 18H13V9H15V18ZM11 18H9V9H11V18Z" fill="#2E3A59"/>
</svg>

After

Width:  |  Height:  |  Size: 334 B

View File

@ -1,215 +1,232 @@
import React from "react"; import React from 'react';
import { useState } from "react"; import { useState } from 'react';
import { RequestCluster } from "../request-cluster"; import { RequestCluster } from '../request-cluster';
import { StolenDataEntry } from "../stolen-data-entry"; import { StolenDataEntry } from '../stolen-data-entry';
import { getDate, toBase64 } from "../util"; import { getDate, toBase64 } from '../util';
import DomainSummary from "./domain-summary"; import DomainSummary from './domain-summary';
type PopupState = "not_clicked" | "clicked_but_no_reject_all"; type PopupState = 'not_clicked' | 'clicked_but_no_reject_all';
export default function EmailTemplate1({ export default function EmailTemplate1({
entries, entries,
clusters, clusters,
}: { }: {
entries: StolenDataEntry[]; entries: StolenDataEntry[];
clusters: Record<string, RequestCluster>; clusters: Record<string, RequestCluster>;
version: number; version: number;
}): JSX.Element { }): JSX.Element {
const [popupState, setPopupState] = useState<PopupState>("not_clicked"); const [popupState, setPopupState] = useState<PopupState>('not_clicked');
const [acceptAllName, setAcceptAllName] = useState<string>( const [acceptAllName, setAcceptAllName] = useState<string>(
"Zaakceptuj wszystkie" 'Zaakceptuj wszystkie'
); );
const [popupScreenshotBase64, setPopupScreenshotBase64] = const [popupScreenshotBase64, setPopupScreenshotBase64] =
useState<string>(null); useState<string>(null);
return ( return (
<div> <div>
<label htmlFor="popupState">Status okienka o rodo:</label> <label htmlFor="popupState">Status okienka o rodo:</label>
<select <select
id="popupState" id="popupState"
value={popupState} value={popupState}
onChange={(e) => setPopupState(e.target.value as PopupState)} onChange={(e) => setPopupState(e.target.value as PopupState)}
> >
<option value="not_clicked">Nic nie kliknięte</option> <option value="not_clicked">Nic nie kliknięte</option>
<option value="clicked_but_no_reject_all"> <option value="clicked_but_no_reject_all">
Kliknięte "akceptuj wszystkie", ale nie było opcji "Odrzuć wszystkie" Kliknięte "akceptuj wszystkie", ale nie było opcji "Odrzuć
</option> wszystkie"
</select> </option>
{popupState === "clicked_but_no_reject_all" ? ( </select>
<> {popupState === 'clicked_but_no_reject_all' ? (
<div> <>
<label htmlFor="acceptAllName"> <div>
Tekst na przycisku do zatwierdzania wszystkich zgód: <label htmlFor="acceptAllName">
</label> Tekst na przycisku do zatwierdzania wszystkich zgód:
<input </label>
{...{ <input
type: "text", {...{
value: acceptAllName, type: 'text',
onChange: (e) => setAcceptAllName(e.target.value), value: acceptAllName,
}} onChange: (e) =>
/> setAcceptAllName(e.target.value),
</div> }}
<div> />
<label htmlFor="popup-screenshot"> </div>
Zrzut ekranu z tego, jak wyglądał popup przed kliknięciem <div>
{acceptAllName}: <label htmlFor="popup-screenshot">
</label> Zrzut ekranu z tego, jak wyglądał popup przed
<input kliknięciem {acceptAllName}:
{...{ </label>
type: "file", <input
id: "popup-screenshot", {...{
onChange: async (e) => { type: 'file',
setPopupScreenshotBase64(await toBase64(e.target.files[0])); id: 'popup-screenshot',
}, onChange: async (e) => {
}} setPopupScreenshotBase64(
/> await toBase64(e.target.files[0])
</div> );
</> },
) : null} }}
<p> />
Dzień dobry, w dniu {getDate()} odwiedziłem stronę{" "} </div>
{entries[0].request.originalURL}. Strona ta wysłała moje dane osobowe do </>
podmiotów trzecich - bez mojej zgody.{" "} ) : null}
</p> <p>
<ul> Dzień dobry, w dniu {getDate()} odwiedziłem stronę{' '}
{Object.values(clusters) {entries[0].request.originalURL}. Strona ta wysłała moje dane
.filter((cluster) => cluster.hasMarks()) osobowe do podmiotów trzecich - bez mojej zgody.{' '}
.map((cluster) => ( </p>
<DomainSummary cluster={cluster} /> <ul>
))} {Object.values(clusters)
</ul> .filter((cluster) => cluster.hasMarks())
<p> .map((cluster) => (
{" "} <DomainSummary cluster={cluster} />
Dane te zostały wysłane przez Państwa stronę - a mówiąc dokładniej, ))}
przez zamieszczone przez Państwa na tej stronie skrypty. </ul>
</p> <p>
{popupState === "not_clicked" ? ( {' '}
<p> Dane te zostały wysłane przez Państwa stronę - a mówiąc
Nastąpiło to, zanim zdążyłem w ogóle przeczytać treść wyskakującego dokładniej, przez zamieszczone przez Państwa na tej stronie
okienka ze zgodami i zanim miałem szansę wyrazić sprzeciw takiemu skrypty.
przetwarzaniu danych osobowych. </p>
</p> {popupState === 'not_clicked' ? (
) : null} <p>
{popupState === "clicked_but_no_reject_all" ? ( Nastąpiło to, zanim zdążyłem w ogóle przeczytać treść
<p> wyskakującego okienka ze zgodami i zanim miałem szansę
O ile po wejściu na stronę wcisnąłem w wyskakującym okienku przycisk wyrazić sprzeciw takiemu przetwarzaniu danych osobowych.
{acceptAllName}, o tyle nie stanowi to według mnie ważnej w świetle </p>
RODO zgody, gdyż brakowało w tym okienku równie łatwo osiągalnego ) : null}
przycisku, którego kliknięcie skutkowałoby zasygnalizowaniem braku {popupState === 'clicked_but_no_reject_all' ? (
mojej zgody na takie przetwarzanie moich danych. Mówiąc wprost - <p>
wyrażenie zgody było łatwiejsze niż jej niewyrażenie. Niewyrażenie O ile po wejściu na stronę wcisnąłem w wyskakującym okienku
zgody wiąże się z negatywną konsekwencją konieczności przechodzenia przycisk {acceptAllName}, o tyle nie stanowi to według
przez dodatkowe kroki w wyskakującym okienku. Zatem tak otrzymana mnie ważnej w świetle RODO zgody, gdyż brakowało w tym
przez Państwo moja zgoda nie jest poprawną podstawą prawną do okienku równie łatwo osiągalnego przycisku, którego
przetwarzania moich danych osobowych, gdyż nie spełnia warunku kliknięcie skutkowałoby zasygnalizowaniem braku mojej zgody
dobrowolności wspomnianego w Art. 4. pkt 11{" "} na takie przetwarzanie moich danych. Mówiąc wprost -
<em> wyrażenie zgody było łatwiejsze niż jej niewyrażenie.
rozporządzenia Parlamentu Europejskiego i Rady (UE) 2016/679 z dnia Niewyrażenie zgody wiąże się z negatywną konsekwencją
27 kwietnia 2016 r. w sprawie ochrony osób fizycznych w związku z konieczności przechodzenia przez dodatkowe kroki w
przetwarzaniem danych osobowych i w sprawie swobodnego przepływu wyskakującym okienku. Zatem tak otrzymana przez Państwo moja
takich danych oraz uchylenia dyrektywy 95/46/WE zgoda nie jest poprawną podstawą prawną do przetwarzania
</em> moich danych osobowych, gdyż nie spełnia warunku
.{<img {...{ src: popupScreenshotBase64 }} />} dobrowolności wspomnianego w Art. 4. pkt 11{' '}
</p> <em>
) : null} rozporządzenia Parlamentu Europejskiego i Rady (UE)
<p> 2016/679 z dnia 27 kwietnia 2016 r. w sprawie ochrony
Udokumentowałem to na zrzutach ekranu z mojej przeglądarki internetowej, osób fizycznych w związku z przetwarzaniem danych
które to zrzuty przesyłam w załączeniu. osobowych i w sprawie swobodnego przepływu takich danych
</p> oraz uchylenia dyrektywy 95/46/WE
<p> </em>
Wiem, że nie wszystkie rodzaje przetwarzania danych wymagają zgody .{<img {...{ src: popupScreenshotBase64 }} />}
użytkownika. W kontekście stron internetowych z wymienionych w Art. 6. </p>
pkt 1. RODO mogą mieć zastosowanie albo zgoda (Art. 6. pkt 1. lit. ) : null}
a)), albo niezbędność tego przetwarzania do wykonania umowy (Art. 6. pkt <p>
1. lit. b)), albo uzasadniony interes (Art. 6. pkt 1. lit. f)). Wiem Udokumentowałem to na zrzutach ekranu z mojej przeglądarki
też, że każda z tych podstaw prawnych ma moc dopiero po spełnieniu internetowej, które to zrzuty przesyłam w załączeniu.
określonych warunków. </p>
</p> <p>
<p> Wiem, że nie wszystkie rodzaje przetwarzania danych wymagają
Nie widzę ważnej podstawy prawnej legalizującej procesy przetwarzania zgody użytkownika. W kontekście stron internetowych z
moich danych osobowych, jakie wymieniłem powyżej (na pewno nie jest to wymienionych w Art. 6. pkt 1. RODO mogą mieć zastosowanie albo
przetwarzanie konieczne do wyświetlenia strony z technicznego punktu zgoda (Art. 6. pkt 1. lit. a)), albo niezbędność tego
widzenia). Jeżeli takie przesłanki legalizujące jednak występują, proszę przetwarzania do wykonania umowy (Art. 6. pkt 1. lit. b)), albo
o ich wskazanie, uzasadniony interes (Art. 6. pkt 1. lit. f)). Wiem też, że każda
<strong> z tych podstaw prawnych ma moc dopiero po spełnieniu określonych
{" "} warunków.
dla każdego z celów i podmiotów z <em>osobna</em> </p>
</strong> <p>
. Nie widzę ważnej podstawy prawnej legalizującej procesy
</p> przetwarzania moich danych osobowych, jakie wymieniłem powyżej
<p> (na pewno nie jest to przetwarzanie konieczne do wyświetlenia
Jeżeli wskazaną przez Państwa przesłanką legalizującą dany element strony z technicznego punktu widzenia). Jeżeli takie przesłanki
procesu przetwarzania danych osobowych przez Państwa stronę jest Art 6. legalizujące jednak występują, proszę o ich wskazanie,
pkt 1 lit. a) RODO (zgoda), na mocy Art. 7 pkt 1 RODO proszę o <strong>
wykazanie, że udzieliłem Państwu zgodę na takie przetwarzanie moich {' '}
danych osobowych zanim to przetwarzanie nastąpiło, oraz że ta zgoda jest dla każdego z celów i podmiotów z <em>osobna</em>
ważna w świetle RODO (odnosząc się w szczególności do art. 7 ust. 3 </strong>
RODO). Z góry zaznaczam, że ustawienia przeglądarki nie stanowią .
ważnej w świetle RODO zgody. </p>
</p> <p>
<p> Jeżeli wskazaną przez Państwa przesłanką legalizującą dany
Jeżeli wskazaną przez Państwa przesłanką legalizującą dany element element procesu przetwarzania danych osobowych przez Państwa
procesu przetwarzania danych osobowych przez Państwa stronę jest Art 6. stronę jest Art 6. pkt 1 lit. a) RODO (zgoda), na mocy Art. 7
pkt 1 lit. b) RODO (niezbędność takiego przetwarzania do wykonania pkt 1 RODO proszę o wykazanie, że udzieliłem Państwu zgodę na
umowy), proszę o wskazanie, w jaki sposób ta konieczność zachodzi, oraz takie przetwarzanie moich danych osobowych zanim to
co sprawia, że Państwa zdaniem nie można wykonać umowy związanej z przetwarzanie nastąpiło, oraz że ta zgoda jest ważna w świetle
wyświetleniem Państwa strony bez przekazywania identyfikatora RODO (odnosząc się w szczególności do art. 7 ust. 3 RODO). Z
internetowego z plików Cookies lub historii przeglądania w nagłówku góry zaznaczam, że ustawienia przeglądarki nie stanowią ważnej
Referer do wskazanych podmiotów trzecich. w świetle RODO zgody.
</p> </p>
<p> <p>
Jeżeli wskazaną przez Państwa przesłanką legalizującą dany element Jeżeli wskazaną przez Państwa przesłanką legalizującą dany
procesu przetwarzania danych osobowych przez Państwa stronę jest Art 6. element procesu przetwarzania danych osobowych przez Państwa
pkt 1 lit. f) RODO (uzasadniony interes), proszę o wskazanie, jaki to stronę jest Art 6. pkt 1 lit. b) RODO (niezbędność takiego
jest <strong>konkretny interes</strong> (prosze o bardziej dokładny opis przetwarzania do wykonania umowy), proszę o wskazanie, w jaki
niż np. tylko "marketing"), oraz o wynik testu równowagi pomiędzy sposób ta konieczność zachodzi, oraz co sprawia, że Państwa
Państwa interesem a moimi podstawowymi wolnościami i prawami - ze zdaniem nie można wykonać umowy związanej z wyświetleniem
wskazaniem tego, co sprawia, że w Państwa ocenie Państwa uzasadniony Państwa strony bez przekazywania identyfikatora internetowego z
interes przeważa moje prawa i interesy w kontekście wspomnianych powyżej plików Cookies lub historii przeglądania w nagłówku Referer do
procesów przetwarzania danych. Proszę też pamiętać, że aby w ramach wskazanych podmiotów trzecich.
danego celu przetwarzania powołać się na prawnie uzasadniony interes, </p>
powinni mi Państo umożliwić wyrażenie sprzeciwu wobec przetwarzania <p>
moich danych w tym celu <em>przed</em> rozpoczęciem przetwarzania - zob.{" "} Jeżeli wskazaną przez Państwa przesłanką legalizującą dany
<a href="https://edpb.europa.eu/system/files/2021-11/edpb_guidelines_082020_on_the_targeting_of_social_media_users_pl_0.pdf"> element procesu przetwarzania danych osobowych przez Państwa
Wytyczne 8/2020 Europejskiej Rady Ochrony Danych dotyczące stronę jest Art 6. pkt 1 lit. f) RODO (uzasadniony interes),
targetowania użytkowników mediów społecznościowych proszę o wskazanie, jaki to jest{' '}
</a> <strong>konkretny interes</strong> (prosze o bardziej dokładny
</p> opis niż np. tylko "marketing"), oraz o wynik testu równowagi
<p> pomiędzy Państwa interesem a moimi podstawowymi wolnościami i
Niniejszym zwracam się także z żądaniem ujawnienia tożsamości podmiotów, prawami - ze wskazaniem tego, co sprawia, że w Państwa ocenie
które właścicielami wyżej wymienionych domen, abym mógł zapoznać się Państwa uzasadniony interes przeważa moje prawa i interesy w
z ich politykami prywatności i zwrócić się do tych podmiotów o usunięcie kontekście wspomnianych powyżej procesów przetwarzania danych.
z ich baz wysłanych przez Państwa stronę moich danych. Proszę też pamiętać, że aby w ramach danego celu przetwarzania
</p> powołać się na prawnie uzasadniony interes, powinni mi Państo
<p> umożliwić wyrażenie sprzeciwu wobec przetwarzania moich danych w
Proszę też o wysłanie kopii danych zebranych na mój temat i wysłanych do tym celu <em>przed</em> rozpoczęciem przetwarzania - zob.{' '}
wyżej wymienionych podmiotów. <a href="https://edpb.europa.eu/system/files/2021-11/edpb_guidelines_082020_on_the_targeting_of_social_media_users_pl_0.pdf">
</p> Wytyczne 8/2020 Europejskiej Rady Ochrony Danych dotyczące
<p> targetowania użytkowników mediów społecznościowych
W odpowiedzi proszę się nie powoływać na IAB Europe i ich rzekomą renomę </a>
w tworzeniu rozwiązań zgodnych z RODO. IAB chroni interes reklamodawców, </p>
a nie Użytkowników, i ich rozwiązania (np. TCF) {" "} <p>
<a href="https://panoptykon.org/search/site/IAB"> Niniejszym zwracam się także z żądaniem ujawnienia tożsamości
notorycznie niezgodne z RODO i pozbawione szacunku dla Użytkowników podmiotów, które właścicielami wyżej wymienionych domen, abym
</a> mógł zapoznać się z ich politykami prywatności i zwrócić się do
. tych podmiotów o usunięcie z ich baz wysłanych przez Państwa
</p> stronę moich danych.
<p> </p>
Apeluję także o wprowadzenie stosownych zmian na stronie tak, aby nie <p>
pozostawiać cienia wątpliwości odnośnie tego, na mocy jakiej przesłanki Proszę też o wysłanie kopii danych zebranych na mój temat i
legalizującej dane przetwarzane przez wspomniane podmioty trzecie, wysłanych do wyżej wymienionych podmiotów.
lub tak, aby te dane po prostu nie były wysyłane. Pomoże to zachować </p>
prywatność innym użytkownikom Państwa strony. Polecam Państwa uwadze <p>
oficjalne wytyczne EROD dotyczące zgody w kontekście RODO: W odpowiedzi proszę się nie powoływać na IAB Europe i ich
https://edpb.europa.eu/sites/default/files/files/file1/edpb_guidelines_202005_consent_pl.pdf rzekomą renomę w tworzeniu rozwiązań zgodnych z RODO. IAB chroni
). Aby na przykład zapobiec automatycznemu wysyłaniu historii interes reklamodawców, a nie Użytkowników, i ich rozwiązania
przeglądania do podmiotów trzecich przez Państwa stronę, można po prostu (np. TCF) {' '}
ustawić odpowiednio treść nagłówka{" "} <a href="https://panoptykon.org/search/site/IAB">
<a href="https://developer.mozilla.org/pl/docs/Web/HTTP/Headers/Referrer-Policy"> notorycznie niezgodne z RODO i pozbawione szacunku dla
Referrer-Policy{" "} Użytkowników
</a> </a>
. .
</p> </p>
</div> <p>
); Apeluję także o wprowadzenie stosownych zmian na stronie tak,
aby nie pozostawiać cienia wątpliwości odnośnie tego, na mocy
jakiej przesłanki legalizującej dane przetwarzane przez
wspomniane podmioty trzecie, lub tak, aby te dane po prostu nie
były wysyłane. Pomoże to zachować prywatność innym użytkownikom
Państwa strony. Polecam Państwa uwadze oficjalne wytyczne EROD
dotyczące zgody w kontekście RODO:
https://edpb.europa.eu/sites/default/files/files/file1/edpb_guidelines_202005_consent_pl.pdf
). Aby na przykład zapobiec automatycznemu wysyłaniu historii
przeglądania do podmiotów trzecich przez Państwa stronę, można
po prostu ustawić odpowiednio treść nagłówka{' '}
<a href="https://developer.mozilla.org/pl/docs/Web/HTTP/Headers/Referrer-Policy">
Referrer-Policy{' '}
</a>
.
</p>
</div>
);
} }

View File

@ -1,163 +1,170 @@
import React from "react"; import React from 'react';
import { Dispatch, SetStateAction } from "react"; import { Dispatch, SetStateAction } from 'react';
import { toBase64 } from "../util"; import { toBase64 } from '../util';
import { EmailTemplate2Config } from "./email-template-2"; import { EmailTemplate2Config } from './email-template-2';
export default function EmailTemplate2Controls({ export default function EmailTemplate2Controls({
config, config,
setConfig, setConfig,
}: { }: {
config: EmailTemplate2Config; config: EmailTemplate2Config;
setConfig: Dispatch<SetStateAction<EmailTemplate2Config>>; setConfig: Dispatch<SetStateAction<EmailTemplate2Config>>;
}): JSX.Element { }): JSX.Element {
return ( return (
<div>
<div>
<label htmlFor="poup_type">Typ okienka o RODO:</label>
<select
id="poup_type"
value={config.popup_type}
onChange={(e) =>
setConfig((v) => ({
...v,
popup_type: e.target.value as EmailTemplate2Config["popup_type"],
}))
}
>
<option value="none">Brak jakiejkolwiek informacji</option>
<option value="passive_cookie_banner">
Pasywne powiadomienie o cookiesach
</option>
<option value="consent">Okienko z pytaniem o zgodę</option>
</select>
</div>
{config.popup_type !== "none" ? (
<div> <div>
<label htmlFor="popup_screenshot">Zrzut ekranu okienka o RODO:</label> <div>
<input <label htmlFor="poup_type">Typ okienka o RODO: </label>
{...{ <select
type: "file", id="poup_type"
id: "popup_screenshot", value={config.popup_type}
onChange: async (e) => { onChange={(e) =>
const popup_screenshot_base64 = await toBase64( setConfig((v) => ({
e.target.files[0] ...v,
); popup_type: e.target
setConfig((v) => ({ .value as EmailTemplate2Config['popup_type'],
...v, }))
popup_screenshot_base64, }
})); >
}, <option value="none">Brak jakiejkolwiek informacji</option>
}} <option value="passive_cookie_banner">
/> Pasywne powiadomienie o cookiesach
</option>
<option value="consent">Okienko z pytaniem o zgodę</option>
</select>
</div>
{config.popup_type !== 'none' ? (
<div>
<label htmlFor="popup_screenshot">
Zrzut ekranu okienka o RODO:
</label>
<input
{...{
type: 'file',
id: 'popup_screenshot',
onChange: async (e) => {
const popup_screenshot_base64 = await toBase64(
e.target.files[0]
);
setConfig((v) => ({
...v,
popup_screenshot_base64,
}));
},
}}
/>
</div>
) : (
''
)}
{config.popup_type === 'consent' ? (
<div>
<label htmlFor="acceptAllName">
Tekst na przycisku do zatwierdzania wszystkich zgód:
</label>
<input
{...{
type: 'text',
value: config.popup_accept_all_text,
onChange: (e) =>
setConfig((v) => ({
...v,
popup_accept_all_text: e.target.value,
})),
}}
/>
</div>
) : (
''
)}
<div>
<label htmlFor="popup_action">
Czy coś klikn*ł*m w informacjach o RODO?
</label>
<select
id="popup_action"
value={config.popup_type}
onChange={(e) =>
setConfig((v) => ({
...v,
popup_action: e.target
.value as EmailTemplate2Config['popup_action'],
}))
}
>
<option value="ignored">Nic nie klin*ł*m</option>
<option value="accepted">
Kliknięte {config.popup_accept_all_text}
</option>
<option value="closed">
Zamkn*ł*m okienko (np. przyciskiem "X")
</option>
</select>
</div>
{config.popup_action === 'closed' ? (
<div>
<label htmlFor="popup_closed_how">
Jak okienko zostało zamknięte? Poprzez
</label>
<input
id="popup_closed_how"
type="text"
placeholder="kliknięcie przycisku „X”"
value={config.popup_closed_how}
style={{ width: '300px' }}
onChange={(e) =>
setConfig((v) => ({
...v,
popup_closed_how: e.target.value,
}))
}
/>
</div>
) : (
''
)}
{config.popup_type !== 'none' ? (
<div>
<input
type="checkbox"
id="popup_mentions_passive_consent"
checked={config.popup_mentions_passive_consent}
onChange={(e) =>
setConfig((v) => ({
...v,
popup_mentions_passive_consent:
e.target.checked,
}))
}
/>
<label htmlFor="popup_mentions_passive_consent">
okienko wspomina o pasywnej zgodzie (np. korzystając ze
strony wyrażasz zgodę)
</label>
</div>
) : (
''
)}
{config.popup_mentions_passive_consent ? (
<div>
<label htmlFor="popup_passive_consent_text">
Jak okienko próbuje wmówić Ci, że wyrażasz zgodę?
Przeklej z treści okienka:
</label>
<input
id="popup_passive_consent_text"
placeholder="Korzystając ze strony wyrażasz zgodę"
value={config.popup_passive_consent_text}
onChange={(e) =>
setConfig((v) => ({
...v,
popup_passive_consent_text: e.target.value,
}))
}
/>
</div>
) : (
''
)}
</div> </div>
) : ( );
""
)}
{config.popup_type === "consent" ? (
<div>
<label htmlFor="acceptAllName">
Tekst na przycisku do zatwierdzania wszystkich zgód:
</label>
<input
{...{
type: "text",
value: config.popup_accept_all_text,
onChange: (e) =>
setConfig((v) => ({
...v,
popup_accept_all_text: e.target.value,
})),
}}
/>
</div>
) : (
""
)}
<div>
<label htmlFor="popup_action">
Czy coś klikn*ł*m w informacjach o RODO?
</label>
<select
id="popup_action"
value={config.popup_type}
onChange={(e) =>
setConfig((v) => ({
...v,
popup_action: e.target
.value as EmailTemplate2Config["popup_action"],
}))
}
>
<option value="ignored">Nic nie klin*ł*m</option>
<option value="accepted">
Kliknięte {config.popup_accept_all_text}
</option>
<option value="closed">
Zamkn*ł*m okienko (np. przyciskiem "X")
</option>
</select>
</div>
{config.popup_action === "closed" ? (
<div>
<label htmlFor="popup_closed_how">
Jak okienko zostało zamknięte? Poprzez
</label>
<input
id="popup_closed_how"
type="text"
placeholder="kliknięcie przycisku „X”"
value={config.popup_closed_how}
style={{ width: "300px" }}
onChange={(e) =>
setConfig((v) => ({ ...v, popup_closed_how: e.target.value }))
}
/>
</div>
) : (
""
)}
{config.popup_type !== "none" ? (
<div>
<input
type="checkbox"
id="popup_mentions_passive_consent"
checked={config.popup_mentions_passive_consent}
onChange={(e) =>
setConfig((v) => ({
...v,
popup_mentions_passive_consent: e.target.checked,
}))
}
/>
<label htmlFor="popup_mentions_passive_consent">
okienko wspomina o pasywnej zgodzie (np. korzystając ze strony
wyrażasz zgodę)
</label>
</div>
) : (
""
)}
{config.popup_mentions_passive_consent ? (
<div>
<label htmlFor="popup_passive_consent_text">
Jak okienko próbuje wmówić Ci, że wyrażasz zgodę? Przeklej z treści
okienka:
</label>
<input
id="popup_passive_consent_text"
placeholder="Korzystając ze strony wyrażasz zgodę"
value={config.popup_passive_consent_text}
onChange={(e) =>
setConfig((v) => ({
...v,
popup_passive_consent_text: e.target.value,
}))
}
/>
</div>
) : (
""
)}
</div>
);
} }

View File

@ -92,370 +92,397 @@ export default function EmailTemplate2({
return ( return (
<> <>
<EmailTemplate2Controls {...{ config, setConfig }} /> <EmailTemplate2Controls {...{ config, setConfig }} />
<p> <article
Dzień dobry, w dniu {getDate()} odwiedziłem stronę {visited_url} style={{
. boxShadow: '0 20px 40px rgba(0,0,0,.2)',
</p> padding: '4rem 3rem',
{config.popup_type === 'none' ? ( borderRadius: '0.25rem',
margin: '2rem 0',
color: 'hsl(240, 5.7%, 15.8%);',
}}
>
<p> <p>
Nie ukazał mi się na stronie żaden mechanizm pozyskujący Dzień dobry, w dniu {getDate()} odwiedziłem stronę{' '}
zgodę na przetwarzanie moich danych osobowych lub {visited_url}.
umożliwiający mi wyrażenie sprzeciwu wobec przetwarzania
przez stronę moich danych osobowych w zakresie wykraczającym
poza procesy konieczne do wyświetlenia strony
</p> </p>
) : config.popup_type == 'passive_cookie_banner' ? ( {config.popup_type === 'none' ? (
<>
<p> <p>
Na stronie była widoczna informacja o plikach Cookie.{' '} Nie ukazał mi się na stronie żaden mechanizm pozyskujący
zgodę na przetwarzanie moich danych osobowych lub
umożliwiający mi wyrażenie sprzeciwu wobec przetwarzania
przez stronę moich danych osobowych w zakresie
wykraczającym poza procesy konieczne do wyświetlenia
strony
</p> </p>
<p> ) : config.popup_type == 'passive_cookie_banner' ? (
<Base64Image
{...{ base64: config.popup_screenshot_base64 }}
/>
</p>
</>
) : (
<>
<p>
Ukazało mi się okienko z informacjami i pytaniami
dotyczącymi sposobów, w jaki strona przetwarza moje dane
osobowe.{' '}
</p>
<p>
<Base64Image
{...{ base64: config.popup_screenshot_base64 }}
/>
</p>
<p>
{config.popup_action === 'ignored'
? /* HTML */ `Nie kliknąłem żadnego przycisku w tym
okienku. W szczególności nie kliknąłem przycisku
${config.popup_accept_all_text}.`
: config.popup_action === 'accepted'
? `Kliknąłem na widoczną w tym okienku opcję „${config.popup_accept_all_text}”.`
: ''}
</p>
</>
)}
<p>
W tym samym czasie rejestrowałem ruch sieciowy generowany przez
stronę za pomocą narzędzi w przeglądarce Firefox. Okazało
się, że Państwa strona wysłała była moje dane osobowe do
następujących podmiotów:
</p>
<ul>
{Object.values(clusters)
.filter((cluster) => cluster.hasMarks())
.map((cluster) => (
<DomainSummary cluster={cluster} key={cluster.id} />
))}
</ul>
{config.popup_action === 'ignored' ? (
<p>
Dane te zostały wysłane, zanim kliknąłem cokolwiek na tej
stronie.
</p>
) : config.popup_action === 'accepted' ? (
<p>
Dane te zostały wysłane po tym, jak kliknąłem przycisk
{config.popup_accept_all_text}
</p>
) : (
''
)}
<p>
W załączeniu przesyłam część zrzutów ekranu dokumentujących fakt
wysłania tych danych przez Państwa stronę.{' '}
</p>
<h3>Podstawa prawna</h3>
<p>
Ustawa Prawo Telekomunikacyjne w art. 173 reguluje warunki,
które musi spełnić administrator strony, aby jego strona mogła
zapisywać i czytać treść plików cookie. Nie reguluje jednak
tego, jakim podmiotom i w jakim zakresie dane mogą być{' '}
<em>ujawniane</em> przez stronę. Tym zajmuje się Rozporządzenie
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) RODO. Zapis/odczyt plików
cookie a ujawnianie ich treści podmiotom trzecim to dwa różne
procesy. Niniejsza wiadomość i pytania w niej zawarte dotyczą
właśnie <em>ujawniania</em> moich danych osobowych (pochodzących
m.in. z Cookies) podmiotom trzecim.
</p>
<p>
W kontekście stron internetowych właściwie dopuszczalne tylko
trzy z sześciu wymienionych w Art. 6 pkt 1 RODO podstaw prawnych
dla przetwarzania danych osobowych:
</p>
<ol>
<li>
Zgoda &mdash; osoba, której dane dotyczą wyraziła zgodę na
przetwarzanie swoich danych osobowych w jednym lub większej
liczbie określonych celów (<em>Art. 6 pkt 1 lit. a)</em>).
</li>
<li>
Niezbędność &mdash; przetwarzanie jest niezbędne do
wykonania umowy, której stroną jest osoba, której dane
dotyczą, lub do podjęcia działań na żądanie osoby, której
dane dotyczą, przed zawarciem umowy (
<em>Art. 6 pkt 1 lit. b)</em>);{' '}
</li>
<li>
Uzasadniony Interes &mdash; przetwarzanie jest niezbędne
do celów wynikających z prawnie uzasadnionych interesów
realizowanych przez administratora lub przez stronę trzecią,
z wyjątkiem sytuacji, w których nadrzędny charakter wobec
tych interesów mają interesy lub podstawowe prawa i wolności
osoby, której dane dotyczą, wymagające ochrony danych
osobowych, w szczególności gdy osoba, której dane dotyczą,
jest dzieckiem (<em>Art. 6 pkt 1 lit. f)</em>
);
</li>
</ol>
<p>
W przypadku opisywanej przeze mnie mojej wizyty na Państwa
stronie nie ma zastosowania Zgoda, gdyż{' '}
{config.popup_action === 'ignored' ? (
<> <>
nie wyrażałem żadnej zgody na takie przetwarzanie moich <p>
danych Na stronie była widoczna informacja o plikach
{config.popup_type === 'consent' ? ( Cookie.{' '}
<> </p>
&mdash; w szczególności nie kliknąłem przycisku <p>
{config.popup_accept_all_text} <Base64Image
</> {...{ base64: config.popup_screenshot_base64 }}
) : ( />
'' </p>
)}
.
</>
) : config.popup_action === 'accepted' ? (
<>
o ile po wejściu na stronę wcisnąłem w wyskakującym
okienku przycisk {config.popup_accept_all_text}, o
tyle nie stanowi to według mnie ważnej w świetle RODO
zgody, gdyż brakowało w tym okienku równie łatwo
osiągalnego przycisku, którego kliknięcie skutkowałoby
zasygnalizowaniem braku mojej zgody na takie
przetwarzanie moich danych. Mówiąc wprost &mdash;
wyrażenie zgody było łatwiejsze niż jej niewyrażenie.
Niewyrażenie zgody wiąże się z negatywną konsekwencją
konieczności przechodzenia przez dodatkowe kroki w
wyskakującym okienku. Zatem tak otrzymana przez Państwo
moja zgoda nie jest poprawną podstawą prawną do
przetwarzania moich danych osobowych, gdyż nie spełnia
warunku dobrowolności wspomnianego w motywie (42) RODO.
</>
) : config.popup_action === 'closed' ? (
<>
zamknąłem okienko pytające o zgodę poprzez{' '}
{config.popup_closed_how}. Nie może być to uznane za
zgodę, bo nie spełnia to warunku jednoznaczności
opisanego w motywie (32) Rozporządzenia 2016/679.{' '}
</> </>
) : ( ) : (
''
)}{' '}
Za zgodę nie można też uznać posiadania włączonej obsługi
cookies w przeglądarce (gdyż aby zgoda była ważna, musi być
szczegółowa dla każdego celów z osobna), jakichkolwiek innych
ustawień przeglądarki, ani pasywnych działań z mojej strony (np.
kontynuowanie korzystania ze strony)
{config.popup_mentions_passive_consent ? (
<> <>
{' '} <p>
&mdash; nieprawdą więc jest zawarty na Państwa stronie Ukazało mi się okienko z informacjami i pytaniami
komunikat {config.popup_passive_consent_text.trim()} dotyczącymi sposobów, w jaki strona przetwarza moje
(por. paragraf 97.{' '} dane osobowe.{' '}
<a href="https://edpb.europa.eu/sites/default/files/files/file1/edpb_guidelines_202005_consent_pl.pdf"> </p>
oficjalnych wytycznych EROD dotyczących zgody na <p>
mocy rozporządzenia 2016/679 <Base64Image
</a> {...{ base64: config.popup_screenshot_base64 }}
) />
</p>
<p>
{config.popup_action === 'ignored'
? /* HTML */ `Nie kliknąłem żadnego przycisku w
tym okienku. W szczególności nie kliknąłem
przycisku ${config.popup_accept_all_text}.`
: config.popup_action === 'accepted'
? `Kliknąłem na widoczną w tym okienku opcję „${config.popup_accept_all_text}”.`
: ''}
</p>
</> </>
) : (
''
)} )}
.
</p>
<p>
W mojej ocenie Niezbędność nie ma zastosowania co do opisanych
powyżej sposobów przetwarzania danych. Nie widzę, co miałoby
sprawiać, aby wysyłanie moich danych osobowych do wspomnianych
powyżej podmiotów trzecich było konieczne do wyświetlenia
Państwa strony na ekranie mojego komputera (zob.{' '}
<a href="https://edpb.europa.eu/system/files/2021-11/edpb_guidelines_082020_on_the_targeting_of_social_media_users_pl_0.pdf">
Wytyczne 8/2020 EROD dotyczące targetowania użytkowników
mediów społecznościowych
</a>
, par. 49);.{' '}
</p>
<p>
Pozostaje zatem Uzasadniony Interes. Aby Administrator mógł
używać uzasadnionego interesu jako podstawy prawnej targetowania
użytkowników Sieci, muszą zostać spełnione m.in. następujące
warunki:{' '}
</p>
<ol>
<li>
Administrator danych lub podmiot trzeci, któremu dane
ujawniane musi{' '}
<strong>
faktycznie realizować dany konkretny uzasadniony interes
</strong>{' '}
(
<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">
Wyrok TSUE z dnia 29 lipca 2019 r. w sprawie Fashion ID,
C-40/17, ECLI:EU:C:2019:629
</a>
, pkt 95.)
</li>
<li>
Takie przetwarzanie danych jest <strong>konieczne</strong>{' '}
dla potrzeb wynikających z danego uzasadnionego interesu (
<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">
Wyrok TSUE z dnia 29 lipca 2019 r. w sprawie Fashion ID,
C-40/17, ECLI:EU:C:2019:629
</a>
, pkt 95.)
</li>
<li>
Wybrany uzasadniony interes musi mieć pierwszeństwo nad
prawami i wolnościami osoby, której dotyczą przetwarzane
dane (
<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">
Wyrok TSUE z dnia 29 lipca 2019 r. w sprawie Fashion ID,
C-40/17, ECLI:EU:C:2019:629
</a>
, pkt 95.)
</li>
<li>
Osoby, których dane dotyczą, powinny mieć możliwość
wyrażenia sprzeciwu wobec przetwarzania ich danych do celów
związanych z targetowaniem{' '}
<strong>przed rozpoczęciem przetwarzania</strong> (zob.{' '}
<a href="https://edpb.europa.eu/system/files/2021-11/edpb_guidelines_082020_on_the_targeting_of_social_media_users_pl_0.pdf">
Wytyczne 8/2020 EROD dotyczące targetowania użytkowników
mediów społecznościowych
</a>
, par. 54);
</li>
</ol>
{config.popup_action !== 'accepted' ? (
<p> <p>
Moje dane zostały ujawnione podmiotom trzecim tuż po W tym samym czasie rejestrowałem ruch sieciowy generowany
włączeniu strony, zatem nie jest spełniony warunek 4. przez stronę za pomocą narzędzi w przeglądarce Firefox.
Apeluję o wdrożenie zmian na stronie, które sprawią, że Okazało się, że Państwa strona wysłała była moje dane
dopiero po świadomym niewyrażeniu sprzeciwu przez osobowe do następujących podmiotów:
użytkownika aktywowane procesy przetwarzania danych
osobowych, których podstawą prawną jest uzasadniony interes.
</p>
) : (
''
)}
<p>
Jeżeli istnieją jednak inne niż uzasadniony interes ważne
podstawy prawne do takiego przetwarzania moich danych osobowych
przez Państwa stronę, proszę o ich wskazanie,{' '}
<em>dla każdego z wymienionych podmiotów z osobna</em>.
(Przypominam, że Art. 173 ustawy Prawo Telekomunikacyjne nie ma
tutaj zastosowania, ponieważ nie pytam o zapis/odczyt plików na
moim komputerze, tylko o ujawnianie moich danych osobowych
podmiotom trzecim). W przeciwnym wypadku, aby ustalić, czy moje
dane były przez Państwa przetwarzane na mocy uzasadnionego
interesu zgodnie z prawem, proszę o wypełnienie następującego
szablonu (lub udzielenie tych samych informacji w innej postaci,
przy zachowaniu zakresu i szczegółowości informacji:
</p>
<div style={{ border: '1px solid black', padding: '1rem' }}>
<p>
W dniu {getDate()} strona {visited_url}:
</p> </p>
<ul> <ul>
{Object.values(clusters) {Object.values(clusters)
.filter((cluster) => cluster.hasMarks()) .filter((cluster) => cluster.hasMarks())
.map((cluster) => ( .map((cluster) => (
<li <DomainSummary cluster={cluster} key={cluster.id} />
key={cluster.id}
style={{ paddingBottom: '1rem' }}
>
ujawniła pańskie dane w zakresie{' '}
<em>
<ClusterRangeSummary {...{ cluster }} />
</em>{' '}
firmie <Placeholder>nazwa firmy</Placeholder>,
która jest właścicielem domeny{' '}
<strong>{cluster.id}</strong> i swoją politykę
prywatności publikuje pod adresem{' '}
<Placeholder>
adres URL polityki prywatności tej firmy
</Placeholder>
. Podstawą prawną takiego przetwarzania danych
przez naszą stronę jest uzasadniony interes:{' '}
<Placeholder>
na czym polega ten uzasadniony interes, tzn.
bieżące działania podejmowane przez podmiot
realizujący ten interes lub korzyści dla
podmiotu realizującego ten interes
oczekiwane w bardzo bliskiej przyszłości
</Placeholder>{' '}
realizowany przez{' '}
<Placeholder>
kogo? jaki podmiot podejmuje wspomniane
działania lub jest beneficjentem
wspomnianych korzyści?
</Placeholder>
. Ujawnienie{' '}
<ClusterRangeSummary {...{ cluster }} /> temu
podmiotowi przez naszą stronę było konieczne dla
potrzeb wynikających z tego interesu, ponieważ
<Placeholder>
uzasadnienie konieczności
</Placeholder>
.<br />
</li>
))} ))}
</ul> </ul>
</div> {config.popup_action === 'ignored' ? (
<p> <p>
Proszę w szczególności zwrócić uwagę na podanie adresów do Dane te zostały wysłane, zanim kliknąłem cokolwiek na
polityk prywatności tych firm, abym wiedział, jak skontaktować tej stronie.
się z nimi i wnioskować o usunięcie z ich baz wysłanych przez </p>
Państwa stronę moich danych. ) ) : config.popup_action === 'accepted' ? (
</p> <p>
<p> Dane te zostały wysłane po tym, jak kliknąłem przycisk
W odpowiedzi proszę się nie powoływać na IAB Europe i ich {config.popup_accept_all_text}
rzekomą renomę w tworzeniu rozwiązań zgodnych z RODO. IAB chroni </p>
interes reklamodawców, a nie Użytkowników, i ich rozwiązania ) : (
(np. TCF) {' '} ''
<a href="https://panoptykon.org/search/site/IAB"> )}
notorycznie niezgodne z RODO i pozbawione szacunku dla <p>
Użytkowników W załączeniu przesyłam część zrzutów ekranu dokumentujących
</a> fakt wysłania tych danych przez Państwa stronę.{' '}
. </p>
</p> <h3>Podstawa prawna</h3>
<p> <p>
Apeluję także o wprowadzenie stosownych zmian na stronie tak, Ustawa Prawo Telekomunikacyjne w art. 173 reguluje warunki,
aby nie pozostawiać cienia wątpliwości odnośnie tego, na mocy które musi spełnić administrator strony, aby jego strona
jakiej przesłanki legalizującej dane przetwarzane przez mogła zapisywać i czytać treść plików cookie. Nie reguluje
wspomniane podmioty trzecie, lub tak, aby te dane po prostu nie jednak tego, jakim podmiotom i w jakim zakresie dane mogą
były wysyłane. Pomoże to zachować prywatność innym użytkownikom być <em>ujawniane</em> przez stronę. Tym zajmuje się
Państwa strony. Polecam Państwa uwadze Rozporządzenie 2016/679 Parlamentu Europejskiego i Rady (UE)
<a href="https://edpb.europa.eu/sites/default/files/files/file1/edpb_guidelines_202005_consent_pl.pdf"> z dnia 27 kwietnia 2016 r. w sprawie ochrony osób fizycznych
{' '} w związku z przetwarzaniem danych osobowych i w sprawie
oficjalne wytyczne EROD dotyczące zgody w kontekście RODO swobodnego przepływu takich danych oraz uchylenia dyrektywy
</a> 95/46/WE (ogólne rozporządzenie o ochronie danych) RODO.
. Aby na przykład zapobiec automatycznemu wysyłaniu historii Zapis/odczyt plików cookie a ujawnianie ich treści podmiotom
przeglądania do podmiotów trzecich przez Państwa stronę, można trzecim to dwa różne procesy. Niniejsza wiadomość i pytania
po prostu ustawić odpowiednio treść nagłówka{' '} w niej zawarte dotyczą właśnie <em>ujawniania</em> moich
<a href="https://developer.mozilla.org/pl/docs/Web/HTTP/Headers/Referrer-Policy"> danych osobowych (pochodzących m.in. z Cookies) podmiotom
Referrer-Policy{' '} trzecim.
</a> </p>
. <p>
</p> W kontekście stron internetowych właściwie dopuszczalne
tylko trzy z sześciu wymienionych w Art. 6 pkt 1 RODO
podstaw prawnych dla przetwarzania danych osobowych:
</p>
<ol>
<li>
Zgoda &mdash; osoba, której dane dotyczą wyraziła
zgodę na przetwarzanie swoich danych osobowych w jednym
lub większej liczbie określonych celów (
<em>Art. 6 pkt 1 lit. a)</em>).
</li>
<li>
Niezbędność &mdash; przetwarzanie jest niezbędne do
wykonania umowy, której stroną jest osoba, której dane
dotyczą, lub do podjęcia działań na żądanie osoby,
której dane dotyczą, przed zawarciem umowy (
<em>Art. 6 pkt 1 lit. b)</em>);{' '}
</li>
<li>
Uzasadniony Interes &mdash; przetwarzanie jest
niezbędne do celów wynikających z prawnie uzasadnionych
interesów realizowanych przez administratora lub przez
stronę trzecią, z wyjątkiem sytuacji, w których
nadrzędny charakter wobec tych interesów mają interesy
lub podstawowe prawa i wolności osoby, której dane
dotyczą, wymagające ochrony danych osobowych, w
szczególności gdy osoba, której dane dotyczą, jest
dzieckiem (<em>Art. 6 pkt 1 lit. f)</em>
);
</li>
</ol>
<p>
W przypadku opisywanej przeze mnie mojej wizyty na Państwa
stronie nie ma zastosowania Zgoda, gdyż{' '}
{config.popup_action === 'ignored' ? (
<>
nie wyrażałem żadnej zgody na takie przetwarzanie
moich danych
{config.popup_type === 'consent' ? (
<>
&mdash; w szczególności nie kliknąłem
przycisku {config.popup_accept_all_text}
</>
) : (
''
)}
.
</>
) : config.popup_action === 'accepted' ? (
<>
o ile po wejściu na stronę wcisnąłem w wyskakującym
okienku przycisk {config.popup_accept_all_text}, o
tyle nie stanowi to według mnie ważnej w świetle
RODO zgody, gdyż brakowało w tym okienku równie
łatwo osiągalnego przycisku, którego kliknięcie
skutkowałoby zasygnalizowaniem braku mojej zgody na
takie przetwarzanie moich danych. Mówiąc wprost
&mdash; wyrażenie zgody było łatwiejsze niż jej
niewyrażenie. Niewyrażenie zgody wiąże się z
negatywną konsekwencją konieczności przechodzenia
przez dodatkowe kroki w wyskakującym okienku. Zatem
tak otrzymana przez Państwo moja zgoda nie jest
poprawną podstawą prawną do przetwarzania moich
danych osobowych, gdyż nie spełnia warunku
dobrowolności wspomnianego w motywie (42) RODO.
</>
) : config.popup_action === 'closed' ? (
<>
zamknąłem okienko pytające o zgodę poprzez{' '}
{config.popup_closed_how}. Nie może być to uznane za
zgodę, bo nie spełnia to warunku jednoznaczności
opisanego w motywie (32) Rozporządzenia 2016/679.{' '}
</>
) : (
''
)}{' '}
Za zgodę nie można też uznać posiadania włączonej obsługi
cookies w przeglądarce (gdyż aby zgoda była ważna, musi być
szczegółowa dla każdego celów z osobna), jakichkolwiek
innych ustawień przeglądarki, ani pasywnych działań z mojej
strony (np. kontynuowanie korzystania ze strony)
{config.popup_mentions_passive_consent ? (
<>
{' '}
&mdash; nieprawdą więc jest zawarty na Państwa
stronie komunikat
{config.popup_passive_consent_text.trim()} (por.
paragraf 97.{' '}
<a href="https://edpb.europa.eu/sites/default/files/files/file1/edpb_guidelines_202005_consent_pl.pdf">
oficjalnych wytycznych EROD dotyczących zgody na
mocy rozporządzenia 2016/679
</a>
)
</>
) : (
''
)}
.
</p>
<p>
W mojej ocenie Niezbędność nie ma zastosowania co do
opisanych powyżej sposobów przetwarzania danych. Nie widzę,
co miałoby sprawiać, aby wysyłanie moich danych osobowych do
wspomnianych powyżej podmiotów trzecich było konieczne do
wyświetlenia Państwa strony na ekranie mojego komputera
(zob.{' '}
<a href="https://edpb.europa.eu/system/files/2021-11/edpb_guidelines_082020_on_the_targeting_of_social_media_users_pl_0.pdf">
Wytyczne 8/2020 EROD dotyczące targetowania użytkowników
mediów społecznościowych
</a>
, par. 49);.{' '}
</p>
<p>
Pozostaje zatem Uzasadniony Interes. Aby Administrator
mógł używać uzasadnionego interesu jako podstawy prawnej
targetowania użytkowników Sieci, muszą zostać spełnione
m.in. następujące warunki:{' '}
</p>
<ol>
<li>
Administrator danych lub podmiot trzeci, któremu dane
ujawniane musi{' '}
<strong>
faktycznie realizować dany konkretny uzasadniony
interes
</strong>{' '}
(
<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">
Wyrok TSUE z dnia 29 lipca 2019 r. w sprawie Fashion
ID, C-40/17, ECLI:EU:C:2019:629
</a>
, pkt 95.)
</li>
<li>
Takie przetwarzanie danych jest{' '}
<strong>konieczne</strong> dla potrzeb wynikających z
danego uzasadnionego interesu (
<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">
Wyrok TSUE z dnia 29 lipca 2019 r. w sprawie Fashion
ID, C-40/17, ECLI:EU:C:2019:629
</a>
, pkt 95.)
</li>
<li>
Wybrany uzasadniony interes musi mieć pierwszeństwo nad
prawami i wolnościami osoby, której dotyczą przetwarzane
dane (
<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">
Wyrok TSUE z dnia 29 lipca 2019 r. w sprawie Fashion
ID, C-40/17, ECLI:EU:C:2019:629
</a>
, pkt 95.)
</li>
<li>
Osoby, których dane dotyczą, powinny mieć możliwość
wyrażenia sprzeciwu wobec przetwarzania ich danych do
celów związanych z targetowaniem{' '}
<strong>przed rozpoczęciem przetwarzania</strong> (zob.{' '}
<a href="https://edpb.europa.eu/system/files/2021-11/edpb_guidelines_082020_on_the_targeting_of_social_media_users_pl_0.pdf">
Wytyczne 8/2020 EROD dotyczące targetowania
użytkowników mediów społecznościowych
</a>
, par. 54);
</li>
</ol>
{config.popup_action !== 'accepted' ? (
<p>
Moje dane zostały ujawnione podmiotom trzecim tuż po
włączeniu strony, zatem nie jest spełniony warunek 4.
Apeluję o wdrożenie zmian na stronie, które sprawią, że
dopiero po świadomym niewyrażeniu sprzeciwu przez
użytkownika aktywowane procesy przetwarzania danych
osobowych, których podstawą prawną jest uzasadniony
interes.
</p>
) : (
''
)}
<p>
Jeżeli istnieją jednak inne niż uzasadniony interes ważne
podstawy prawne do takiego przetwarzania moich danych
osobowych przez Państwa stronę, proszę o ich wskazanie,{' '}
<em>dla każdego z wymienionych podmiotów z osobna</em>.
(Przypominam, że Art. 173 ustawy Prawo Telekomunikacyjne nie
ma tutaj zastosowania, ponieważ nie pytam o zapis/odczyt
plików na moim komputerze, tylko o ujawnianie moich danych
osobowych podmiotom trzecim). W przeciwnym wypadku, aby
ustalić, czy moje dane były przez Państwa przetwarzane na
mocy uzasadnionego interesu zgodnie z prawem, proszę o
wypełnienie następującego szablonu (lub udzielenie tych
samych informacji w innej postaci, przy zachowaniu zakresu i
szczegółowości informacji:
</p>
<div style={{ border: '1px solid black', padding: '1rem' }}>
<p>
W dniu {getDate()} strona {visited_url}:
</p>
<ul>
{Object.values(clusters)
.filter((cluster) => cluster.hasMarks())
.map((cluster) => (
<li
key={cluster.id}
style={{ paddingBottom: '1rem' }}
>
ujawniła pańskie dane w zakresie{' '}
<em>
<ClusterRangeSummary {...{ cluster }} />
</em>{' '}
firmie{' '}
<Placeholder>nazwa firmy</Placeholder>,
która jest właścicielem domeny{' '}
<strong>{cluster.id}</strong> i swoją
politykę prywatności publikuje pod adresem{' '}
<Placeholder>
adres URL polityki prywatności tej firmy
</Placeholder>
. Podstawą prawną takiego przetwarzania
danych przez naszą stronę jest uzasadniony
interes:{' '}
<Placeholder>
na czym polega ten uzasadniony interes,
tzn. bieżące działania podejmowane przez
podmiot realizujący ten interes lub
korzyści dla podmiotu realizującego ten
interes oczekiwane w bardzo bliskiej
przyszłości
</Placeholder>{' '}
realizowany przez{' '}
<Placeholder>
kogo? jaki podmiot podejmuje wspomniane
działania lub jest beneficjentem
wspomnianych korzyści?
</Placeholder>
. Ujawnienie{' '}
<ClusterRangeSummary {...{ cluster }} />{' '}
temu podmiotowi przez naszą stronę było
konieczne dla potrzeb wynikających z tego
interesu, ponieważ
<Placeholder>
uzasadnienie konieczności
</Placeholder>
.<br />
</li>
))}
</ul>
</div>
<p>
Proszę w szczególności zwrócić uwagę na podanie adresów do
polityk prywatności tych firm, abym wiedział, jak
skontaktować się z nimi i wnioskować o usunięcie z ich baz
wysłanych przez Państwa stronę moich danych. )
</p>
<p>
W odpowiedzi proszę się nie powoływać na IAB Europe i ich
rzekomą renomę w tworzeniu rozwiązań zgodnych z RODO. IAB
chroni interes reklamodawców, a nie Użytkowników, i ich
rozwiązania (np. TCF) {' '}
<a href="https://panoptykon.org/search/site/IAB">
notorycznie niezgodne z RODO i pozbawione szacunku dla
Użytkowników
</a>
.
</p>
<p>
Apeluję także o wprowadzenie stosownych zmian na stronie
tak, aby nie pozostawiać cienia wątpliwości odnośnie tego,
na mocy jakiej przesłanki legalizującej dane przetwarzane
przez wspomniane podmioty trzecie, lub tak, aby te dane po
prostu nie były wysyłane. Pomoże to zachować prywatność
innym użytkownikom Państwa strony. Polecam Państwa uwadze
<a href="https://edpb.europa.eu/sites/default/files/files/file1/edpb_guidelines_202005_consent_pl.pdf">
{' '}
oficjalne wytyczne EROD dotyczące zgody w kontekście
RODO
</a>
. Aby na przykład zapobiec automatycznemu wysyłaniu historii
przeglądania do podmiotów trzecich przez Państwa stronę,
można po prostu ustawić odpowiednio treść nagłówka{' '}
<a href="https://developer.mozilla.org/pl/docs/Web/HTTP/Headers/Referrer-Policy">
Referrer-Policy{' '}
</a>
.
</p>
</article>
</> </>
); );
} }

View File

@ -1,16 +1,22 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head>
<head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<title>Wygeneruj maila co zgłoszenia</title> <title>Treść maila do zgłoszenia</title>
</head> </head>
<body>
<div id="app"></div> <body>
<div
id="app"
style="max-width: 50rem; margin: 0 auto; padding: 1rem 0rem 2rem;"
></div>
<style> <style>
tr:hover { tr:hover {
background-color: hsla(0, 0%, 0%, 0.1); background-color: hsla(0, 0%, 0%, 0.1);
} }
</style> </style>
<script src="/lib/report-window/report-window.js"></script> <script src="/lib/report-window/report-window.js"></script>
</body> </body>
</html>
</html>

View File

@ -1,179 +1,183 @@
import { EventEmitter } from "events"; import { EventEmitter } from 'events';
import ExtendedRequest from "./extended-request"; import ExtendedRequest from './extended-request';
import { Sources, StolenDataEntry } from "./stolen-data-entry"; 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", 'cookie',
"pathname", 'pathname',
"queryparams", 'queryparams',
"header", 'header',
]; ];
export class RequestCluster extends EventEmitter { export class RequestCluster extends EventEmitter {
public requests: ExtendedRequest[] = []; public requests: ExtendedRequest[] = [];
public representativeStolenData: StolenDataEntry[] = []; public representativeStolenData: StolenDataEntry[] = [];
public expanded: boolean; public expanded: boolean;
constructor(public id: string) { constructor(public id: string) {
super(); super();
}
add(request: ExtendedRequest) {
this.requests.push(request);
this.emit("change");
}
toggleExpanded(state: boolean) {
this.expanded = state;
this.emit("change");
}
hasCookies() {
for (const request of this.requests) {
if (request.hasCookie()) {
return true;
}
} }
return false; add(request: ExtendedRequest) {
} this.requests.push(request);
this.emit('change');
calculateRepresentativeStolenData(
filter: {
minValueLength: number;
cookiesOnly: boolean;
cookiesOrOriginOnly: boolean;
} = { minValueLength: 0, cookiesOnly: false, cookiesOrOriginOnly: false }
): StolenDataEntry[] {
this.representativeStolenData = this.requests
.map((request) => request.stolenData)
.reduce((a, b) => a.concat(b), [])
.filter((entry) => {
return entry.value.length >= filter.minValueLength;
})
.filter((entry) => !filter.cookiesOnly || entry.source === "cookie")
.filter(
(entry) =>
!filter.cookiesOrOriginOnly ||
entry.source === "cookie" ||
entry.classification === "history"
)
.sort((entry1, entry2) => {
if (entry1.value > entry2.value) {
return -1;
} else if (entry1.value < entry2.value) {
return 1;
} else {
const indexA = source_priority.indexOf(entry1.source);
const indexB = source_priority.indexOf(entry2.source);
if (indexA < indexB) {
return -1;
} else if (indexA > indexB) {
return 1;
} else if (entry1.value.length > entry2.value.length) {
return -1;
} else if (entry1.value.length < entry2.value.length) {
return 1;
} else if (entry1.isMarked && !entry2.isMarked) {
return -1;
} else if (!entry1.isMarked && entry2.isMarked) {
return 1;
} else {
return 0;
}
}
})
.filter((_, index, array) => {
// removing value duplicates
if (index == 0) {
return true;
}
if (
array[index].getValuePreview() ===
array[index - 1].getValuePreview() ||
isSameURL(array[index].value, array[index - 1].value)
) {
return false;
} else {
return true;
}
})
.sort((entry1, entry2) => {
if (entry1.name < entry2.name) {
return -1;
} else if (entry1.name > entry2.name) {
return 1;
} else {
if (entry1.value.length > entry2.value.length) {
return 1;
} else {
return -1;
}
}
})
.filter((_, index, array) => {
// removing name duplicates, keeping only the first - which is the longest. Some data loss may occur.
if (index == 0) {
return true;
}
if (array[index].name === array[index - 1].name) {
return false;
} else {
return true;
}
})
.sort((entry1, entry2) =>
entry1.getPriority() > entry2.getPriority() ? -1 : 1
);
return this.representativeStolenData;
}
static sortCompare(a: RequestCluster, b: RequestCluster) {
if (a.hasCookies() == b.hasCookies()) {
if (a.id < b.id) {
return -1;
} else {
return 1;
}
} else {
if (a.hasCookies()) {
return -1;
} else {
return 1;
}
} }
}
getMarkedRequests() { toggleExpanded(state: boolean) {
return this.requests.filter((request) => request.hasMark()); this.expanded = state;
} this.emit('change');
}
getFullHosts() { hasCookies() {
return unique( for (const request of this.requests) {
this.requests if (request.hasCookie()) {
.map((request) => allSubhosts(request.getHost())) return true;
.reduce((a, b) => a.concat(b), []) }
); }
} return false;
}
hasMarks() { calculateRepresentativeStolenData(
return this.requests.some((request) => request.hasMark()); filter: {
} minValueLength: number;
cookiesOnly: boolean;
cookiesOrOriginOnly: boolean;
} = {
minValueLength: 0,
cookiesOnly: false,
cookiesOrOriginOnly: false,
}
): StolenDataEntry[] {
this.representativeStolenData = this.requests
.map((request) => request.stolenData)
getMarkedEntries(): StolenDataEntry[] { .reduce((a, b) => a.concat(b), [])
return this.requests .filter((entry) => {
.map((request) => request.getMarkedEntries()) return entry.value.length >= filter.minValueLength;
.reduce(reduceConcat, []); })
} .filter((entry) => !filter.cookiesOnly || entry.source === 'cookie')
.filter(
(entry) =>
!filter.cookiesOrOriginOnly ||
entry.source === 'cookie' ||
entry.classification === 'history'
)
.sort((entry1, entry2) => {
if (entry1.value > entry2.value) {
return -1;
} else if (entry1.value < entry2.value) {
return 1;
} else {
const indexA = source_priority.indexOf(entry1.source);
const indexB = source_priority.indexOf(entry2.source);
if (indexA < indexB) {
return -1;
} else if (indexA > indexB) {
return 1;
} else if (entry1.value.length > entry2.value.length) {
return -1;
} else if (entry1.value.length < entry2.value.length) {
return 1;
} else if (entry1.isMarked && !entry2.isMarked) {
return -1;
} else if (!entry1.isMarked && entry2.isMarked) {
return 1;
} else {
return 0;
}
}
})
.filter((_, index, array) => {
// removing value duplicates
if (index == 0) {
return true;
}
if (
array[index].getValuePreview() ===
array[index - 1].getValuePreview() ||
isSameURL(array[index].value, array[index - 1].value)
) {
return false;
} else {
return true;
}
})
.sort((entry1, entry2) => {
if (entry1.name < entry2.name) {
return -1;
} else if (entry1.name > entry2.name) {
return 1;
} else {
if (entry1.value.length > entry2.value.length) {
return 1;
} else {
return -1;
}
}
})
.filter((_, index, array) => {
// removing name duplicates, keeping only the first - which is the longest. Some data loss may occur.
if (index == 0) {
return true;
}
if (array[index].name === array[index - 1].name) {
return false;
} else {
return true;
}
})
.sort((entry1, entry2) =>
entry1.getPriority() > entry2.getPriority() ? -1 : 1
);
return this.representativeStolenData;
}
exposesOrigin() { static sortCompare(a: RequestCluster, b: RequestCluster) {
return this.requests.some((request) => request.exposesOrigin()); if (a.hasCookies() == b.hasCookies()) {
} if (a.id < b.id) {
return -1;
} else {
return 1;
}
} else {
if (a.hasCookies()) {
return -1;
} else {
return 1;
}
}
}
autoMark() { getMarkedRequests() {
this.calculateRepresentativeStolenData(); return this.requests.filter((request) => request.hasMark());
this.representativeStolenData.forEach((entry) => { }
entry.autoMark();
}); getFullHosts() {
} return unique(
this.requests
.map((request) => allSubhosts(request.getHost()))
.reduce((a, b) => a.concat(b), [])
);
}
hasMarks() {
return this.requests.some((request) => request.hasMark());
}
getMarkedEntries(): StolenDataEntry[] {
return this.requests
.map((request) => request.getMarkedEntries())
.reduce(reduceConcat, []);
}
exposesOrigin() {
return this.requests.some((request) => request.exposesOrigin());
}
autoMark() {
this.calculateRepresentativeStolenData();
this.representativeStolenData.forEach((entry) => {
entry.autoMark();
});
}
} }

View File

@ -5,10 +5,12 @@
text-rendering: optimizelegibility; text-rendering: optimizelegibility;
font-smooth: auto; font-smooth: auto;
-webkit-font-smoothing: auto; -webkit-font-smoothing: auto;
user-select: none;
} }
html { html {
font-size: 1rem; font-size: 1rem;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
} }
button { button {
@ -38,7 +40,7 @@ select {
#app { #app {
user-select: text; user-select: text;
padding: 0.5rem 1rem; padding: 0rem 1rem;
display: flex; display: flex;
flex-flow: column; flex-flow: column;
justify-content: flex-start; justify-content: flex-start;

View File

@ -4,8 +4,12 @@ header {
display: grid; display: grid;
grid-template-columns: 8rem 1fr 1rem; grid-template-columns: 8rem 1fr 1rem;
max-height: 4rem; max-height: 4rem;
padding-top: 0.5rem;
padding-bottom: 0.5rem; padding-bottom: 0.5rem;
border-bottom: 1px solid $light-grey; border-bottom: 1px solid $light-grey;
position: sticky;
top: 0;
background: #fff;
.webpage-metadata { .webpage-metadata {
word-break: break-all; word-break: break-all;
@ -31,5 +35,37 @@ header {
border: none; border: none;
background: transparent; background: transparent;
cursor: pointer; cursor: pointer;
padding: 0;
}
}
nav {
padding: 0.25rem 0;
border-bottom: 1px solid $light-grey;
button {
border: none;
cursor: pointer;
color: $mid-grey;
padding: 0.25rem 0rem;
display: flex;
flex-wrap: nowrap;
line-height: 1rem;
line-height: 1.5rem;
background: #fff;
width: 100%;
&:hover {
color: #000;
text-decoration: underline;
svg path {
fill: #000;
}
}
span {
padding-left: 0.5rem;
font-size: 0.875rem;
}
} }
} }

View File

@ -2,9 +2,14 @@ import React, { Fragment, useEffect, useState } from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import Options from '../options'; import Options from '../options';
import { StolenData } from './stolen-data'; import { StolenData } from './stolen-data';
import { useEmitter } from '../util'; import { getshorthost, useEmitter } from '../util';
import { getMemory } from '../memory'; import { getMemory } from '../memory';
import InfoCircle from '../assets/icons/info_circle_outline.svg'; import { RequestCluster } from '../request-cluster';
import InfoCircleIcon from '../assets/icons/info_circle_outline.svg';
import SettingsIcon from '../assets/icons/settings.svg';
import TrashIcon from '../assets/icons/trash_full.svg';
import MailIcon from '../assets/icons/mail.svg';
import ShortLeftIcon from '../assets/icons/short_left.svg';
async function getCurrentTab() { async function getCurrentTab() {
const [tab] = await browser.tabs.query({ const [tab] = await browser.tabs.query({
@ -64,14 +69,54 @@ const Sidebar = () => {
{origin} {origin}
</span> </span>
</div> </div>
<a href="https://internet-czas-dzialac.pl"> {stolenDataView ? (
<InfoCircle /> <a href="https://internet-czas-dzialac.pl">
</a> <InfoCircleIcon />
</a>
) : (
<button onClick={() => setStolenDataView(true)}>
<ShortLeftIcon />
</button>
)}
</header> </header>
<nav> <nav>
<button onClick={() => setStolenDataView(!stolenDataView)}> <button onClick={() => setStolenDataView(!stolenDataView)}>
{stolenDataView ? 'Options' : 'Data'} {/* {stolenDataView ? 'Options' : 'Data'}
*/}
<SettingsIcon />
<span>Ustawienia wtyczki</span>
</button>
<button
onClick={() => {
getMemory().removeCookiesFor(
origin,
getshorthost(new URL(origin).host)
);
}}
>
{/* {stolenDataView ? 'Options' : 'Data'}
*/}
<TrashIcon />
<span>Wyczyść ciasteczka tej domeny</span>
</button>
<button
// disabled={RequestCluster.hasMarks()}
onClick={() => {
const params = [
'height=' + screen.height,
'width=' + screen.width,
'fullscreen=yes',
].join(',');
window.open(
`/report-window/report-window.html?origin=${origin}`,
'new_window',
params
);
}}
>
<MailIcon />
<span>Utwórz wiadomość dla administratora tej witryny</span>
</button> </button>
</nav> </nav>

View File

@ -1,93 +1,94 @@
import React from "react"; import React from 'react';
import { RequestCluster } from "../request-cluster"; import { RequestCluster } from '../request-cluster';
import StolenDataCluster from "./stolen-data-cluster"; import StolenDataCluster from './stolen-data-cluster';
import { getshorthost } from "../util"; import { getshorthost } from '../util';
import { getMemory } from "../memory"; import { getMemory } from '../memory';
export function StolenData({ export function StolenData({
origin, origin,
minValueLength, minValueLength,
refreshToken, refreshToken,
refresh, refresh,
cookiesOnly, cookiesOnly,
cookiesOrOriginOnly, cookiesOrOriginOnly,
}: { }: {
origin: string; origin: string;
refreshToken: number; refreshToken: number;
refresh: () => void; refresh: () => void;
minValueLength: number; minValueLength: number;
cookiesOnly: boolean; cookiesOnly: boolean;
cookiesOrOriginOnly: boolean; cookiesOrOriginOnly: boolean;
}) { }) {
if (!origin) { if (!origin) {
return <div></div>; return <div></div>;
} }
const clusters = Object.values(getMemory().getClustersForOrigin(origin)) const clusters = Object.values(getMemory().getClustersForOrigin(origin))
.sort(RequestCluster.sortCompare) .sort(RequestCluster.sortCompare)
.filter((cluster) => !cookiesOnly || cluster.hasCookies()) .filter((cluster) => !cookiesOnly || cluster.hasCookies())
.filter( .filter(
(cluster) => (cluster) =>
!cookiesOrOriginOnly || cluster.hasCookies() || cluster.exposesOrigin() !cookiesOrOriginOnly ||
cluster.hasCookies() ||
cluster.exposesOrigin()
);
return (
<div style={{ padding: '5px' }}>
<div>
{/* <button
style={{ marginLeft: '1rem' }}
onClick={() =>
getMemory().removeCookiesFor(
origin,
getshorthost(new URL(origin).host)
)
}
>
Wyczyść cookiesy 1st party
</button>
<button
style={{ marginLeft: '1rem' }}
onClick={() => {
getMemory().removeRequestsFor(origin);
refresh();
}}
>
Wyczyść pamięć
</button> */}
<button
onClick={() =>
clusters.forEach((cluster) => cluster.autoMark())
}
>
Zaznacz automatycznie
</button>
{/* <button
style={{ marginLeft: '1rem' }}
onClick={() =>
window.open(
`/report-window/report-window.html?origin=${origin}`,
'new_window',
'width=800,height=600'
)
}
>
Generuj maila
</button> */}
{clusters.map((cluster) => {
return (
<StolenDataCluster
origin={origin}
shorthost={cluster.id}
key={cluster.id + origin}
refreshToken={refreshToken}
minValueLength={minValueLength}
cookiesOnly={cookiesOnly}
cookiesOrOriginOnly={cookiesOrOriginOnly}
/>
);
})}
</div>
</div>
); );
return (
<div style={{ padding: "5px" }}>
{" "}
<div>
<h1>
{origin}
<button
style={{ marginLeft: "1rem" }}
onClick={() =>
getMemory().removeCookiesFor(
origin,
getshorthost(new URL(origin).host)
)
}
>
Wyczyść cookiesy 1st party
</button>
<button
style={{ marginLeft: "1rem" }}
onClick={() => {
getMemory().removeRequestsFor(origin);
refresh();
}}
>
Wyczyść pamięć
</button>
<button
onClick={() => clusters.forEach((cluster) => cluster.autoMark())}
>
Zaznacz automatycznie
</button>
<button
style={{ marginLeft: "1rem" }}
onClick={() =>
window.open(
`/report-window/report-window.html?origin=${origin}`,
"new_window",
"width=800,height=600"
)
}
>
Generuj maila
</button>
</h1>
{clusters.map((cluster) => {
return (
<StolenDataCluster
origin={origin}
shorthost={cluster.id}
key={cluster.id + origin}
refreshToken={refreshToken}
minValueLength={minValueLength}
cookiesOnly={cookiesOnly}
cookiesOrOriginOnly={cookiesOrOriginOnly}
/>
);
})}
</div>
</div>
);
} }