From b92a472569feb2cb10a9c3bc224e3740a8572419 Mon Sep 17 00:00:00 2001 From: Arkadiusz Wieczorek Date: Sun, 24 Apr 2022 22:11:33 +0200 Subject: [PATCH] Update designs --- assets/icons/bulb.svg | 2 +- assets/icons/file_find.svg | 2 +- assets/icons/file_minus.svg | 2 +- components/report-window/deduce-problems.tsx | 20 +- components/report-window/email-content.tsx | 88 +- components/report-window/explainers.tsx | 20 +- .../generate-survey-questions.ts | 750 +++++++++--------- components/report-window/har-converter.tsx | 28 +- components/report-window/parse-answers.ts | 98 +-- .../problems/no-information-at-all.tsx | 75 +- components/report-window/problems/problem.tsx | 52 +- .../problems/unlawful-cookies.tsx | 335 ++++---- .../report-window/problems/unlawful-data.tsx | 43 +- components/report-window/raw-answers.ts | 100 +-- components/report-window/report-window.tsx | 124 +-- components/report-window/verbs.ts | 76 +- components/sidebar/sidebar.scss | 43 +- components/sidebar/sidebar.tsx | 76 +- components/sidebar/stolen-data-cluster.scss | 1 + components/sidebar/stolen-data-cluster.tsx | 26 +- components/toolbar/toolbar.tsx | 20 + options.tsx | 168 ++-- 22 files changed, 1107 insertions(+), 1042 deletions(-) diff --git a/assets/icons/bulb.svg b/assets/icons/bulb.svg index f322749..5854fd3 100644 --- a/assets/icons/bulb.svg +++ b/assets/icons/bulb.svg @@ -1,3 +1,3 @@ - + diff --git a/assets/icons/file_find.svg b/assets/icons/file_find.svg index 568052d..a8ec8bb 100644 --- a/assets/icons/file_find.svg +++ b/assets/icons/file_find.svg @@ -1,3 +1,3 @@ - + diff --git a/assets/icons/file_minus.svg b/assets/icons/file_minus.svg index f841b0f..5bf1356 100644 --- a/assets/icons/file_minus.svg +++ b/assets/icons/file_minus.svg @@ -1,3 +1,3 @@ - + diff --git a/components/report-window/deduce-problems.tsx b/components/report-window/deduce-problems.tsx index 48e9a07..6694be7 100644 --- a/components/report-window/deduce-problems.tsx +++ b/components/report-window/deduce-problems.tsx @@ -5,15 +5,15 @@ import { Problem } from './problems/problem'; import { UnlawfulCookieAccess } from './problems/unlawful-cookies'; export default function deduceProblems( - answers: ParsedAnswers, - clusters: Record + answers: ParsedAnswers, + clusters: Record ): Problem[] { - const problems = []; - if (answers.popup_type === 'none') { - problems.push(new NoInformationAtAllProblem(answers, clusters)); - } - if (UnlawfulCookieAccess.qualifies(answers, Object.values(clusters))) { - problems.push(new UnlawfulCookieAccess(answers, clusters)); - } - return problems; + const problems = []; + if (answers.popup_type === 'none') { + problems.push(new NoInformationAtAllProblem(answers, clusters)); + } + if (UnlawfulCookieAccess.qualifies(answers, Object.values(clusters))) { + problems.push(new UnlawfulCookieAccess(answers, clusters)); + } + return problems; } diff --git a/components/report-window/email-content.tsx b/components/report-window/email-content.tsx index 9b61637..b2ae6b8 100644 --- a/components/report-window/email-content.tsx +++ b/components/report-window/email-content.tsx @@ -9,50 +9,50 @@ declare var PLUGIN_NAME: string; declare var PLUGIN_URL: string; export default function EmailContent({ - answers, - visited_url, - clusters, + answers, + visited_url, + clusters, }: { - answers: ParsedAnswers; - visited_url: string; - clusters: Record; + answers: ParsedAnswers; + visited_url: string; + clusters: Record; }) { - const _ = (key: string) => v(key, answers.zaimek); - const problems = deduceProblems(answers, clusters); - const explainers = Array.from( - new Set( - problems - .map((problem) => problem.getNecessaryExplainers()) - .reduce((a, b) => a.concat(b), []) - ) - ).map((explainer_key) => Explainers[explainer_key]); - return ( -
-
{JSON.stringify(answers, null, 3)}
-

Dzień dobry,

-

- w dniu {getDate()} {_('odwiedziłem')} stronę {visited_url}. Po podejrzeniu ruchu - sieciowego generowanego przez tę stronę za pomocą wtyczki{' '} - {PLUGIN_NAME} w przeglądarce Firefox {_('mam')} pytania - dotyczące przetwarzania {_('moich')} danych osobowych, na które nie {_('znalazłem')}{' '} - odpowiedzi nigdzie na Państwa stronie. -

- {problems.map((problem) => problem.getEmailContent())} - {explainers.map((explainer) => explainer(answers.zaimek))} -

Państwa rola jako współadministratora danych osobowych

-

- {_('Zwracam')} Państwa uwagę na fakt, że w myśl{' '} - - treści wyroku TSUE w sprawie C-40/17 - {' '} - poprzez wysyłanie moich danych w wyżej opisanym zakresie stają się Państwo - współadministratorem moich danych osobowych, dlatego ciąży na Państwu obowiązek - odpowiedzi na moje pytania na mocy Art. 12 i 13 Rozporządzenia 2016/679 Parlamentu - Europejskiego i Rady (UE) z dnia 27 kwietnia 2016 r. w sprawie ochrony osób fizycznych w - związku z przetwarzaniem danych osobowych i w sprawie swobodnego przepływu takich danych - oraz uchylenia dyrektywy 95/46/WE (ogólne rozporządzenie o ochronie danych, dalej: - „RODO”). -

-
- ); + const _ = (key: string) => v(key, answers.zaimek); + const problems = deduceProblems(answers, clusters); + const explainers = Array.from( + new Set( + problems + .map((problem) => problem.getNecessaryExplainers()) + .reduce((a, b) => a.concat(b), []) + ) + ).map((explainer_key) => Explainers[explainer_key]); + return ( +
+
{JSON.stringify(answers, null, 3)}
+

Dzień dobry,

+

+ w dniu {getDate()} {_('odwiedziłem')} stronę {visited_url}. Po podejrzeniu ruchu + sieciowego generowanego przez tę stronę za pomocą wtyczki{' '} + {PLUGIN_NAME} w przeglądarce Firefox {_('mam')} pytania + dotyczące przetwarzania {_('moich')} danych osobowych, na które nie {_('znalazłem')}{' '} + odpowiedzi nigdzie na Państwa stronie. +

+ {problems.map((problem) => problem.getEmailContent())} + {explainers.map((explainer) => explainer(answers.zaimek))} +

Państwa rola jako współadministratora danych osobowych

+

+ {_('Zwracam')} Państwa uwagę na fakt, że w myśl{' '} + + treści wyroku TSUE w sprawie C-40/17 + {' '} + poprzez wysyłanie moich danych w wyżej opisanym zakresie stają się Państwo + współadministratorem moich danych osobowych, dlatego ciąży na Państwu obowiązek + odpowiedzi na moje pytania na mocy Art. 12 i 13 Rozporządzenia 2016/679 Parlamentu + Europejskiego i Rady (UE) z dnia 27 kwietnia 2016 r. w sprawie ochrony osób + fizycznych w związku z przetwarzaniem danych osobowych i w sprawie swobodnego + przepływu takich danych oraz uchylenia dyrektywy 95/46/WE (ogólne rozporządzenie o + ochronie danych, dalej: „RODO”). +

+
+ ); } diff --git a/components/report-window/explainers.tsx b/components/report-window/explainers.tsx index e7cc86c..8ca10f2 100644 --- a/components/report-window/explainers.tsx +++ b/components/report-window/explainers.tsx @@ -1,14 +1,14 @@ export type ExplainerKey = 'cookies_are_pii'; export const Explainers: Record JSX.Element> = { - cookies_are_pii: () => ( - <> -

Ciasteczka stanowią dane osobowe

-

- Sztucznie wygenerowane identyfikatory przechowywane w plikach Cookies stanowią dane - osobowe. Wskazuje na to wprost Art. 4. pkt 1. RODO, wymieniając „identyfikator - internetowy” i „numer identyfikacyjny” jako przykłady danych osobowych. -

- - ), + cookies_are_pii: () => ( + <> +

Ciasteczka stanowią dane osobowe

+

+ Sztucznie wygenerowane identyfikatory przechowywane w plikach Cookies stanowią dane + osobowe. Wskazuje na to wprost Art. 4. pkt 1. RODO, wymieniając „identyfikator + internetowy” i „numer identyfikacyjny” jako przykłady danych osobowych. +

+ + ), }; diff --git a/components/report-window/generate-survey-questions.ts b/components/report-window/generate-survey-questions.ts index 12fc78b..2485ce2 100644 --- a/components/report-window/generate-survey-questions.ts +++ b/components/report-window/generate-survey-questions.ts @@ -1,382 +1,382 @@ function generateHostPage( - host: string, - index: number, - all_hosts: string[] + host: string, + index: number, + all_hosts: string[] ): { title: string; elements: any[]; visibleIf: string } { - function f(name: string, h = host) { - return `${h.replace(/\./g, '_')}|${name}`; - } - const previous_host: string | null = index > 0 ? all_hosts[index - 1] : null; - function defaultValue(name: string) { - if (!previous_host) { - return {}; - } - return { defaultValueExpression: `{${f(name, previous_host)}}` }; - } - return { - title: host, - elements: [ - { - type: 'radiogroup', - name: f('present'), - isRequired: true, - title: `Cel ujawnienia danych właścicielowi domeny ${host}`, - ...defaultValue('present'), - visibleIf: '{popup_type} != "none"', - choices: [ - { - value: 'not_mentioned', - text: 'nie jest podany nigdzie na stronie', - visibleIf: "{policy_readable} = 'yes' ", - }, - { - value: 'not_before_making_a_choice', - text: 'nie jest podany w żadnym miejscu na stronie, do którego można się dostać bez podejmowania wyboru dotyczącego przetwarzania danych osobowych', - }, - { - value: 'mentioned_in_policy', - text: 'jest podany w polityce prywatności', - visibleIf: "{policy_readable} = 'yes' ", - }, + function f(name: string, h = host) { + return `${h.replace(/\./g, '_')}|${name}`; + } + const previous_host: string | null = index > 0 ? all_hosts[index - 1] : null; + function defaultValue(name: string) { + if (!previous_host) { + return {}; + } + return { defaultValueExpression: `{${f(name, previous_host)}}` }; + } + return { + title: host, + elements: [ + { + type: 'radiogroup', + name: f('present'), + isRequired: true, + title: `Cel ujawnienia danych właścicielowi domeny ${host}`, + ...defaultValue('present'), + visibleIf: '{popup_type} != "none"', + choices: [ + { + value: 'not_mentioned', + text: 'nie jest podany nigdzie na stronie', + visibleIf: "{policy_readable} = 'yes' ", + }, + { + value: 'not_before_making_a_choice', + text: 'nie jest podany w żadnym miejscu na stronie, do którego można się dostać bez podejmowania wyboru dotyczącego przetwarzania danych osobowych', + }, + { + value: 'mentioned_in_policy', + text: 'jest podany w polityce prywatności', + visibleIf: "{policy_readable} = 'yes' ", + }, - { - value: 'mentioned_in_popup', - text: 'jest podany w okienku RODO', - visibleIf: "{popup_type} != 'none' ", - }, - ], - }, - { - type: 'radiogroup', - name: f('legal_basis_type'), - ...defaultValue('legal_basis_type'), - isRequired: true, - title: `Podstawa prawna dla tego konkretnego celu`, - visibleIf: `{${f('present')}} notempty and {${f( - 'present' - )}} != "not_mentioned" and {${f('present')}} != "not_before_making_a_choice"`, - choices: [ - { value: 'consent', text: 'to zgoda.' }, - { - value: 'legitimate_interest', - text: 'to uzasadniony interes.', - }, - { value: 'not_mentioned', text: 'nie jest wskazana nigdzie na stronie.' }, - ], - }, - { - type: 'radiogroup', - name: f('consent_problems'), - ...defaultValue('consent_problems'), - isRequired: true, - title: `Jak ma się ta podstawa prawna do stanu faktycznego?`, - visibleIf: `{${f('legal_basis_type')}} = "consent"`, - defaultValueExpression: - 'iif({popup_action} = "none" or {popup_action} = "closed_popup", "claims_consent_but_sends_before_consent", iif({popup_action} = "accept_all" and {rejection_is_hard} = "yes", "claims_consent_but_there_was_no_easy_refuse", ""))', - choices: [ - { - value: 'claims_consent_but_sends_before_consent', - text: `Strona wysłała {moje} dane do ${host} zanim {wyraziłem} na to zgodę`, - }, - { - value: 'claims_consent_but_there_was_no_easy_refuse', - text: '{Kliknąłem} przycisk od wyrażania zgody, ale w okienku o zgodę nie było natychmiastowo dostępnego przycisku do niewyrażenia zgody jednym kliknięciem', - }, - { value: 'none', text: 'żadne z powyższych.' }, - ], - }, - { - type: 'radiogroup', - name: f('legitimate_interest_activity_specified'), - ...defaultValue('legitimate_interest_activity_specified'), - isRequired: true, - title: /* HTML */ `Czy administrator strony opisał szczegółowo, na czym polega - uzasadniony interes w kontekście tego celu?`, - visibleIf: `{${f('legal_basis_type')}} = "legitimate_interest"`, - choices: [ - { - value: 'precise', - text: /* HTML */ `Tak, wskazuje jasno na bieżące działania lub korzyści wynikające - z takiego przetwarzania danych.`, - }, - { - value: 'vague', - text: `Wskazuje tylko ogólnie, jak np. „marketing” czy „statystyki”.`, - }, - { - value: 'no', - text: `Nie. Nie wiadomo, na czym ten uzasadniony interes polega.`, - }, - ], - }, - { - type: 'text', - title: `Jak administrator opisał to, na czym polega uzasadniony interes w kontekście ${host}?`, - name: f('legitimate_interest_description'), - visibleIf: `{${f('legitimate_interest_activity_specified')}} = 'vague'`, - placeholder: 'marketing', - defaultValueExpression: - index == 0 - ? 'marketing' - : `{${f('legitimate_interest_description', previous_host)}}`, - }, - { - type: 'radiogroup', - title: `Czy domena ${host} należy do podmiotu spoza Europy (np. Google, Facebook)?`, - name: f('outside_eu'), - ...defaultValue('outside_eu'), - visibleIf: `{${f('legitimate_interest_activity_specified')}} = "precise" or {${f( - 'consent_problems' - )}} = "none"`, - choices: [ - { value: 'yes', text: 'Tak' }, - { value: 'no', text: 'Nie' }, - { value: 'not_sure', text: 'Nie wiem' }, - ], - }, - { - type: 'radiogroup', - title: `Czy w {Twojej} ocenie wysłanie {Twoich} danych do właściciela domeny ${host} było konieczne do świadczenia zażądanej przez {Ciebie} usługi drogą elektroniczną?`, - name: f('was_processing_necessary'), - ...defaultValue('was_processing_necessary'), - visibleIf: `{${f('legal_basis_type')}} = "legitimate_interest" or {${f( - 'present' - )}} = "not_mentioned" or {popup_type} = "none"`, - choices: [ - { value: 'yes', text: 'Tak, było konieczne' }, - { value: 'no', text: 'Nie, nie było konieczne' }, - { value: 'not_sure', text: 'Nie mam zdania' }, - ], - }, - ], - }; + { + value: 'mentioned_in_popup', + text: 'jest podany w okienku RODO', + visibleIf: "{popup_type} != 'none' ", + }, + ], + }, + { + type: 'radiogroup', + name: f('legal_basis_type'), + ...defaultValue('legal_basis_type'), + isRequired: true, + title: `Podstawa prawna dla tego konkretnego celu`, + visibleIf: `{${f('present')}} notempty and {${f( + 'present' + )}} != "not_mentioned" and {${f('present')}} != "not_before_making_a_choice"`, + choices: [ + { value: 'consent', text: 'to zgoda.' }, + { + value: 'legitimate_interest', + text: 'to uzasadniony interes.', + }, + { value: 'not_mentioned', text: 'nie jest wskazana nigdzie na stronie.' }, + ], + }, + { + type: 'radiogroup', + name: f('consent_problems'), + ...defaultValue('consent_problems'), + isRequired: true, + title: `Jak ma się ta podstawa prawna do stanu faktycznego?`, + visibleIf: `{${f('legal_basis_type')}} = "consent"`, + defaultValueExpression: + 'iif({popup_action} = "none" or {popup_action} = "closed_popup", "claims_consent_but_sends_before_consent", iif({popup_action} = "accept_all" and {rejection_is_hard} = "yes", "claims_consent_but_there_was_no_easy_refuse", ""))', + choices: [ + { + value: 'claims_consent_but_sends_before_consent', + text: `Strona wysłała {moje} dane do ${host} zanim {wyraziłem} na to zgodę`, + }, + { + value: 'claims_consent_but_there_was_no_easy_refuse', + text: '{Kliknąłem} przycisk od wyrażania zgody, ale w okienku o zgodę nie było natychmiastowo dostępnego przycisku do niewyrażenia zgody jednym kliknięciem', + }, + { value: 'none', text: 'żadne z powyższych.' }, + ], + }, + { + type: 'radiogroup', + name: f('legitimate_interest_activity_specified'), + ...defaultValue('legitimate_interest_activity_specified'), + isRequired: true, + title: /* HTML */ `Czy administrator strony opisał szczegółowo, na czym polega + uzasadniony interes w kontekście tego celu?`, + visibleIf: `{${f('legal_basis_type')}} = "legitimate_interest"`, + choices: [ + { + value: 'precise', + text: /* HTML */ `Tak, wskazuje jasno na bieżące działania lub korzyści + wynikające z takiego przetwarzania danych.`, + }, + { + value: 'vague', + text: `Wskazuje tylko ogólnie, jak np. „marketing” czy „statystyki”.`, + }, + { + value: 'no', + text: `Nie. Nie wiadomo, na czym ten uzasadniony interes polega.`, + }, + ], + }, + { + type: 'text', + title: `Jak administrator opisał to, na czym polega uzasadniony interes w kontekście ${host}?`, + name: f('legitimate_interest_description'), + visibleIf: `{${f('legitimate_interest_activity_specified')}} = 'vague'`, + placeholder: 'marketing', + defaultValueExpression: + index == 0 + ? 'marketing' + : `{${f('legitimate_interest_description', previous_host)}}`, + }, + { + type: 'radiogroup', + title: `Czy domena ${host} należy do podmiotu spoza Europy (np. Google, Facebook)?`, + name: f('outside_eu'), + ...defaultValue('outside_eu'), + visibleIf: `{${f('legitimate_interest_activity_specified')}} = "precise" or {${f( + 'consent_problems' + )}} = "none"`, + choices: [ + { value: 'yes', text: 'Tak' }, + { value: 'no', text: 'Nie' }, + { value: 'not_sure', text: 'Nie wiem' }, + ], + }, + { + type: 'radiogroup', + title: `Czy w {Twojej} ocenie wysłanie {Twoich} danych do właściciela domeny ${host} było konieczne do świadczenia zażądanej przez {Ciebie} usługi drogą elektroniczną?`, + name: f('was_processing_necessary'), + ...defaultValue('was_processing_necessary'), + visibleIf: `{${f('legal_basis_type')}} = "legitimate_interest" or {${f( + 'present' + )}} = "not_mentioned" or {popup_type} = "none"`, + choices: [ + { value: 'yes', text: 'Tak, było konieczne' }, + { value: 'no', text: 'Nie, nie było konieczne' }, + { value: 'not_sure', text: 'Nie mam zdania' }, + ], + }, + ], + }; } export default function generateSurveyQuestions(hosts: string[]) { - return { - showQuestionNumbers: 'off', - showProgressBar: 'top', - clearInvisibleValues: 'onHidden', - pages: [ - { - title: 'Zaimki', - elements: [ - { - type: 'radiogroup', - name: 'zaimek', - title: 'Forma czasownika:', - isRequired: true, - choices: [ - { value: 0, text: 'Wysłałem' }, - { value: 1, text: 'Wysłałam' }, - { value: 2, text: 'Wysłałom' }, - { value: 3, text: 'Wysłaliśmy' }, - ], - }, - ], - }, - { - title: 'Obowiązek informacyjny i machanizm pozyskiwania zgody', - elements: [ - { - type: 'radiogroup', - title: 'Jaką formę informacji o przetwarzaniu danych osobowych stosuje ta strona?', - name: 'popup_type', - isRequired: true, - choices: [ - { value: 'none', text: 'Brak informacji' }, - { - value: 'page', - text: 'Tylko w postaci tekstu na podstronie np. "prywatność" lub "polityka cookies"', - }, - { - value: 'passive_popup', - text: /* HTML */ `Okienko o cookiesach, bez możliwości podjęcia żadnego - wyboru (np. tylko opcja „zamknij”)`, - }, - { - value: 'some_choice', - text: 'Okienko o cookiesach, z możliwością podjęcia wyboru', - }, - ], - }, - { - type: 'checkbox', - title: /* HTML */ `Istnieje możliwość, że okienko z informacjami i wyborami - dotyczącymi przetwarzania {Twoich} danych osobowych ukazało się dawno temu w - trakcie {twojej} wcześniejszej wizyty i wtedy je {odkliknąłeś}. {Otwórz} tę samą - stronę w Trybie Prywatnym (Incognito). Co {widzisz}?`, - visibleIf: "{popup_type} = 'none' or {popup_type} = 'page'", - name: 'is_incognito_different', - isRequired: true, - choices: [ - { - value: 'incognito_is_the_same', - text: 'W Trybie prywatnym {widzę} to samo, co {widziałem} w normalnym trybie', - }, - ], - }, - { - type: 'html', - visibleIf: - '{is_incognito_different} != "no" and ({popup_type} = "none" or {popup_type} = "page") ', - html: /* HTML */ `Jeżeli w trybie incognito widzisz więcej okienek z informacjami - o przetwarzaniu danych osobowych, wykonaj analizę w normalnym trybie ponownie - - ale najpierw usuń pliki cookies tej strony. - - Zobacz, jak to zrobić - `, - }, - { - type: 'radiogroup', - name: 'mentions_passive_consent', - isRequired: true, - visibleIf: '{popup_type} = "passive_popup"', - title: 'Czy treść okienka wskazuje na zgodę wyrażoną pasywnie, np. „Korzystając z naszej strony wyrażasz zgodę”, „Brak zmiany ustawień przeglądarki oznacza zgodę”, „Klikając przycisk "X" (zamknij) wyrażasz zgodę”?', - choices: [ - { - value: 'yes', - text: 'Tak', - }, - { - value: 'no', - text: 'Nie', - }, - ], - }, - { - type: 'text', - name: 'passive_consent_description', - isRequired: true, - visibleIf: '{mentions_passive_consent} = "yes"', - title: 'Jakimi słowami administrator opisuje to pasywne wyrażenie zgody? Zacytuj wprost. Na przykład: „Korzystając ze strony wyrażasz zgodę”, albo „Pozostawiając ustawienia przeglądarki bez zmian (..) wyrażasz zgodę”', - defaultValue: 'Korzystając ze strony wyrażasz zgodę', - }, - { - type: 'radiogroup', - name: 'cookie_wall', - isRequired: true, - visibleIf: '{popup_type} = "passive_popup"', - title: 'Czy treść strony jest wygodnie czytelna bez odkliknięcia tego okienka o RODO?', - choices: [ - { - value: 'no', // wiem, że tu jest "no", a odpowiedź brzmi "tak" - ale nazwa pytania dotyczy obecności cookie walla - text: 'Tak, jest czytelna', - }, - { - value: 'yes', - text: 'Nie. Jest zupełnie niewidoczna albo jest przesłonięta w stopniu uniemożliwiającym lub znacznie utrudniającym czytanie treści strony.', - }, - ], - }, - { - type: 'radiogroup', - name: 'rejection_is_hard', - isRequired: true, - visibleIf: '{popup_type} = "some_choice"', - title: 'Czy wyrażenie zgody na wszystkie cele jest dokładnie tak samo łatwe, jak odmowa zgody na wszystkie cele?', - choices: [ - { - value: 'no', // wiem, że tu jest "no", a odpowiedź brzmi "tak" - ale nazwa pytania dotyczy braku równowagi - text: 'Tak. Opcja odmowy zgody na wszystkie cele jest równie widoczna i łatwo dostępna, co opcja wyrażenia zgody.', - }, - { - 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.', - }, - ], - }, - { - type: 'radiogroup', - name: 'popup_action', - isRequired: true, - visibleIf: '{popup_type} = "some_choice" or {popup_type} = "passive_popup"', - title: 'Jaką akcję {podjąłeś} w ramach wyskakującego okienka?', - choices: [ - { - value: 'none', - text: 'Nic nie {kliknąłem}', - }, - { - value: 'closed_popup', - text: '{Zamknąłem} okienko za pomocą przycisku „X” lub „Zamknij”, lub podobnego', - }, - { - value: 'accept_all', - text: '{Kliknąłem} przycisk od akceptacji wszystkich zgód', - }, - { - value: 'deny_all', - text: '{Odmówiłem} wyrażenia zgody na wszystkie cele', - }, - { - value: 'other', - text: 'Coś innego', - }, - ], - }, - { - type: 'text', - name: 'popup_closed_how', - isRequired: true, - visibleIf: '{popup_action} = "closed_popup"', - title: 'W jaki sposób {zamknąłeś} okienko o zgodę? Opisz pełnym zdaniem', - defaultValueExpression: '{Kliknąłem} przycisk „X”.', - }, - { - type: 'text', - name: 'popup_deny_all_how', - isRequired: true, - visibleIf: '{popup_action} = "deny_all"', - title: 'W jaki sposób {zamknąłeś} okienko o zgodę? Opisz pełnym zdaniem, np.: „{Kliknąłem} przycisk ” lub „{Odznaczyłem} wszystkie opcje w ustawieniach zaawansowanych”', - defaultValueExpression: '{Kliknąłem} przycisk „odmawiam wyrażenia zgody”.', - }, - { - type: 'radiogroup', - name: 'administrator_identity_available_before_choice', - isRequired: true, - visibleIf: '{popup_type} = "some_choice"', - title: 'Czy przed podjęciem wyboru dot. {Twoich} danych masz możliwość poznać tożsamość administratora strony?', - choices: [ - { - value: 'yes', - text: 'Tak.', - }, - { - value: 'no', - text: 'Nie.', - }, - ], - }, - ], - }, - { - title: 'Obowiązek informacyjny, polityka prywatności', - visibleIf: "{popup_type} != 'none'", - elements: [ - { - type: 'radiogroup', - title: 'Czy polityka prywatności jest dostępna i czytelna?', - name: 'policy_readable', - isRequired: true, - choices: [ - { value: 'yes', text: 'dostępna i czytelna' }, - { - value: 'entirely_obscured_by_popup', - text: 'dostępna, ale nieczytelna. Zasłania ją całkowicie lub prawie całkowicie popup o RODO lub nie można się do niej doklikać bez podjęcia wyboru w okienku', - }, - { - value: 'cant_find', - text: `Niedostępna. {Szukałem}, ale nie {znalazłem} jej na stronie`, - }, - ], - }, - ], - }, - ...hosts.map(generateHostPage), - ], - }; + return { + showQuestionNumbers: 'off', + showProgressBar: 'top', + clearInvisibleValues: 'onHidden', + pages: [ + { + title: 'Zaimki', + elements: [ + { + type: 'radiogroup', + name: 'zaimek', + title: 'Forma czasownika:', + isRequired: true, + choices: [ + { value: 0, text: 'Wysłałem' }, + { value: 1, text: 'Wysłałam' }, + { value: 2, text: 'Wysłałom' }, + { value: 3, text: 'Wysłaliśmy' }, + ], + }, + ], + }, + { + title: 'Obowiązek informacyjny i machanizm pozyskiwania zgody', + elements: [ + { + type: 'radiogroup', + title: 'Jaką formę informacji o przetwarzaniu danych osobowych stosuje ta strona?', + name: 'popup_type', + isRequired: true, + choices: [ + { value: 'none', text: 'Brak informacji' }, + { + value: 'page', + text: 'Tylko w postaci tekstu na podstronie np. "prywatność" lub "polityka cookies"', + }, + { + value: 'passive_popup', + text: /* HTML */ `Okienko o cookiesach, bez możliwości podjęcia + żadnego wyboru (np. tylko opcja „zamknij”)`, + }, + { + value: 'some_choice', + text: 'Okienko o cookiesach, z możliwością podjęcia wyboru', + }, + ], + }, + { + type: 'checkbox', + title: /* HTML */ `Istnieje możliwość, że okienko z informacjami i wyborami + dotyczącymi przetwarzania {Twoich} danych osobowych ukazało się dawno temu w + trakcie {twojej} wcześniejszej wizyty i wtedy je {odkliknąłeś}. {Otwórz} tę + samą stronę w Trybie Prywatnym (Incognito). Co {widzisz}?`, + visibleIf: "{popup_type} = 'none' or {popup_type} = 'page'", + name: 'is_incognito_different', + isRequired: true, + choices: [ + { + value: 'incognito_is_the_same', + text: 'W Trybie prywatnym {widzę} to samo, co {widziałem} w normalnym trybie', + }, + ], + }, + { + type: 'html', + visibleIf: + '{is_incognito_different} != "no" and ({popup_type} = "none" or {popup_type} = "page") ', + html: /* HTML */ `Jeżeli w trybie incognito widzisz więcej okienek z + informacjami o przetwarzaniu danych osobowych, wykonaj analizę w + normalnym trybie ponownie - ale najpierw usuń pliki cookies tej strony. + + Zobacz, jak to zrobić + `, + }, + { + type: 'radiogroup', + name: 'mentions_passive_consent', + isRequired: true, + visibleIf: '{popup_type} = "passive_popup"', + title: 'Czy treść okienka wskazuje na zgodę wyrażoną pasywnie, np. „Korzystając z naszej strony wyrażasz zgodę”, „Brak zmiany ustawień przeglądarki oznacza zgodę”, „Klikając przycisk "X" (zamknij) wyrażasz zgodę”?', + choices: [ + { + value: 'yes', + text: 'Tak', + }, + { + value: 'no', + text: 'Nie', + }, + ], + }, + { + type: 'text', + name: 'passive_consent_description', + isRequired: true, + visibleIf: '{mentions_passive_consent} = "yes"', + title: 'Jakimi słowami administrator opisuje to pasywne wyrażenie zgody? Zacytuj wprost. Na przykład: „Korzystając ze strony wyrażasz zgodę”, albo „Pozostawiając ustawienia przeglądarki bez zmian (..) wyrażasz zgodę”', + defaultValue: 'Korzystając ze strony wyrażasz zgodę', + }, + { + type: 'radiogroup', + name: 'cookie_wall', + isRequired: true, + visibleIf: '{popup_type} = "passive_popup"', + title: 'Czy treść strony jest wygodnie czytelna bez odkliknięcia tego okienka o RODO?', + choices: [ + { + value: 'no', // wiem, że tu jest "no", a odpowiedź brzmi "tak" - ale nazwa pytania dotyczy obecności cookie walla + text: 'Tak, jest czytelna', + }, + { + value: 'yes', + text: 'Nie. Jest zupełnie niewidoczna albo jest przesłonięta w stopniu uniemożliwiającym lub znacznie utrudniającym czytanie treści strony.', + }, + ], + }, + { + type: 'radiogroup', + name: 'rejection_is_hard', + isRequired: true, + visibleIf: '{popup_type} = "some_choice"', + title: 'Czy wyrażenie zgody na wszystkie cele jest dokładnie tak samo łatwe, jak odmowa zgody na wszystkie cele?', + choices: [ + { + value: 'no', // wiem, że tu jest "no", a odpowiedź brzmi "tak" - ale nazwa pytania dotyczy braku równowagi + text: 'Tak. Opcja odmowy zgody na wszystkie cele jest równie widoczna i łatwo dostępna, co opcja wyrażenia zgody.', + }, + { + 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.', + }, + ], + }, + { + type: 'radiogroup', + name: 'popup_action', + isRequired: true, + visibleIf: '{popup_type} = "some_choice" or {popup_type} = "passive_popup"', + title: 'Jaką akcję {podjąłeś} w ramach wyskakującego okienka?', + choices: [ + { + value: 'none', + text: 'Nic nie {kliknąłem}', + }, + { + value: 'closed_popup', + text: '{Zamknąłem} okienko za pomocą przycisku „X” lub „Zamknij”, lub podobnego', + }, + { + value: 'accept_all', + text: '{Kliknąłem} przycisk od akceptacji wszystkich zgód', + }, + { + value: 'deny_all', + text: '{Odmówiłem} wyrażenia zgody na wszystkie cele', + }, + { + value: 'other', + text: 'Coś innego', + }, + ], + }, + { + type: 'text', + name: 'popup_closed_how', + isRequired: true, + visibleIf: '{popup_action} = "closed_popup"', + title: 'W jaki sposób {zamknąłeś} okienko o zgodę? Opisz pełnym zdaniem', + defaultValueExpression: '{Kliknąłem} przycisk „X”.', + }, + { + type: 'text', + name: 'popup_deny_all_how', + isRequired: true, + visibleIf: '{popup_action} = "deny_all"', + title: 'W jaki sposób {zamknąłeś} okienko o zgodę? Opisz pełnym zdaniem, np.: „{Kliknąłem} przycisk ” lub „{Odznaczyłem} wszystkie opcje w ustawieniach zaawansowanych”', + defaultValueExpression: '{Kliknąłem} przycisk „odmawiam wyrażenia zgody”.', + }, + { + type: 'radiogroup', + name: 'administrator_identity_available_before_choice', + isRequired: true, + visibleIf: '{popup_type} = "some_choice"', + title: 'Czy przed podjęciem wyboru dot. {Twoich} danych masz możliwość poznać tożsamość administratora strony?', + choices: [ + { + value: 'yes', + text: 'Tak.', + }, + { + value: 'no', + text: 'Nie.', + }, + ], + }, + ], + }, + { + title: 'Obowiązek informacyjny, polityka prywatności', + visibleIf: "{popup_type} != 'none'", + elements: [ + { + type: 'radiogroup', + title: 'Czy polityka prywatności jest dostępna i czytelna?', + name: 'policy_readable', + isRequired: true, + choices: [ + { value: 'yes', text: 'dostępna i czytelna' }, + { + value: 'entirely_obscured_by_popup', + text: 'dostępna, ale nieczytelna. Zasłania ją całkowicie lub prawie całkowicie popup o RODO lub nie można się do niej doklikać bez podjęcia wyboru w okienku', + }, + { + value: 'cant_find', + text: `Niedostępna. {Szukałem}, ale nie {znalazłem} jej na stronie`, + }, + ], + }, + ], + }, + ...hosts.map(generateHostPage), + ], + }; } diff --git a/components/report-window/har-converter.tsx b/components/report-window/har-converter.tsx index 9be4ea3..16fe731 100644 --- a/components/report-window/har-converter.tsx +++ b/components/report-window/har-converter.tsx @@ -11,13 +11,10 @@ function handleNewFile( const reader = new FileReader(); reader.addEventListener('load', () => { const content = JSON.parse(reader.result as string); - content.log.entries = content.log.entries.filter( - (har_entry: HAREntry) => - entries.some((entry) => entry.matchesHAREntry(har_entry)) - ); - setFiltered( - new Blob([JSON.stringify(content)], { type: 'application/json' }) + content.log.entries = content.log.entries.filter((har_entry: HAREntry) => + entries.some((entry) => entry.matchesHAREntry(har_entry)) ); + setFiltered(new Blob([JSON.stringify(content)], { type: 'application/json' })); }); reader.readAsText(element.files[0]); } @@ -30,10 +27,7 @@ function generateFakeHAR(entries: StolenDataEntry[]) { } else if (request1.shorthost > request2.shorthost) { return 1; } else { - return ( - request2.getBalancedPriority() - - request1.getBalancedPriority() - ); + return request2.getBalancedPriority() - request1.getBalancedPriority(); } }) .filter((_, index, array) => { @@ -43,10 +37,7 @@ function generateFakeHAR(entries: StolenDataEntry[]) { } return true; }) - .sort( - (entry1, entry2) => - entry2.getBalancedPriority() - entry1.getBalancedPriority() - ); + .sort((entry1, entry2) => entry2.getBalancedPriority() - entry1.getBalancedPriority()); return { log: { @@ -75,15 +66,10 @@ function generateFakeHAR(entries: StolenDataEntry[]) { }; } -export default function HARConverter({ - entries, -}: { - entries: StolenDataEntry[]; -}) { +export default function HARConverter({ entries }: { entries: StolenDataEntry[] }) { const [filtered, setFiltered] = React.useState(null); const [filename, setFilename] = React.useState(''); - const [fakeHAR, setFakeHAR] = - React.useState>(); + const [fakeHAR, setFakeHAR] = React.useState>(); React.useEffect(() => { setFakeHAR(generateFakeHAR(entries)); }, []); diff --git a/components/report-window/parse-answers.ts b/components/report-window/parse-answers.ts index 0005559..7aebc79 100644 --- a/components/report-window/parse-answers.ts +++ b/components/report-window/parse-answers.ts @@ -3,65 +3,65 @@ import RawAnswers, { BasicRawAnswers, HostRawAnswers } from './raw-answers'; export type RecordValue = T extends Record ? R : any; export type ParsedHostAnswers = ({ - present: - | 'not_mentioned' - | 'not_before_making_a_choice' - | 'mentioned_in_policy' - | 'mentioned_in_popup'; - legal_basis_type: 'consent' | 'legitimate_interes' | 'not_mentioned'; - was_processing_necessary: 'yes' | 'no' | 'not_sure'; + present: + | 'not_mentioned' + | 'not_before_making_a_choice' + | 'mentioned_in_policy' + | 'mentioned_in_popup'; + legal_basis_type: 'consent' | 'legitimate_interes' | 'not_mentioned'; + was_processing_necessary: 'yes' | 'no' | 'not_sure'; } & ( - | { - consent_problems: - | 'claims_consent_but_sends_before_consent' - | 'claims_consent_but_there_was_no_easy_refuse'; - } - | { consent_problems: 'none'; outside_eu: 'yes' | 'no' | 'not_sure' } + | { + consent_problems: + | 'claims_consent_but_sends_before_consent' + | 'claims_consent_but_there_was_no_easy_refuse'; + } + | { consent_problems: 'none'; outside_eu: 'yes' | 'no' | 'not_sure' } )) & { - legitimate_interest_activity_specified: 'no' | 'precise' | 'vague'; - outside_eu: 'yes' | 'no' | 'not_sure'; - legitimate_interest_description?: string; + legitimate_interest_activity_specified: 'no' | 'precise' | 'vague'; + outside_eu: 'yes' | 'no' | 'not_sure'; + legitimate_interest_description?: string; }; export type ParsedAnswers = BasicRawAnswers & { hosts: Record }; function parseHostAnswers( - raw_answers: Record + raw_answers: Record ): Record { - const result: Record> = {}; - for (const [key, value] of Object.entries(raw_answers)) { - const [masked_host, attr] = key.split('|'); - const host = masked_host.replace(/_/g, '.'); - if (!result[host]) { - result[host] = {} as ParsedHostAnswers; - } - result[host][attr] = value; - } - return result as Record; + const result: Record> = {}; + for (const [key, value] of Object.entries(raw_answers)) { + const [masked_host, attr] = key.split('|'); + const host = masked_host.replace(/_/g, '.'); + if (!result[host]) { + result[host] = {} as ParsedHostAnswers; + } + result[host][attr] = value; + } + return result as Record; } export function parseAnswers({ - zaimek, - is_incognito_different, - policy_readable, - popup_type, - cookie_wall, - passive_consent_description, - mentions_passive_consent, - rejection_is_hard, - administrator_identity_available_before_choice, - ...rest + zaimek, + is_incognito_different, + policy_readable, + popup_type, + cookie_wall, + passive_consent_description, + mentions_passive_consent, + rejection_is_hard, + administrator_identity_available_before_choice, + ...rest }: RawAnswers): ParsedAnswers { - return { - zaimek, - is_incognito_different, - policy_readable, - popup_type, - cookie_wall, - passive_consent_description, - mentions_passive_consent, - rejection_is_hard, - administrator_identity_available_before_choice, - hosts: parseHostAnswers(rest), - } as ParsedAnswers; + return { + zaimek, + is_incognito_different, + policy_readable, + popup_type, + cookie_wall, + passive_consent_description, + mentions_passive_consent, + rejection_is_hard, + administrator_identity_available_before_choice, + hosts: parseHostAnswers(rest), + } as ParsedAnswers; } diff --git a/components/report-window/problems/no-information-at-all.tsx b/components/report-window/problems/no-information-at-all.tsx index d51e1e3..cc0f667 100644 --- a/components/report-window/problems/no-information-at-all.tsx +++ b/components/report-window/problems/no-information-at-all.tsx @@ -3,42 +3,43 @@ import { v } from '../verbs'; import { Problem } from './problem'; export default class NoInformationAtAllProblem extends Problem { - getEmailContent() { - const _ = (word: string) => v(word, this.answers.zaimek); - return ( - <> -

Brak informacji na temat przetwarzania danych osobowych

-

- {_('Moje')} dane osobowe zostały ujawnione podmiotom, które są właścicielami domen: -

- {this.getRangeDescription()} -

- Na stronie brakuje jednak jakichkolwiek informacji o tym, jakie są cele przetwarzania - takich danych oraz jakie są podstawy prawne takiego przetwarzania. -

-

Zwracam się zatem do Państwa z następującymi pytaniami:

-
    -
  • Jaka jest tożsamość właścicieli tych domen?
  • -
  • Jaki jest cel takiego przetwarzania danych przez Państwa stronę?
  • -
  • - Jaka jest podstawa prawna takiego przetwarzania moich danych osobowych przez - Państwa stronę? -
  • -
- - ); - } - getNecessaryExplainers() { - const explainers = [] as Array; + getEmailContent() { + const _ = (word: string) => v(word, this.answers.zaimek); + return ( + <> +

Brak informacji na temat przetwarzania danych osobowych

+

+ {_('Moje')} dane osobowe zostały ujawnione podmiotom, które są właścicielami + domen: +

+ {this.getRangeDescription()} +

+ Na stronie brakuje jednak jakichkolwiek informacji o tym, jakie są cele + przetwarzania takich danych oraz jakie są podstawy prawne takiego przetwarzania. +

+

Zwracam się zatem do Państwa z następującymi pytaniami:

+
    +
  • Jaka jest tożsamość właścicieli tych domen?
  • +
  • Jaki jest cel takiego przetwarzania danych przez Państwa stronę?
  • +
  • + Jaka jest podstawa prawna takiego przetwarzania moich danych osobowych przez + Państwa stronę? +
  • +
+ + ); + } + getNecessaryExplainers() { + const explainers = [] as Array; - if ( - this.getMarkedClusters().some((cluster) => { - console.log(cluster); - return cluster.hasMarkedCookies(); - }) - ) { - explainers.push('cookies_are_pii'); - } - return explainers; - } + if ( + this.getMarkedClusters().some((cluster) => { + console.log(cluster); + return cluster.hasMarkedCookies(); + }) + ) { + explainers.push('cookies_are_pii'); + } + return explainers; + } } diff --git a/components/report-window/problems/problem.tsx b/components/report-window/problems/problem.tsx index 7d6bdbe..7815171 100644 --- a/components/report-window/problems/problem.tsx +++ b/components/report-window/problems/problem.tsx @@ -3,36 +3,36 @@ import { ExplainerKey } from '../explainers'; import { ParsedAnswers } from '../parse-answers'; function formatRange(cluster: RequestCluster) { - const parts = [] as string[]; - console.log(cluster); - if (cluster.hasMarkedCookies()) { - parts.push('mojego identyfikatora internetowego pozyskanego z Cookie'); - } - if (cluster.exposesOrigin()) { - parts.push('części mojej historii przeglądania'); - } - return parts.join(' oraz '); + const parts = [] as string[]; + console.log(cluster); + if (cluster.hasMarkedCookies()) { + parts.push('mojego identyfikatora internetowego pozyskanego z Cookie'); + } + if (cluster.exposesOrigin()) { + parts.push('części mojej historii przeglądania'); + } + return parts.join(' oraz '); } export abstract class Problem { - constructor(public answers: ParsedAnswers, public clusters: Record) {} + constructor(public answers: ParsedAnswers, public clusters: Record) {} - abstract getEmailContent(): JSX.Element; - abstract getNecessaryExplainers(): ExplainerKey[]; + abstract getEmailContent(): JSX.Element; + abstract getNecessaryExplainers(): ExplainerKey[]; - getMarkedClusters() { - return Object.values(this.clusters).filter((c) => c.hasMarks()); - } + getMarkedClusters() { + return Object.values(this.clusters).filter((c) => c.hasMarks()); + } - getRangeDescription() { - return ( -
    - {this.getMarkedClusters().map((cluster) => ( -
  • - {cluster.id} (w zakresie: {formatRange(cluster)}) -
  • - ))} -
- ); - } + getRangeDescription() { + return ( +
    + {this.getMarkedClusters().map((cluster) => ( +
  • + {cluster.id} (w zakresie: {formatRange(cluster)}) +
  • + ))} +
+ ); + } } diff --git a/components/report-window/problems/unlawful-cookies.tsx b/components/report-window/problems/unlawful-cookies.tsx index fd3c550..53e98b7 100644 --- a/components/report-window/problems/unlawful-cookies.tsx +++ b/components/report-window/problems/unlawful-cookies.tsx @@ -6,171 +6,178 @@ import { v } from '../verbs'; import { Problem } from './problem'; export class UnlawfulCookieAccess extends Problem { - getNecessaryExplainers(): ExplainerKey[] { - return []; - } + getNecessaryExplainers(): ExplainerKey[] { + return []; + } - static qualifies(answers: ParsedAnswers, clusters: RequestCluster[]): boolean { - // są cookiesy, nie było zgody, nie są konieczne do działania strony - const cookie_clusters = Object.values(clusters).filter((c) => c.hasMarkedCookies()); - return cookie_clusters.some((cluster) => { - const hostAnswers = answers.hosts[cluster.id]; - return ( - (hostAnswers.present == 'not_mentioned' || - hostAnswers.present == 'not_before_making_a_choice' || - ['none', 'closed_popup', 'deny_all'].includes(answers.popup_action) || - answers.popup_type === 'none') && - hostAnswers.was_processing_necessary != 'yes' - ); - }); - } + static qualifies(answers: ParsedAnswers, clusters: RequestCluster[]): boolean { + // są cookiesy, nie było zgody, nie są konieczne do działania strony + const cookie_clusters = Object.values(clusters).filter((c) => c.hasMarkedCookies()); + return cookie_clusters.some((cluster) => { + const hostAnswers = answers.hosts[cluster.id]; + return ( + (hostAnswers.present == 'not_mentioned' || + hostAnswers.present == 'not_before_making_a_choice' || + ['none', 'closed_popup', 'deny_all'].includes(answers.popup_action) || + answers.popup_type === 'none') && + hostAnswers.was_processing_necessary != 'yes' + ); + }); + } - getEmailContent() { - const cookie_clusters = Object.values(this.clusters).filter((c) => c.hasMarkedCookies()); - const unnecessary_hosts = Object.entries(this.answers.hosts) - .filter(([, answers]) => answers.was_processing_necessary === 'no') - .map(([host]) => host); - const maybe_unnecessary_hosts = Object.entries(this.answers.hosts) - .filter(([, answers]) => answers.was_processing_necessary === 'not_sure') - .map(([host]) => host); - const _ = (key: string) => v(key, this.answers.zaimek); - return ( - <> -

Dostęp do cookies niezgodny z ustawą Prawo Telekomunikacyjne

-

- Państwa strona dokonała odczytu plików Cookie zapisanych na dysku twardym mojego - komputera. Dotyczy to plików cookie przypisanych do domen: -

-
    - {cookie_clusters.map((cluster, index) => { - const names = cluster - .getMarkedEntries() - .filter((e) => e.source === 'cookie') - .map((e) => e.name); + getEmailContent() { + const cookie_clusters = Object.values(this.clusters).filter((c) => c.hasMarkedCookies()); + const unnecessary_hosts = Object.entries(this.answers.hosts) + .filter(([, answers]) => answers.was_processing_necessary === 'no') + .map(([host]) => host); + const maybe_unnecessary_hosts = Object.entries(this.answers.hosts) + .filter(([, answers]) => answers.was_processing_necessary === 'not_sure') + .map(([host]) => host); + const _ = (key: string) => v(key, this.answers.zaimek); + return ( + <> +

    Dostęp do cookies niezgodny z ustawą Prawo Telekomunikacyjne

    +

    + Państwa strona dokonała odczytu plików Cookie zapisanych na dysku twardym mojego + komputera. Dotyczy to plików cookie przypisanych do domen: +

    +
      + {cookie_clusters.map((cluster, index) => { + const names = cluster + .getMarkedEntries() + .filter((e) => e.source === 'cookie') + .map((e) => e.name); - return ( -
    • - {cluster.id} ({names.length > 1 ? 'pliki' : 'plik'}{' '} - {names.map((name, index) => { - return ( - <> - {index > 0 ? ', ' : ''} - {name} - - ); - })} - ){index === cookie_clusters.length - 1 ? '.' : ';'} -
    • - ); - })} -
    -

    - Zgodnie z treścią Art. 173.{' '} - - ustawy Prawo Telekomunikacyjne - - , strona może pozyskać dostęp do treści plików cookies pod warunkiem spełnienia - jednego z następujących warunków: -

    -
      -
    1. - Użytkownik wyraził zgodę na takie przetwarzanie danych po tym, jak został - poinformowany bezpośrednio o celu uzyskania dostępu do tej informacji; -
    2. -
    3. - Dostęp do treści plików cookies jest konieczny do dostarczania usługi świadczonej - drogą elektroniczną zażądanej przez użytkownika. -
    4. -
    - {(() => { - if (this.answers.popup_type == 'none' || this.answers.popup_type == 'page') { - return ( -

    - Jako, że strona nie pytała {_('mnie')} nigdy o zgodę, nie jest spełniony - warunek 1. -

    - ); - } else if (this.answers.popup_type === 'passive_popup') { - return ( -

    - Państwa strona nie dała mi nigdy faktycznego wyboru dotyczącego wyrażenia - lub odmówienia zgody na takie przetwarzanie danych osobowych, dlatego nie - jest spełniony warunek 1.{' '} - {this.answers.mentions_passive_consent ? ( - <> - Zgody wyrażonej w sposób bierny lub milczący nie można uznać za ważną - w świetle obowiązujących przepisów rozporządzenia 2016/679. Dlatego - zaniechanie zmiany ustawień przeglądarki lub po prostu korzystanie ze - strony nie stanowi ważnej zgody. Takie jest{' '} - - stanowisko polskiego UODO - - . - - ) : ( - '' - )} -

    - ); - } else if (this.answers.popup_type === 'some_choice') { - if (this.answers.popup_action === 'none') { - return ( -

    - Nie {_('wyraziłem')} zgody na takie przetwarzanie {_('moich')} danych - osobowych. W okienku pytającym o zgodję nic nie {_('kliknąłem')}. Nie - jest zatem spełniony warunek 1. -

    - ); - } else if (this.answers.popup_action === 'closed_popup') { - return ( -

    - Nie {_('wyraziłem')} zgody na takie przetwarzanie {_('moich')} danych - osobowych. {this.answers.popup_closed_how.trim()} - {this.answers.popup_closed_how.trim().at(-1) != '.' ? '.' : ''} Takiego - działania nie można uznać za ważną zgodę na przetwarzanie danych - osobowych, gdyż nie spełnia warunku jednoznaczności opisanego w Art. 4, - pkt 11 RODO. Nie jest zatem spełniony warunek 1. -

    - ); - } else if (this.answers.popup_action == 'deny_all') { - return ( -

    - {this.answers.popup_deny_all_how.trim()} - {this.answers.popup_closed_how.trim().at(-1) != '.' ? '.' : ''} Zatem nie - jest spełniony warunek 1. -

    - ); - } - } - })()} - {unnecessary_hosts.length > 0 ? ( -

    - W {_('mojej')} ocenie odczytywanie przez Państwa stronę treści plików cookies z{' '} - {wordlist(unnecessary_hosts)} nie jest konieczne do wyświetlenia treści Państwa - strony, dlatego nie jest dla nich spełniony warunek 2. Jeżeli Państwa zdaniem jest - inaczej, {_('proszę')} o wskazanie, co jest źródłem tej konieczności i co odróżnia - Państwa stronę od wielu innych stron, które realizują te same funkcjonalności{' '} - bez korzystania z plików Cookie. -

    - ) : ( - '' - )} -

    - {_('Proszę')} o wskazanie, czy być może stosowali Państwo inną podstawę prawną do - takiego przetwarzania {_('moich')} danych osobowych, czy przetwarzali je państwo bez - ważnej podstawy prawnej? -

    - {maybe_unnecessary_hosts.length > 1 ? ( -

    - {_('Proszę')} też o wskazanie, czy dostęp do treści plików cookie z - {wordlist(maybe_unnecessary_hosts)} jest konieczny do poprawnego działania strony? - Jeżeli tak, to {_('proszę')} wskazać, w jaki sposób. Co sprawia, że strona nie - może działać bez nich? -

    - ) : ( - '' - )} - - ); - } + return ( +
  • + {cluster.id} ({names.length > 1 ? 'pliki' : 'plik'}{' '} + {names.map((name, index) => { + return ( + <> + {index > 0 ? ', ' : ''} + {name} + + ); + })} + ){index === cookie_clusters.length - 1 ? '.' : ';'} +
  • + ); + })} +
+

+ Zgodnie z treścią Art. 173.{' '} + + ustawy Prawo Telekomunikacyjne + + , strona może pozyskać dostęp do treści plików cookies pod warunkiem spełnienia + jednego z następujących warunków: +

+
    +
  1. + Użytkownik wyraził zgodę na takie przetwarzanie danych po tym, jak + został poinformowany bezpośrednio o celu uzyskania dostępu do tej + informacji; +
  2. +
  3. + Dostęp do treści plików cookies jest konieczny do dostarczania usługi + świadczonej drogą elektroniczną zażądanej przez użytkownika. +
  4. +
+ {(() => { + if (this.answers.popup_type == 'none' || this.answers.popup_type == 'page') { + return ( +

+ Jako, że strona nie pytała {_('mnie')} nigdy o zgodę, nie jest + spełniony warunek 1. +

+ ); + } else if (this.answers.popup_type === 'passive_popup') { + return ( +

+ Państwa strona nie dała mi nigdy faktycznego wyboru dotyczącego + wyrażenia lub odmówienia zgody na takie przetwarzanie danych + osobowych, dlatego nie jest spełniony warunek 1.{' '} + {this.answers.mentions_passive_consent ? ( + <> + Zgody wyrażonej w sposób bierny lub milczący nie można uznać + za ważną w świetle obowiązujących przepisów rozporządzenia + 2016/679. Dlatego zaniechanie zmiany ustawień przeglądarki + lub po prostu korzystanie ze strony nie stanowi ważnej + zgody. Takie jest{' '} + + stanowisko polskiego UODO + + . + + ) : ( + '' + )} +

+ ); + } else if (this.answers.popup_type === 'some_choice') { + if (this.answers.popup_action === 'none') { + return ( +

+ Nie {_('wyraziłem')} zgody na takie przetwarzanie {_('moich')}{' '} + danych osobowych. W okienku pytającym o zgodję nic nie{' '} + {_('kliknąłem')}. Nie jest zatem spełniony warunek 1. +

+ ); + } else if (this.answers.popup_action === 'closed_popup') { + return ( +

+ Nie {_('wyraziłem')} zgody na takie przetwarzanie {_('moich')}{' '} + danych osobowych. {this.answers.popup_closed_how.trim()} + {this.answers.popup_closed_how.trim().at(-1) != '.' + ? '.' + : ''}{' '} + Takiego działania nie można uznać za ważną zgodę na + przetwarzanie danych osobowych, gdyż nie spełnia warunku + jednoznaczności opisanego w Art. 4, pkt 11 RODO. Nie jest zatem + spełniony warunek 1. +

+ ); + } else if (this.answers.popup_action == 'deny_all') { + return ( +

+ {this.answers.popup_deny_all_how.trim()} + {this.answers.popup_closed_how.trim().at(-1) != '.' + ? '.' + : ''}{' '} + Zatem nie jest spełniony warunek 1. +

+ ); + } + } + })()} + {unnecessary_hosts.length > 0 ? ( +

+ W {_('mojej')} ocenie odczytywanie przez Państwa stronę treści plików + cookies z {wordlist(unnecessary_hosts)} nie jest konieczne do wyświetlenia + treści Państwa strony, dlatego nie jest dla nich spełniony warunek 2. Jeżeli + Państwa zdaniem jest inaczej, {_('proszę')} o wskazanie, co jest źródłem tej + konieczności i co odróżnia Państwa stronę od wielu innych stron, które + realizują te same funkcjonalności bez korzystania z plików Cookie. +

+ ) : ( + '' + )} +

+ {_('Proszę')} o wskazanie, czy być może stosowali Państwo inną podstawę prawną + do takiego przetwarzania {_('moich')} danych osobowych, czy przetwarzali je + państwo bez ważnej podstawy prawnej? +

+ {maybe_unnecessary_hosts.length > 1 ? ( +

+ {_('Proszę')} też o wskazanie, czy dostęp do treści plików cookie z + {wordlist(maybe_unnecessary_hosts)} jest konieczny do poprawnego działania + strony? Jeżeli tak, to {_('proszę')} wskazać, w jaki sposób. Co sprawia, że + strona nie może działać bez nich? +

+ ) : ( + '' + )} + + ); + } } diff --git a/components/report-window/problems/unlawful-data.tsx b/components/report-window/problems/unlawful-data.tsx index 9b2433c..8bd8e99 100644 --- a/components/report-window/problems/unlawful-data.tsx +++ b/components/report-window/problems/unlawful-data.tsx @@ -7,29 +7,30 @@ import { Problem } from './problem'; type UnlawfulDataClassification = 'no_purpose'; export function classifyUnlawfulData( - hostAnswers: ParsedHostAnswers, - cluster: RequestCluster + hostAnswers: ParsedHostAnswers, + cluster: RequestCluster ): UnlawfulDataClassification { - if (hostAnswers.present == 'not_mentioned' && hostAnswers.was_processing_necessary == 'no') { - return 'no_purpose'; - } + if (hostAnswers.present == 'not_mentioned' && hostAnswers.was_processing_necessary == 'no') { + return 'no_purpose'; + } } export class UnlawfulData extends Problem { - static qualifies(answers: ParsedAnswers, clusters: RequestCluster[]): boolean {} - getEmailContent() { - const _ = (key: string) => v(key, this.answers.zaimek); - return ( - <> -

Przetwarzanie danych osobowych bez ważnej podsawy prawnej

-

- {_('Moje')} dane osobowe zostały ujawnione podmiotom, które są właścicielami domen: -

- {this.getRangeDescription()} - - ); - } - getNecessaryExplainers() { - return [] as ExplainerKey[]; - } + static qualifies(answers: ParsedAnswers, clusters: RequestCluster[]): boolean {} + getEmailContent() { + const _ = (key: string) => v(key, this.answers.zaimek); + return ( + <> +

Przetwarzanie danych osobowych bez ważnej podsawy prawnej

+

+ {_('Moje')} dane osobowe zostały ujawnione podmiotom, które są właścicielami + domen: +

+ {this.getRangeDescription()} + + ); + } + getNecessaryExplainers() { + return [] as ExplainerKey[]; + } } diff --git a/components/report-window/raw-answers.ts b/components/report-window/raw-answers.ts index b93775e..a1e9e08 100644 --- a/components/report-window/raw-answers.ts +++ b/components/report-window/raw-answers.ts @@ -1,58 +1,58 @@ export type HostRawAnswers = { - [key: `${string}|present`]: - | 'not_mentioned' - | 'not_before_making_a_choice' - | 'mentioned_in_policy' - | 'mentioned_in_popup'; - [key: `${string}|legal_basis_type`]: 'consent' | 'legitimate_interest' | 'not_mentioned'; - [key: `${string}|consent`]: - | 'claims_consent_but_sends_before_consent' - | 'claims_consent_but_there_was_no_easy_refuse' - | 'none'; - [key: `${string}|legitimate_interest_activity_specified`]: 'precise' | 'vague' | 'no'; - [key: `${string}|legitimate_interest_description`]: string; - [key: `${string}|outside_eu`]: 'yes' | 'no' | 'not_sure'; + [key: `${string}|present`]: + | 'not_mentioned' + | 'not_before_making_a_choice' + | 'mentioned_in_policy' + | 'mentioned_in_popup'; + [key: `${string}|legal_basis_type`]: 'consent' | 'legitimate_interest' | 'not_mentioned'; + [key: `${string}|consent`]: + | 'claims_consent_but_sends_before_consent' + | 'claims_consent_but_there_was_no_easy_refuse' + | 'none'; + [key: `${string}|legitimate_interest_activity_specified`]: 'precise' | 'vague' | 'no'; + [key: `${string}|legitimate_interest_description`]: string; + [key: `${string}|outside_eu`]: 'yes' | 'no' | 'not_sure'; }; export type BasicRawAnswers = { - zaimek: 0 | 1 | 2 | 3; - is_incognito_different: [] | ['incognito_is_the_same']; - policy_readable: 'yes' | 'vague' | 'cant_find'; - popup_action: 'none' | 'closed_popup' | 'accept_all' | 'deny_all' | 'other'; - popup_closed_how: string; - popup_deny_all_how: string; + zaimek: 0 | 1 | 2 | 3; + is_incognito_different: [] | ['incognito_is_the_same']; + policy_readable: 'yes' | 'vague' | 'cant_find'; + popup_action: 'none' | 'closed_popup' | 'accept_all' | 'deny_all' | 'other'; + popup_closed_how: string; + popup_deny_all_how: string; } & ( - | ({ - popup_type: 'passive_popup'; - cookie_wall: 'yes' | 'no'; - rejection_is_hard: undefined; - administrator_identity_available_before_choice: undefined; - } & ( - | { - mentions_passive_consent?: 'yes'; - passive_consent_description: string; - } - | { - mentions_passive_consent?: 'no'; - passive_consent_description: undefined; - } - )) - | { - popup_type: 'some_choice'; - rejection_is_hard: 'yes' | 'no'; - administrator_identity_available_before_choice: 'yes' | 'no'; - cookie_wall: undefined; - passive_consent_description: undefined; - mentions_passive_consent: undefined; - } - | { - popup_type: 'none' | 'page'; - cookie_wall: undefined; - passive_consent_description: undefined; - mentions_passive_consent: undefined; - rejection_is_hard: undefined; - administrator_identity_available_before_choice: undefined; - } + | ({ + popup_type: 'passive_popup'; + cookie_wall: 'yes' | 'no'; + rejection_is_hard: undefined; + administrator_identity_available_before_choice: undefined; + } & ( + | { + mentions_passive_consent?: 'yes'; + passive_consent_description: string; + } + | { + mentions_passive_consent?: 'no'; + passive_consent_description: undefined; + } + )) + | { + popup_type: 'some_choice'; + rejection_is_hard: 'yes' | 'no'; + administrator_identity_available_before_choice: 'yes' | 'no'; + cookie_wall: undefined; + passive_consent_description: undefined; + mentions_passive_consent: undefined; + } + | { + popup_type: 'none' | 'page'; + cookie_wall: undefined; + passive_consent_description: undefined; + mentions_passive_consent: undefined; + rejection_is_hard: undefined; + administrator_identity_available_before_choice: undefined; + } ); type RawAnswers = BasicRawAnswers & HostRawAnswers; diff --git a/components/report-window/report-window.tsx b/components/report-window/report-window.tsx index c71034e..2a9b4e1 100644 --- a/components/report-window/report-window.tsx +++ b/components/report-window/report-window.tsx @@ -9,70 +9,70 @@ import EmailContent from './email-content'; import { parseAnswers, ParsedAnswers } from './parse-answers'; function Report() { - try { - const url = new URL(document.location.toString()); - const origin = url.searchParams.get('origin'); - const [counter] = useEmitter(getMemory()); - const [answers, setAnswers] = React.useState( - url.searchParams.get('answers') ? JSON.parse(url.searchParams.get('answers')) : null - ); - const [mode, setMode] = React.useState(url.searchParams.get('mode') || 'survey'); - const clusters = getMemory().getClustersForOrigin(origin); - /* const [entries, setEntries] = React.useState([]); */ - /* React.useEffect(() => { - * setEntries( - * Object.values(clusters) - * .map((cluster) => { - * cluster.calculateRepresentativeStolenData(); - * return cluster.representativeStolenData; - * }) - * .reduce(reduceConcat, []) - * .filter((entry) => entry.isMarked) - * ); - * }, []); */ - /* if (entries.length == 0) { - * return <>Wczytywanie...; - * } */ + try { + const url = new URL(document.location.toString()); + const origin = url.searchParams.get('origin'); + const [counter] = useEmitter(getMemory()); + const [answers, setAnswers] = React.useState( + url.searchParams.get('answers') ? JSON.parse(url.searchParams.get('answers')) : null + ); + const [mode, setMode] = React.useState(url.searchParams.get('mode') || 'survey'); + const clusters = getMemory().getClustersForOrigin(origin); + /* const [entries, setEntries] = React.useState([]); */ + /* React.useEffect(() => { + * setEntries( + * Object.values(clusters) + * .map((cluster) => { + * cluster.calculateRepresentativeStolenData(); + * return cluster.representativeStolenData; + * }) + * .reduce(reduceConcat, []) + * .filter((entry) => entry.isMarked) + * ); + * }, []); */ + /* if (entries.length == 0) { + * return <>Wczytywanie...; + * } */ - React.useEffect(() => { - const url = new URL(document.location.toString()); - url.searchParams.set('origin', origin); - url.searchParams.set('answers', JSON.stringify(answers)); - url.searchParams.set('mode', mode); - history.pushState({}, 'Rentgen', url.toString()); - }, [mode, answers, origin]); - const visited_url = Object.values(clusters) - .find((cluster) => cluster.getMarkedRequests().length > 0) - ?.getMarkedRequests()[0].originalURL; + React.useEffect(() => { + const url = new URL(document.location.toString()); + url.searchParams.set('origin', origin); + url.searchParams.set('answers', JSON.stringify(answers)); + url.searchParams.set('mode', mode); + history.pushState({}, 'Rentgen', url.toString()); + }, [mode, answers, origin]); + const visited_url = Object.values(clusters) + .find((cluster) => cluster.getMarkedRequests().length > 0) + ?.getMarkedRequests()[0].originalURL; - const result = ( -
- - {mode === 'survey' ? ( - cluster.getMarkedRequests().length > 0) - .map((cluster) => cluster.id)} - onComplete={(answers) => { - setAnswers(parseAnswers(answers)); - setMode('preview'); - }} - > - ) : ( - '' - )} - {mode === 'preview' ? : ''} - {/* */} -
- ); - return result; - } catch (e) { - console.error(e); - return
ERROR! {JSON.stringify(e)}
; - } + const result = ( +
+ + {mode === 'survey' ? ( + cluster.getMarkedRequests().length > 0) + .map((cluster) => cluster.id)} + onComplete={(answers) => { + setAnswers(parseAnswers(answers)); + setMode('preview'); + }} + > + ) : ( + '' + )} + {mode === 'preview' ? : ''} + {/* */} +
+ ); + return result; + } catch (e) { + console.error(e); + return
ERROR! {JSON.stringify(e)}
; + } } ReactDOM.render(, document.getElementById('app')); diff --git a/components/report-window/verbs.ts b/components/report-window/verbs.ts index 96f5761..6360913 100644 --- a/components/report-window/verbs.ts +++ b/components/report-window/verbs.ts @@ -1,45 +1,45 @@ const words = { - zrobiłem: ['zrobiłem', 'zrobiłam', 'zrobiłom', 'zrobiliśmy'], - szukałem: ['szukałem', 'szukałam', 'szukałom', 'szukaliśmy'], - znalazłem: ['znalazłem', 'znalazłam', 'znalazłom', 'znaleźliśmy'], - moje: ['moje', 'moje', 'moje', 'nasze'], - mojej: ['mojej', 'mojej', 'mojej', 'naszej'], - wyraziłem: ['wyraziłem', 'wyraziłam', 'wyraziłom', 'wyraziliśmy'], - kliknąłem: ['kliknąłem', 'kliknęłam', 'klinkęłom', 'kliknęliśmy'], - odwiedzałeś: ['odwiedzałeś', 'odwiedzałaś', 'odwiedzałoś', 'odwiedzaliście'], - wyraziłeś: ['wyraziłeś', 'wyraziłaś', 'wyraziłoś', 'wyraziliście'], - jesteś: ['jesteś', 'jesteś', 'jesteś', 'jesteście'], - twoich: ['twoich', 'twoich', 'twoich', 'waszych'], - tobie: ['tobie', 'tobie', 'tobie', 'wam'], - twojej: ['twojej', 'twojej', 'twojej', 'waszej'], - odkliknąłeś: ['odkliknąłeś', 'odkliknęłaś', 'odklikęłoś', 'odkliknęliście'], - otwórz: ['otwórz', 'otwórz', 'otwórz', 'otwórzcie'], - widzisz: ['widzisz', 'widzisz', 'widzisz', 'widzicie'], - widzę: ['widzę', 'widzę', 'widzę', 'widzimy'], - widziałem: ['widziałem', 'widziałam', 'widziałom', 'widzieliśmy'], - odwiedziłem: ['odwiedziłem', 'odwiedziłam', 'odwiedziłom', 'odwiedziliśmy'], - mam: ['mam', 'mam', 'mam', 'mamy'], - podjąłeś: ['podjąłeś', 'podjęłaś', 'podjęłoś', 'podjęliście'], - zamknąłem: ['zamknąłem', 'zamknęłom', 'zamknęłom', 'zamknęliśmy'], - zamknąłeś: ['zamknąłeś', 'zamknęłaś', 'zamknęłoś', 'zamknęliście'], - zwracam: ['zwracam', 'zwracam', 'zwracam', 'zwracamy'], - moich: ['moich', 'moich', 'moich', 'naszych'], - ciebie: ['ciebie', 'ciebie', 'ciebie', 'was'], - mnie: ['mnie', 'mnie', 'mnie', 'nas'], - podjąłem: ['podjąłem', 'podjęłam', 'podjęłom', 'podjęliśmy'], - dokonałeś: ['dokonałeś', 'dokonałaś', 'dokonałoś', 'dokonaliście'], - odmówiłeś: ['odmówiłeś', 'odmówiłaś', 'odmówiłoś', 'odmówiliście'], - odznaczyłem: ['odznaczyłem', 'odznaczyłam', 'odznaczyłom', 'odznaczyliśmy'], - proszę: ['proszę', 'proszę', 'proszę', 'prosimy'], - odmówiłem: ['odmówiłem', 'odmówiłam', 'odmówiłom', 'odmówiliśmy'], + zrobiłem: ['zrobiłem', 'zrobiłam', 'zrobiłom', 'zrobiliśmy'], + szukałem: ['szukałem', 'szukałam', 'szukałom', 'szukaliśmy'], + znalazłem: ['znalazłem', 'znalazłam', 'znalazłom', 'znaleźliśmy'], + moje: ['moje', 'moje', 'moje', 'nasze'], + mojej: ['mojej', 'mojej', 'mojej', 'naszej'], + wyraziłem: ['wyraziłem', 'wyraziłam', 'wyraziłom', 'wyraziliśmy'], + kliknąłem: ['kliknąłem', 'kliknęłam', 'klinkęłom', 'kliknęliśmy'], + odwiedzałeś: ['odwiedzałeś', 'odwiedzałaś', 'odwiedzałoś', 'odwiedzaliście'], + wyraziłeś: ['wyraziłeś', 'wyraziłaś', 'wyraziłoś', 'wyraziliście'], + jesteś: ['jesteś', 'jesteś', 'jesteś', 'jesteście'], + twoich: ['twoich', 'twoich', 'twoich', 'waszych'], + tobie: ['tobie', 'tobie', 'tobie', 'wam'], + twojej: ['twojej', 'twojej', 'twojej', 'waszej'], + odkliknąłeś: ['odkliknąłeś', 'odkliknęłaś', 'odklikęłoś', 'odkliknęliście'], + otwórz: ['otwórz', 'otwórz', 'otwórz', 'otwórzcie'], + widzisz: ['widzisz', 'widzisz', 'widzisz', 'widzicie'], + widzę: ['widzę', 'widzę', 'widzę', 'widzimy'], + widziałem: ['widziałem', 'widziałam', 'widziałom', 'widzieliśmy'], + odwiedziłem: ['odwiedziłem', 'odwiedziłam', 'odwiedziłom', 'odwiedziliśmy'], + mam: ['mam', 'mam', 'mam', 'mamy'], + podjąłeś: ['podjąłeś', 'podjęłaś', 'podjęłoś', 'podjęliście'], + zamknąłem: ['zamknąłem', 'zamknęłom', 'zamknęłom', 'zamknęliśmy'], + zamknąłeś: ['zamknąłeś', 'zamknęłaś', 'zamknęłoś', 'zamknęliście'], + zwracam: ['zwracam', 'zwracam', 'zwracam', 'zwracamy'], + moich: ['moich', 'moich', 'moich', 'naszych'], + ciebie: ['ciebie', 'ciebie', 'ciebie', 'was'], + mnie: ['mnie', 'mnie', 'mnie', 'nas'], + podjąłem: ['podjąłem', 'podjęłam', 'podjęłom', 'podjęliśmy'], + dokonałeś: ['dokonałeś', 'dokonałaś', 'dokonałoś', 'dokonaliście'], + odmówiłeś: ['odmówiłeś', 'odmówiłaś', 'odmówiłoś', 'odmówiliście'], + odznaczyłem: ['odznaczyłem', 'odznaczyłam', 'odznaczyłom', 'odznaczyliśmy'], + proszę: ['proszę', 'proszę', 'proszę', 'prosimy'], + odmówiłem: ['odmówiłem', 'odmówiłam', 'odmówiłom', 'odmówiliśmy'], } as { [key: string]: string[] }; export default words; export function v(key: string, index: number) { - let result = words[key.toLowerCase()]?.[index] || key; - if (key[0] == key[0].toUpperCase()) { - result = [result[0].toUpperCase(), ...result.slice(1)].join(''); - } - return result; + let result = words[key.toLowerCase()]?.[index] || key; + if (key[0] == key[0].toUpperCase()) { + result = [result[0].toUpperCase(), ...result.slice(1)].join(''); + } + return result; } diff --git a/components/sidebar/sidebar.scss b/components/sidebar/sidebar.scss index a26168b..bee6c43 100644 --- a/components/sidebar/sidebar.scss +++ b/components/sidebar/sidebar.scss @@ -3,7 +3,7 @@ .sidebar { .header { display: grid; - grid-template-columns: 1.75rem 1fr 1.25rem; + grid-template-columns: 1.75rem 1fr 10rem; align-items: center; max-height: 3.5rem; min-height: 3.5rem; @@ -13,10 +13,6 @@ background: #ffffff; z-index: 1; - &--without-logo { - grid-template-columns: 1fr 1.25rem; - } - .webpage-metadata { word-break: break-all; display: flex; @@ -112,4 +108,41 @@ align-self: flex-start; } } + + + .button { + border: 0; + outline: 0; + height: 3rem; + font-size: 0.875rem; + line-height: 0.875rem; + height: 2.5rem; + cursor: pointer; + background-color: #000 !important; + + &--report { + font-weight: 800; + padding: 0 1.5rem; + margin-left: 0.5rem; + background-color: #000; + color: $icd-rentgen-color; + + &:hover { + background-image: linear-gradient( + to right, + $icd-rentgen-color 0%, + $icd-rentgen-color 4%, + #000 4%, + #000 100% + ); + animation: slidebg 1s cubic-bezier(0.19, 1, 0.22, 1) infinite; + } + } + + @keyframes slidebg { + to { + background-position: 155px; + } + } + } } diff --git a/components/sidebar/sidebar.tsx b/components/sidebar/sidebar.tsx index c5de4c7..55f9cba 100644 --- a/components/sidebar/sidebar.tsx +++ b/components/sidebar/sidebar.tsx @@ -17,7 +17,6 @@ import './../../styles/global.scss'; import './sidebar.scss'; const Sidebar = () => { - // const [origin, setOrigin] = React.useState(null); const url = new URL(document.location.toString()); const origin = url.searchParams.get('origin'); @@ -70,15 +69,23 @@ const Sidebar = () => { Przejdź do wybranej strony internetowej )} - {stolenDataView ? ( - - - - ) : ( - - )} + {stolenDataView ? ( @@ -126,34 +133,32 @@ const Sidebar = () => { {detailsVisibility ? 'Ukryj szczegóły' : 'Wyświetlaj szczegóły'} - + }} + > + + Odwiedź wszystkie domeny + + ) : null} ) : null} @@ -202,6 +207,7 @@ const Sidebar = () => { setWarningDataDialogAck={setWarningDataDialogAck} detailsVisibility={detailsVisibility} setDetailsVisibility={setDetailsVisibility} + setStolenDataView={setStolenDataView} /> )} diff --git a/components/sidebar/stolen-data-cluster.scss b/components/sidebar/stolen-data-cluster.scss index 96d4594..82e3083 100644 --- a/components/sidebar/stolen-data-cluster.scss +++ b/components/sidebar/stolen-data-cluster.scss @@ -83,6 +83,7 @@ word-break: break-all; text-overflow: clip; padding-left: 0.25rem; + padding-right: 0.25rem; } .icons { diff --git a/components/sidebar/stolen-data-cluster.tsx b/components/sidebar/stolen-data-cluster.tsx index 52c2a52..73b32c7 100644 --- a/components/sidebar/stolen-data-cluster.tsx +++ b/components/sidebar/stolen-data-cluster.tsx @@ -15,7 +15,7 @@ function StolenDataValue({ entry }: { entry: StolenDataEntry; prefixKey?: string body = <>; } else { body = ( -
{maskString(entry.value, 1, MAX_STRING_VALUE_LENGTH)}
+
{entry.value}
); } return ( @@ -26,7 +26,7 @@ function StolenDataValue({ entry }: { entry: StolenDataEntry; prefixKey?: string getMemory().emit('change', false, entry.request.shorthost, 'clicked value'); e.stopPropagation(); }} - title={maskString(entry.value, 1, MAX_STRING_VALUE_LENGTH)} + title={entry.value} > {body} @@ -41,7 +41,7 @@ function StolenDataRow({ entry }: { entry: StolenDataEntry }) { data-version={version} className={`${entry.isMarked ? 'toggled' : 'untoggled'}`} > - + {/* - + */} { - entry.toggleMark(); - getMemory().emit( - 'change', - false, - entry.request.shorthost, - 'Clicked entry name' - ); - }} + // onClick={() => { + // entry.toggleMark(); + // getMemory().emit( + // 'change', + // false, + // entry.request.shorthost, + // 'Clicked entry name' + // ); + // }} > {entry.name} diff --git a/components/toolbar/toolbar.tsx b/components/toolbar/toolbar.tsx index 8ba8192..8bfa93b 100644 --- a/components/toolbar/toolbar.tsx +++ b/components/toolbar/toolbar.tsx @@ -19,6 +19,7 @@ const Toolbar = () => { const [stolenDataView, setStolenDataView] = React.useState(true); const [eventCounts, setEventCounts] = useEmitter(getMemory()); const [cookieDomainCopy, setCookieDomainCopy] = React.useState(null); + const [marksOccurrence, setMarksOccurrence] = React.useState(false); const [exposedOriginDomainCopy, setExposedOriginDomainCopy] = React.useState( null ); @@ -109,6 +110,23 @@ const Toolbar = () => { } }, [eventCounts['*'], origin]); + React.useEffect(() => { + for (const cluster of Object.values(getMemory().getClustersForOrigin(origin))) { + if (cluster.hasMarks()) { + return setMarksOccurrence(true); + } + } + + return setMarksOccurrence(false); + }, [eventCounts['*']]); + + function autoMark() { + for (const cluster of Object.values(getMemory().getClustersForOrigin(origin))) { + cluster.autoMark(); + } + return setMarksOccurrence(true); + } + return (
@@ -204,6 +222,7 @@ const Toolbar = () => { 'width=' + screen.width, 'fullscreen=yes', ].join(','); + autoMark(); window.open( `/components/sidebar/sidebar.html?origin=${origin}`, 'new_window', @@ -221,6 +240,7 @@ const Toolbar = () => { 'width=' + screen.width, 'fullscreen=yes', ].join(','); + autoMark(); window.open( `/components/report-window/report-window.html?origin=${origin}`, 'new_window', diff --git a/options.tsx b/options.tsx index 9d5322f..c5f7e05 100644 --- a/options.tsx +++ b/options.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { Fragment } from 'react'; import './options.scss'; export default function Options({ @@ -12,6 +12,7 @@ export default function Options({ setWarningDataDialogAck, detailsVisibility, setDetailsVisibility, + setStolenDataView, }: { minValueLength: number; setMinValueLength: (n: number) => void; @@ -23,85 +24,94 @@ export default function Options({ setWarningDataDialogAck: (b: boolean) => void; detailsVisibility: boolean; setDetailsVisibility: (b: boolean) => void; + setStolenDataView: (b: boolean) => void; }) { return ( -
- Interfejs -
-
- { - setDetailsVisibility(e.target.checked); - localStorage.setItem( - 'detailsVisibility', - e.target.checked as unknown as string - ); - }} - /> - -
-
- { - setWarningDataDialogAck(e.target.checked); - localStorage.setItem( - 'warningDataDialogAck', - e.target.checked as unknown as string - ); - }} - /> - -
-
- Ustawienia zaawansowane -
-
- - { - setMinValueLength(parseInt(e.target.value)); - localStorage.setItem('minValueLength', e.target.value); - }} - /> -
-
- setCookiesOnly(e.target.checked)} - /> - -
-
- setCookiesOrOriginOnly(e.target.checked)} - /> - -
-
-
+ + +
+ Interfejs +
+
+ { + setDetailsVisibility(e.target.checked); + localStorage.setItem( + 'detailsVisibility', + e.target.checked as unknown as string + ); + }} + /> + +
+
+ { + setWarningDataDialogAck(e.target.checked); + localStorage.setItem( + 'warningDataDialogAck', + e.target.checked as unknown as string + ); + }} + /> + +
+
+ Ustawienia zaawansowane +
+
+ + { + setMinValueLength(parseInt(e.target.value)); + localStorage.setItem('minValueLength', e.target.value); + }} + /> +
+
+ setCookiesOnly(e.target.checked)} + /> + +
+
+ setCookiesOrOriginOnly(e.target.checked)} + /> + +
+
+
+
); }