Various improvement to make the sidebar and the email more concise

This commit is contained in:
Kuba Orlik 2021-11-21 22:38:32 +01:00
parent a84a8f8c10
commit 25cd2c2a0c
6 changed files with 108 additions and 39 deletions

View File

@ -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;
}

View File

@ -15,6 +15,13 @@ 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,
}: {
@ -27,13 +34,37 @@ export default function DomainSummary({
<li>Mój adres IP</li>
{cluster
.getMarks()
.sort((markA, markB) =>
markA.entry.value > markB.entry.value ? -1 : 1
)
.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;
}
})
.map((mark) => (
<li>
{emailClassifications[mark.classification]}{" "}
{emailSources[mark.source]} (nazwa: {mark.name},{" "}
{emailSources[mark.source]} (nazwa: <code>{mark.name}</code>,{" "}
{mark.key ? (
<>
pozycja <code>{mark.key}</code>,

View File

@ -59,7 +59,7 @@ function Report() {
>
{mark.valuePreview}
{/* always gonna have
one key, because unwrapEntry is calle above */}
one key, because unwrapEntry is called above */}
</td>
<td>
<select
@ -67,7 +67,6 @@ function Report() {
onChange={(e) => {
mark.classification = e.target
.value as keyof typeof Classifications;
console.log("changed classification!");
refresh();
}}
>

View File

@ -17,7 +17,9 @@ 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>(true);
const [cookiesOrOriginOnly, setCookiesOrOriginOnly] = useState<boolean>(
false
);
const [counter, setCounter] = useEmitter(getMemory());
useEffect(() => {

View File

@ -4,6 +4,8 @@ import { MergedStolenDataEntry, Sources } from "../stolen-data-entry";
import { hyphenate } from "../util";
const MAX_STRING_VALUE_LENGTH = 100;
function StolenDataValueTable({
entry,
prefixKey = "",
@ -14,24 +16,29 @@ function StolenDataValueTable({
return (
<table>
<tbody>
{Object.keys(entry.getParsedValues(prefixKey)[0]).map((key) => (
<tr key={`${prefixKey}.${key}`}>
<th
onClick={(e) => {
entry.toggleMark(prefixKey);
e.stopPropagation();
}}
>
{hyphenate(key)}
</th>
<td>
<StolenDataValue
entry={entry}
prefixKey={`${prefixKey}.${key}`}
/>
</td>
</tr>
))}
{Object.keys(entry.getParsedValues(prefixKey)[0]).map((key) => {
const subkey = `${prefixKey}.${key}`;
return (
<tr key={`${prefixKey}.${key}`}>
<th
onClick={(e) => {
entry.toggleMark(subkey);
e.stopPropagation();
}}
style={{
border: entry.hasMark(subkey)
? "2px solid red"
: "2px solid transparent",
}}
>
{hyphenate(key)}
</th>
<td>
<StolenDataValue entry={entry} prefixKey={subkey} />
</td>
</tr>
);
})}
</tbody>
</table>
);
@ -49,9 +56,17 @@ function StolenDataValue({
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" : "" }}>
{entry.getParsedValues(prefixKey)[0] as string}
<div
style={{
border: entry.hasMark(prefixKey)
? "2px solid red"
: "2px solid transparent",
}}
>
{content.slice(0, MAX_STRING_VALUE_LENGTH)}{" "}
{content.length > MAX_STRING_VALUE_LENGTH ? "(...)" : ""}
</div>
);
} else {
@ -70,6 +85,13 @@ function StolenDataValue({
);
}
const icons: Record<Sources, string> = {
cookie: "🍪",
pathname: "🛣",
queryparams: "🅿",
header: "H",
};
export default function StolenDataCluster({
origin,
shorthost,
@ -85,12 +107,6 @@ 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>
@ -122,9 +138,11 @@ export default function StolenDataCluster({
style={{
width: "100px",
overflowWrap: "anywhere",
border: entry.hasMark("") ? "2px solid red" : "",
border: entry.hasMark("")
? "2px solid red"
: "2px solid transparent",
}}
onClick={() => entry.addMark("")}
onClick={() => entry.toggleMark("")}
>
{entry.getNames().map(hyphenate).join(", ")}
</th>

View File

@ -81,8 +81,26 @@ export class StolenDataEntry {
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,
[Symbol.for("originalURL")]: value, // so it doesn't appear raw in the table but can be easily retrieved later
host: url.host,
path: url.pathname,
...Object.fromEntries(
@ -90,6 +108,7 @@ export class StolenDataEntry {
entries: () => Iterable<[string, string]>;
}).entries()
),
...(hash === "" ? {} : typeof hash === "string" ? { hash } : hash),
};
return object;
} else {
@ -121,7 +140,7 @@ export class StolenDataEntry {
removeMark(key: string) {
this.marks = this.marks.filter((mark) => mark.key != key);
getMemory().emit("change"); // to trigger rerender
getMemory().emit("change", true); // to trigger rerender
}
toggleMark(key: string) {
@ -163,7 +182,7 @@ export class StolenDataEntry {
getValuePreview(key = ""): string {
const value = this.getParsedValue(key);
const str = value.toString();
if (this.classification == "id") {
if (typeof value !== "object" && this.classification == "id") {
return (
str.slice(0, Math.min(str.length / 3, ID_PREVIEW_MAX_LENGTH)) + "(...)"
);