Compare commits
No commits in common. "3eb5dc6f9de174d49913061083833ad699855ee4" and "a84a8f8c1031e4e7070d3fae5b615f5af1adae2a" have entirely different histories.
3eb5dc6f9d
...
a84a8f8c10
@ -8,7 +8,7 @@ export default class Memory extends EventEmitter {
|
||||
private throttle = makeThrottle(200);
|
||||
async register(request: ExtendedRequest) {
|
||||
await request.init();
|
||||
// console.log("registering request for", request.origin);
|
||||
console.log("registering request for", request.origin);
|
||||
if (!request.isThirdParty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -15,13 +15,6 @@ const emailSources: Record<Sources, string> = {
|
||||
queryparams: "jako część adresu URL (query-params)",
|
||||
};
|
||||
|
||||
const source_priority: Array<Sources> = [
|
||||
"cookie",
|
||||
"pathname",
|
||||
"queryparams",
|
||||
"header",
|
||||
];
|
||||
|
||||
export default function DomainSummary({
|
||||
cluster,
|
||||
}: {
|
||||
@ -34,37 +27,13 @@ export default function DomainSummary({
|
||||
<li>Mój adres IP</li>
|
||||
{cluster
|
||||
.getMarks()
|
||||
.sort((markA, markB) => {
|
||||
if (markA.entry.value > markB.entry.value) {
|
||||
return -1;
|
||||
} else if (markA.entry.value > markB.entry.value) {
|
||||
return 1;
|
||||
} else {
|
||||
const indexA = source_priority.indexOf(markA.source);
|
||||
const indexB = source_priority.indexOf(markB.source);
|
||||
if (indexA < indexB) {
|
||||
return -1;
|
||||
} else if (indexA > indexB) {
|
||||
return 1;
|
||||
} else {
|
||||
return markA.name > markB.name ? -1 : 1;
|
||||
}
|
||||
}
|
||||
})
|
||||
.filter((_, index, array) => {
|
||||
if (index == 0) {
|
||||
return true;
|
||||
}
|
||||
if (array[index].valuePreview === array[index - 1].valuePreview) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
})
|
||||
.sort((markA, markB) =>
|
||||
markA.entry.value > markB.entry.value ? -1 : 1
|
||||
)
|
||||
.map((mark) => (
|
||||
<li>
|
||||
{emailClassifications[mark.classification]}{" "}
|
||||
{emailSources[mark.source]} (nazwa: <code>{mark.name}</code>,{" "}
|
||||
{emailSources[mark.source]} (nazwa: {mark.name},{" "}
|
||||
{mark.key ? (
|
||||
<>
|
||||
pozycja <code>{mark.key}</code>,
|
||||
|
@ -59,7 +59,7 @@ function Report() {
|
||||
>
|
||||
{mark.valuePreview}
|
||||
{/* always gonna have
|
||||
one key, because unwrapEntry is called above */}
|
||||
one key, because unwrapEntry is calle above */}
|
||||
</td>
|
||||
<td>
|
||||
<select
|
||||
@ -67,6 +67,7 @@ function Report() {
|
||||
onChange={(e) => {
|
||||
mark.classification = e.target
|
||||
.value as keyof typeof Classifications;
|
||||
console.log("changed classification!");
|
||||
refresh();
|
||||
}}
|
||||
>
|
||||
|
@ -17,9 +17,7 @@ const Sidebar = () => {
|
||||
const [origin, setOrigin] = useState<string | null>(null);
|
||||
const [minValueLength, setMinValueLength] = useState<number | null>(7);
|
||||
const [cookiesOnly, setCookiesOnly] = useState<boolean>(false);
|
||||
const [cookiesOrOriginOnly, setCookiesOrOriginOnly] = useState<boolean>(
|
||||
false
|
||||
);
|
||||
const [cookiesOrOriginOnly, setCookiesOrOriginOnly] = useState<boolean>(true);
|
||||
const [counter, setCounter] = useEmitter(getMemory());
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -1,15 +1,8 @@
|
||||
import React from "react";
|
||||
import { getMemory } from "../memory";
|
||||
import { RequestCluster } from "../request-cluster";
|
||||
import {
|
||||
MergedStolenDataEntry,
|
||||
Sources,
|
||||
StolenDataEntry,
|
||||
} from "../stolen-data-entry";
|
||||
import { MergedStolenDataEntry, Sources } from "../stolen-data-entry";
|
||||
|
||||
import { hyphenate, useEmitter } from "../util";
|
||||
|
||||
const MAX_STRING_VALUE_LENGTH = 100;
|
||||
import { hyphenate } from "../util";
|
||||
|
||||
function StolenDataValueTable({
|
||||
entry,
|
||||
@ -21,29 +14,24 @@ function StolenDataValueTable({
|
||||
return (
|
||||
<table>
|
||||
<tbody>
|
||||
{Object.keys(entry.getParsedValues(prefixKey)[0]).map((key) => {
|
||||
const subkey = `${prefixKey}.${key}`;
|
||||
return (
|
||||
{Object.keys(entry.getParsedValues(prefixKey)[0]).map((key) => (
|
||||
<tr key={`${prefixKey}.${key}`}>
|
||||
<th
|
||||
onClick={(e) => {
|
||||
entry.toggleMark(subkey);
|
||||
entry.toggleMark(prefixKey);
|
||||
e.stopPropagation();
|
||||
}}
|
||||
style={{
|
||||
border: entry.hasMark(subkey)
|
||||
? "2px solid red"
|
||||
: "2px solid transparent",
|
||||
}}
|
||||
>
|
||||
{hyphenate(key)}
|
||||
</th>
|
||||
<td>
|
||||
<StolenDataValue entry={entry} prefixKey={subkey} />
|
||||
<StolenDataValue
|
||||
entry={entry}
|
||||
prefixKey={`${prefixKey}.${key}`}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
@ -56,24 +44,14 @@ function StolenDataValue({
|
||||
entry: MergedStolenDataEntry;
|
||||
prefixKey?: string;
|
||||
}) {
|
||||
const [version] = useEmitter(entry);
|
||||
const value = entry.getParsedValues(prefixKey)[0];
|
||||
let body = null;
|
||||
if (!value) {
|
||||
body = <></>;
|
||||
} else if (typeof value === "string") {
|
||||
const content = entry.getParsedValues(prefixKey)[0] as string;
|
||||
body = (
|
||||
<div
|
||||
style={{
|
||||
border: entry.hasMark(prefixKey)
|
||||
? "2px solid red"
|
||||
: "2px solid transparent",
|
||||
}}
|
||||
data-version={version}
|
||||
>
|
||||
{content.slice(0, MAX_STRING_VALUE_LENGTH)}{" "}
|
||||
{content.length > MAX_STRING_VALUE_LENGTH ? "(...)" : ""}
|
||||
<div style={{ border: entry.hasMark(prefixKey) ? "2px solid red" : "" }}>
|
||||
{entry.getParsedValues(prefixKey)[0] as string}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
@ -92,45 +70,6 @@ function StolenDataValue({
|
||||
);
|
||||
}
|
||||
|
||||
const icons: Record<Sources, string> = {
|
||||
cookie: "🍪",
|
||||
pathname: "🛣",
|
||||
queryparams: "🅿",
|
||||
header: "H",
|
||||
};
|
||||
|
||||
function StolenDataRow({
|
||||
entry,
|
||||
cluster,
|
||||
}: {
|
||||
entry: MergedStolenDataEntry;
|
||||
cluster: RequestCluster;
|
||||
}) {
|
||||
const [version] = useEmitter(entry);
|
||||
return (
|
||||
<tr
|
||||
key={origin + cluster.id + entry.getUniqueKey()}
|
||||
data-key={origin + cluster.id + entry.getUniqueKey()}
|
||||
data-version={version}
|
||||
>
|
||||
<th
|
||||
style={{
|
||||
width: "100px",
|
||||
overflowWrap: "anywhere",
|
||||
border: entry.hasMark("") ? "2px solid red" : "2px solid transparent",
|
||||
}}
|
||||
onClick={() => entry.toggleMark("")}
|
||||
>
|
||||
{entry.getNames().map(hyphenate).join(", ")}
|
||||
</th>
|
||||
<td>{entry.getSources().map((source) => icons[source])}</td>
|
||||
<td style={{ wordWrap: "anywhere" as any }}>
|
||||
<StolenDataValue entry={entry} />
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
export default function StolenDataCluster({
|
||||
origin,
|
||||
shorthost,
|
||||
@ -146,6 +85,12 @@ export default function StolenDataCluster({
|
||||
cookiesOrOriginOnly: boolean;
|
||||
}) {
|
||||
const cluster = getMemory().getClustersForOrigin(origin)[shorthost];
|
||||
const icons: Record<Sources, string> = {
|
||||
cookie: "🍪",
|
||||
pathname: "🛣",
|
||||
queryparams: "🅿",
|
||||
header: "H",
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<h2>
|
||||
@ -169,13 +114,25 @@ export default function StolenDataCluster({
|
||||
{cluster
|
||||
.getStolenData({ minValueLength, cookiesOnly, cookiesOrOriginOnly })
|
||||
.map((entry) => (
|
||||
<StolenDataRow
|
||||
{...{
|
||||
entry,
|
||||
cluster,
|
||||
key: origin + cluster.id + entry.getUniqueKey(),
|
||||
<tr
|
||||
key={origin + cluster.id + entry.getUniqueKey()}
|
||||
data-key={origin + cluster.id + entry.getUniqueKey()}
|
||||
>
|
||||
<th
|
||||
style={{
|
||||
width: "100px",
|
||||
overflowWrap: "anywhere",
|
||||
border: entry.hasMark("") ? "2px solid red" : "",
|
||||
}}
|
||||
/>
|
||||
onClick={() => entry.addMark("")}
|
||||
>
|
||||
{entry.getNames().map(hyphenate).join(", ")}
|
||||
</th>
|
||||
<td>{entry.getSources().map((source) => icons[source])}</td>
|
||||
<td style={{ wordWrap: "anywhere" as any }}>
|
||||
<StolenDataValue entry={entry} />
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { TCModel } from "@iabtcf/core";
|
||||
import { EventEmitter } from "events";
|
||||
import ExtendedRequest, { HAREntry } from "./extended-request";
|
||||
import Mark from "./mark";
|
||||
import { getMemory } from "./memory";
|
||||
import {
|
||||
getshorthost,
|
||||
isJSONObject,
|
||||
@ -29,7 +29,7 @@ const id = (function* id() {
|
||||
}
|
||||
})();
|
||||
|
||||
export class StolenDataEntry extends EventEmitter {
|
||||
export class StolenDataEntry {
|
||||
public isIAB = false;
|
||||
public iab: TCModel | null = null;
|
||||
public id: number;
|
||||
@ -47,7 +47,6 @@ export class StolenDataEntry extends EventEmitter {
|
||||
// // console.log(this.iab);
|
||||
// this.isIAB = true;
|
||||
// } catch (e) {}
|
||||
super();
|
||||
this.id = id.next().value as number;
|
||||
this.classification = this.classify();
|
||||
}
|
||||
@ -82,26 +81,8 @@ export class StolenDataEntry extends EventEmitter {
|
||||
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 object = {
|
||||
[Symbol.for("originalURL")]: value, // so it doesn't appear raw in the table but can be easily retrieved later
|
||||
[Symbol.for("originalURL")]: value,
|
||||
host: url.host,
|
||||
path: url.pathname,
|
||||
...Object.fromEntries(
|
||||
@ -109,7 +90,6 @@ export class StolenDataEntry extends EventEmitter {
|
||||
entries: () => Iterable<[string, string]>;
|
||||
}).entries()
|
||||
),
|
||||
...(hash === "" ? {} : typeof hash === "string" ? { hash } : hash),
|
||||
};
|
||||
return object;
|
||||
} else {
|
||||
@ -128,7 +108,7 @@ export class StolenDataEntry extends EventEmitter {
|
||||
|
||||
addMark(key: string) {
|
||||
this.marks.push(new Mark(this, key));
|
||||
this.emit("change");
|
||||
getMemory().emit("change", true); // to trigger rerender
|
||||
}
|
||||
|
||||
hasMark(key?: string) {
|
||||
@ -141,7 +121,7 @@ export class StolenDataEntry extends EventEmitter {
|
||||
|
||||
removeMark(key: string) {
|
||||
this.marks = this.marks.filter((mark) => mark.key != key);
|
||||
this.emit("change");
|
||||
getMemory().emit("change"); // to trigger rerender
|
||||
}
|
||||
|
||||
toggleMark(key: string) {
|
||||
@ -183,7 +163,7 @@ export class StolenDataEntry extends EventEmitter {
|
||||
getValuePreview(key = ""): string {
|
||||
const value = this.getParsedValue(key);
|
||||
const str = value.toString();
|
||||
if (typeof value !== "object" && this.classification == "id") {
|
||||
if (this.classification == "id") {
|
||||
return (
|
||||
str.slice(0, Math.min(str.length / 3, ID_PREVIEW_MAX_LENGTH)) + "(...)"
|
||||
);
|
||||
@ -195,9 +175,8 @@ export class StolenDataEntry extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
export class MergedStolenDataEntry extends EventEmitter {
|
||||
export class MergedStolenDataEntry {
|
||||
constructor(public entries: StolenDataEntry[]) {
|
||||
super();
|
||||
const all_marks = unique(
|
||||
entries.map((entry) => entry.marks).reduce(reduceConcat, [])
|
||||
);
|
||||
@ -207,20 +186,6 @@ export class MergedStolenDataEntry extends EventEmitter {
|
||||
// getMemory().emit("change"); // to trigger render
|
||||
}
|
||||
|
||||
on(event: string, listener: () => void) {
|
||||
for (const entry of this.entries) {
|
||||
entry.on(event, listener);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
removeListener(event: string, listener: () => void) {
|
||||
for (const entry of this.entries) {
|
||||
entry.removeListener(event, listener);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
hasValue(value: string) {
|
||||
return this.entries.some((entry) => entry.value === value);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user