diff --git a/.prettierrc b/.prettierrc index 3840076..dc524c2 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,5 +1,5 @@ trailingComma: "es5" -tabWidth: 4 +tabWidth: 3 printWidth: 100 semi: true singleQuote: true diff --git a/report-window/deduce-problems.tsx b/report-window/deduce-problems.tsx index 3df5711..0d80416 100644 --- a/report-window/deduce-problems.tsx +++ b/report-window/deduce-problems.tsx @@ -4,140 +4,248 @@ import { ParsedAnswers } from './parse-answers'; import { v } from './verbs'; abstract class Problem { - constructor(public answers: ParsedAnswers, public clusters: Record) {} + constructor(public answers: ParsedAnswers, public clusters: Record) {} - getMarkedClusters() { - return Object.values(this.clusters).filter((c) => c.hasMarks()); - } + getMarkedClusters() { + return Object.values(this.clusters).filter((c) => c.hasMarks()); + } - abstract getEmailContent(): JSX.Element; - abstract getNecessaryExplainers(): ExplainerKey[]; + abstract getEmailContent(): JSX.Element; + abstract getNecessaryExplainers(): ExplainerKey[]; } function formatRange(cluster: RequestCluster) { - const parts = [] as string[]; - console.log(cluster); - if (cluster.hasMarkedCookies()) { - parts.push('mojego identyfikatora internetowego pozyskanego z Cookie'); - } - if (cluster.exposesOrigin()) { - parts.push('części mojej historii przeglądania'); - } - return parts.join(' oraz '); + const parts = [] as string[]; + console.log(cluster); + if (cluster.hasMarkedCookies()) { + parts.push('mojego identyfikatora internetowego pozyskanego z Cookie'); + } + if (cluster.exposesOrigin()) { + parts.push('części mojej historii przeglądania'); + } + return parts.join(' oraz '); } class NoInformationAtAllProblem extends Problem { - getEmailContent() { - const _ = (word: string) => v(word, this.answers.zaimek); - return ( - <> -

Brak informacji na temat przetwarzania danych osobowych

-

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

- -

- 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:

- - - ); - } - 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.getMarkedClusters().map((cluster) => ( +
  • + {cluster.id} (w zakresie: {formatRange(cluster)}) +
  • + ))} +
+

+ 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; + } } class UnlawfulCookieAccess extends Problem { - getNecessaryExplainers(): ExplainerKey[] { - return []; - } - getEmailContent() { - const cookie_clusters = Object.values(this.clusters).filter((c) => c.hasMarkedCookies()); - 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); + getNecessaryExplainers(): ExplainerKey[] { + return []; + } + 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 ? '.' : ';'} -
    • - ); - })} -
    - - ); - } - static qualifies(answers: ParsedAnswers, clusters: RequestCluster[]): boolean { - // są cookiesy, nie było zgody, nie są konieczne do działania strony - const cookie_clusters = Object.values(clusters).filter((c) => c.hasMarkedCookies()); - return cookie_clusters.some((cluster) => { - const hostAnswers = answers.hosts[cluster.id]; - return ( - (hostAnswers.present == 'not_mentioned' || - hostAnswers.present == 'not_before_making_a_choice' || - ['none', 'closed_popup', 'deny_all'].includes(hostAnswers.popup_action)) && - hostAnswers.was_processing_necessary != 'yes' - ); - }); - } + 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 dotyczacego 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{' '} + {unnecessary_hosts.join(', ')} 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? +

+

+ {_('Proszę')} też o wskazanie, czy dostęp do treści plików cookie z $ + {maybe_unnecessary_hosts.join(', ')} 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? +

+ + ); + } + static qualifies(answers: ParsedAnswers, clusters: RequestCluster[]): boolean { + // są cookiesy, nie było zgody, nie są konieczne do działania strony + const cookie_clusters = Object.values(clusters).filter((c) => c.hasMarkedCookies()); + return cookie_clusters.some((cluster) => { + const hostAnswers = answers.hosts[cluster.id]; + return ( + (hostAnswers.present == 'not_mentioned' || + hostAnswers.present == 'not_before_making_a_choice' || + ['none', 'closed_popup', 'deny_all'].includes(hostAnswers.popup_action)) && + hostAnswers.was_processing_necessary != 'yes' + ); + }); + } } export default function deduceProblems( - answers: ParsedAnswers, - clusters: Record + 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/report-window/generate-survey-questions.ts b/report-window/generate-survey-questions.ts index 3c18f37..1045834 100644 --- a/report-window/generate-survey-questions.ts +++ b/report-window/generate-survey-questions.ts @@ -1,366 +1,381 @@ 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, - visibleIf: "{popup_type} != 'none'", - elements: [ - { - type: 'radiogroup', - name: f('present'), - isRequired: true, - title: `Cel ujawnienia danych właścicielowi domeny ${host}`, - ...defaultValue('present'), - 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'), + 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"`, - 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"`, + 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', - 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: '{Kliknąłem} przycisk do odmówienia zgody na wszystkie cele', - }, - { - value: 'other', - text: 'Coś innego', - }, - ], - }, - { - 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/report-window/raw-answers.ts b/report-window/raw-answers.ts index 8f81aff..a1e9e08 100644 --- a/report-window/raw-answers.ts +++ b/report-window/raw-answers.ts @@ -19,6 +19,8 @@ export type BasicRawAnswers = { 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'; diff --git a/report-window/verbs.ts b/report-window/verbs.ts index bc0aa05..c962f01 100644 --- a/report-window/verbs.ts +++ b/report-window/verbs.ts @@ -1,36 +1,44 @@ 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'], - 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ęłaś', 'zamknęłoś', 'zamknęliście'], - zwracam: ['zwracam', 'zwracam', 'zwracam', 'zwracamy'], - moich: ['moich', 'moich', 'moich', 'naszych'], - ciebie: ['ciebie', 'ciebie', 'ciebie', 'was'], + 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'], } 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; }