@naturalcycles/nodejs-lib 13.7.2 → 13.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -32,3 +32,16 @@ export declare function decryptString(str: Base64String, secretKeyBuffer: Buffer
32
32
  * Output is base64 string.
33
33
  */
34
34
  export declare function encryptString(str: string, secretKeyBuffer: Buffer): Base64String;
35
+ /**
36
+ * Wraps `crypto.timingSafeEqual` and allows it to be used with String inputs:
37
+ *
38
+ * 1. Does length check first and short-circuits on length mismatch. Because `crypto.timingSafeEqual` only works with same-length inputs.
39
+ *
40
+ * Relevant read:
41
+ * https://medium.com/nerd-for-tech/checking-api-key-without-shooting-yourself-in-the-foot-javascript-nodejs-f271e47bb428
42
+ * https://codahale.com/a-lesson-in-timing-attacks/
43
+ * https://github.com/suryagh/tsscmp/blob/master/lib/index.js
44
+ *
45
+ * Returns true if inputs are equal, false otherwise.
46
+ */
47
+ export declare function timingSafeStringEqual(s1: string | undefined, s2: string | undefined): boolean;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.encryptString = exports.decryptString = exports.encryptObject = exports.decryptObject = exports.decryptRandomIVBuffer = exports.encryptRandomIVBuffer = void 0;
3
+ exports.timingSafeStringEqual = exports.encryptString = exports.decryptString = exports.encryptObject = exports.decryptObject = exports.decryptRandomIVBuffer = exports.encryptRandomIVBuffer = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const node_crypto_1 = tslib_1.__importDefault(require("node:crypto"));
6
6
  const js_lib_1 = require("@naturalcycles/js-lib");
@@ -88,3 +88,21 @@ function getCryptoParams(secretKeyBuffer) {
88
88
  const iv = (0, hash_util_1.md5AsBuffer)(Buffer.concat([secretKeyBuffer, key]));
89
89
  return { key, iv };
90
90
  }
91
+ /**
92
+ * Wraps `crypto.timingSafeEqual` and allows it to be used with String inputs:
93
+ *
94
+ * 1. Does length check first and short-circuits on length mismatch. Because `crypto.timingSafeEqual` only works with same-length inputs.
95
+ *
96
+ * Relevant read:
97
+ * https://medium.com/nerd-for-tech/checking-api-key-without-shooting-yourself-in-the-foot-javascript-nodejs-f271e47bb428
98
+ * https://codahale.com/a-lesson-in-timing-attacks/
99
+ * https://github.com/suryagh/tsscmp/blob/master/lib/index.js
100
+ *
101
+ * Returns true if inputs are equal, false otherwise.
102
+ */
103
+ function timingSafeStringEqual(s1, s2) {
104
+ if (s1 === undefined || s2 === undefined || s1.length !== s2.length)
105
+ return false;
106
+ return node_crypto_1.default.timingSafeEqual(Buffer.from(s1), Buffer.from(s2));
107
+ }
108
+ exports.timingSafeStringEqual = timingSafeStringEqual;
@@ -10,7 +10,7 @@ const __1 = require("../..");
10
10
  * Zips output file automatically, if it ends with `.gz`.
11
11
  */
12
12
  async function ndjsonMap(mapper, opt) {
13
- const { inputFilePath, outputFilePath, logEveryOutput = 100000, limitInput, limitOutput } = opt;
13
+ const { inputFilePath, outputFilePath, logEveryOutput = 100_000, limitInput, limitOutput } = opt;
14
14
  (0, __1.requireFileToExist)(inputFilePath);
15
15
  console.log({
16
16
  inputFilePath,
@@ -14,7 +14,7 @@ const inspectOpt = {
14
14
  * Pass-through transform that optionally logs progress.
15
15
  */
16
16
  function transformLogProgress(opt = {}) {
17
- const { metric = 'progress', heapTotal: logHeapTotal = false, heapUsed: logHeapUsed = false, rss: logRss = true, peakRSS: logPeakRSS = true, logRPS = true, logEvery = 1000, logSizes = false, logSizesBuffer = 100000, logZippedSizes = false, batchSize = 1, extra, logger = console, } = opt;
17
+ const { metric = 'progress', heapTotal: logHeapTotal = false, heapUsed: logHeapUsed = false, rss: logRss = true, peakRSS: logPeakRSS = true, logRPS = true, logEvery = 1000, logSizes = false, logSizesBuffer = 100_000, logZippedSizes = false, batchSize = 1, extra, logger = console, } = opt;
18
18
  const logProgress = opt.logProgress !== false && logEvery !== 0; // true by default
19
19
  const logEvery10 = logEvery * 10;
20
20
  const started = Date.now();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/nodejs-lib",
3
- "version": "13.7.2",
3
+ "version": "13.8.0",
4
4
  "scripts": {
5
5
  "prepare": "husky install",
6
6
  "docs-serve": "vuepress dev docs",
@@ -35,7 +35,7 @@
35
35
  "yargs": "^17.0.0"
36
36
  },
37
37
  "devDependencies": {
38
- "@naturalcycles/bench-lib": "^1.0.7",
38
+ "@naturalcycles/bench-lib": "^2.0.0",
39
39
  "@naturalcycles/dev-lib": "^13.0.0",
40
40
  "@types/node": "^20.1.0",
41
41
  "@types/yargs": "^16.0.0",
@@ -48,7 +48,7 @@ export function csvStringParse<T extends AnyObject = any>(
48
48
 
49
49
  return arr.map(row => {
50
50
  // eslint-disable-next-line unicorn/no-array-reduce
51
- return header!.reduce((obj, col, i) => {
51
+ return header.reduce((obj, col, i) => {
52
52
  ;(obj as any)[col] = row[i]
53
53
  return obj
54
54
  }, {} as T)
@@ -93,3 +93,20 @@ function getCryptoParams(secretKeyBuffer: Buffer): { key: Buffer; iv: Buffer } {
93
93
  const iv = md5AsBuffer(Buffer.concat([secretKeyBuffer, key]))
94
94
  return { key, iv }
95
95
  }
96
+
97
+ /**
98
+ * Wraps `crypto.timingSafeEqual` and allows it to be used with String inputs:
99
+ *
100
+ * 1. Does length check first and short-circuits on length mismatch. Because `crypto.timingSafeEqual` only works with same-length inputs.
101
+ *
102
+ * Relevant read:
103
+ * https://medium.com/nerd-for-tech/checking-api-key-without-shooting-yourself-in-the-foot-javascript-nodejs-f271e47bb428
104
+ * https://codahale.com/a-lesson-in-timing-attacks/
105
+ * https://github.com/suryagh/tsscmp/blob/master/lib/index.js
106
+ *
107
+ * Returns true if inputs are equal, false otherwise.
108
+ */
109
+ export function timingSafeStringEqual(s1: string | undefined, s2: string | undefined): boolean {
110
+ if (s1 === undefined || s2 === undefined || s1.length !== s2.length) return false
111
+ return crypto.timingSafeEqual(Buffer.from(s1), Buffer.from(s2))
112
+ }