Various improvement to make the sidebar and the email more concise
This commit is contained in:
parent
a84a8f8c10
commit
25cd2c2a0c
|
@ -8,7 +8,7 @@ export default class Memory extends EventEmitter {
|
||||||
private throttle = makeThrottle(200);
|
private throttle = makeThrottle(200);
|
||||||
async register(request: ExtendedRequest) {
|
async register(request: ExtendedRequest) {
|
||||||
await request.init();
|
await request.init();
|
||||||
console.log("registering request for", request.origin);
|
// console.log("registering request for", request.origin);
|
||||||
if (!request.isThirdParty()) {
|
if (!request.isThirdParty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,13 @@ const emailSources: Record<Sources, string> = {
|
||||||
queryparams: "jako część adresu URL (query-params)",
|
queryparams: "jako część adresu URL (query-params)",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const source_priority: Array<Sources> = [
|
||||||
|
"cookie",
|
||||||
|
"pathname",
|
||||||
|
"queryparams",
|
||||||
|
"header",
|
||||||
|
];
|
||||||
|
|
||||||
export default function DomainSummary({
|
export default function DomainSummary({
|
||||||
cluster,
|
cluster,
|
||||||
}: {
|
}: {
|
||||||
|
@ -27,13 +34,37 @@ export default function DomainSummary({
|
||||||
<li>Mój adres IP</li>
|
<li>Mój adres IP</li>
|
||||||
{cluster
|
{cluster
|
||||||
.getMarks()
|
.getMarks()
|
||||||
.sort((markA, markB) =>
|
.sort((markA, markB) => {
|
||||||
markA.entry.value > markB.entry.value ? -1 : 1
|
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) => (
|
.map((mark) => (
|
||||||
<li>
|
<li>
|
||||||
{emailClassifications[mark.classification]}{" "}
|
{emailClassifications[mark.classification]}{" "}
|
||||||
{emailSources[mark.source]} (nazwa: {mark.name},{" "}
|
{emailSources[mark.source]} (nazwa: <code>{mark.name}</code>,{" "}
|
||||||
{mark.key ? (
|
{mark.key ? (
|
||||||
<>
|
<>
|
||||||
pozycja <code>{mark.key}</code>,
|
pozycja <code>{mark.key}</code>,
|
||||||
|
|
|
@ -59,7 +59,7 @@ function Report() {
|
||||||
>
|
>
|
||||||
{mark.valuePreview}
|
{mark.valuePreview}
|
||||||
{/* always gonna have
|
{/* always gonna have
|
||||||
one key, because unwrapEntry is calle above */}
|
one key, because unwrapEntry is called above */}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<select
|
<select
|
||||||
|
@ -67,7 +67,6 @@ function Report() {
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
mark.classification = e.target
|
mark.classification = e.target
|
||||||
.value as keyof typeof Classifications;
|
.value as keyof typeof Classifications;
|
||||||
console.log("changed classification!");
|
|
||||||
refresh();
|
refresh();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
|
@ -17,7 +17,9 @@ const Sidebar = () => {
|
||||||
const [origin, setOrigin] = useState<string | null>(null);
|
const [origin, setOrigin] = useState<string | null>(null);
|
||||||
const [minValueLength, setMinValueLength] = useState<number | null>(7);
|
const [minValueLength, setMinValueLength] = useState<number | null>(7);
|
||||||
const [cookiesOnly, setCookiesOnly] = useState<boolean>(false);
|
const [cookiesOnly, setCookiesOnly] = useState<boolean>(false);
|
||||||
const [cookiesOrOriginOnly, setCookiesOrOriginOnly] = useState<boolean>(true);
|
const [cookiesOrOriginOnly, setCookiesOrOriginOnly] = useState<boolean>(
|
||||||
|
false
|
||||||
|
);
|
||||||
const [counter, setCounter] = useEmitter(getMemory());
|
const [counter, setCounter] = useEmitter(getMemory());
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
@ -4,6 +4,8 @@ import { MergedStolenDataEntry, Sources } from "../stolen-data-entry";
|
||||||
|
|
||||||
import { hyphenate } from "../util";
|
import { hyphenate } from "../util";
|
||||||
|
|
||||||
|
const MAX_STRING_VALUE_LENGTH = 100;
|
||||||
|
|
||||||
function StolenDataValueTable({
|
function StolenDataValueTable({
|
||||||
entry,
|
entry,
|
||||||
prefixKey = "",
|
prefixKey = "",
|
||||||
|
@ -14,24 +16,29 @@ function StolenDataValueTable({
|
||||||
return (
|
return (
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
{Object.keys(entry.getParsedValues(prefixKey)[0]).map((key) => (
|
{Object.keys(entry.getParsedValues(prefixKey)[0]).map((key) => {
|
||||||
<tr key={`${prefixKey}.${key}`}>
|
const subkey = `${prefixKey}.${key}`;
|
||||||
<th
|
return (
|
||||||
onClick={(e) => {
|
<tr key={`${prefixKey}.${key}`}>
|
||||||
entry.toggleMark(prefixKey);
|
<th
|
||||||
e.stopPropagation();
|
onClick={(e) => {
|
||||||
}}
|
entry.toggleMark(subkey);
|
||||||
>
|
e.stopPropagation();
|
||||||
{hyphenate(key)}
|
}}
|
||||||
</th>
|
style={{
|
||||||
<td>
|
border: entry.hasMark(subkey)
|
||||||
<StolenDataValue
|
? "2px solid red"
|
||||||
entry={entry}
|
: "2px solid transparent",
|
||||||
prefixKey={`${prefixKey}.${key}`}
|
}}
|
||||||
/>
|
>
|
||||||
</td>
|
{hyphenate(key)}
|
||||||
</tr>
|
</th>
|
||||||
))}
|
<td>
|
||||||
|
<StolenDataValue entry={entry} prefixKey={subkey} />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
);
|
);
|
||||||
|
@ -49,9 +56,17 @@ function StolenDataValue({
|
||||||
if (!value) {
|
if (!value) {
|
||||||
body = <></>;
|
body = <></>;
|
||||||
} else if (typeof value === "string") {
|
} else if (typeof value === "string") {
|
||||||
|
const content = entry.getParsedValues(prefixKey)[0] as string;
|
||||||
body = (
|
body = (
|
||||||
<div style={{ border: entry.hasMark(prefixKey) ? "2px solid red" : "" }}>
|
<div
|
||||||
{entry.getParsedValues(prefixKey)[0] as string}
|
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>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -70,6 +85,13 @@ function StolenDataValue({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const icons: Record<Sources, string> = {
|
||||||
|
cookie: "🍪",
|
||||||
|
pathname: "🛣",
|
||||||
|
queryparams: "🅿",
|
||||||
|
header: "H",
|
||||||
|
};
|
||||||
|
|
||||||
export default function StolenDataCluster({
|
export default function StolenDataCluster({
|
||||||
origin,
|
origin,
|
||||||
shorthost,
|
shorthost,
|
||||||
|
@ -85,12 +107,6 @@ export default function StolenDataCluster({
|
||||||
cookiesOrOriginOnly: boolean;
|
cookiesOrOriginOnly: boolean;
|
||||||
}) {
|
}) {
|
||||||
const cluster = getMemory().getClustersForOrigin(origin)[shorthost];
|
const cluster = getMemory().getClustersForOrigin(origin)[shorthost];
|
||||||
const icons: Record<Sources, string> = {
|
|
||||||
cookie: "🍪",
|
|
||||||
pathname: "🛣",
|
|
||||||
queryparams: "🅿",
|
|
||||||
header: "H",
|
|
||||||
};
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h2>
|
<h2>
|
||||||
|
@ -122,9 +138,11 @@ export default function StolenDataCluster({
|
||||||
style={{
|
style={{
|
||||||
width: "100px",
|
width: "100px",
|
||||||
overflowWrap: "anywhere",
|
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(", ")}
|
{entry.getNames().map(hyphenate).join(", ")}
|
||||||
</th>
|
</th>
|
||||||
|
|
|
@ -81,8 +81,26 @@ export class StolenDataEntry {
|
||||||
return object;
|
return object;
|
||||||
} else if (isURL(value)) {
|
} else if (isURL(value)) {
|
||||||
const url = new URL(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 = {
|
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,
|
host: url.host,
|
||||||
path: url.pathname,
|
path: url.pathname,
|
||||||
...Object.fromEntries(
|
...Object.fromEntries(
|
||||||
|
@ -90,6 +108,7 @@ export class StolenDataEntry {
|
||||||
entries: () => Iterable<[string, string]>;
|
entries: () => Iterable<[string, string]>;
|
||||||
}).entries()
|
}).entries()
|
||||||
),
|
),
|
||||||
|
...(hash === "" ? {} : typeof hash === "string" ? { hash } : hash),
|
||||||
};
|
};
|
||||||
return object;
|
return object;
|
||||||
} else {
|
} else {
|
||||||
|
@ -121,7 +140,7 @@ export class StolenDataEntry {
|
||||||
|
|
||||||
removeMark(key: string) {
|
removeMark(key: string) {
|
||||||
this.marks = this.marks.filter((mark) => mark.key != key);
|
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) {
|
toggleMark(key: string) {
|
||||||
|
@ -163,7 +182,7 @@ export class StolenDataEntry {
|
||||||
getValuePreview(key = ""): string {
|
getValuePreview(key = ""): string {
|
||||||
const value = this.getParsedValue(key);
|
const value = this.getParsedValue(key);
|
||||||
const str = value.toString();
|
const str = value.toString();
|
||||||
if (this.classification == "id") {
|
if (typeof value !== "object" && this.classification == "id") {
|
||||||
return (
|
return (
|
||||||
str.slice(0, Math.min(str.length / 3, ID_PREVIEW_MAX_LENGTH)) + "(...)"
|
str.slice(0, Math.min(str.length / 3, ID_PREVIEW_MAX_LENGTH)) + "(...)"
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user