Compare commits

...

2 Commits

3 changed files with 75 additions and 40 deletions

View File

@ -21,7 +21,11 @@ export type HAREntry = {
method: string;
postData?: {
mimeType: string;
params: NameValue[];
params: (NameValue & {
fileName: string;
contentType: string;
comment: "";
})[];
text: string;
};
queryString: NameValue[];
@ -201,27 +205,23 @@ export default class ExtendedRequest {
this.requestBody.raw || {}
).map(([key, value], index) => [`${key}.${index}`, value])
),
})
.map(([key, value]) => {
// to handle how ocdn.eu encrypts POST body on https://businessinsider.com.pl/
if (
(Array.isArray(value) && value.length === 1 && !value[0]) ||
!value
) {
return ["requestBody", key];
} else if (!Array.isArray(value)) {
return [
"raw",
String.fromCharCode.apply(null, new Uint8Array(value.bytes)),
];
} else {
return [key, value || ""];
}
})
.map(([key, value]) => {
const parsed = StolenDataEntry.parseValue(value);
return [key, parsed];
}) as [string, unknown][]
}).map(([key, value]) => {
// to handle how ocdn.eu encrypts POST body on https://businessinsider.com.pl/
if (
(Array.isArray(value) && value.length === 1 && !value[0]) ||
!value
) {
return ["requestBody", key];
} else if (!Array.isArray(value)) {
return [
"raw",
String.fromCharCode.apply(null, new Uint8Array(value.bytes)),
];
} else {
return [key, value || ""];
}
}),
StolenDataEntry.parseValue
).map(
([key, value]) => new StolenDataEntry(this, "request_body", key, value)
);
@ -319,10 +319,14 @@ export default class ExtendedRequest {
pageref: "page_1",
startedDateTime: `${new Date().toJSON().replace("Z", "+01:00")}`,
request: {
bodySize: 0,
bodySize:
JSON.stringify(this.requestBody.formData || {}).length +
(this.requestBody.raw || [])
.map((e) => e.bytes.byteLength)
.reduce((a, b) => a + b, 0),
method: this.data.method,
url: this.data.url,
headersSize: 100,
headersSize: JSON.stringify(this.requestHeaders).length,
httpVersion: "HTTP/2",
headers: this.requestHeaders as NameValue[],
cookies: this.getCookieData().map((cookie) => ({
@ -333,6 +337,22 @@ export default class ExtendedRequest {
name: param.name,
value: param.value,
})),
postData: {
mimeType: "application/x-www-form-urlencoded",
params: this.stolenData
.filter((e) => e.source == "request_body")
.map((e) => ({
name: e.name,
value: e.value,
fileName: "--" + Math.ceil(Math.random() * 1000000000),
contentType: "text/plain",
comment: "",
})),
text: this.stolenData
.filter((e) => e.source == "request_body")
.map((e) => `${e.name}:\t${StolenDataEntry.parseValue(e.value)}`)
.join("\n\n"),
},
},
response: {
status: 200,

View File

@ -1,3 +1,5 @@
import ExtendedRequest from "./extended-request";
import { StolenDataEntry } from "./stolen-data-entry";
import { flattenObject, maskString } from "./util";
console.log(flattenObject({ a: { b: { c: [1, 2, 3] } } }));
@ -5,3 +7,9 @@ console.log(flattenObject({ a: { b: { c: [1, 2, 3] } } }));
console.log(maskString("abcdefghijklmnopqrstuvwxyz", 1 / 3, 5));
console.log(maskString("abcdefghijklmnopqrstuvwxyz", 1, 30));
console.log(
StolenDataEntry.parseValue(
`[{"@context":"https://schema.org/","@type":"Product","image":["/medias/sys_master/root/images/h95/h8b/10873724928030/oppo-reno6-black-front.png","/medias/sys_master/root/images/h15/hb9/10873725681694/oppo-reno6-black-side.png","/medias/sys_master/root/images/hf8/h81/10873728729118/oppo-reno6-black-back.png"],"description":"OPPO Reno6 5G bez umowy lub w abonamencie w sklepie Orange. Zamów do domu lub odbierz w salonie w 24h. Transport gratis!","sku":"1100027218","brand":{"@type":"Thing","name":"OPPO"},"offers":{"@type":"Offer","priceCurrency":"PLN","priceValidUntil":"2099-12-31T00:00:00","itemCondition":"https://schema.org/UsedCondition","availability":"https://schema.org/InStock","url":"/esklep/smartfony/oppo/oppo-reno6-5g","seller":{"@type":"Organization","name":"Orange Polska S.A"},"price":"2199"},"name":"OPPO Reno6 5G"},{"@context":"http://schema.org/","@type":"Product","name":"OPPO Reno6 5G","description":"null","offers":{"@type":"Offer","priceCurrency":"PLN","price":"1248.00"}}]`
)
);

39
util.ts
View File

@ -197,31 +197,38 @@ export function isBase64JSON(s: unknown): s is string {
}
export function flattenObject(
obj: Record<string, unknown>
obj: unknown,
parser: (to_parse: unknown) => string | Record<string, unknown> = (id) =>
id.toString(),
key = "",
ret = [],
parsed = false
): [string, string][] {
const ret: [string, string][] = [];
for (const [key, value] of Object.entries(obj)) {
const value = obj[key];
if (value === null) {
ret.push([key, "null"]);
continue;
if (Array.isArray(obj)) {
for (let i in obj) {
flattenObject(obj[i], parser, key + "." + i, ret);
}
if (typeof value === "object") {
const flattened = flattenObject(value as Record<string, unknown>);
for (const [subkey, subvalue] of flattened) {
ret.push([`${key}.${subkey}`, subvalue]);
}
} else {
ret.push([key, value ? value.toString() : "<empty>"]);
} else if (typeof obj === "object") {
for (const [subkey, value] of Object.entries(obj)) {
flattenObject(value, parser, key + "." + subkey, ret);
}
} else if (!parsed) {
flattenObject(parser(obj), parser, key, ret, true);
} else {
ret.push([key, obj]);
}
if (key == "") {
console.log("FLATTENING!", obj, ret);
}
return ret;
}
export function flattenObjectEntries(
entries: [string, unknown][]
entries: [string, unknown][],
parser: (to_parse: unknown) => string | Record<string, unknown> = (id) =>
id.toString()
): [string, string][] {
return flattenObject(Object.fromEntries(entries));
return flattenObject(Object.fromEntries(entries), parser);
}
export function maskString(