UNPKG

@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
"use strict"; // 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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