Compare commits

..

No commits in common. "b1c84b99ac6a4c26be4cc5253106a19e60cd4472" and "9c1eb3122456269010ce2af793bf29f1cededf8e" have entirely different histories.

13 changed files with 251 additions and 295 deletions

View File

@ -1,5 +1,6 @@
import esbuild from 'esbuild'; import esbuild from 'esbuild';
import scss from 'esbuild-plugin-sass'; import scss from 'esbuild-plugin-sass';
import svg from 'esbuild-plugin-svgr';
const watch = process.argv.includes('--watch') && { const watch = process.argv.includes('--watch') && {
onRebuild(error) { onRebuild(error) {
@ -8,39 +9,6 @@ const watch = process.argv.includes('--watch') && {
}, },
}; };
// see https://github.com/evanw/esbuild/issues/806#issuecomment-779138268
let skipReactImports = {
name: 'skipReactImports',
setup(build) {
build.onResolve({ filter: /^react(-dom)?$/ }, (args) => {
return {
path: args.path,
namespace: `globalExternal_${args.path}`,
};
});
build.onLoad(
{ filter: /.*/, namespace: 'globalExternal_react' },
() => {
return {
contents: `module.exports = globalThis.React`,
loader: 'js',
};
}
);
build.onLoad(
{ filter: /.*/, namespace: 'globalExternal_react-dom' },
() => {
return {
contents: `module.exports = globalThis.ReactDOM`,
loader: 'js',
};
}
);
},
};
esbuild esbuild
.build({ .build({
entryPoints: [ entryPoints: [
@ -53,8 +21,7 @@ esbuild
// minify: true, // minify: true,
outdir: './lib', outdir: './lib',
loader: { '.woff': 'file', '.woff2': 'file' }, loader: { '.woff': 'file', '.woff2': 'file' },
plugins: [scss(), skipReactImports], plugins: [scss(), svg()],
external: ['react', 'react-dom'],
watch, watch,
}) })
.then(() => console.log('Add-on was built')) .then(() => console.log('Add-on was built'))

View File

@ -44,6 +44,7 @@
"addons-linter": "^4.7.0", "addons-linter": "^4.7.0",
"esbuild": "^0.14.14", "esbuild": "^0.14.14",
"esbuild-plugin-sass": "^1.0.1", "esbuild-plugin-sass": "^1.0.1",
"esbuild-plugin-svgr": "^1.0.0",
"web-ext": "^6.6.0", "web-ext": "^6.6.0",
"web-ext-types": "^3.2.1" "web-ext-types": "^3.2.1"
} }

View File

@ -1,4 +1,5 @@
import React from 'react'; import React from 'react';
import { useState } from 'react';
import { RequestCluster } from '../request-cluster'; import { RequestCluster } from '../request-cluster';
import { StolenDataEntry } from '../stolen-data-entry'; import { StolenDataEntry } from '../stolen-data-entry';
import { getDate, toBase64 } from '../util'; import { getDate, toBase64 } from '../util';
@ -14,13 +15,12 @@ export default function EmailTemplate1({
clusters: Record<string, RequestCluster>; clusters: Record<string, RequestCluster>;
version: number; version: number;
}): JSX.Element { }): JSX.Element {
const [popupState, setPopupState] = const [popupState, setPopupState] = useState<PopupState>('not_clicked');
React.useState<PopupState>('not_clicked'); const [acceptAllName, setAcceptAllName] = useState<string>(
const [acceptAllName, setAcceptAllName] = React.useState<string>(
'Zaakceptuj wszystkie' 'Zaakceptuj wszystkie'
); );
const [popupScreenshotBase64, setPopupScreenshotBase64] = const [popupScreenshotBase64, setPopupScreenshotBase64] =
React.useState<string>(null); useState<string>(null);
return ( return (
<div> <div>

View File

@ -1,4 +1,5 @@
import React from 'react'; import React from 'react';
import { Dispatch, SetStateAction } from 'react';
import { toBase64 } from '../util'; import { toBase64 } from '../util';
import { EmailTemplate2Config } from './email-template-2'; import { EmailTemplate2Config } from './email-template-2';
@ -7,7 +8,7 @@ export default function EmailTemplate2Controls({
setConfig, setConfig,
}: { }: {
config: EmailTemplate2Config; config: EmailTemplate2Config;
setConfig: React.Dispatch<React.SetStateAction<EmailTemplate2Config>>; setConfig: Dispatch<SetStateAction<EmailTemplate2Config>>;
}): JSX.Element { }): JSX.Element {
return ( return (
<div> <div>

View File

@ -1,4 +1,4 @@
import React from 'react'; import React, { useState } from 'react';
import { RequestCluster } from '../request-cluster'; import { RequestCluster } from '../request-cluster';
import { StolenDataEntry } from '../stolen-data-entry'; import { StolenDataEntry } from '../stolen-data-entry';
import { getDate, unique } from '../util'; import { getDate, unique } from '../util';
@ -75,7 +75,7 @@ export default function EmailTemplate2({
clusters: Record<string, RequestCluster>; clusters: Record<string, RequestCluster>;
version: number; version: number;
}): JSX.Element { }): JSX.Element {
const [config, setConfig] = React.useState<EmailTemplate2Config>({ const [config, setConfig] = useState<EmailTemplate2Config>({
popup_type: 'none', popup_type: 'none',
popup_action: 'ignored', popup_action: 'ignored',
popup_screenshot_base64: null, popup_screenshot_base64: null,

View File

@ -1,4 +1,4 @@
import React from 'react'; import React, { useState } from 'react';
import { RequestCluster } from '../request-cluster'; import { RequestCluster } from '../request-cluster';
import { StolenDataEntry } from '../stolen-data-entry'; import { StolenDataEntry } from '../stolen-data-entry';
import EmailTemplate1 from './email-template-1'; import EmailTemplate1 from './email-template-1';
@ -13,7 +13,7 @@ export default function EmailTemplate({
clusters: Record<string, RequestCluster>; clusters: Record<string, RequestCluster>;
version: number; version: number;
}) { }) {
const [templateVersion, setTemplateVersion] = React.useState('2'); const [templateVersion, setTemplateVersion] = useState('2');
return ( return (
<div> <div>
<select <select

View File

@ -1,4 +1,4 @@
import React from 'react'; import React, { useEffect, useState } from 'react';
import { HAREntry } from '../extended-request'; import { HAREntry } from '../extended-request';
import { StolenDataEntry } from '../stolen-data-entry'; import { StolenDataEntry } from '../stolen-data-entry';
import { getshorthost, unique } from '../util'; import { getshorthost, unique } from '../util';
@ -80,11 +80,11 @@ export default function HARConverter({
}: { }: {
entries: StolenDataEntry[]; entries: StolenDataEntry[];
}) { }) {
const [filtered, setFiltered] = React.useState<Blob | null>(null); const [filtered, setFiltered] = useState<Blob | null>(null);
const [filename, setFilename] = React.useState(''); const [filename, setFilename] = useState('');
const [fakeHAR, setFakeHAR] = const [fakeHAR, setFakeHAR] =
React.useState<ReturnType<typeof generateFakeHAR>>(); useState<ReturnType<typeof generateFakeHAR>>();
React.useEffect(() => { useEffect(() => {
setFakeHAR(generateFakeHAR(entries)); setFakeHAR(generateFakeHAR(entries));
}, []); }, []);

View File

@ -1,4 +1,4 @@
import React from 'react'; import React, { useEffect, useState } from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import { getMemory } from '../memory'; import { getMemory } from '../memory';
import { Classifications, StolenDataEntry } from '../stolen-data-entry'; import { Classifications, StolenDataEntry } from '../stolen-data-entry';
@ -88,12 +88,15 @@ function Report() {
console.time('useMemory'); console.time('useMemory');
const [counter, setCounter] = useEmitter(getMemory()); const [counter, setCounter] = useEmitter(getMemory());
console.timeEnd('useMemory'); console.timeEnd('useMemory');
function refresh() {
setCounter((c) => c + 1);
}
console.time('getClustersForOrigin'); console.time('getClustersForOrigin');
const clusters = getMemory().getClustersForOrigin(origin); const clusters = getMemory().getClustersForOrigin(origin);
console.timeEnd('getClustersForOrigin'); console.timeEnd('getClustersForOrigin');
const [entries, setEntries] = React.useState<StolenDataEntry[]>([]); const [entries, setEntries] = useState<StolenDataEntry[]>([]);
console.time('useEffect report-window'); console.time('useEffect report-window');
React.useEffect(() => { useEffect(() => {
setEntries( setEntries(
Object.values(clusters) Object.values(clusters)
.map((cluster) => { .map((cluster) => {

View File

@ -18,8 +18,6 @@
rel="stylesheet" rel="stylesheet"
href="/lib/sidebar/sidebar.css" href="/lib/sidebar/sidebar.css"
> >
<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="/lib/sidebar/sidebar.js"></script> <script src="/lib/sidebar/sidebar.js"></script>
</body> </body>

View File

@ -1,4 +1,4 @@
import React from 'react'; import React, { Fragment, useEffect, useState } from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import Options from '../options'; import Options from '../options';
import { StolenData } from './stolen-data'; import { StolenData } from './stolen-data';
@ -17,247 +17,232 @@ import './global.scss';
import './sidebar.scss'; import './sidebar.scss';
const Sidebar = () => { const Sidebar = () => {
try { const [origin, setOrigin] = useState<string | null>(null);
const [origin, setOrigin] = React.useState<string | null>(null); const [minValueLength, setMinValueLength] = useState<number | null>(
const [minValueLength, setMinValueLength] = React.useState< localStorage.getItem('minValueLength') === null
number | null ? 7
>( : (localStorage.getItem('minValueLength') as unknown as number)
localStorage.getItem('minValueLength') === null );
? 7 const [cookiesOnly, setCookiesOnly] = useState<boolean>(false);
: (localStorage.getItem('minValueLength') as unknown as number) const [stolenDataView, setStolenDataView] = useState<boolean>(true);
); const [cookiesOrOriginOnly, setCookiesOrOriginOnly] =
const [cookiesOnly, setCookiesOnly] = React.useState<boolean>(false); useState<boolean>(false);
const [stolenDataView, setStolenDataView] = const [counter, setCounter] = useEmitter(getMemory());
React.useState<boolean>(true); const [marksOccurrence, setMarksOccurrence] = useState<boolean>(false);
const [cookiesOrOriginOnly, setCookiesOrOriginOnly] = const [warningDataDialogAck, setWarningDataDialogAck] = useState<boolean>(
React.useState<boolean>(false); localStorage.getItem('warningDataDialogAck') === null
const [counter, setCounter] = useEmitter(getMemory()); ? true
const [marksOccurrence, setMarksOccurrence] = : localStorage.getItem('warningDataDialogAck') == 'true'
React.useState<boolean>(false); ? true
const [warningDataDialogAck, setWarningDataDialogAck] = : false
React.useState<boolean>( );
localStorage.getItem('warningDataDialogAck') === null const [logoVisibility, setLogoVisibility] = useState<boolean>(
? true localStorage.getItem('logoVisibility') === null
: localStorage.getItem('warningDataDialogAck') == 'true' ? false
? true : localStorage.getItem('logoVisibility') == 'true'
: false ? true
); : false
const [logoVisibility, setLogoVisibility] = React.useState<boolean>( );
localStorage.getItem('logoVisibility') === null
? false
: localStorage.getItem('logoVisibility') == 'true'
? true
: false
);
React.useEffect(() => { useEffect(() => {
const listener = async (data: any) => { const listener = async (data: any) => {
console.log('tab change!'); console.log('tab change!');
const tab = await getCurrentTab(); const tab = await getCurrentTab();
const url = new URL(tab.url); const url = new URL(tab.url);
if (url.origin.startsWith('moz-extension')) { if (url.origin.startsWith('moz-extension')) {
return; return;
}
setOrigin(url.origin);
};
browser.tabs.onUpdated.addListener(listener);
return () => {
browser.tabs.onUpdated.removeListener(listener);
};
});
React.useEffect(() => {
for (const cluster of Object.values(
getMemory().getClustersForOrigin(origin)
)) {
if (cluster.hasMarks()) {
return setMarksOccurrence(true);
}
} }
return setMarksOccurrence(false); setOrigin(url.origin);
}, [counter, origin]); };
browser.tabs.onUpdated.addListener(listener);
return () => {
browser.tabs.onUpdated.removeListener(listener);
};
});
return ( useEffect(() => {
<div className="sidebar"> for (const cluster of Object.values(
<header getMemory().getClustersForOrigin(origin)
)) {
if (cluster.hasMarks()) {
return setMarksOccurrence(true);
}
}
return setMarksOccurrence(false);
}, [counter, origin]);
return (
<div className="sidebar">
<header
className={
logoVisibility ? 'header' : 'header header--without-logo'
}
>
<img
src="../assets/logo-internet-czas-dzialac.svg"
height={40}
style={!logoVisibility ? { display: 'none' } : null}
></img>
<div
className={ className={
logoVisibility logoVisibility
? 'header' ? 'webpage-metadata'
: 'header header--without-logo' : 'webpage-metadata webpage-metadata--without-logo'
} }
> >
<img {origin ? (
src="../assets/logo-internet-czas-dzialac.svg" <Fragment>
height={40} <span>Analiza strony</span>
style={!logoVisibility ? { display: 'none' } : null} <span className="webpage-metadata--hyperlink">
></img> {origin}
<div
className={
logoVisibility
? 'webpage-metadata'
: 'webpage-metadata webpage-metadata--without-logo'
}
>
{origin ? (
<>
<span>Analiza strony</span>
<span className="webpage-metadata--hyperlink">
{origin}
</span>
</>
) : (
<span>Przejdź do wybranej strony internetowej</span>
)}
</div>
{stolenDataView ? (
<a href="https://internet-czas-dzialac.pl">
<img
src="/assets/icons/info_circle_outline.svg"
width="20"
height="20"
/>
</a>
) : (
<button onClick={() => setStolenDataView(true)}>
<img
src="/assets/icons/short_left.svg"
width="20"
height="20"
/>
</button>
)}
</header>
{stolenDataView ? (
<nav>
<button
onClick={() => setStolenDataView(!stolenDataView)}
>
<img
src="/assets/icons/settings.svg"
width="20"
height="20"
/>
<span>Ustawienia</span>
</button>
<button
onClick={() => {
getMemory().removeRequestsFor(origin);
setCounter((c) => c + 1);
setMarksOccurrence(false);
}}
>
<img
src="/assets/icons/trash_full.svg"
width="20"
height="20"
/>
<span>Wyczyść historię wtyczki</span>
</button>
<button
onClick={() => {
getMemory().removeCookiesFor(origin);
setCounter((c) => c + 1);
setMarksOccurrence(false);
}}
>
<img
src="/assets/icons/cookie.svg"
width="20"
height="20"
/>
<span>Wyczyść ciasteczka</span>
</button>
<button
disabled={!marksOccurrence}
title={
marksOccurrence
? 'Kliknij, aby wygenerować wiadomość'
: 'Zaznacz poniżej elementy, aby móc wygenerować wiadomość'
}
onClick={() => {
const params = [
'height=' + screen.height,
'width=' + screen.width,
'fullscreen=yes',
].join(',');
window.open(
`/report-window/report-window.html?origin=${origin}`,
'new_window',
params
);
}}
>
<img
src="/assets/icons/mail.svg"
width="20"
height="20"
/>
<span>
Utwórz wiadomość dla administratora witryny
</span> </span>
</button> </Fragment>
</nav>
) : null}
<section>
{stolenDataView ? (
<>
{warningDataDialogAck ? (
<section className="warning-container">
<span>
<strong>Uwaga!</strong> Niekoniecznie
każda przechwycona poniżej informacja
jest daną osobową. Niektóre z podanych
domen mogą należeć do właściciela strony
i nie reprezentować podmiotów trzecich.
</span>
<button
onClick={() => {
setWarningDataDialogAck(false);
localStorage.setItem(
'warningDataDialogAck',
false as unknown as string
);
}}
>
<img
src="/assets/icons/close_big.svg"
width="16"
height="16"
/>
</button>
</section>
) : null}
<StolenData
origin={origin}
refreshToken={counter}
refresh={() => setCounter((c) => c + 1)}
minValueLength={minValueLength}
cookiesOnly={cookiesOnly}
cookiesOrOriginOnly={cookiesOrOriginOnly}
/>
</>
) : ( ) : (
<Options <span>Przejdź do wybranej strony internetowej</span>
minValueLength={minValueLength}
setMinValueLength={setMinValueLength}
cookiesOnly={cookiesOnly}
setCookiesOnly={setCookiesOnly}
cookiesOrOriginOnly={cookiesOrOriginOnly}
setCookiesOrOriginOnly={setCookiesOrOriginOnly}
warningDataDialogAck={warningDataDialogAck}
setWarningDataDialogAck={setWarningDataDialogAck}
logoVisibility={logoVisibility}
setLogoVisibility={setLogoVisibility}
/>
)} )}
</section> </div>
</div> {stolenDataView ? (
); <a href="https://internet-czas-dzialac.pl">
} catch (e) { <img
console.error(e); src="/assets/icons/info_circle_outline.svg"
} width="20"
height="20"
/>
</a>
) : (
<button onClick={() => setStolenDataView(true)}>
<img
src="/assets/icons/short_left.svg"
width="20"
height="20"
/>
</button>
)}
</header>
{stolenDataView ? (
<nav>
<button onClick={() => setStolenDataView(!stolenDataView)}>
<img
src="/assets/icons/settings.svg"
width="20"
height="20"
/>
<span>Ustawienia</span>
</button>
<button
onClick={() => {
getMemory().removeRequestsFor(origin);
setCounter((c) => c + 1);
setMarksOccurrence(false);
}}
>
<img
src="/assets/icons/trash_full.svg"
width="20"
height="20"
/>
<span>Wyczyść historię wtyczki</span>
</button>
<button
onClick={() => {
getMemory().removeCookiesFor(origin);
setCounter((c) => c + 1);
setMarksOccurrence(false);
}}
>
<img
src="/assets/icons/cookie.svg"
width="20"
height="20"
/>
<span>Wyczyść ciasteczka</span>
</button>
<button
disabled={!marksOccurrence}
title={
marksOccurrence
? 'Kliknij, aby wygenerować wiadomość'
: 'Zaznacz poniżej elementy, aby móc wygenerować wiadomość'
}
onClick={() => {
const params = [
'height=' + screen.height,
'width=' + screen.width,
'fullscreen=yes',
].join(',');
window.open(
`/report-window/report-window.html?origin=${origin}`,
'new_window',
params
);
}}
>
<img
src="/assets/icons/mail.svg"
width="20"
height="20"
/>
<span>Utwórz wiadomość dla administratora witryny</span>
</button>
</nav>
) : null}
<section>
{stolenDataView ? (
<Fragment>
{warningDataDialogAck ? (
<section className="warning-container">
<span>
<strong>Uwaga!</strong> Niekoniecznie każda
przechwycona poniżej informacja jest daną
osobową. Niektóre z podanych domen mogą
należeć do właściciela strony i nie
reprezentować podmiotów trzecich.
</span>
<button
onClick={() => {
setWarningDataDialogAck(false);
localStorage.setItem(
'warningDataDialogAck',
false as unknown as string
);
}}
>
<img
src="/assets/icons/close_big.svg"
width="16"
height="16"
/>
</button>
</section>
) : null}
<StolenData
origin={origin}
refreshToken={counter}
refresh={() => setCounter((c) => c + 1)}
minValueLength={minValueLength}
cookiesOnly={cookiesOnly}
cookiesOrOriginOnly={cookiesOrOriginOnly}
/>
</Fragment>
) : (
<Options
minValueLength={minValueLength}
setMinValueLength={setMinValueLength}
cookiesOnly={cookiesOnly}
setCookiesOnly={setCookiesOnly}
cookiesOrOriginOnly={cookiesOrOriginOnly}
setCookiesOrOriginOnly={setCookiesOrOriginOnly}
warningDataDialogAck={warningDataDialogAck}
setWarningDataDialogAck={setWarningDataDialogAck}
logoVisibility={logoVisibility}
setLogoVisibility={setLogoVisibility}
/>
)}
</section>
</div>
);
}; };
debugger;
ReactDOM.render(<Sidebar />, document.getElementById('app')); ReactDOM.render(<Sidebar />, document.getElementById('app'));

View File

@ -1,4 +1,5 @@
import React from 'react'; import React from 'react';
import { useEffect, useState } from 'react';
export default function TabDropdown({ export default function TabDropdown({
setPickedTab, setPickedTab,
@ -7,8 +8,8 @@ export default function TabDropdown({
setPickedTab: (tab_id: number) => void; setPickedTab: (tab_id: number) => void;
pickedTab: number; pickedTab: number;
}) { }) {
const [tabs, setTabs] = React.useState([]); const [tabs, setTabs] = useState([]);
React.useEffect(() => { useEffect(() => {
browser.tabs.query({ currentWindow: true }).then(setTabs); browser.tabs.query({ currentWindow: true }).then(setTabs);
}, []); }, []);
return ( return (

View File

@ -1,6 +1,6 @@
{ {
"compilerOptions": { "compilerOptions": {
"jsx": "react-jsx", "jsx": "react",
"noImplicitAny": true, "noImplicitAny": true,
"esModuleInterop": true, "esModuleInterop": true,
"lib": ["es2017", "dom", "es2019"], "lib": ["es2017", "dom", "es2019"],

View File

@ -1,5 +1,5 @@
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import React from 'react'; import { Dispatch, SetStateAction, useEffect, useState } from 'react';
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;
@ -47,9 +47,9 @@ export function getshorthost(host: string) {
export function useEmitter( export function useEmitter(
e: EventEmitter e: EventEmitter
): [number, React.Dispatch<React.SetStateAction<number>>] { ): [number, Dispatch<SetStateAction<number>>] {
const [counter, setCounter] = React.useState<number>(0); const [counter, setCounter] = useState<number>(0);
React.useEffect(() => { useEffect(() => {
const callback = () => { const callback = () => {
setCounter((counter) => counter + 1); setCounter((counter) => counter + 1);
}; };