Merge pull request 'Problem: nieznany cel. Dodanie narzędzi diagnostycznych' (#99) from unknown-purpose into develop
Reviewed-on: #99
This commit is contained in:
		
						commit
						1106e86b41
					
				@ -5,6 +5,7 @@ import { Problem } from './problems/problem';
 | 
				
			|||||||
import { TransferOutsideEU } from './problems/transfer-outside-eu';
 | 
					import { TransferOutsideEU } from './problems/transfer-outside-eu';
 | 
				
			||||||
import { UnknownIdentity } from './problems/unknown-identity';
 | 
					import { UnknownIdentity } from './problems/unknown-identity';
 | 
				
			||||||
import { UnknownLegalBasis } from './problems/unknown-legal-basis';
 | 
					import { UnknownLegalBasis } from './problems/unknown-legal-basis';
 | 
				
			||||||
 | 
					import { UnknownPurposes } from './problems/unknown-purpose';
 | 
				
			||||||
import { UnlawfulCookieAccess } from './problems/unlawful-cookies';
 | 
					import { UnlawfulCookieAccess } from './problems/unlawful-cookies';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function deduceProblems(
 | 
					export default function deduceProblems(
 | 
				
			||||||
@ -13,6 +14,7 @@ export default function deduceProblems(
 | 
				
			|||||||
): Problem[] {
 | 
					): Problem[] {
 | 
				
			||||||
    return [
 | 
					    return [
 | 
				
			||||||
        NoInformationAtAllProblem,
 | 
					        NoInformationAtAllProblem,
 | 
				
			||||||
 | 
					        UnknownPurposes,
 | 
				
			||||||
        UnlawfulCookieAccess,
 | 
					        UnlawfulCookieAccess,
 | 
				
			||||||
        UnknownLegalBasis,
 | 
					        UnknownLegalBasis,
 | 
				
			||||||
        UnknownIdentity,
 | 
					        UnknownIdentity,
 | 
				
			||||||
 | 
				
			|||||||
@ -7,6 +7,8 @@ import './email-content.scss';
 | 
				
			|||||||
import { Fragment, useState } from 'react';
 | 
					import { Fragment, useState } from 'react';
 | 
				
			||||||
import emailIntro from './email-intro';
 | 
					import emailIntro from './email-intro';
 | 
				
			||||||
import { reportIntro } from './report-intro';
 | 
					import { reportIntro } from './report-intro';
 | 
				
			||||||
 | 
					import { downloadText } from '../../util';
 | 
				
			||||||
 | 
					import { getFakeClusterData } from './fake-clusters';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const SS_URL = 'http://65.108.60.135:3000';
 | 
					const SS_URL = 'http://65.108.60.135:3000';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -136,6 +138,23 @@ export default function EmailContent({
 | 
				
			|||||||
                        </p>
 | 
					                        </p>
 | 
				
			||||||
                    </section>
 | 
					                    </section>
 | 
				
			||||||
                ) : null}
 | 
					                ) : null}
 | 
				
			||||||
 | 
					                <div className="diag-toolbox">
 | 
				
			||||||
 | 
					                    <a
 | 
				
			||||||
 | 
					                        href="#"
 | 
				
			||||||
 | 
					                        onClick={() =>
 | 
				
			||||||
 | 
					                            downloadText(
 | 
				
			||||||
 | 
					                                'diag.json',
 | 
				
			||||||
 | 
					                                JSON.stringify({
 | 
				
			||||||
 | 
					                                    answers,
 | 
				
			||||||
 | 
					                                    fake_clusters_data: getFakeClusterData(clusters),
 | 
				
			||||||
 | 
					                                    visited_url,
 | 
				
			||||||
 | 
					                                })
 | 
				
			||||||
 | 
					                            )
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    >
 | 
				
			||||||
 | 
					                        Pobierz plik diagnostyczny
 | 
				
			||||||
 | 
					                    </a>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </Fragment>
 | 
					        </Fragment>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										56
									
								
								components/report-window/fake-clusters.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								components/report-window/fake-clusters.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					// good for diagnostic purposes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { RequestCluster } from '../../request-cluster';
 | 
				
			||||||
 | 
					import { DataLocation } from '../../stolen-data-entry';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type FakeRequestClusterData = {
 | 
				
			||||||
 | 
					    id: string;
 | 
				
			||||||
 | 
					    hasCookies: boolean;
 | 
				
			||||||
 | 
					    hasMarkedCookies: boolean;
 | 
				
			||||||
 | 
					    hasMarks: boolean;
 | 
				
			||||||
 | 
					    exposesOriginWhere: DataLocation[];
 | 
				
			||||||
 | 
					    exposesOrigin: boolean;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function getFakeClusterData(
 | 
				
			||||||
 | 
					    clusters: Record<string, RequestCluster>
 | 
				
			||||||
 | 
					): Record<string, FakeRequestClusterData> {
 | 
				
			||||||
 | 
					    return Object.fromEntries(
 | 
				
			||||||
 | 
					        Object.entries(clusters).map(([key, cluster]) => [key, cluster.makeDataForFake()])
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function makeFakeClusters(
 | 
				
			||||||
 | 
					    fake_clusters_data: Record<string, FakeRequestClusterData>
 | 
				
			||||||
 | 
					): Record<string, FakeCluster> {
 | 
				
			||||||
 | 
					    return Object.fromEntries(
 | 
				
			||||||
 | 
					        Object.entries(fake_clusters_data).map(([key, cluster_data]) => [
 | 
				
			||||||
 | 
					            key,
 | 
				
			||||||
 | 
					            new FakeCluster(cluster_data),
 | 
				
			||||||
 | 
					        ])
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class FakeCluster extends RequestCluster {
 | 
				
			||||||
 | 
					    constructor(public data: FakeRequestClusterData) {
 | 
				
			||||||
 | 
					        super(data.id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (const key of [
 | 
				
			||||||
 | 
					            'hasCookies',
 | 
				
			||||||
 | 
					            'hasMarkedCookies',
 | 
				
			||||||
 | 
					            'hasMarks',
 | 
				
			||||||
 | 
					            'exposesOriginWhere',
 | 
				
			||||||
 | 
					            'exposesOrigin',
 | 
				
			||||||
 | 
					        ]) {
 | 
				
			||||||
 | 
					            //@ts-ignore
 | 
				
			||||||
 | 
					            this[key] = () => {
 | 
				
			||||||
 | 
					                //@ts-ignore
 | 
				
			||||||
 | 
					                return this.data[key];
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    hasCookies() {
 | 
				
			||||||
 | 
					        return this.data.hasCookies;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										109
									
								
								components/report-window/problems/unknown-purpose.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								components/report-window/problems/unknown-purpose.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,109 @@
 | 
				
			|||||||
 | 
					import { RequestCluster } from '../../../request-cluster';
 | 
				
			||||||
 | 
					import { dataLocationToText, wordlist } from '../../../util';
 | 
				
			||||||
 | 
					import { ExplainerKey } from '../explainers';
 | 
				
			||||||
 | 
					import { v } from '../verbs';
 | 
				
			||||||
 | 
					import { Problem } from './problem';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class UnknownPurposes extends Problem {
 | 
				
			||||||
 | 
					    getNecessaryExplainers(): ExplainerKey[] {
 | 
				
			||||||
 | 
					        return [];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    isHostAffected(host: string) {
 | 
				
			||||||
 | 
					        const answers = this.answers.hosts[host];
 | 
				
			||||||
 | 
					        if (!answers) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					            ['not_mentioned', 'not_before_making_a_choice'].includes(answers.present) &&
 | 
				
			||||||
 | 
					            ['no', 'not_sure'].includes(answers.was_processing_necessary) &&
 | 
				
			||||||
 | 
					            (this.clusters[host].hasCookies() || this.clusters[host].exposesOrigin())
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qualifies(): boolean {
 | 
				
			||||||
 | 
					        return Object.keys(this.answers.hosts).some((host) => this.isHostAffected(host));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getAffectedClusters(): RequestCluster[] {
 | 
				
			||||||
 | 
					        return Object.keys(this.answers.hosts)
 | 
				
			||||||
 | 
					            .filter((host) => this.isHostAffected(host))
 | 
				
			||||||
 | 
					            .map((host) => this.clusters[host]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getEmailContent({ mode, tone }: { mode: 'email' | 'report'; tone: 'official' | 'polite' }) {
 | 
				
			||||||
 | 
					        const _ = (key: string) => v(key, this.answers.zaimek);
 | 
				
			||||||
 | 
					        const affected_clusters = this.getAffectedClusters();
 | 
				
			||||||
 | 
					        const has_history = affected_clusters.some((cluster) => cluster.exposesOrigin());
 | 
				
			||||||
 | 
					        const has_cookies = affected_clusters.some((cluster) => cluster.hasCookies());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					            <>
 | 
				
			||||||
 | 
					                <h2>Cele przetwarzania danych</h2>
 | 
				
			||||||
 | 
					                <p>
 | 
				
			||||||
 | 
					                    Państwa strona{' '}
 | 
				
			||||||
 | 
					                    {mode == 'email'
 | 
				
			||||||
 | 
					                        ? `ujawniła dane ${_('mnie')} dotyczące`
 | 
				
			||||||
 | 
					                        : 'ujawnia dane dotyczące użytkowników'}{' '}
 | 
				
			||||||
 | 
					                    w zakresie{' '}
 | 
				
			||||||
 | 
					                    {wordlist([
 | 
				
			||||||
 | 
					                        ...(has_cookies ? ['treści plików cookies'] : []),
 | 
				
			||||||
 | 
					                        ...(has_history
 | 
				
			||||||
 | 
					                            ? [
 | 
				
			||||||
 | 
					                                  mode === 'email'
 | 
				
			||||||
 | 
					                                      ? `części ${_('mojej')} historii przeglądania`
 | 
				
			||||||
 | 
					                                      : `części historii przeglądania`,
 | 
				
			||||||
 | 
					                              ]
 | 
				
			||||||
 | 
					                            : []),
 | 
				
			||||||
 | 
					                    ])}{' '}
 | 
				
			||||||
 | 
					                    podmiotom, które są właścicielami nastepujących domen:
 | 
				
			||||||
 | 
					                </p>
 | 
				
			||||||
 | 
					                <ul>
 | 
				
			||||||
 | 
					                    {affected_clusters.map((cluster, index) => {
 | 
				
			||||||
 | 
					                        const locations = cluster.exposesOriginWhere();
 | 
				
			||||||
 | 
					                        return (
 | 
				
			||||||
 | 
					                            <li>
 | 
				
			||||||
 | 
					                                <strong>{cluster.id}</strong>:{' '}
 | 
				
			||||||
 | 
					                                {wordlist([
 | 
				
			||||||
 | 
					                                    ...(cluster.hasCookies() ? ['treść plików cookies'] : []),
 | 
				
			||||||
 | 
					                                    ...(cluster.exposesOrigin()
 | 
				
			||||||
 | 
					                                        ? [
 | 
				
			||||||
 | 
					                                              (mode === 'email'
 | 
				
			||||||
 | 
					                                                  ? `część ${_('mojej')} historii przeglądania`
 | 
				
			||||||
 | 
					                                                  : `część historii przeglądania użytkownika`) +
 | 
				
			||||||
 | 
					                                                  ' (' +
 | 
				
			||||||
 | 
					                                                  wordlist(
 | 
				
			||||||
 | 
					                                                      locations.map((l) => dataLocationToText(l))
 | 
				
			||||||
 | 
					                                                  ) +
 | 
				
			||||||
 | 
					                                                  ')',
 | 
				
			||||||
 | 
					                                          ]
 | 
				
			||||||
 | 
					                                        : []),
 | 
				
			||||||
 | 
					                                ])}
 | 
				
			||||||
 | 
					                                {index === affected_clusters.length - 1 ? '.' : ';'}
 | 
				
			||||||
 | 
					                            </li>
 | 
				
			||||||
 | 
					                        );
 | 
				
			||||||
 | 
					                    })}
 | 
				
			||||||
 | 
					                </ul>
 | 
				
			||||||
 | 
					                {mode === 'email' ? (
 | 
				
			||||||
 | 
					                    tone === 'official' ? (
 | 
				
			||||||
 | 
					                        <p>
 | 
				
			||||||
 | 
					                            Proszę o wskazanie, jakie są cele takiego przetwarzania danych, które
 | 
				
			||||||
 | 
					                            mnie dotyczą.
 | 
				
			||||||
 | 
					                        </p>
 | 
				
			||||||
 | 
					                    ) : (
 | 
				
			||||||
 | 
					                        <p>
 | 
				
			||||||
 | 
					                            Apeluję o umieszczenie informacji na temat na Państwa stronie, aby jej
 | 
				
			||||||
 | 
					                            użytkownicy mogli podejmować w pełni świadome wybory dotyczące
 | 
				
			||||||
 | 
					                            przetwarzania danych ich dotyczących.
 | 
				
			||||||
 | 
					                        </p>
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                ) : (
 | 
				
			||||||
 | 
					                    <p>
 | 
				
			||||||
 | 
					                        <strong>Zalecenie</strong>: warto dodać informacje o tym, jakie są cele
 | 
				
			||||||
 | 
					                        ujawniania wyżej opisanych danych wyżej opisanym podmiotom trzecim.
 | 
				
			||||||
 | 
					                    </p>
 | 
				
			||||||
 | 
					                )}
 | 
				
			||||||
 | 
					            </>
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -5,6 +5,17 @@
 | 
				
			|||||||
    font-family: 'OpenSans' !important;
 | 
					    font-family: 'OpenSans' !important;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#app {
 | 
				
			||||||
 | 
					    min-height: 100vh;
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    flex-flow: column;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#main-section {
 | 
				
			||||||
 | 
					    flex-grow: 1;
 | 
				
			||||||
 | 
					    margin-bottom: 20px; // to contain diag section
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
html {
 | 
					html {
 | 
				
			||||||
    font-size: 1rem;
 | 
					    font-size: 1rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -289,3 +300,9 @@ h1 {
 | 
				
			|||||||
        color: $ultra-black-color;
 | 
					        color: $ultra-black-color;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.diag-toolbox {
 | 
				
			||||||
 | 
					    position: fixed;
 | 
				
			||||||
 | 
					    bottom: 10px;
 | 
				
			||||||
 | 
					    left: 10px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -110,7 +110,7 @@ function Report() {
 | 
				
			|||||||
                        )}
 | 
					                        )}
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </header>
 | 
					                </header>
 | 
				
			||||||
                <section>{result}</section>
 | 
					                <section id="main-section">{result}</section>
 | 
				
			||||||
            </Fragment>
 | 
					            </Fragment>
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    } catch (e) {
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
				
			|||||||
@ -104,13 +104,11 @@ export default function StolenDataCluster({
 | 
				
			|||||||
    shorthost,
 | 
					    shorthost,
 | 
				
			||||||
    minValueLength,
 | 
					    minValueLength,
 | 
				
			||||||
    cookiesOnly,
 | 
					    cookiesOnly,
 | 
				
			||||||
    refreshToken,
 | 
					 | 
				
			||||||
    cookiesOrOriginOnly,
 | 
					    cookiesOrOriginOnly,
 | 
				
			||||||
    detailsVisibility,
 | 
					    detailsVisibility,
 | 
				
			||||||
}: {
 | 
					}: {
 | 
				
			||||||
    origin: string;
 | 
					    origin: string;
 | 
				
			||||||
    shorthost: string;
 | 
					    shorthost: string;
 | 
				
			||||||
    refreshToken: number;
 | 
					 | 
				
			||||||
    minValueLength: number;
 | 
					    minValueLength: number;
 | 
				
			||||||
    cookiesOnly: boolean;
 | 
					    cookiesOnly: boolean;
 | 
				
			||||||
    cookiesOrOriginOnly: boolean;
 | 
					    cookiesOrOriginOnly: boolean;
 | 
				
			||||||
@ -130,6 +128,10 @@ export default function StolenDataCluster({
 | 
				
			|||||||
                        data-version={version}
 | 
					                        data-version={version}
 | 
				
			||||||
                        checked={cluster.hasMarks()}
 | 
					                        checked={cluster.hasMarks()}
 | 
				
			||||||
                        onChange={() => {
 | 
					                        onChange={() => {
 | 
				
			||||||
 | 
					                            console.log('Clicked checkbox!', {
 | 
				
			||||||
 | 
					                                cluster_id: cluster.id,
 | 
				
			||||||
 | 
					                                has_marks: cluster.hasMarks(),
 | 
				
			||||||
 | 
					                            });
 | 
				
			||||||
                            cluster.hasMarks() ? cluster.undoMark() : cluster.autoMark();
 | 
					                            cluster.hasMarks() ? cluster.undoMark() : cluster.autoMark();
 | 
				
			||||||
                            getMemory().emit('change', cluster.id);
 | 
					                            getMemory().emit('change', cluster.id);
 | 
				
			||||||
                        }}
 | 
					                        }}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										13
									
								
								diag.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								diag.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html>
 | 
				
			||||||
 | 
					    <head>
 | 
				
			||||||
 | 
					        <title>RENTGEN DIAG</title>
 | 
				
			||||||
 | 
					    </head>
 | 
				
			||||||
 | 
					    <body>
 | 
				
			||||||
 | 
					        <div id="app"></div>
 | 
				
			||||||
 | 
					    </body>
 | 
				
			||||||
 | 
					    <script src="/node_modules/react/umd/react.production.min.js"></script>
 | 
				
			||||||
 | 
					    <script src="/node_modules/react-dom/umd/react-dom.production.min.js"></script>
 | 
				
			||||||
 | 
					    <script src="/node_modules/survey-react/survey.react.min.js"></script>
 | 
				
			||||||
 | 
					    <script src="./lib/diag.js"></script>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										65
									
								
								diag.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								diag.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,65 @@
 | 
				
			|||||||
 | 
					import React, { Fragment } from 'react';
 | 
				
			||||||
 | 
					import ReactDOM from 'react-dom';
 | 
				
			||||||
 | 
					import EmailContent from './components/report-window/email-content';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { makeFakeClusters } from './components/report-window/fake-clusters';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ErrorBoundary extends React.Component<any, { hasError: boolean; error: any }> {
 | 
				
			||||||
 | 
					    constructor(props: any) {
 | 
				
			||||||
 | 
					        super(props);
 | 
				
			||||||
 | 
					        this.state = { hasError: false, error: null };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static getDerivedStateFromError(error: any) {
 | 
				
			||||||
 | 
					        return { hasError: true, error };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    render() {
 | 
				
			||||||
 | 
					        if (this.state.hasError) {
 | 
				
			||||||
 | 
					            return <h1>Something went wrong.</h1>;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return this.props.children;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function Diag() {
 | 
				
			||||||
 | 
					    const [json, setjson] = React.useState(
 | 
				
			||||||
 | 
					        JSON.stringify({ answers: { hosts: {} }, visited_url: '', fake_clusters_data: {} })
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    const { answers, visited_url, fake_clusters_data } = JSON.parse(json);
 | 
				
			||||||
 | 
					    const fake_clusters = makeFakeClusters(fake_clusters_data);
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <div style={{ display: 'grid', gridTemplateColumns: '50% 50%', minHeight: '100vh' }}>
 | 
				
			||||||
 | 
					            <div>
 | 
				
			||||||
 | 
					                <textarea
 | 
				
			||||||
 | 
					                    style={{ width: 'calc(100% - 50px)', height: '100%' }}
 | 
				
			||||||
 | 
					                    value={json}
 | 
				
			||||||
 | 
					                    onChange={(e) => {
 | 
				
			||||||
 | 
					                        setjson(e.target.value);
 | 
				
			||||||
 | 
					                    }}
 | 
				
			||||||
 | 
					                ></textarea>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div>
 | 
				
			||||||
 | 
					                <EmailContent
 | 
				
			||||||
 | 
					                    {...{
 | 
				
			||||||
 | 
					                        answers,
 | 
				
			||||||
 | 
					                        visited_url,
 | 
				
			||||||
 | 
					                        clusters: fake_clusters,
 | 
				
			||||||
 | 
					                        scrRequestPath: '/screenshots',
 | 
				
			||||||
 | 
					                        downloadFiles: () => {
 | 
				
			||||||
 | 
					                            alert('download!');
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                        user_role: 'user',
 | 
				
			||||||
 | 
					                    }}
 | 
				
			||||||
 | 
					                />
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ReactDOM.render(
 | 
				
			||||||
 | 
					    <ErrorBoundary>
 | 
				
			||||||
 | 
					        <Diag />
 | 
				
			||||||
 | 
					    </ErrorBoundary>,
 | 
				
			||||||
 | 
					    document.getElementById('app')
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
@ -48,6 +48,7 @@ esbuild
 | 
				
			|||||||
            'components/sidebar/sidebar.tsx',
 | 
					            'components/sidebar/sidebar.tsx',
 | 
				
			||||||
            'components/report-window/report-window.tsx',
 | 
					            'components/report-window/report-window.tsx',
 | 
				
			||||||
            'background.ts',
 | 
					            'background.ts',
 | 
				
			||||||
 | 
					            'diag.tsx',
 | 
				
			||||||
            'styles/global.scss',
 | 
					            'styles/global.scss',
 | 
				
			||||||
            'styles/fonts.scss',
 | 
					            'styles/fonts.scss',
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
import { StolenDataEntry } from './stolen-data-entry';
 | 
					import { DataLocation, StolenDataEntry } from './stolen-data-entry';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
    flattenObjectEntries,
 | 
					    flattenObjectEntries,
 | 
				
			||||||
    getshorthost,
 | 
					    getshorthost,
 | 
				
			||||||
@ -164,12 +164,12 @@ export default class ExtendedRequest {
 | 
				
			|||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    exposesOrigin() {
 | 
					    exposesOriginWhere(): null | DataLocation {
 | 
				
			||||||
        const host = this.originalHost;
 | 
					        const host = this.originalHost;
 | 
				
			||||||
        const path = this.originalPathname || '/';
 | 
					        const path = this.originalPathname || '/';
 | 
				
			||||||
        const shorthost = getshorthost(host);
 | 
					        const shorthost = getshorthost(host);
 | 
				
			||||||
        if (this.getReferer().includes(shorthost)) {
 | 
					        if (this.getReferer().includes(shorthost)) {
 | 
				
			||||||
            return true;
 | 
					            return { path: this.url, source: 'header', key: 'Referer' };
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        for (const entry of this.stolenData) {
 | 
					        for (const entry of this.stolenData) {
 | 
				
			||||||
            if (
 | 
					            if (
 | 
				
			||||||
@ -177,10 +177,14 @@ export default class ExtendedRequest {
 | 
				
			|||||||
                entry.value.includes(path) ||
 | 
					                entry.value.includes(path) ||
 | 
				
			||||||
                entry.value.includes(shorthost)
 | 
					                entry.value.includes(shorthost)
 | 
				
			||||||
            ) {
 | 
					            ) {
 | 
				
			||||||
                return true;
 | 
					                return entry.toDataLocation();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return false;
 | 
					        return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    exposesOrigin() {
 | 
				
			||||||
 | 
					        return this.exposesOriginWhere() !== null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private getAllStolenData(): StolenDataEntry[] {
 | 
					    private getAllStolenData(): StolenDataEntry[] {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,7 @@
 | 
				
			|||||||
 | 
					import { FakeRequestClusterData } from './components/report-window/fake-clusters';
 | 
				
			||||||
import ExtendedRequest from './extended-request';
 | 
					import ExtendedRequest from './extended-request';
 | 
				
			||||||
import { SaferEmitter } from './safer-emitter';
 | 
					import { SaferEmitter } from './safer-emitter';
 | 
				
			||||||
import { Sources, StolenDataEntry } from './stolen-data-entry';
 | 
					import { DataLocation, Sources, StolenDataEntry } from './stolen-data-entry';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { allSubhosts, isSameURL, reduceConcat, unique } from './util';
 | 
					import { allSubhosts, isSameURL, reduceConcat, unique } from './util';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -171,7 +172,13 @@ export class RequestCluster extends SaferEmitter {
 | 
				
			|||||||
        return this.requests.map((request) => request.getMarkedEntries()).reduce(reduceConcat, []);
 | 
					        return this.requests.map((request) => request.getMarkedEntries()).reduce(reduceConcat, []);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    exposesOrigin() {
 | 
					    exposesOriginWhere(): DataLocation[] {
 | 
				
			||||||
 | 
					        return this.requests
 | 
				
			||||||
 | 
					            .map((request) => request.exposesOriginWhere())
 | 
				
			||||||
 | 
					            .filter((l) => l !== null) as DataLocation[];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    exposesOrigin(): boolean {
 | 
				
			||||||
        return this.requests.some((request) => request.exposesOrigin());
 | 
					        return this.requests.some((request) => request.exposesOrigin());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -203,4 +210,15 @@ export class RequestCluster extends SaferEmitter {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        return types_of_data.join(', ');
 | 
					        return types_of_data.join(', ');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    makeDataForFake(): FakeRequestClusterData {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					            id: this.id,
 | 
				
			||||||
 | 
					            hasCookies: this.hasCookies(),
 | 
				
			||||||
 | 
					            hasMarkedCookies: this.hasMarkedCookies(),
 | 
				
			||||||
 | 
					            hasMarks: this.hasMarks(),
 | 
				
			||||||
 | 
					            exposesOriginWhere: this.exposesOriginWhere(),
 | 
				
			||||||
 | 
					            exposesOrigin: this.exposesOrigin(),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -33,6 +33,12 @@ const id = (function* id() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export type DecodingSchema = 'base64' | 'raw';
 | 
					export type DecodingSchema = 'base64' | 'raw';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type DataLocation = {
 | 
				
			||||||
 | 
					    path: string;
 | 
				
			||||||
 | 
					    source: Sources;
 | 
				
			||||||
 | 
					    key: string;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class StolenDataEntry extends SaferEmitter {
 | 
					export class StolenDataEntry extends SaferEmitter {
 | 
				
			||||||
    public isIAB = false;
 | 
					    public isIAB = false;
 | 
				
			||||||
    public id: number;
 | 
					    public id: number;
 | 
				
			||||||
@ -253,4 +259,12 @@ export class StolenDataEntry extends SaferEmitter {
 | 
				
			|||||||
            haystack.includes(getshorthost(this.request.origin))
 | 
					            haystack.includes(getshorthost(this.request.origin))
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    toDataLocation(): DataLocation {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					            path: this.request.url,
 | 
				
			||||||
 | 
					            source: this.source,
 | 
				
			||||||
 | 
					            key: this.name,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										34
									
								
								util.ts
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								util.ts
									
									
									
									
									
								
							@ -1,5 +1,6 @@
 | 
				
			|||||||
import { EventEmitter } from 'events';
 | 
					import { EventEmitter } from 'events';
 | 
				
			||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import { DataLocation, Sources } from './stolen-data-entry';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type Unpromisify<T> = T extends Promise<infer R> ? R : T;
 | 
					export type Unpromisify<T> = T extends Promise<infer R> ? R : T;
 | 
				
			||||||
export type Unarray<T> = T extends Array<infer R> ? R : T;
 | 
					export type Unarray<T> = T extends Array<infer R> ? R : T;
 | 
				
			||||||
@ -283,8 +284,37 @@ export function normalizeForClassname(string: string) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function wordlist(words: string[]) {
 | 
					export function wordlist(words: string[]) {
 | 
				
			||||||
    return words.reduce(
 | 
					    return Array.from(new Set(words)).reduce(
 | 
				
			||||||
        (acc, word, i) => `${acc}${i > 0 ? (i < words.length - 1 ? ',' : ' i') : ''} ${word}`,
 | 
					        (acc, word, i) =>
 | 
				
			||||||
 | 
					            `${acc}${
 | 
				
			||||||
 | 
					                i > 0 ? (i < words.length - 1 ? ', ' : Math.random() > 0.5 ? ' i ' : ' oraz ') : ''
 | 
				
			||||||
 | 
					            }${word}`,
 | 
				
			||||||
        ''
 | 
					        ''
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const source_to_word: Record<Sources, string> = {
 | 
				
			||||||
 | 
					    cookie: 'plik cookie o nazwie',
 | 
				
			||||||
 | 
					    pathname: 'fragment ścieżki w URL',
 | 
				
			||||||
 | 
					    queryparams: 'query params w URL o nazwie',
 | 
				
			||||||
 | 
					    header: 'nagłówek HTTP',
 | 
				
			||||||
 | 
					    request_body: 'body zapytania HTTP, pod kluczem',
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function dataLocationToText(l: DataLocation) {
 | 
				
			||||||
 | 
					    return `${source_to_word[l.source]} ${l.key}`;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function downloadText(filename: string, text: string) {
 | 
				
			||||||
 | 
					    // https://stackoverflow.com/questions/45831191/generate-and-download-file-from-js
 | 
				
			||||||
 | 
					    var element = document.createElement('a');
 | 
				
			||||||
 | 
					    element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
 | 
				
			||||||
 | 
					    element.setAttribute('download', filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    element.style.display = 'none';
 | 
				
			||||||
 | 
					    document.body.appendChild(element);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    element.click();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    document.body.removeChild(element);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user