@zkp2p/reclaim-witness-sdk
Version:
<div> <div> <img src="https://raw.githubusercontent.com/reclaimprotocol/.github/main/assets/banners/Attestor-Core.png" /> </div> </div>
360 lines • 27.2 kB
JavaScript
// noinspection ExceptionCaughtLocallyJS
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractHTMLElement = extractHTMLElement;
exports.extractHTMLElements = extractHTMLElements;
exports.extractHTMLElementIndex = extractHTMLElementIndex;
exports.extractHTMLElementsIndexes = extractHTMLElementsIndexes;
exports.extractJSONValueIndex = extractJSONValueIndex;
exports.extractJSONValueIndexes = extractJSONValueIndexes;
exports.buildHeaders = buildHeaders;
exports.convertResponsePosToAbsolutePos = convertResponsePosToAbsolutePos;
exports.getRedactionsForChunkHeaders = getRedactionsForChunkHeaders;
exports.parseHttpResponse = parseHttpResponse;
exports.makeRegex = makeRegex;
exports.matchRedactedStrings = matchRedactedStrings;
exports.generateRequstAndResponseFromTranscript = generateRequstAndResponseFromTranscript;
const tls_1 = require("@reclaimprotocol/tls");
const esprima_next_1 = require("esprima-next");
const jsonpath_plus_1 = require("jsonpath-plus");
const utils_1 = require("../../utils");
let RE2;
try {
RE2 = require('re2');
if (!Object.keys(RE2).length) {
RE2 = undefined;
throw new Error();
}
}
catch (_a) {
console.log('RE2 not found. Using standard regex');
}
let jsd;
if (typeof window !== 'undefined') {
// @ts-ignore
jsd = window.jsdom;
}
else {
jsd = require('jsdom');
}
/**
* Returns only first extracted element
* @param html
* @param xpathExpression
* @param contentsOnly
*/
function extractHTMLElement(html, xpathExpression, contentsOnly) {
const { start, end } = extractHTMLElementIndex(html, xpathExpression, contentsOnly);
return html.slice(start, end);
}
/**
* Returns all extracted elements
* @param html
* @param xpathExpression
* @param contentsOnly
*/
function extractHTMLElements(html, xpathExpression, contentsOnly) {
const indexes = extractHTMLElementsIndexes(html, xpathExpression, contentsOnly);
const res = [];
for (const { start, end } of indexes) {
res.push(html.slice(start, end));
}
return res;
}
/**
* returns a single index of extracted element
* @param html
* @param xpathExpression
* @param contentsOnly
*/
function extractHTMLElementIndex(html, xpathExpression, contentsOnly) {
return extractHTMLElementsIndexes(html, xpathExpression, contentsOnly)[0];
}
/**
* Returns indexes of all extracted elements
* @param html
* @param xpathExpression
* @param contentsOnly
*/
function extractHTMLElementsIndexes(html, xpathExpression, contentsOnly) {
const dom = new jsd.JSDOM(html, {
contentType: 'text/html',
includeNodeLocations: true
});
const document = dom.window.document;
const xpathResult = document.evaluate(xpathExpression, document, null, dom.window.XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
const nodes = [];
if ((xpathResult === null || xpathResult === void 0 ? void 0 : xpathResult.resultType) === dom.window.XPathResult.ORDERED_NODE_SNAPSHOT_TYPE &&
(xpathResult === null || xpathResult === void 0 ? void 0 : xpathResult.snapshotLength)) {
for (let i = 0; i < xpathResult.snapshotLength; ++i) {
nodes.push(xpathResult.snapshotItem(i));
}
}
if (!nodes.length) {
throw new Error(`Failed to find XPath: "${xpathExpression}"`);
}
const res = [];
for (const node of nodes) {
const nodeLocation = dom.nodeLocation(node);
if (!nodeLocation) {
throw new Error(`Failed to find XPath node location: "${xpathExpression}"`);
}
if (contentsOnly) {
const start = nodeLocation.startTag ? nodeLocation.startTag.endOffset : nodeLocation.startOffset;
const end = nodeLocation.endTag ? nodeLocation.endTag.startOffset : nodeLocation.endOffset;
res.push({ start, end });
}
else {
res.push({ start: nodeLocation.startOffset, end: nodeLocation.endOffset });
}
}
return res;
}
function extractJSONValueIndex(json, jsonPath) {
return extractJSONValueIndexes(json, jsonPath)[0];
}
function extractJSONValueIndexes(json, jsonPath) {
const pointers = (0, jsonpath_plus_1.JSONPath)({
path: jsonPath,
json: JSON.parse(json),
wrap: false,
resultType: 'pointer',
eval: 'safe',
// @ts-ignore
ignoreEvalErrors: true
});
if (!pointers) {
throw new Error('jsonPath not found');
}
const tree = (0, esprima_next_1.parseScript)('(' + json + ')', { range: true }); //wrap in parentheses for esprima to parse
if (tree.body[0] instanceof esprima_next_1.ExpressionStatement
&& (tree.body[0].expression instanceof esprima_next_1.ObjectExpression || tree.body[0].expression instanceof esprima_next_1.ArrayExpression)) {
const traversePointers = Array.isArray(pointers) ? pointers : [pointers];
const res = [];
for (const pointer of traversePointers) {
const index = traverse(tree.body[0].expression, '', [pointer]);
if (index) {
res.push({
start: index.start - 1, //account for '('
end: index.end - 1,
});
}
}
return res;
}
throw new Error('jsonPath not found');
}
/**
* recursively go through AST tree and build a JSON path while it's not equal to the one we search for
* @param o - esprima expression for root object
* @param path - path that is being built
* @param pointers - JSON pointers to compare to
*/
function traverse(o, path, pointers) {
if (o instanceof esprima_next_1.ObjectExpression) {
for (const p of o.properties) {
if (!(p instanceof esprima_next_1.Property)) {
continue;
}
const localPath = p.key.type === esprima_next_1.Syntax.Literal
? path + '/' + p.key.value
: path;
if (pointers.includes(localPath) && 'range' in p && Array.isArray(p.range)) {
return {
start: p.range[0],
end: p.range[1],
};
}
if (p.value instanceof esprima_next_1.ObjectExpression
|| p.value instanceof esprima_next_1.ArrayExpression) {
const res = traverse(p.value, localPath, pointers);
if (res) {
return res;
}
}
}
}
if (o instanceof esprima_next_1.ArrayExpression) {
for (let i = 0; i < o.elements.length; i++) {
const element = o.elements[i];
if (!element) {
continue;
}
const localPath = path + '/' + i;
if (pointers.includes(localPath) &&
'range' in element &&
Array.isArray(element.range)) {
return {
start: element.range[0],
end: element.range[1],
};
}
if (element instanceof esprima_next_1.ObjectExpression) {
const res = traverse(element, localPath, pointers);
if (res) {
return res;
}
}
if (element instanceof esprima_next_1.ArrayExpression) {
const res = traverse(element, localPath, pointers);
if (res) {
return res;
}
}
}
}
return null;
}
function buildHeaders(input) {
const headers = [];
for (const [key, value] of Object.entries(input || {})) {
headers.push(`${key}: ${value}`);
}
return headers;
}
/**
* Converts position in HTTP response body to an absolute position in TLS transcript considering chunked encoding
* @param pos
* @param bodyStartIdx
* @param chunks
*/
function convertResponsePosToAbsolutePos(pos, bodyStartIdx, chunks) {
if (chunks === null || chunks === void 0 ? void 0 : chunks.length) {
let chunkBodyStart = 0;
for (const chunk of chunks) {
const chunkSize = chunk.toIndex - chunk.fromIndex;
if (pos >= chunkBodyStart && pos <= (chunkBodyStart + chunkSize)) {
return pos - chunkBodyStart + chunk.fromIndex;
}
chunkBodyStart += chunkSize;
}
throw new Error('position out of range');
}
return bodyStartIdx + pos;
}
/**
* If this reveal spans the boundary of two chunks, we'll
*
*/
function getRedactionsForChunkHeaders(from, to, chunks) {
const res = [];
if (!(chunks === null || chunks === void 0 ? void 0 : chunks.length)) {
return res;
}
for (let i = 1; i < (chunks === null || chunks === void 0 ? void 0 : chunks.length); i++) {
const chunk = chunks[i];
if (chunk.fromIndex > from && chunk.fromIndex < to) {
res.push({
fromIndex: chunks[i - 1].toIndex,
toIndex: chunk.fromIndex,
});
}
}
return res;
}
function parseHttpResponse(buff) {
const parser = (0, utils_1.makeHttpResponseParser)();
parser.onChunk(buff);
parser.streamEnded();
return parser.res;
}
function makeRegex(str) {
if (RE2 !== undefined) {
return RE2(str, 'sgiu');
}
return new RegExp(str, 'sgi');
}
const TEMPLATE_START_CHARCODE = '{'.charCodeAt(0);
const TEMPLATE_END_CHARCODE = '}'.charCodeAt(0);
/**
* Try to match strings that contain templates like {{param}}
* against redacted string that has *** instead of that param
*/
function matchRedactedStrings(templateString, redactedString) {
if (templateString.length === 0 && (redactedString === null || redactedString === void 0 ? void 0 : redactedString.length) === 0) {
return true;
}
if (!redactedString) {
return false;
}
let ts = -1;
let rs = -1;
while (ts < templateString.length && rs < redactedString.length) {
let ct = getTChar();
let cr = getRChar();
if (ct !== cr) {
// only valid if param contains "{" & redacted contains "*"
if (ct === TEMPLATE_START_CHARCODE && cr === utils_1.REDACTION_CHAR_CODE) {
//check that the char after first "{" is also "{"
if (getTChar() !== TEMPLATE_START_CHARCODE) {
return false;
}
//look for first closing bracket
while (((ct = getTChar()) !== TEMPLATE_END_CHARCODE) && ct !== -1) {
}
//look for second closing bracket
while (((ct = getTChar()) !== TEMPLATE_END_CHARCODE) && ct !== -1) {
}
if (ct === -1) {
return false;
}
//find the end of redaction
while (((cr = getRChar()) === utils_1.REDACTION_CHAR_CODE) && cr !== -1) {
}
if (cr === -1) {
//if there's nothing after template too then both ended at the end of strings
return getTChar() === -1;
}
//rewind redacted string position back 1 char because we read one extra
rs--;
}
else {
return false;
}
}
}
function getTChar() {
ts++;
if (ts < templateString.length) {
return templateString[ts];
}
else {
return -1;
}
}
function getRChar() {
if (!redactedString) {
return -1;
}
rs++;
if (rs < redactedString.length) {
return redactedString[rs];
}
else {
return -1;
}
}
return ts === templateString.length && rs === redactedString.length;
}
function generateRequstAndResponseFromTranscript(transcript, tlsVersion) {
const allPackets = transcript;
const packets = [];
for (const b of allPackets) {
if (b.message.type !== 'ciphertext'
|| !(0, utils_1.isApplicationData)(b.message, tlsVersion)) {
continue;
}
const plaintext = tlsVersion === 'TLS1_3'
? b.message.plaintext.slice(0, -1)
: b.message.plaintext;
packets.push({
message: plaintext,
sender: b.sender
});
}
const req = (0, utils_1.getHttpRequestDataFromTranscript)(packets);
const responsePackets = (0, tls_1.concatenateUint8Arrays)(packets.filter(p => p.sender === 'server').map(p => p.message).filter(b => !b.every(b => b === utils_1.REDACTION_CHAR_CODE)));
const res = parseHttpResponse(responsePackets);
return { req, res };
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcHJvdmlkZXJzL2h0dHAvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHdDQUF3Qzs7QUFpRHhDLGdEQU9DO0FBUUQsa0RBWUM7QUFRRCwwREFNQztBQVFELGdFQTRDQztBQUVELHNEQUVDO0FBRUQsMERBa0NDO0FBaUZELG9DQVFDO0FBUUQsMEVBa0JDO0FBTUQsb0VBbUJDO0FBRUQsOENBS0M7QUFFRCw4QkFNQztBQVNELG9EQTRFQztBQUVELDBGQTBCQztBQWhjRCw4Q0FBNkQ7QUFDN0QsK0NBUXFCO0FBQ3JCLGlEQUF3QztBQUV4QyxxQ0FBdUo7QUFTdkosSUFBSSxHQUFHLENBQUE7QUFDUCxJQUFJLENBQUM7SUFDSixHQUFHLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ3BCLElBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQzdCLEdBQUcsR0FBRyxTQUFTLENBQUE7UUFDZixNQUFNLElBQUksS0FBSyxFQUFFLENBQUE7SUFDbEIsQ0FBQztBQUNGLENBQUM7QUFBQyxXQUFLLENBQUM7SUFDUCxPQUFPLENBQUMsR0FBRyxDQUFDLHFDQUFxQyxDQUFDLENBQUE7QUFDbkQsQ0FBQztBQUVELElBQUksR0FBRyxDQUFBO0FBRVAsSUFBRyxPQUFPLE1BQU0sS0FBSyxXQUFXLEVBQUUsQ0FBQztJQUNsQyxhQUFhO0lBQ2IsR0FBRyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUE7QUFDbkIsQ0FBQztLQUFNLENBQUM7SUFDUCxHQUFHLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFBO0FBQ3ZCLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQWdCLGtCQUFrQixDQUNqQyxJQUFZLEVBQ1osZUFBdUIsRUFDdkIsWUFBcUI7SUFFckIsTUFBTSxFQUFFLEtBQUssRUFBRSxHQUFH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
;