Generuj treść maila dla {origin}
diff --git a/sidebar/sidebar.tsx b/sidebar/sidebar.tsx
index 8e75107..6a2fd89 100644
--- a/sidebar/sidebar.tsx
+++ b/sidebar/sidebar.tsx
@@ -10,6 +10,8 @@ import TrashIcon from '../assets/icons/trash_full.svg';
import MailIcon from '../assets/icons/mail.svg';
import ShortLeftIcon from '../assets/icons/short_left.svg';
import CloseBigIcon from '../assets/icons/close_big.svg';
+import CookiesIcon from '../assets/icons/cookie.svg';
+import DataIcon from '../assets/icons/data.svg';
async function getCurrentTab() {
const [tab] = await browser.tabs.query({
@@ -75,15 +77,6 @@ const Sidebar = () => {
return (
- {/*
-
-
-
*/}
{
{stolenDataView ? (
@@ -232,8 +223,6 @@ const Sidebar = () => {
/>
)}
-
- {/* */}
);
};
diff --git a/sidebar/stolen-data-cluster.tsx b/sidebar/stolen-data-cluster.tsx
index 340002c..611c845 100644
--- a/sidebar/stolen-data-cluster.tsx
+++ b/sidebar/stolen-data-cluster.tsx
@@ -1,4 +1,4 @@
-import React, { Fragment } from 'react';
+import React from 'react';
import { getMemory } from '../memory';
import { StolenDataEntry } from '../stolen-data-entry';
@@ -38,7 +38,6 @@ function StolenDataValue({
e.stopPropagation();
}}
title={maskString(entry.value, 1, MAX_STRING_VALUE_LENGTH)}
- // style={{ color: entry.isMarked ? 'black' : 'gray' }}
>
{body}
@@ -120,8 +119,6 @@ function StolenDataRow({
) : null}
- {/* */}
-
);
@@ -194,56 +191,5 @@ export default function StolenDataCluster({
-
- //
- //
- //
- //
- //
- // {cluster
- // .calculateRepresentativeStolenData({
- // minValueLength,
- // cookiesOnly,
- // cookiesOrOriginOnly,
- // })
- // .map((entry) => (
- //
- // ))}
- //
- //
- //
);
}
diff --git a/sidebar/stolen-data.tsx b/sidebar/stolen-data.tsx
index c39a4f1..6f40441 100644
--- a/sidebar/stolen-data.tsx
+++ b/sidebar/stolen-data.tsx
@@ -40,49 +40,6 @@ export function StolenData({
);
return (
- {/*
- */}
-
- {/* */}
-
- {/* */}
-
Domeny oraz przesłane informacje
{clusters.map((cluster) => {
diff --git a/stolen-data-entry.ts b/stolen-data-entry.ts
index 6183ffd..f14ed1e 100644
--- a/stolen-data-entry.ts
+++ b/stolen-data-entry.ts
@@ -1,265 +1,269 @@
-// import { TCModel } from "@iabtcf/core";
-import { EventEmitter } from "events";
-import ExtendedRequest, { HAREntry } from "./extended-request";
+import { EventEmitter } from 'events';
+import ExtendedRequest, { HAREntry } from './extended-request';
import {
- getshorthost,
- isBase64,
- isBase64JSON,
- isJSONObject,
- isURL,
- maskString,
- parseToObject,
- safeDecodeURIComponent,
-} from "./util";
+ getshorthost,
+ isBase64,
+ isBase64JSON,
+ isJSONObject,
+ isURL,
+ maskString,
+ parseToObject,
+ safeDecodeURIComponent,
+} from './util';
export type Sources =
- | "cookie"
- | "pathname"
- | "queryparams"
- | "header"
- | "request_body";
+ | 'cookie'
+ | 'pathname'
+ | 'queryparams'
+ | 'header'
+ | 'request_body';
export const Classifications = {
- id: "Identyfikator internetowy",
- history: "Część historii przeglądania",
- location: "Informacje na temat mojego położenia",
+ id: 'Identyfikator internetowy',
+ history: 'Część historii przeglądania',
+ location: 'Informacje na temat mojego położenia',
};
const ID_PREVIEW_MAX_LENGTH = 20;
const MIN_COOKIE_LENGTH_FOR_AUTO_MARK = 15;
const id = (function* id() {
- let i = 0;
- while (true) {
- i++;
- yield i;
- }
+ let i = 0;
+ while (true) {
+ i++;
+ yield i;
+ }
})();
-export type DecodingSchema = "base64" | "raw";
+export type DecodingSchema = 'base64' | 'raw';
export class StolenDataEntry extends EventEmitter {
- public isIAB = false;
- // public iab: TCModel | null = null;
- public id: number;
- private marked = false;
- public classification: keyof typeof Classifications;
- public decoding_applied: DecodingSchema = "raw";
- public decodings_available: DecodingSchema[] = ["raw"];
+ public isIAB = false;
+ public id: number;
+ private marked = false;
+ public classification: keyof typeof Classifications;
+ public decoding_applied: DecodingSchema = 'raw';
+ public decodings_available: DecodingSchema[] = ['raw'];
- constructor(
- public request: ExtendedRequest,
- public source: Sources,
- public name: string,
- public value: string
- ) {
- // try {
- // this.iab = TCString.decode(value);
- // // console.log(this.iab);
- // this.isIAB = true;
- // } catch (e) {}
- super();
- this.id = id.next().value as number;
- this.classification = this.classify();
- if (isBase64(value)) {
- this.decodings_available.push("base64");
- }
- }
-
- getPriority() {
- let priority = 0;
- priority += Math.min(this.value.length, 50);
- const url = new URL(this.request.originalURL);
- if (this.value.includes(url.host)) {
- priority += 100;
- }
- if (this.value.includes(url.pathname)) {
- priority += 100;
- }
- if (this.source === "cookie") {
- priority += 200;
- }
- return priority;
- }
-
- get isMarked() {
- return this.marked;
- }
-
- hasValue(value: string) {
- return this.value === value;
- }
-
- static parseValue(value: unknown): string | Record {
- if (isBase64JSON(value)) {
- return StolenDataEntry.parseValue({ base64: JSON.parse(atob(value)) });
- }
- if (value === undefined) {
- return "";
- }
- if (isJSONObject(value)) {
- const object = parseToObject(value);
- return object;
- } else if (isURL(value)) {
- const url = new URL(value);
- let hash = url.hash;
- if (hash.includes("=")) {
- //facebook sometimes includes querystring-encoded data into the hash... attempt to parse it
- try {
- hash = Object.fromEntries(
- hash
- .slice(1)
- .split("&")
- .map((kv) => kv.split("="))
- );
- } catch (e) {
- // failed to parse as query string
- console.log(
- "Failed attempt to parse hash location as query string, probably safe to ignore:",
- e
- );
+ constructor(
+ public request: ExtendedRequest,
+ public source: Sources,
+ public name: string,
+ public value: string
+ ) {
+ super();
+ this.id = id.next().value as number;
+ this.classification = this.classify();
+ if (isBase64(value)) {
+ this.decodings_available.push('base64');
}
- }
- const searchParams = Object.fromEntries(
- (
- url.searchParams as unknown as {
- entries: () => Iterable<[string, string]>;
- }
- ).entries()
- );
- if (typeof hash !== "object" && Object.keys(searchParams).length === 0) {
- return value; // just a string;
- }
- const object = {
- [Symbol.for("originalString")]: value, // so it doesn't appear raw in the table but can be easily retrieved later
- host: url.host,
- path: url.pathname,
- searchParams,
- ...(hash === "" ? {} : typeof hash === "string" ? { hash } : hash),
- };
- return object;
- } else if (value === null) {
- return "null";
- } else {
- return value.toString();
}
- }
- getParsedValue(key_path: string): string | Record {
- let object = StolenDataEntry.parseValue(this.value);
- for (const key of key_path.split(".")) {
- if (key === "") continue;
- object = StolenDataEntry.parseValue(object[key]);
+ getPriority() {
+ let priority = 0;
+ priority += Math.min(this.value.length, 50);
+ const url = new URL(this.request.originalURL);
+ if (this.value.includes(url.host)) {
+ priority += 100;
+ }
+ if (this.value.includes(url.pathname)) {
+ priority += 100;
+ }
+ if (this.source === 'cookie') {
+ priority += 200;
+ }
+ return priority;
}
- return object;
- }
- mark() {
- const had_been_marked_before = this.marked;
- this.marked = true;
- if (!had_been_marked_before) {
- this.emit("change");
+ get isMarked() {
+ return this.marked;
}
- }
- unmark() {
- const had_been_marked_before = this.marked;
- this.marked = false;
- if (had_been_marked_before) {
- this.emit("change");
+ hasValue(value: string) {
+ return this.value === value;
}
- }
- toggleMark() {
- if (this.marked) {
- this.unmark();
- } else {
- this.mark();
+ static parseValue(value: unknown): string | Record {
+ if (isBase64JSON(value)) {
+ return StolenDataEntry.parseValue({
+ base64: JSON.parse(atob(value)),
+ });
+ }
+ if (value === undefined) {
+ return '';
+ }
+ if (isJSONObject(value)) {
+ const object = parseToObject(value);
+ return object;
+ } else if (isURL(value)) {
+ const url = new URL(value);
+ let hash = url.hash;
+ if (hash.includes('=')) {
+ //facebook sometimes includes querystring-encoded data into the hash... attempt to parse it
+ try {
+ hash = Object.fromEntries(
+ hash
+ .slice(1)
+ .split('&')
+ .map((kv) => kv.split('='))
+ );
+ } catch (e) {
+ // failed to parse as query string
+ console.log(
+ 'Failed attempt to parse hash location as query string, probably safe to ignore:',
+ e
+ );
+ }
+ }
+ const searchParams = Object.fromEntries(
+ (
+ url.searchParams as unknown as {
+ entries: () => Iterable<[string, string]>;
+ }
+ ).entries()
+ );
+ if (
+ typeof hash !== 'object' &&
+ Object.keys(searchParams).length === 0
+ ) {
+ return value; // just a string;
+ }
+ const object = {
+ [Symbol.for('originalString')]: value, // so it doesn't appear raw in the table but can be easily retrieved later
+ host: url.host,
+ path: url.pathname,
+ searchParams,
+ ...(hash === ''
+ ? {}
+ : typeof hash === 'string'
+ ? { hash }
+ : hash),
+ };
+ return object;
+ } else if (value === null) {
+ return 'null';
+ } else {
+ return value.toString();
+ }
}
- }
- private classify(): keyof typeof Classifications {
- let result: keyof typeof Classifications;
- if (this.exposesOrigin()) {
- result = "history";
- } else {
- result = "id";
+ getParsedValue(
+ key_path: string
+ ): string | Record {
+ let object = StolenDataEntry.parseValue(this.value);
+ for (const key of key_path.split('.')) {
+ if (key === '') continue;
+ object = StolenDataEntry.parseValue(object[key]);
+ }
+ return object;
}
- return result;
- }
- isRelatedToID() {
- return this.request.stolenData.some(
- (entry) => entry.classification == "id"
- );
- }
-
- matchesHAREntry(har: HAREntry): boolean {
- return this.request.matchesHAREntry(har);
- }
-
- getValuePreview(key = ""): string {
- const value = this.getParsedValue(key);
- const str =
- typeof value === "object" && value[Symbol.for("originalString")]
- ? (value[Symbol.for("originalString")] as string)
- : value.toString();
- if (typeof value !== "object" && this.classification == "id") {
- return maskString(value, 1 / 3, ID_PREVIEW_MAX_LENGTH);
- } else if (
- typeof value === "object" &&
- value[Symbol.for("originalString")]
- ) {
- return value[Symbol.for("originalString")] as string;
- } else {
- return str;
+ mark() {
+ const had_been_marked_before = this.marked;
+ this.marked = true;
+ if (!had_been_marked_before) {
+ this.emit('change');
+ }
}
- }
- getUniqueKey() {
- return this.request.shorthost + ";" + this.name + ";" + this.value;
- }
-
- exposesOrigin(): boolean {
- return this.exposesHost() || this.exposesPath();
- }
-
- autoMark() {
- if (
- this.classification == "history" ||
- ((this.source === "cookie" ||
- this.name.toLowerCase().includes("id") ||
- this.name.toLowerCase().includes("cookie") ||
- this.name.toLowerCase().includes("ga") ||
- this.name.toLowerCase().includes("ses") ||
- this.name.toLowerCase().includes("fb")) &&
- this.value.length > MIN_COOKIE_LENGTH_FOR_AUTO_MARK)
- ) {
- if (
- (this.request.shorthost.includes("google") ||
- this.request.shorthost.includes("youtube")) &&
- this.name == "CONSENT"
- ) {
- // this cookie contains "YES" and might distract the person looking at it into thinking i gave consent on the reported site
- return;
- }
- this.mark();
+ unmark() {
+ const had_been_marked_before = this.marked;
+ this.marked = false;
+ if (had_been_marked_before) {
+ this.emit('change');
+ }
}
- }
- exposesPath() {
- return (
- this.request.originalPathname !== "/" &&
- [this.value, safeDecodeURIComponent(this.value)].some((haystack) =>
- haystack.includes(this.request.originalPathname)
- )
- );
- }
+ toggleMark() {
+ if (this.marked) {
+ this.unmark();
+ } else {
+ this.mark();
+ }
+ }
- exposesHost() {
- return [this.value, safeDecodeURIComponent(this.value)].some((haystack) =>
- haystack.includes(getshorthost(this.request.origin))
- );
- }
+ private classify(): keyof typeof Classifications {
+ let result: keyof typeof Classifications;
+ if (this.exposesOrigin()) {
+ result = 'history';
+ } else {
+ result = 'id';
+ }
+ return result;
+ }
+
+ isRelatedToID() {
+ return this.request.stolenData.some(
+ (entry) => entry.classification == 'id'
+ );
+ }
+
+ matchesHAREntry(har: HAREntry): boolean {
+ return this.request.matchesHAREntry(har);
+ }
+
+ getValuePreview(key = ''): string {
+ const value = this.getParsedValue(key);
+ const str =
+ typeof value === 'object' && value[Symbol.for('originalString')]
+ ? (value[Symbol.for('originalString')] as string)
+ : value.toString();
+ if (typeof value !== 'object' && this.classification == 'id') {
+ return maskString(value, 1 / 3, ID_PREVIEW_MAX_LENGTH);
+ } else if (
+ typeof value === 'object' &&
+ value[Symbol.for('originalString')]
+ ) {
+ return value[Symbol.for('originalString')] as string;
+ } else {
+ return str;
+ }
+ }
+
+ getUniqueKey() {
+ return this.request.shorthost + ';' + this.name + ';' + this.value;
+ }
+
+ exposesOrigin(): boolean {
+ return this.exposesHost() || this.exposesPath();
+ }
+
+ autoMark() {
+ if (
+ this.classification == 'history' ||
+ ((this.source === 'cookie' ||
+ this.name.toLowerCase().includes('id') ||
+ this.name.toLowerCase().includes('cookie') ||
+ this.name.toLowerCase().includes('ga') ||
+ this.name.toLowerCase().includes('ses') ||
+ this.name.toLowerCase().includes('fb')) &&
+ this.value.length > MIN_COOKIE_LENGTH_FOR_AUTO_MARK)
+ ) {
+ if (
+ (this.request.shorthost.includes('google') ||
+ this.request.shorthost.includes('youtube')) &&
+ this.name == 'CONSENT'
+ ) {
+ // this cookie contains "YES" and might distract the person looking at it into thinking i gave consent on the reported site
+ return;
+ }
+ this.mark();
+ }
+ }
+
+ exposesPath() {
+ return (
+ this.request.originalPathname !== '/' &&
+ [this.value, safeDecodeURIComponent(this.value)].some((haystack) =>
+ haystack.includes(this.request.originalPathname)
+ )
+ );
+ }
+
+ exposesHost() {
+ return [this.value, safeDecodeURIComponent(this.value)].some(
+ (haystack) => haystack.includes(getshorthost(this.request.origin))
+ );
+ }
}
|