Skip to content

Commit

Permalink
Test case is added for browser codes, Test samples are updated, Crypt…
Browse files Browse the repository at this point in the history
…o implemented for web and node.
  • Loading branch information
darsan-in committed Nov 21, 2024
1 parent 90f3c58 commit 2cae1dc
Show file tree
Hide file tree
Showing 32 changed files with 17,710 additions and 74 deletions.
4 changes: 2 additions & 2 deletions lib/aggregators/product.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ export default async function makeProductPage(
).toISOString();
} else {
validTill = new Date(
(await this.stat(this.resolve(htmlPath))).mtimeMs + validityMs,
).toISOString();
(await this.stat(this.resolve(htmlPath)))?.mtimeMs ?? 0 + validityMs,
)?.toISOString();
}

$(`[class^="${productBaseID}-"]`).each((_index: number, elem: any) => {
Expand Down
2 changes: 1 addition & 1 deletion lib/base-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ const baseConfig: Partial<configurationOptions> = {
product: {
baseID: "rjs-prod",
productPriceValidUntilNext: 30,
productGroupIDHashLength: "128",
productGroupIDHashVar: "128",
producrVariableDelimiter: "|",
skuID: "sku",
mpnCode: "mpn",
Expand Down
3 changes: 2 additions & 1 deletion lib/browser/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Plugins } from "../types";
import { webGenerateProductGroupID } from "../utils";
import {
basename,
cwd,
Expand All @@ -24,12 +25,12 @@ const browPlugins: Plugins = {
sep: "/",
cwd: cwd,
},
cryptoLib: { createHash: () => {}, randomBytes: () => {} },
fsLib: {
readFileSync: (_, __) => "",
stat: () => "" as any,
existsSync: () => false,
},
generateProductGroupID: webGenerateProductGroupID,
};

export const config: Partial<configurationOptions> = {
Expand Down
8 changes: 7 additions & 1 deletion lib/browser/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import { config } from "./config";

import branding from "./branding";

import { richieGroupA, richieGroupB, richieReactOptions } from "../types";
import {
richieGroupA,
richieGroupB,
richieGroupC,
richieReactOptions,
} from "../types";

/* not supported
1-breadcrumb
Expand Down Expand Up @@ -38,6 +43,7 @@ export default async function richieReact({
const aggregatorParams: string[] | boolean =
richieGroupA.includes(richieName) ? [source]
: richieGroupB.includes(richieName) ? [source, docPath]
: richieGroupC.includes(richieName) ? [docPath]
: false;

if (!aggregatorParams) {
Expand Down
41 changes: 41 additions & 0 deletions lib/node-utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { format } from "@prettier/sync";
import { load } from "cheerio";
import { createHash, randomBytes } from "node:crypto";
import { writeFile } from "node:fs/promises";

/* //it is only good if you have google business page
Expand Down Expand Up @@ -96,3 +97,43 @@ export function writeOutput(
});
});
}

export function nodeGenerateProductGroupID(
productID1: string,
productID2: string,
hashVarient: "128" | "256" | "512",
): string {
const concatenatedID: string = productID1.concat(productID2);

const salt: string = randomBytes(8).toString("hex");

const randomPosition: number = Math.floor(
Math.random() * concatenatedID.length,
);

//interjoin salt in randomindex position
const dataWithSalt: string = concatenatedID
.slice(0, randomPosition)
.concat(salt)
.concat(concatenatedID.slice(randomPosition));

let hashFunction;
if (hashVarient == "512") {
hashFunction = createHash("sha512");
} else if (hashVarient == "128" || hashVarient == "256") {
hashFunction = createHash("shake" + hashVarient);
} else {
throw new Error(
"Configuration Error: Hash variant should be 128 or 256 or 512",
);
}

// Update hash with data
hashFunction.update(dataWithSalt, "utf8");

// Get hash digest as a buffer
// Convert buffer to hexadecimal string
const hashHex: string = hashFunction.digest().toString("hex");

return hashHex;
}
8 changes: 1 addition & 7 deletions lib/serializers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export default class Serializer {
generateProductGroupID: (
productID1: string,
productID2: string,
productGroupIDHashVar: "128" | "256" | "512",
) => string;

httpsDomainBase: string;
Expand All @@ -56,15 +57,11 @@ export default class Serializer {
basename: (filepath: string, ext?: string) => string;
dirname: (filePath: string) => string;

randomBytes: (length: number) => any;
createHash: (algorithm: string) => any;

constructor(configurations: configurationOptions) {
const {
reservedNames,
preference,
pathLib: { cwd, relative, join, basename, dirname },
cryptoLib: { createHash, randomBytes },
} = configurations;

const { generateProductGroupID, httpsDomainBase } = new BaseUtils(
Expand All @@ -80,9 +77,6 @@ export default class Serializer {
this.basename = basename;
this.dirname = dirname;

this.createHash = createHash;
this.randomBytes = randomBytes;

this.reservedNames = reservedNames;
this.preference = preference;
}
Expand Down
2 changes: 2 additions & 0 deletions lib/serializers/product.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,11 @@ export function serializeproductWithVarientPage(
"@type": "Brand",
name: productPageData[0].brandName,
},

productGroupID: this.generateProductGroupID(
productPageData[0].skuid ?? productPageData[0].mpncode ?? "no id",
productPageData[1]?.skuid ?? productPageData[1]?.mpncode ?? "no id",
this.reservedNames.product.productGroupIDHashVar,
),
variesBy: variesBy,
hasVariant: this.productPage(productPageData),
Expand Down
11 changes: 6 additions & 5 deletions lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@ export interface configurationOptions extends Plugins {
product: {
baseID: string;
productPriceValidUntilNext: number;
productGroupIDHashLength: string;
productGroupIDHashVar: "128" | "256" | "512";
producrVariableDelimiter: string;
skuID: string;
mpnCode: string;
Expand Down Expand Up @@ -827,10 +827,6 @@ export interface Plugins {
sep: "\\" | "/";
cwd: () => string;
};
cryptoLib: {
createHash: (algorithm: string) => any;
randomBytes: (length: number) => any;
};
fsLib: {
stat: (
path: PathLike,
Expand All @@ -849,6 +845,11 @@ export interface Plugins {
) => string;
existsSync: (path: PathLike) => boolean;
};
generateProductGroupID: (
productID1: string,
productID2: string,
productGroupIDHashLength: "128" | "256" | "512",
) => string;
}

export interface richieOptions {
Expand Down
89 changes: 54 additions & 35 deletions lib/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { sha3_512, shake128, shake256 } from "js-sha3";
import { DateTime } from "luxon";

import {
Expand Down Expand Up @@ -264,8 +265,7 @@ export default class BaseUtils {
httpsDomainBase: string;
htmlParser: (htmlString: string) => any;
dirname: (filepath: string) => string;
createHash: (algorithm: string) => any;
randomBytes: (length: number) => any;

readFileSync: (
path: string,
options: {
Expand All @@ -274,15 +274,22 @@ export default class BaseUtils {
},
) => string;

generateProductGroupID: (
productID1: string,
productID2: string,
productGroupIDHashLength: "128" | "256" | "512",
) => string;

constructor(configurations: configurationOptions) {
const {
domainAddress,
reservedNames,
timeFormat,
htmlParser,
pathLib: { dirname },
cryptoLib: { createHash, randomBytes },

fsLib: { readFileSync },
generateProductGroupID,
} = configurations;

this.domainAddress = domainAddress;
Expand All @@ -292,9 +299,9 @@ export default class BaseUtils {

this.htmlParser = htmlParser;
this.dirname = dirname;
this.createHash = createHash;
this.randomBytes = randomBytes;

this.readFileSync = readFileSync;
this.generateProductGroupID = generateProductGroupID;
}

parseDateString(date: string): string {
Expand Down Expand Up @@ -378,36 +385,6 @@ export default class BaseUtils {
};
}

generateProductGroupID(productID1: string, productID2: string): string {
const concatenatedID: string = productID1.concat(productID2);

const salt: string = this.randomBytes(8).toString("hex");

const randomPosition: number = Math.floor(
Math.random() * concatenatedID.length,
);

//interjoin salt in randomindex position
const dataWithSalt: string = concatenatedID
.slice(0, randomPosition)
.concat(salt)
.concat(concatenatedID.slice(randomPosition));

// Create SHAKE256 hash
const shake256 = this.createHash(
"shake" + this.reservedNames.product.productGroupIDHashLength,
);

// Update hash with data
shake256.update(dataWithSalt, "utf8");

// Get hash digest as a buffer
// Convert buffer to hexadecimal string
const hashHex: string = shake256.digest().toString("hex");

return hashHex;
}

generateMeta(
currentUrl: string,
realLevel: number,
Expand Down Expand Up @@ -505,3 +482,45 @@ export default class BaseUtils {
return totalTime;
}
}

export function webGenerateProductGroupID(
productID1: string,
productID2: string,
hashVarient: "128" | "256" | "512",
) {
const concatenatedID: string = productID1 + productID2;

// Generate a random salt (16 characters = 8 bytes in hex)
const saltArray = new Uint8Array(8);
window.crypto.getRandomValues(saltArray);

const salt = Array.from(saltArray, (byte) =>
byte.toString(16).padStart(2, "0"),
).join("");

// Generate a random position within the concatenated ID
const randomPosition: number = Math.floor(
Math.random() * concatenatedID.length,
);

// Interjoin the salt at the random position
const dataWithSalt =
concatenatedID.slice(0, randomPosition) +
salt +
concatenatedID.slice(randomPosition);

let hashHex;
if (hashVarient == "128") {
hashHex = shake128(dataWithSalt, 128); // 128-bit output for SHAKE128
} else if (hashVarient == "256") {
hashHex = shake256(dataWithSalt, 256); // 256-bit output for SHAKE256
} else if (hashVarient == "512") {
hashHex = sha3_512(dataWithSalt); // 512-bit output for SHAKE512
} else {
throw new Error(
"Configuration Error: Hash variant should be 128 or 256 or 512",
);
}

return hashHex;
}
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"cheerio": "1.0.0",
"country-list": "2.3.0",
"glob": "11.0.0",
"js-sha3": "^0.9.3",
"luxon": "3.5.0",
"prettier": "^3.3.3",
"yargs": "17.7.2"
Expand All @@ -89,8 +90,9 @@
"esbuild": "^0.24.0",
"eslint": "^9.15.0",
"jest": "29.7.0",
"puppeteer": "^23.8.0",
"rimraf": "6.0.1",
"ts-node": "10.9.2",
"typescript": "^5.6.3"
}
}
}
4 changes: 2 additions & 2 deletions richie.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { load as cheerio } from "cheerio";
import { createHash, randomBytes } from "node:crypto";
import { existsSync, readFileSync } from "node:fs";
import { stat } from "node:fs/promises";
import {
Expand All @@ -12,6 +11,7 @@ import {
} from "node:path";
import { cwd } from "node:process";
import baseConfig from "./lib/base-config";
import { nodeGenerateProductGroupID } from "./lib/node-utils";
import { configurationOptions, Plugins } from "./lib/types";

const nodePlugins: Plugins = {
Expand All @@ -26,12 +26,12 @@ const nodePlugins: Plugins = {
sep: sep,
cwd: cwd,
},
cryptoLib: { createHash: createHash, randomBytes: randomBytes },
fsLib: {
readFileSync: readFileSync,
stat: stat,
existsSync: existsSync,
},
generateProductGroupID: nodeGenerateProductGroupID,
};

const config: Partial<configurationOptions> = {
Expand Down
Loading

0 comments on commit 2cae1dc

Please sign in to comment.