From eef43f36e84e258037f54932da3db8c5457423d0 Mon Sep 17 00:00:00 2001 From: Samuel Alarco Date: Thu, 30 Nov 2023 10:32:16 +0000 Subject: [PATCH 1/2] fix(L402): include base64 encoded macs in parsing --- src/l402/parse.js | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/l402/parse.js b/src/l402/parse.js index 25c24b1..ee7e47f 100644 --- a/src/l402/parse.js +++ b/src/l402/parse.js @@ -1,16 +1,20 @@ export const parseL402 = (string) => { - string = string.replace("L402", ""); - string = string.replace("LSAT", ""); - // Split the string into key-value pairs - const pairs = string.split(","); + // Remove the L402 and LSAT identifiers + string = string.replace("L402", "").replace("LSAT", "").trim(); - // Split each pair into key and value - const keyValuePairArray = pairs.map((pair) => { - const [key, valuePotentiallyQuoted] = pair.split("=").map((e) => e.trim()); - const valueMatch = valuePotentiallyQuoted.match(/"?([^"]*)"?/); - const value = valueMatch[1]; - return [key, value]; - }); + // Initialize an object to store the key-value pairs + const keyValuePairs = {}; - return Object.fromEntries(keyValuePairArray); + // Regular expression to match key and (quoted or unquoted) value + const regex = /(\w+)=("([^"]*)"|'([^']*)'|([^,]*))/g; + let match; + + // Use regex to find all key-value pairs + while ((match = regex.exec(string)) !== null) { + // Key is always match[1] + // Value is either match[3] (double-quoted), match[4] (single-quoted), or match[5] (unquoted) + keyValuePairs[match[1]] = match[3] || match[4] || match[5]; + } + + return keyValuePairs; }; From df6d5bee214de54315582229a9558d59c67fa69f Mon Sep 17 00:00:00 2001 From: Samuel Alarco Date: Thu, 30 Nov 2023 10:59:52 +0000 Subject: [PATCH 2/2] fix(parse): added unit tests --- src/l402/parse.test.ts | 40 +++++++++++++++++++++++++++++++++ src/l402/{parse.js => parse.ts} | 4 ++-- 2 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 src/l402/parse.test.ts rename src/l402/{parse.js => parse.ts} (80%) diff --git a/src/l402/parse.test.ts b/src/l402/parse.test.ts new file mode 100644 index 0000000..3ed0e5d --- /dev/null +++ b/src/l402/parse.test.ts @@ -0,0 +1,40 @@ +import { parseL402 } from "./parse"; + +const BASE64_MAC = + "AgEEbHNhdAJCAAAClGOZrh7C569Yc7UMk8merfnMdIviyXr1qscW7VgpChNl21LkZ8Jex5QiPp+E1VaabeJDuWmlrh/j583axFpNAAIXc2VydmljZXM9cmFuZG9tbnVtYmVyOjAAAiZyYW5kb21udW1iZXJfY2FwYWJpbGl0aZVzPWFkZCxzdWJ0cmFjdAAABiAvFpzXGyc+8d/I9nMKKvAYP8w7kUlhuxS0eFN2sqmqHQ=="; +const HEX_MAC = + "jkse4mpp5q22x8xdwrmpw0t6cww6sey7fn6klnnr5303vj7h44tr3dm2c9y9qdq8f4f5z4qcqzzsxqyz5vqsp5mmhp6cx4xxysc8x"; +const HEX_INVOICE = + "lnbc100n1pjkse4mpp5q22x8xdwrmpw0t6cww6sey7fn6klnnr5303vj7h44tr3dm2c9y9qdq8f4f5z4qcqzzsxqyz5vqsp5mmhp6cx4xxysc8xvxaj984eue9pm83lxgezmk3umx6wxr9rrq2ns9qyyssqmmrrwthves6z3d85nafj2ds4z20qju2vpaatep8uwrvxz0xs4kznm99m7f6pmkzax09k2k9saldy34z0p0l8gm0zm5xsmg2g667pnlqp7a0qdz"; + +describe("parseL402", () => { + test("should correctly parse L402 string", () => { + const testString = `L402 macaroon="${BASE64_MAC}", invoice="${HEX_INVOICE}"`; + const result = parseL402(testString); + expect(result).toEqual({ macaroon: BASE64_MAC, invoice: HEX_INVOICE }); + }); + + test("should correctly parse LSAT string", () => { + const testString = `LSAT macaroon="${BASE64_MAC}", invoice="${HEX_INVOICE}"`; + const result = parseL402(testString); + expect(result).toEqual({ macaroon: BASE64_MAC, invoice: HEX_INVOICE }); + }); + + test("should correctly handle unquoted values", () => { + const testString = `L402 macaroon=${BASE64_MAC}, invoice=${HEX_INVOICE}`; + const result = parseL402(testString); + expect(result).toEqual({ macaroon: BASE64_MAC, invoice: HEX_INVOICE }); + }); + + test("should correctly handle single-quoted values", () => { + const testString = `LSAT macaroon='${BASE64_MAC}', invoice='${HEX_INVOICE}'`; + const result = parseL402(testString); + expect(result).toEqual({ macaroon: BASE64_MAC, invoice: HEX_INVOICE }); + }); + + test("should correctly handle hexadecimal macaroon values", () => { + const testString = `LSAT macaroon='${HEX_MAC}', invoice='${HEX_INVOICE}'`; + const result = parseL402(testString); + expect(result).toEqual({ macaroon: HEX_MAC, invoice: HEX_INVOICE }); + }); +}); diff --git a/src/l402/parse.js b/src/l402/parse.ts similarity index 80% rename from src/l402/parse.js rename to src/l402/parse.ts index ee7e47f..d781881 100644 --- a/src/l402/parse.js +++ b/src/l402/parse.ts @@ -1,6 +1,6 @@ -export const parseL402 = (string) => { +export const parseL402 = (input: string): Record => { // Remove the L402 and LSAT identifiers - string = string.replace("L402", "").replace("LSAT", "").trim(); + const string = input.replace("L402", "").replace("LSAT", "").trim(); // Initialize an object to store the key-value pairs const keyValuePairs = {};