Add unknown-legal-basis problem

This commit is contained in:
Kuba Orlik 2022-07-07 21:16:48 +02:00
parent 6e062f92d7
commit f39bfd12b5
13 changed files with 100 additions and 26 deletions

View File

@ -2,18 +2,14 @@ import { RequestCluster } from '../../request-cluster';
import { ParsedAnswers } from './parse-answers'; import { ParsedAnswers } from './parse-answers';
import NoInformationAtAllProblem from './problems/no-information-at-all'; import NoInformationAtAllProblem from './problems/no-information-at-all';
import { Problem } from './problems/problem'; import { Problem } from './problems/problem';
import { UnknownLegalBasis } from './problems/unknown-legal-basis';
import { UnlawfulCookieAccess } from './problems/unlawful-cookies'; import { UnlawfulCookieAccess } from './problems/unlawful-cookies';
export default function deduceProblems( export default function deduceProblems(
answers: ParsedAnswers, answers: ParsedAnswers,
clusters: Record<string, RequestCluster> clusters: Record<string, RequestCluster>
): Problem[] { ): Problem[] {
const problems = []; return [NoInformationAtAllProblem, UnlawfulCookieAccess, UnknownLegalBasis]
if (answers.popup_type === 'none') { .map((c) => new c(answers, clusters))
problems.push(new NoInformationAtAllProblem(answers, clusters)); .filter((p) => p.qualifies());
}
if (UnlawfulCookieAccess.qualifies(answers, Object.values(clusters))) {
problems.push(new UnlawfulCookieAccess(answers, clusters));
}
return problems;
} }

View File

@ -19,6 +19,7 @@ export default function EmailContent({
visited_url: string; visited_url: string;
clusters: Record<string, RequestCluster>; clusters: Record<string, RequestCluster>;
}) { }) {
console.log('rendering email!', answers);
const _ = (key: string) => v(key, answers.zaimek); const _ = (key: string) => v(key, answers.zaimek);
const problems = deduceProblems(answers, clusters); const problems = deduceProblems(answers, clusters);
const explainers = Array.from( const explainers = Array.from(

View File

@ -20,7 +20,7 @@ export const Explainers: Record<ExplainerKey, (zaimek_index: 0 | 1 | 2 | 3) => J
W wypadku, gdy ujawnienie czy dostęp do danych osobowych zostało dokonane przez W wypadku, gdy ujawnienie czy dostęp do danych osobowych zostało dokonane przez
skrypty podmiotów trzecich (np. Google, Facebook, itp), których autorem nie jest skrypty podmiotów trzecich (np. Google, Facebook, itp), których autorem nie jest
Administrator strony, Administrator wciąż jest odpowiedzialny za procesy Administrator strony, Administrator wciąż jest odpowiedzialny za procesy
przetwarzania danych osobowych, jakie realizują te skrypty&mdash;w myśl treści{' '} przetwarzania danych osobowych, jakie realizują te skrypty - w myśl treści{' '}
<a href="https://curia.europa.eu/juris/document/document.jsf?text=&docid=216555&pageIndex=0&doclang=PL&mode=lst&dir=&occ=first&part=1&cid=1254905"> <a href="https://curia.europa.eu/juris/document/document.jsf?text=&docid=216555&pageIndex=0&doclang=PL&mode=lst&dir=&occ=first&part=1&cid=1254905">
wyroku TSUE w sprawie C-40/17 wyroku TSUE w sprawie C-40/17
</a> </a>

View File

@ -16,14 +16,7 @@ function generateHostPage(
return { defaultValueExpression: `{${f(name, previous_cluster)}}` }; return { defaultValueExpression: `{${f(name, previous_cluster)}}` };
} }
const domain = cluster.id; const domain = cluster.id;
let types_of_data: string[] = []; const danych = cluster.getDataTypeDescription();
if (cluster.exposesOrigin()) {
types_of_data.push('część Twojej historii przeglądania');
}
if (cluster.hasMarkedCookies()) {
types_of_data.push('unikalne ID z cookies');
}
const danych = types_of_data.join(', ');
return { return {
title: cluster.id, title: cluster.id,
elements: [ elements: [

View File

@ -50,6 +50,7 @@ export function parseAnswers({
mentions_passive_consent, mentions_passive_consent,
rejection_is_hard, rejection_is_hard,
administrator_identity_available_before_choice, administrator_identity_available_before_choice,
popup_action,
...rest ...rest
}: RawAnswers): ParsedAnswers { }: RawAnswers): ParsedAnswers {
return { return {
@ -62,6 +63,7 @@ export function parseAnswers({
mentions_passive_consent, mentions_passive_consent,
rejection_is_hard, rejection_is_hard,
administrator_identity_available_before_choice, administrator_identity_available_before_choice,
popup_action,
hosts: parseHostAnswers(rest), hosts: parseHostAnswers(rest),
} as ParsedAnswers; } as ParsedAnswers;
} }

View File

@ -3,6 +3,9 @@ import { v } from '../verbs';
import { Problem } from './problem'; import { Problem } from './problem';
export default class NoInformationAtAllProblem extends Problem { export default class NoInformationAtAllProblem extends Problem {
qualifies() {
return this.answers.popup_type === 'none';
}
getEmailContent() { getEmailContent() {
const _ = (word: string) => v(word, this.answers.zaimek); const _ = (word: string) => v(word, this.answers.zaimek);
return ( return (

View File

@ -19,6 +19,7 @@ export abstract class Problem {
abstract getEmailContent(): JSX.Element; abstract getEmailContent(): JSX.Element;
abstract getNecessaryExplainers(): ExplainerKey[]; abstract getNecessaryExplainers(): ExplainerKey[];
abstract qualifies(): boolean;
getMarkedClusters() { getMarkedClusters() {
return Object.values(this.clusters).filter((c) => c.hasMarks()); return Object.values(this.clusters).filter((c) => c.hasMarks());

View File

@ -0,0 +1,70 @@
import { RequestCluster } from '../../../request-cluster';
import { ExplainerKey } from '../explainers';
import { ParsedHostAnswers } from '../parse-answers';
import { v } from '../verbs';
import { Problem } from './problem';
const testCluster: (cluster: RequestCluster, answers: ParsedHostAnswers | undefined) => boolean = (
cluster,
hostAnswers
) => {
if (!hostAnswers) {
return false;
}
if (cluster.hasMarkedCookies()) {
/* if it has cookies, it will be picked up by the UnlawfulCookieAccess problem, and that one
is pretty detailed, so no need to mention it here. */
return false;
}
return hostAnswers.legal_basis_type == 'not_mentioned';
};
export class UnknownLegalBasis extends Problem {
getNecessaryExplainers(): ExplainerKey[] {
return ['responsibility_for_third_parties'];
}
qualifies(): boolean {
return Object.values(this.clusters).some((cluster) =>
testCluster(cluster, this.answers.hosts[cluster.id])
);
}
getRelatedClusters() {
return Object.values(this.clusters).filter((cluster) =>
testCluster(cluster, this.answers.hosts[cluster.id])
);
}
getEmailContent() {
const clusters = this.getRelatedClusters();
const _ = (key: string) => v(key, this.answers.zaimek);
return (
<>
<h2>Przetwarzanie danych osobowych bez podania podstawy prawnej</h2>
<p>Państwa strona przetworzyła {_('moje')} dane osobowe poprzez ujawnienie:</p>
<ul>
{clusters.map((cluster) => (
<li key={cluster.id}>
Właścicielowi domeny <strong>{cluster.id}</strong>:{' '}
{cluster.getDataTypeDescription('mojej')}
</li>
))}
</ul>
<p>
{_('Moja')} historia przeglądania stanowi {_('moje')} dane osobowe. Zgodnie z
treścią Artykułu 13 p. 1 lit. c){' '}
<a href="https://eur-lex.europa.eu/legal-content/PL/TXT/HTML/?uri=CELEX:32016R0679&qid=1632163985520&from=PL#d1e1822-1-1">
RODO
</a>
, aby przetwarzać dane osobowe, trzeba poinformować osobę, której dane dotyczą,
o tym, jaka jest podstawa prawna takiego przetwarzania danych.
</p>
<p>
Zwracam się zatem z pytaniem: jakie były podstawy prawne ujawnienia moich danych
każdemu z wyżej wymienionych podmiotów przez Państwa stronę?
</p>
</>
);
}
}

View File

@ -1,7 +1,5 @@
import { RequestCluster } from '../../../request-cluster';
import { wordlist } from '../../../util'; import { wordlist } from '../../../util';
import { ExplainerKey } from '../explainers'; import { ExplainerKey } from '../explainers';
import { ParsedAnswers } from '../parse-answers';
import { v } from '../verbs'; import { v } from '../verbs';
import { Problem } from './problem'; import { Problem } from './problem';
@ -10,16 +8,16 @@ export class UnlawfulCookieAccess extends Problem {
return ['cookies_are_pii', 'responsibility_for_third_parties']; return ['cookies_are_pii', 'responsibility_for_third_parties'];
} }
static qualifies(answers: ParsedAnswers, clusters: RequestCluster[]): boolean { qualifies(): boolean {
// są cookiesy, nie było zgody, nie są konieczne do działania strony // są cookiesy, nie było zgody, nie są konieczne do działania strony
const cookie_clusters = Object.values(clusters).filter((c) => c.hasMarkedCookies()); const cookie_clusters = Object.values(this.clusters).filter((c) => c.hasMarkedCookies());
return cookie_clusters.some((cluster) => { return cookie_clusters.some((cluster) => {
const hostAnswers = answers.hosts[cluster.id]; const hostAnswers = this.answers.hosts[cluster.id];
return ( return (
(hostAnswers.present == 'not_mentioned' || (hostAnswers.present == 'not_mentioned' ||
hostAnswers.present == 'not_before_making_a_choice' || hostAnswers.present == 'not_before_making_a_choice' ||
['none', 'closed_popup', 'deny_all'].includes(answers.popup_action) || ['none', 'closed_popup', 'deny_all'].includes(this.answers.popup_action) ||
answers.popup_type === 'none') && this.answers.popup_type === 'none') &&
hostAnswers.was_processing_necessary != 'yes' hostAnswers.was_processing_necessary != 'yes'
); );
}); });

View File

@ -8,6 +8,7 @@ const words = {
mnie: ['mnie', 'mnie', 'mnie', 'nas'], mnie: ['mnie', 'mnie', 'mnie', 'nas'],
moich: ['moich', 'moich', 'moich', 'naszych'], moich: ['moich', 'moich', 'moich', 'naszych'],
moje: ['moje', 'moje', 'moje', 'nasze'], moje: ['moje', 'moje', 'moje', 'nasze'],
moja: ['moja', 'moja', 'moja', 'nasza'],
mojej: ['mojej', 'mojej', 'mojej', 'naszej'], mojej: ['mojej', 'mojej', 'mojej', 'naszej'],
muszę: ['muszę', 'muszę', 'muszę', 'musimy'], muszę: ['muszę', 'muszę', 'muszę', 'musimy'],
odkliknąłeś: ['odkliknąłeś', 'odkliknęłaś', 'odklikęłoś', 'odkliknęliście'], odkliknąłeś: ['odkliknąłeś', 'odkliknęłaś', 'odklikęłoś', 'odkliknęliście'],

1
package-lock.json generated
View File

@ -5,7 +5,6 @@
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "rentgen",
"version": "0.0.3", "version": "0.0.3",
"license": "GPL-3.0-or-later", "license": "GPL-3.0-or-later",
"dependencies": { "dependencies": {

View File

@ -182,4 +182,15 @@ export class RequestCluster extends SaferEmitter {
entry.unmark(); entry.unmark();
}); });
} }
getDataTypeDescription(noun = 'Twojej') {
let types_of_data: string[] = [];
if (this.exposesOrigin()) {
types_of_data.push(`część ${noun} historii przeglądania`);
}
if (this.hasMarkedCookies()) {
types_of_data.push('unikalne ID z cookies');
}
return types_of_data.join(', ');
}
} }

View File

@ -48,7 +48,6 @@ export class SaferEmitter extends EventEmitter {
Reflect.apply(listener, this, args); Reflect.apply(listener, this, args);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
debugger;
} }
}); });
} }