@node-cli/secret 1.2.4 → 1.2.6

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.
package/dist/lib.d.ts CHANGED
@@ -1,9 +1,8 @@
1
1
  import { Logger } from "@node-cli/logger";
2
2
  export declare const logger: Logger;
3
3
  /**
4
- * Create an hexadecimal hash from a given string. The default
5
- * algorithm is md5 but it can be changed to anything that
6
- * crypto.createHash allows.
4
+ * Create an hexadecimal hash from a given string. The default algorithm is md5
5
+ * but it can be changed to anything that crypto.createHash allows.
7
6
  * @param {String} string the string to hash
8
7
  * @param {String} [algorithm='md5'] the algorithm to use or hashing
9
8
  * @return {String} the hashed string in hexa format
@@ -16,8 +15,7 @@ export declare const createHash: (string: string, algorithm?: string) => string;
16
15
  */
17
16
  export declare const createSalt: (bytes?: number) => string;
18
17
  /**
19
- * Encrypts a string or a buffer using AES-256-CTR
20
- * algorithm.
18
+ * Encrypts a string or a buffer using AES-256-CTR algorithm.
21
19
  * @param {String} password a unique password
22
20
  * @param {String} data a string to encrypt
23
21
  * @return {String} the encrypted data in hexa
@@ -26,12 +24,10 @@ export declare const createSalt: (bytes?: number) => string;
26
24
  */
27
25
  export declare const encrypt: (password: string, data: string) => string;
28
26
  /**
29
- * Decrypts a string that was encrypted using the
30
- * AES-256-CRT algorithm via `encrypt`. It expects
31
- * the encrypted string to have the corresponding
32
- * initialization vector appended at the end, after
33
- * a dollar sign ($) - which was done via the
34
- * corresponding `encrypt` method.
27
+ * Decrypts a string that was encrypted using the AES-256-CRT algorithm via
28
+ * `encrypt`. It expects the encrypted string to have the corresponding
29
+ * initialization vector appended at the end, after a dollar sign ($) - which
30
+ * was done via the corresponding `encrypt` method.
35
31
  * @param {String} password a unique password
36
32
  * @param {String} data a string to decrypt
37
33
  * @return {String} the decrypted data
@@ -43,6 +39,7 @@ export declare const decrypt: (password: string, data: string) => string;
43
39
  * @param {String} password the password to hash
44
40
  * @param {String} salt the salt to use
45
41
  * @returns {String} the hashed password
42
+ *
46
43
  */
47
44
  export declare const hashPassword: (password: string, salt?: string) => string;
48
45
  /**
@@ -51,5 +48,6 @@ export declare const hashPassword: (password: string, salt?: string) => string;
51
48
  * @param {String} password the password to verify
52
49
  * @param {String} hash the hash to verify against
53
50
  * @returns {Boolean} true if the password is correct, false otherwise
51
+ *
54
52
  */
55
53
  export declare const verifyPassword: (password: string, hash: string) => boolean;
package/dist/lib.js CHANGED
@@ -11,9 +11,8 @@ const DEFAULT_BYTES_FOR_IV = 16;
11
11
  const DEFAULT_BYTES_FOR_SALT = 256;
12
12
  const DEFAULT_SALT_SIZE_FOR_HASH = 16;
13
13
  /**
14
- * Create an hexadecimal hash from a given string. The default
15
- * algorithm is md5 but it can be changed to anything that
16
- * crypto.createHash allows.
14
+ * Create an hexadecimal hash from a given string. The default algorithm is md5
15
+ * but it can be changed to anything that crypto.createHash allows.
17
16
  * @param {String} string the string to hash
18
17
  * @param {String} [algorithm='md5'] the algorithm to use or hashing
19
18
  * @return {String} the hashed string in hexa format
@@ -29,8 +28,7 @@ const DEFAULT_SALT_SIZE_FOR_HASH = 16;
29
28
  return crypto.randomBytes(bytes).toString(HEX);
30
29
  };
31
30
  /**
32
- * Encrypts a string or a buffer using AES-256-CTR
33
- * algorithm.
31
+ * Encrypts a string or a buffer using AES-256-CTR algorithm.
34
32
  * @param {String} password a unique password
35
33
  * @param {String} data a string to encrypt
36
34
  * @return {String} the encrypted data in hexa
@@ -52,19 +50,17 @@ const DEFAULT_SALT_SIZE_FOR_HASH = 16;
52
50
  */ return `${encrypted}$${iv.toString(HEX)}`;
53
51
  };
54
52
  /**
55
- * Decrypts a string that was encrypted using the
56
- * AES-256-CRT algorithm via `encrypt`. It expects
57
- * the encrypted string to have the corresponding
58
- * initialization vector appended at the end, after
59
- * a dollar sign ($) - which was done via the
60
- * corresponding `encrypt` method.
53
+ * Decrypts a string that was encrypted using the AES-256-CRT algorithm via
54
+ * `encrypt`. It expects the encrypted string to have the corresponding
55
+ * initialization vector appended at the end, after a dollar sign ($) - which
56
+ * was done via the corresponding `encrypt` method.
61
57
  * @param {String} password a unique password
62
58
  * @param {String} data a string to decrypt
63
59
  * @return {String} the decrypted data
64
60
  */ export const decrypt = (password, data)=>{
65
61
  // Extract encrypted data and initialization vector (IV).
66
62
  const [encrypted, ivHex] = data.split("$");
67
- // Create a buffer out of the raw hex IV
63
+ // Create a buffer out of the raw hex IV.
68
64
  const iv = Buffer.from(ivHex, HEX);
69
65
  // Hash the given password (result is always the same).
70
66
  const hash = createHash(password);
@@ -74,13 +70,13 @@ const DEFAULT_SALT_SIZE_FOR_HASH = 16;
74
70
  return decipher.update(encrypted, HEX, UTF8) + decipher.final("utf8");
75
71
  };
76
72
  /**
77
- * Function using the scrypt Password-Based Key Derivation method.
78
- * It generates a derived key of a given length from the given data
79
- * and salt.
73
+ * Function using the scrypt Password-Based Key Derivation method. It generates
74
+ * a derived key of a given length from the given data and salt.
80
75
  *
81
76
  * @param {String} data the data to derive the key from
82
77
  * @param {String} salt the salt to use
83
78
  * @returns {String} the derived key in hex format
79
+ *
84
80
  */ function generateScryptKey(data, salt) {
85
81
  const encodedData = new TextEncoder().encode(data);
86
82
  const encodedSalt = new TextEncoder().encode(salt);
@@ -94,7 +90,8 @@ const DEFAULT_SALT_SIZE_FOR_HASH = 16;
94
90
  * - The size parameter should be set to 64.
95
91
  *
96
92
  * Reference:
97
- * https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
93
+ * https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html.
94
+ *
98
95
  */ const derivedKey = crypto.scryptSync(encodedData, encodedSalt, 64, {
99
96
  cost: Math.pow(2, 14),
100
97
  blockSize: 8,
@@ -108,6 +105,7 @@ const DEFAULT_SALT_SIZE_FOR_HASH = 16;
108
105
  * @param {String} password the password to hash
109
106
  * @param {String} salt the salt to use
110
107
  * @returns {String} the hashed password
108
+ *
111
109
  */ export const hashPassword = (password, salt)=>{
112
110
  const pepper = salt || createSalt(DEFAULT_SALT_SIZE_FOR_HASH);
113
111
  const key = generateScryptKey(password.normalize("NFKC"), pepper);
@@ -119,6 +117,7 @@ const DEFAULT_SALT_SIZE_FOR_HASH = 16;
119
117
  * @param {String} password the password to verify
120
118
  * @param {String} hash the hash to verify against
121
119
  * @returns {Boolean} true if the password is correct, false otherwise
120
+ *
122
121
  */ export const verifyPassword = (password, hash)=>{
123
122
  const [salt, key] = hash.split(":");
124
123
  const keyBuffer = Buffer.from(key, HEX);
package/dist/lib.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib.ts"],"sourcesContent":["import crypto from \"node:crypto\";\nimport { Logger } from \"@node-cli/logger\";\n\nexport const logger = new Logger({\n\tboring: process.env.NODE_ENV === \"test\",\n});\n\nconst HEX = \"hex\";\nconst UTF8 = \"utf8\";\n\nconst DEFAULT_CRYPTO_ALGO = \"aes-256-ctr\";\nconst DEFAULT_HASH_ALGO = \"md5\";\nconst DEFAULT_BYTES_FOR_IV = 16;\nconst DEFAULT_BYTES_FOR_SALT = 256;\nconst DEFAULT_SALT_SIZE_FOR_HASH = 16;\n\n/**\n * Create an hexadecimal hash from a given string. The default\n * algorithm is md5 but it can be changed to anything that\n * crypto.createHash allows.\n * @param {String} string the string to hash\n * @param {String} [algorithm='md5'] the algorithm to use or hashing\n * @return {String} the hashed string in hexa format\n */\nexport const createHash = (\n\tstring: string,\n\talgorithm: string = DEFAULT_HASH_ALGO,\n): string => {\n\treturn crypto.createHash(algorithm).update(string, UTF8).digest(HEX);\n};\n\n/**\n * Creates a random SALT value using the crypto library.\n * @param {Number} [bytes=256] the number of bytes to generate\n * @return {String} the generated salt in hexa format\n */\nexport const createSalt = (bytes?: number): string => {\n\tbytes = bytes || DEFAULT_BYTES_FOR_SALT;\n\treturn crypto.randomBytes(bytes).toString(HEX);\n};\n\n/**\n * Encrypts a string or a buffer using AES-256-CTR\n * algorithm.\n * @param {String} password a unique password\n * @param {String} data a string to encrypt\n * @return {String} the encrypted data in hexa\n * encoding, followed by a dollar sign ($) and by a\n * unique random initialization vector.\n */\nexport const encrypt = (password: string, data: string): string => {\n\t// Ensure that the initialization vector (IV) is random.\n\tconst iv = crypto.randomBytes(DEFAULT_BYTES_FOR_IV);\n\t// Hash the given password (result is always the same).\n\tconst key = createHash(password);\n\t// Create a cipher.\n\tconst cipher = crypto.createCipheriv(DEFAULT_CRYPTO_ALGO, key, iv);\n\t// Encrypt the data using the newly created cipher.\n\tconst encrypted = cipher.update(data, UTF8, HEX) + cipher.final(HEX);\n\t/*\n\t * Append the IV at the end of the encrypted data\n\t * to reuse it for decryption (IV is not a key,\n\t * it can be public).\n\t */\n\treturn `${encrypted}$${iv.toString(HEX)}`;\n};\n\n/**\n * Decrypts a string that was encrypted using the\n * AES-256-CRT algorithm via `encrypt`. It expects\n * the encrypted string to have the corresponding\n * initialization vector appended at the end, after\n * a dollar sign ($) - which was done via the\n * corresponding `encrypt` method.\n * @param {String} password a unique password\n * @param {String} data a string to decrypt\n * @return {String} the decrypted data\n */\nexport const decrypt = (password: string, data: string): string => {\n\t// Extract encrypted data and initialization vector (IV).\n\tconst [encrypted, ivHex] = data.split(\"$\");\n\t// Create a buffer out of the raw hex IV\n\tconst iv = Buffer.from(ivHex, HEX);\n\t// Hash the given password (result is always the same).\n\tconst hash = createHash(password);\n\t// Create a cipher.\n\tconst decipher = crypto.createDecipheriv(DEFAULT_CRYPTO_ALGO, hash, iv);\n\t// Return the decrypted data using the newly created cipher.\n\treturn decipher.update(encrypted, HEX, UTF8) + decipher.final(\"utf8\");\n};\n\n/**\n * Function using the scrypt Password-Based Key Derivation method.\n * It generates a derived key of a given length from the given data\n * and salt.\n *\n * @param {String} data the data to derive the key from\n * @param {String} salt the salt to use\n * @returns {String} the derived key in hex format\n */\nfunction generateScryptKey(data: string, salt: string): string {\n\tconst encodedData = new TextEncoder().encode(data);\n\tconst encodedSalt = new TextEncoder().encode(salt);\n\t/**\n\t * The scryptSync parameters are based on the following recommendations:\n\t * - The cost parameter should be set as high as possible without causing\n\t * significant performance degradation. OWASP recommends a cost of 2^17,\n\t * but this fails on some systems due to the high memory requirements.\n\t * - The blockSize parameter should be set to 8 at a minimum.\n\t * - The parallelization parameter should be set to 1.\n\t * - The size parameter should be set to 64.\n\t *\n\t * Reference:\n\t * https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html\n\t */\n\tconst derivedKey = crypto.scryptSync(encodedData, encodedSalt, 64, {\n\t\tcost: Math.pow(2, 14),\n\t\tblockSize: 8,\n\t\tparallelization: 1,\n\t});\n\treturn (derivedKey as Buffer).toString(HEX);\n}\n\n/**\n * Method to hash a password using the scrypt algorithm.\n *\n * @param {String} password the password to hash\n * @param {String} salt the salt to use\n * @returns {String} the hashed password\n */\nexport const hashPassword = (password: string, salt?: string): string => {\n\tconst pepper = salt || createSalt(DEFAULT_SALT_SIZE_FOR_HASH);\n\tconst key = generateScryptKey(password.normalize(\"NFKC\"), pepper);\n\treturn `${pepper}:${key}`;\n};\n\n/**\n * Method to verify a password against a hash using the scrypt algorithm.\n *\n * @param {String} password the password to verify\n * @param {String} hash the hash to verify against\n * @returns {Boolean} true if the password is correct, false otherwise\n */\nexport const verifyPassword = (password: string, hash: string): boolean => {\n\tconst [salt, key] = hash.split(\":\");\n\tconst keyBuffer = Buffer.from(key, HEX);\n\n\tconst derivedKey = generateScryptKey(password.normalize(\"NFKC\"), salt);\n\tconst derivedKeyBuffer = Buffer.from(derivedKey, HEX);\n\n\ttry {\n\t\treturn crypto.timingSafeEqual(keyBuffer, derivedKeyBuffer);\n\t} catch (_error) {\n\t\treturn false;\n\t}\n};\n"],"names":["crypto","Logger","logger","boring","process","env","NODE_ENV","HEX","UTF8","DEFAULT_CRYPTO_ALGO","DEFAULT_HASH_ALGO","DEFAULT_BYTES_FOR_IV","DEFAULT_BYTES_FOR_SALT","DEFAULT_SALT_SIZE_FOR_HASH","createHash","string","algorithm","update","digest","createSalt","bytes","randomBytes","toString","encrypt","password","data","iv","key","cipher","createCipheriv","encrypted","final","decrypt","ivHex","split","Buffer","from","hash","decipher","createDecipheriv","generateScryptKey","salt","encodedData","TextEncoder","encode","encodedSalt","derivedKey","scryptSync","cost","Math","pow","blockSize","parallelization","hashPassword","pepper","normalize","verifyPassword","keyBuffer","derivedKeyBuffer","timingSafeEqual","_error"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/lib.ts"],"sourcesContent":["import crypto from \"node:crypto\";\nimport { Logger } from \"@node-cli/logger\";\n\nexport const logger = new Logger({\n\tboring: process.env.NODE_ENV === \"test\",\n});\n\nconst HEX = \"hex\";\nconst UTF8 = \"utf8\";\n\nconst DEFAULT_CRYPTO_ALGO = \"aes-256-ctr\";\nconst DEFAULT_HASH_ALGO = \"md5\";\nconst DEFAULT_BYTES_FOR_IV = 16;\nconst DEFAULT_BYTES_FOR_SALT = 256;\nconst DEFAULT_SALT_SIZE_FOR_HASH = 16;\n\n/**\n * Create an hexadecimal hash from a given string. The default algorithm is md5\n * but it can be changed to anything that crypto.createHash allows.\n * @param {String} string the string to hash\n * @param {String} [algorithm='md5'] the algorithm to use or hashing\n * @return {String} the hashed string in hexa format\n */\nexport const createHash = (\n\tstring: string,\n\talgorithm: string = DEFAULT_HASH_ALGO,\n): string => {\n\treturn crypto.createHash(algorithm).update(string, UTF8).digest(HEX);\n};\n\n/**\n * Creates a random SALT value using the crypto library.\n * @param {Number} [bytes=256] the number of bytes to generate\n * @return {String} the generated salt in hexa format\n */\nexport const createSalt = (bytes?: number): string => {\n\tbytes = bytes || DEFAULT_BYTES_FOR_SALT;\n\treturn crypto.randomBytes(bytes).toString(HEX);\n};\n\n/**\n * Encrypts a string or a buffer using AES-256-CTR algorithm.\n * @param {String} password a unique password\n * @param {String} data a string to encrypt\n * @return {String} the encrypted data in hexa\n * encoding, followed by a dollar sign ($) and by a\n * unique random initialization vector.\n */\nexport const encrypt = (password: string, data: string): string => {\n\t// Ensure that the initialization vector (IV) is random.\n\tconst iv = crypto.randomBytes(DEFAULT_BYTES_FOR_IV);\n\t// Hash the given password (result is always the same).\n\tconst key = createHash(password);\n\t// Create a cipher.\n\tconst cipher = crypto.createCipheriv(DEFAULT_CRYPTO_ALGO, key, iv);\n\t// Encrypt the data using the newly created cipher.\n\tconst encrypted = cipher.update(data, UTF8, HEX) + cipher.final(HEX);\n\t/*\n\t * Append the IV at the end of the encrypted data\n\t * to reuse it for decryption (IV is not a key,\n\t * it can be public).\n\t */\n\treturn `${encrypted}$${iv.toString(HEX)}`;\n};\n\n/**\n * Decrypts a string that was encrypted using the AES-256-CRT algorithm via\n * `encrypt`. It expects the encrypted string to have the corresponding\n * initialization vector appended at the end, after a dollar sign ($) - which\n * was done via the corresponding `encrypt` method.\n * @param {String} password a unique password\n * @param {String} data a string to decrypt\n * @return {String} the decrypted data\n */\nexport const decrypt = (password: string, data: string): string => {\n\t// Extract encrypted data and initialization vector (IV).\n\tconst [encrypted, ivHex] = data.split(\"$\");\n\t// Create a buffer out of the raw hex IV.\n\tconst iv = Buffer.from(ivHex, HEX);\n\t// Hash the given password (result is always the same).\n\tconst hash = createHash(password);\n\t// Create a cipher.\n\tconst decipher = crypto.createDecipheriv(DEFAULT_CRYPTO_ALGO, hash, iv);\n\t// Return the decrypted data using the newly created cipher.\n\treturn decipher.update(encrypted, HEX, UTF8) + decipher.final(\"utf8\");\n};\n\n/**\n * Function using the scrypt Password-Based Key Derivation method. It generates\n * a derived key of a given length from the given data and salt.\n *\n * @param {String} data the data to derive the key from\n * @param {String} salt the salt to use\n * @returns {String} the derived key in hex format\n *\n */\nfunction generateScryptKey(data: string, salt: string): string {\n\tconst encodedData = new TextEncoder().encode(data);\n\tconst encodedSalt = new TextEncoder().encode(salt);\n\t/**\n\t * The scryptSync parameters are based on the following recommendations:\n\t * - The cost parameter should be set as high as possible without causing\n\t * significant performance degradation. OWASP recommends a cost of 2^17,\n\t * but this fails on some systems due to the high memory requirements.\n\t * - The blockSize parameter should be set to 8 at a minimum.\n\t * - The parallelization parameter should be set to 1.\n\t * - The size parameter should be set to 64.\n\t *\n\t * Reference:\n\t * https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html.\n\t *\n\t */\n\tconst derivedKey = crypto.scryptSync(encodedData, encodedSalt, 64, {\n\t\tcost: Math.pow(2, 14),\n\t\tblockSize: 8,\n\t\tparallelization: 1,\n\t});\n\treturn (derivedKey as Buffer).toString(HEX);\n}\n\n/**\n * Method to hash a password using the scrypt algorithm.\n *\n * @param {String} password the password to hash\n * @param {String} salt the salt to use\n * @returns {String} the hashed password\n *\n */\nexport const hashPassword = (password: string, salt?: string): string => {\n\tconst pepper = salt || createSalt(DEFAULT_SALT_SIZE_FOR_HASH);\n\tconst key = generateScryptKey(password.normalize(\"NFKC\"), pepper);\n\treturn `${pepper}:${key}`;\n};\n\n/**\n * Method to verify a password against a hash using the scrypt algorithm.\n *\n * @param {String} password the password to verify\n * @param {String} hash the hash to verify against\n * @returns {Boolean} true if the password is correct, false otherwise\n *\n */\nexport const verifyPassword = (password: string, hash: string): boolean => {\n\tconst [salt, key] = hash.split(\":\");\n\tconst keyBuffer = Buffer.from(key, HEX);\n\n\tconst derivedKey = generateScryptKey(password.normalize(\"NFKC\"), salt);\n\tconst derivedKeyBuffer = Buffer.from(derivedKey, HEX);\n\n\ttry {\n\t\treturn crypto.timingSafeEqual(keyBuffer, derivedKeyBuffer);\n\t} catch (_error) {\n\t\treturn false;\n\t}\n};\n"],"names":["crypto","Logger","logger","boring","process","env","NODE_ENV","HEX","UTF8","DEFAULT_CRYPTO_ALGO","DEFAULT_HASH_ALGO","DEFAULT_BYTES_FOR_IV","DEFAULT_BYTES_FOR_SALT","DEFAULT_SALT_SIZE_FOR_HASH","createHash","string","algorithm","update","digest","createSalt","bytes","randomBytes","toString","encrypt","password","data","iv","key","cipher","createCipheriv","encrypted","final","decrypt","ivHex","split","Buffer","from","hash","decipher","createDecipheriv","generateScryptKey","salt","encodedData","TextEncoder","encode","encodedSalt","derivedKey","scryptSync","cost","Math","pow","blockSize","parallelization","hashPassword","pepper","normalize","verifyPassword","keyBuffer","derivedKeyBuffer","timingSafeEqual","_error"],"mappings":"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"}
package/dist/secret.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- /* v8 ignore start */ import { displayConfirmation, displayPromptWithPassword, logger, processFileWithPassword, shouldContinue } from "./utilities.js";
3
- import path from "node:path";
2
+ /* v8 ignore start */ import path from "node:path";
4
3
  import fs from "fs-extra";
5
4
  import { config } from "./parse.js";
5
+ import { displayConfirmation, displayPromptWithPassword, logger, processFileWithPassword, shouldContinue } from "./utilities.js";
6
6
  const ENCRYPT = "encrypt";
7
7
  const DECRYPT = "decrypt";
8
8
  /**
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/secret.ts"],"sourcesContent":["#!/usr/bin/env node\n/* v8 ignore start */\n\nimport {\n\tdisplayConfirmation,\n\tdisplayPromptWithPassword,\n\tlogger,\n\tprocessFileWithPassword,\n\tshouldContinue,\n} from \"./utilities.js\";\n\nimport path from \"node:path\";\nimport fs from \"fs-extra\";\nimport { config } from \"./parse.js\";\n\nconst ENCRYPT = \"encrypt\";\nconst DECRYPT = \"decrypt\";\n\n/**\n * Caching the \"action\" for future usage (encrypt or decrypt).\n */\nconst actionName = config.flags.encrypt ? ENCRYPT : DECRYPT;\n\n/**\n * Extracting the input and output files.\n */\nlet inputFile: string,\n\toutputFile: string,\n\toutputFileExists: boolean = false;\nif (Object.entries(config.parameters).length > 0) {\n\tinputFile = config.parameters[\"0\"];\n\toutputFile = config.parameters[\"1\"];\n\tif (!fs.existsSync(inputFile)) {\n\t\tlogger.printErrorsAndExit([`File \"${inputFile}\" does not exist!`], 1);\n\t}\n\tif (fs.existsSync(outputFile)) {\n\t\toutputFileExists = true;\n\t}\n}\n\nif (outputFileExists) {\n\tconst goodToGo = await displayConfirmation(\n\t\t`The file ${outputFile} already exists, overwrite it?`,\n\t);\n\tshouldContinue(goodToGo);\n}\n\nconst password = await displayPromptWithPassword(\n\t`Enter password to ${actionName} the file`,\n);\n\ntry {\n\tawait processFileWithPassword({\n\t\tencode: config.flags.encrypt,\n\t\tinput: inputFile,\n\t\toutput: outputFile,\n\t\tpassword,\n\t});\n\tlogger.log();\n\tlogger.info(`File ${path.basename(inputFile)} was ${actionName}ed.`);\n\tif (outputFileExists) {\n\t\tlogger.info(`The result was saved in the file ${outputFile}`);\n\t}\n} catch (error) {\n\tlogger.error(error);\n}\n/* v8 ignore stop */\n"],"names":["displayConfirmation","displayPromptWithPassword","logger","processFileWithPassword","shouldContinue","path","fs","config","ENCRYPT","DECRYPT","actionName","flags","encrypt","inputFile","outputFile","outputFileExists","Object","entries","parameters","length","existsSync","printErrorsAndExit","goodToGo","password","encode","input","output","log","info","basename","error"],"mappings":";AACA,mBAAmB,GAEnB,SACCA,mBAAmB,EACnBC,yBAAyB,EACzBC,MAAM,EACNC,uBAAuB,EACvBC,cAAc,QACR,iBAAiB;AAExB,OAAOC,UAAU,YAAY;AAC7B,OAAOC,QAAQ,WAAW;AAC1B,SAASC,MAAM,QAAQ,aAAa;AAEpC,MAAMC,UAAU;AAChB,MAAMC,UAAU;AAEhB;;CAEC,GACD,MAAMC,aAAaH,OAAOI,KAAK,CAACC,OAAO,GAAGJ,UAAUC;AAEpD;;CAEC,GACD,IAAII,WACHC,YACAC,mBAA4B;AAC7B,IAAIC,OAAOC,OAAO,CAACV,OAAOW,UAAU,EAAEC,MAAM,GAAG,GAAG;IACjDN,YAAYN,OAAOW,UAAU,CAAC,IAAI;IAClCJ,aAAaP,OAAOW,UAAU,CAAC,IAAI;IACnC,IAAI,CAACZ,GAAGc,UAAU,CAACP,YAAY;QAC9BX,OAAOmB,kBAAkB,CAAC;YAAC,CAAC,MAAM,EAAER,UAAU,iBAAiB,CAAC;SAAC,EAAE;IACpE;IACA,IAAIP,GAAGc,UAAU,CAACN,aAAa;QAC9BC,mBAAmB;IACpB;AACD;AAEA,IAAIA,kBAAkB;IACrB,MAAMO,WAAW,MAAMtB,oBACtB,CAAC,SAAS,EAAEc,WAAW,8BAA8B,CAAC;IAEvDV,eAAekB;AAChB;AAEA,MAAMC,WAAW,MAAMtB,0BACtB,CAAC,kBAAkB,EAAES,WAAW,SAAS,CAAC;AAG3C,IAAI;IACH,MAAMP,wBAAwB;QAC7BqB,QAAQjB,OAAOI,KAAK,CAACC,OAAO;QAC5Ba,OAAOZ;QACPa,QAAQZ;QACRS;IACD;IACArB,OAAOyB,GAAG;IACVzB,OAAO0B,IAAI,CAAC,CAAC,KAAK,EAAEvB,KAAKwB,QAAQ,CAAChB,WAAW,KAAK,EAAEH,WAAW,GAAG,CAAC;IACnE,IAAIK,kBAAkB;QACrBb,OAAO0B,IAAI,CAAC,CAAC,iCAAiC,EAAEd,YAAY;IAC7D;AACD,EAAE,OAAOgB,OAAO;IACf5B,OAAO4B,KAAK,CAACA;AACd,EACA,kBAAkB"}
1
+ {"version":3,"sources":["../src/secret.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/* v8 ignore start */\n\nimport path from \"node:path\";\nimport fs from \"fs-extra\";\nimport { config } from \"./parse.js\";\nimport {\n\tdisplayConfirmation,\n\tdisplayPromptWithPassword,\n\tlogger,\n\tprocessFileWithPassword,\n\tshouldContinue,\n} from \"./utilities.js\";\n\nconst ENCRYPT = \"encrypt\";\nconst DECRYPT = \"decrypt\";\n\n/**\n * Caching the \"action\" for future usage (encrypt or decrypt).\n */\nconst actionName = config.flags.encrypt ? ENCRYPT : DECRYPT;\n\n/**\n * Extracting the input and output files.\n */\nlet inputFile: string,\n\toutputFile: string,\n\toutputFileExists: boolean = false;\nif (Object.entries(config.parameters).length > 0) {\n\tinputFile = config.parameters[\"0\"];\n\toutputFile = config.parameters[\"1\"];\n\tif (!fs.existsSync(inputFile)) {\n\t\tlogger.printErrorsAndExit([`File \"${inputFile}\" does not exist!`], 1);\n\t}\n\tif (fs.existsSync(outputFile)) {\n\t\toutputFileExists = true;\n\t}\n}\n\nif (outputFileExists) {\n\tconst goodToGo = await displayConfirmation(\n\t\t`The file ${outputFile} already exists, overwrite it?`,\n\t);\n\tshouldContinue(goodToGo);\n}\n\nconst password = await displayPromptWithPassword(\n\t`Enter password to ${actionName} the file`,\n);\n\ntry {\n\tawait processFileWithPassword({\n\t\tencode: config.flags.encrypt,\n\t\tinput: inputFile,\n\t\toutput: outputFile,\n\t\tpassword,\n\t});\n\tlogger.log();\n\tlogger.info(`File ${path.basename(inputFile)} was ${actionName}ed.`);\n\tif (outputFileExists) {\n\t\tlogger.info(`The result was saved in the file ${outputFile}`);\n\t}\n} catch (error) {\n\tlogger.error(error);\n}\n/* v8 ignore stop */\n"],"names":["path","fs","config","displayConfirmation","displayPromptWithPassword","logger","processFileWithPassword","shouldContinue","ENCRYPT","DECRYPT","actionName","flags","encrypt","inputFile","outputFile","outputFileExists","Object","entries","parameters","length","existsSync","printErrorsAndExit","goodToGo","password","encode","input","output","log","info","basename","error"],"mappings":";AAEA,mBAAmB,GAEnB,OAAOA,UAAU,YAAY;AAC7B,OAAOC,QAAQ,WAAW;AAC1B,SAASC,MAAM,QAAQ,aAAa;AACpC,SACCC,mBAAmB,EACnBC,yBAAyB,EACzBC,MAAM,EACNC,uBAAuB,EACvBC,cAAc,QACR,iBAAiB;AAExB,MAAMC,UAAU;AAChB,MAAMC,UAAU;AAEhB;;CAEC,GACD,MAAMC,aAAaR,OAAOS,KAAK,CAACC,OAAO,GAAGJ,UAAUC;AAEpD;;CAEC,GACD,IAAII,WACHC,YACAC,mBAA4B;AAC7B,IAAIC,OAAOC,OAAO,CAACf,OAAOgB,UAAU,EAAEC,MAAM,GAAG,GAAG;IACjDN,YAAYX,OAAOgB,UAAU,CAAC,IAAI;IAClCJ,aAAaZ,OAAOgB,UAAU,CAAC,IAAI;IACnC,IAAI,CAACjB,GAAGmB,UAAU,CAACP,YAAY;QAC9BR,OAAOgB,kBAAkB,CAAC;YAAC,CAAC,MAAM,EAAER,UAAU,iBAAiB,CAAC;SAAC,EAAE;IACpE;IACA,IAAIZ,GAAGmB,UAAU,CAACN,aAAa;QAC9BC,mBAAmB;IACpB;AACD;AAEA,IAAIA,kBAAkB;IACrB,MAAMO,WAAW,MAAMnB,oBACtB,CAAC,SAAS,EAAEW,WAAW,8BAA8B,CAAC;IAEvDP,eAAee;AAChB;AAEA,MAAMC,WAAW,MAAMnB,0BACtB,CAAC,kBAAkB,EAAEM,WAAW,SAAS,CAAC;AAG3C,IAAI;IACH,MAAMJ,wBAAwB;QAC7BkB,QAAQtB,OAAOS,KAAK,CAACC,OAAO;QAC5Ba,OAAOZ;QACPa,QAAQZ;QACRS;IACD;IACAlB,OAAOsB,GAAG;IACVtB,OAAOuB,IAAI,CAAC,CAAC,KAAK,EAAE5B,KAAK6B,QAAQ,CAAChB,WAAW,KAAK,EAAEH,WAAW,GAAG,CAAC;IACnE,IAAIK,kBAAkB;QACrBV,OAAOuB,IAAI,CAAC,CAAC,iCAAiC,EAAEd,YAAY;IAC7D;AACD,EAAE,OAAOgB,OAAO;IACfzB,OAAOyB,KAAK,CAACA;AACd,EACA,kBAAkB"}
@@ -1,8 +1,8 @@
1
1
  import { Logger } from "@node-cli/logger";
2
2
  export declare const logger: Logger;
3
3
  /**
4
- * Process a file with a given password. The file can be
5
- * encoded or decoded depending on the `encode` flag.
4
+ * Process a file with a given password. The file can be encoded or decoded
5
+ * depending on the `encode` flag.
6
6
  * @param {Boolean} encode whether to encode or decode the file
7
7
  * @param {String} input the input file path
8
8
  * @param {String} [output] the output file path
package/dist/utilities.js CHANGED
@@ -12,10 +12,10 @@ export const processFileWithPassword = async (options)=>{
12
12
  const fileProcessor = encode ? encrypt : decrypt;
13
13
  const data = await fs.readFile(input, DEFAULT_FILE_ENCODING);
14
14
  if (output) {
15
- // Save data to output file
15
+ // Save data to output file.
16
16
  await fs.outputFile(output, fileProcessor(password, data));
17
17
  } else {
18
- // Print to stdout directly
18
+ // Print to stdout directly.
19
19
  logger.log(fileProcessor(password, data));
20
20
  }
21
21
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utilities.ts"],"sourcesContent":["import { Logger } from \"@node-cli/logger\";\nimport fs from \"fs-extra\";\nimport inquirer from \"inquirer\";\n\nimport { decrypt, encrypt } from \"./lib.js\";\n\nexport const logger = new Logger({\n\tboring: process.env.NODE_ENV === \"test\",\n});\n\nconst UTF8 = \"utf8\";\nconst DEFAULT_FILE_ENCODING = UTF8;\n\n/**\n * Process a file with a given password. The file can be\n * encoded or decoded depending on the `encode` flag.\n * @param {Boolean} encode whether to encode or decode the file\n * @param {String} input the input file path\n * @param {String} [output] the output file path\n * @param {String} password the password to use\n * @return {Promise} a promise that resolves when\n * the file has been processed.\n */\nexport type ProcessFileOptions = {\n\tencode: boolean;\n\tinput: string;\n\toutput?: string;\n\tpassword: string;\n};\nexport const processFileWithPassword = async (\n\toptions: ProcessFileOptions,\n): Promise<void> => {\n\tconst { encode, input, output, password } = options;\n\tconst fileProcessor = encode ? encrypt : decrypt;\n\tconst data = await fs.readFile(input, DEFAULT_FILE_ENCODING);\n\n\tif (output) {\n\t\t// Save data to output file\n\t\tawait fs.outputFile(output, fileProcessor(password, data));\n\t} else {\n\t\t// Print to stdout directly\n\t\tlogger.log(fileProcessor(password, data));\n\t}\n};\n\n/* v8 ignore next 12 */\nexport const displayConfirmation = async (message: string) => {\n\tconst questions = {\n\t\tdefault: true,\n\t\tmessage: message || \"Do you want to continue?\",\n\t\tname: \"goodToGo\",\n\t\ttype: \"confirm\",\n\t};\n\tlogger.log();\n\tconst answers = await inquirer.prompt(questions);\n\treturn answers.goodToGo;\n};\n\n/* v8 ignore next 16 */\nexport const displayPromptWithPassword = async (message: string) => {\n\tconst questions = {\n\t\tmessage: message,\n\t\tname: \"password\",\n\t\ttype: \"password\",\n\t\tvalidate(value: string) {\n\t\t\tif (!value) {\n\t\t\t\treturn \"Password cannot be empty...\";\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\t};\n\tconst answers = await inquirer.prompt(questions);\n\treturn answers.password;\n};\n\n/* v8 ignore next 8 */\nexport const shouldContinue = (goodToGo: boolean) => {\n\tif (!goodToGo) {\n\t\tlogger.log(\"\\nBye then!\");\n\t\t// eslint-disable-next-line unicorn/no-process-exit\n\t\tprocess.exit(0);\n\t}\n\treturn true;\n};\n"],"names":["Logger","fs","inquirer","decrypt","encrypt","logger","boring","process","env","NODE_ENV","UTF8","DEFAULT_FILE_ENCODING","processFileWithPassword","options","encode","input","output","password","fileProcessor","data","readFile","outputFile","log","displayConfirmation","message","questions","default","name","type","answers","prompt","goodToGo","displayPromptWithPassword","validate","value","shouldContinue","exit"],"mappings":"AAAA,SAASA,MAAM,QAAQ,mBAAmB;AAC1C,OAAOC,QAAQ,WAAW;AAC1B,OAAOC,cAAc,WAAW;AAEhC,SAASC,OAAO,EAAEC,OAAO,QAAQ,WAAW;AAE5C,OAAO,MAAMC,SAAS,IAAIL,OAAO;IAChCM,QAAQC,QAAQC,GAAG,CAACC,QAAQ,KAAK;AAClC,GAAG;AAEH,MAAMC,OAAO;AACb,MAAMC,wBAAwBD;AAkB9B,OAAO,MAAME,0BAA0B,OACtCC;IAEA,MAAM,EAAEC,MAAM,EAAEC,KAAK,EAAEC,MAAM,EAAEC,QAAQ,EAAE,GAAGJ;IAC5C,MAAMK,gBAAgBJ,SAASV,UAAUD;IACzC,MAAMgB,OAAO,MAAMlB,GAAGmB,QAAQ,CAACL,OAAOJ;IAEtC,IAAIK,QAAQ;QACX,2BAA2B;QAC3B,MAAMf,GAAGoB,UAAU,CAACL,QAAQE,cAAcD,UAAUE;IACrD,OAAO;QACN,2BAA2B;QAC3Bd,OAAOiB,GAAG,CAACJ,cAAcD,UAAUE;IACpC;AACD,EAAE;AAEF,qBAAqB,GACrB,OAAO,MAAMI,sBAAsB,OAAOC;IACzC,MAAMC,YAAY;QACjBC,SAAS;QACTF,SAASA,WAAW;QACpBG,MAAM;QACNC,MAAM;IACP;IACAvB,OAAOiB,GAAG;IACV,MAAMO,UAAU,MAAM3B,SAAS4B,MAAM,CAACL;IACtC,OAAOI,QAAQE,QAAQ;AACxB,EAAE;AAEF,qBAAqB,GACrB,OAAO,MAAMC,4BAA4B,OAAOR;IAC/C,MAAMC,YAAY;QACjBD,SAASA;QACTG,MAAM;QACNC,MAAM;QACNK,UAASC,KAAa;YACrB,IAAI,CAACA,OAAO;gBACX,OAAO;YACR;YACA,OAAO;QACR;IACD;IACA,MAAML,UAAU,MAAM3B,SAAS4B,MAAM,CAACL;IACtC,OAAOI,QAAQZ,QAAQ;AACxB,EAAE;AAEF,oBAAoB,GACpB,OAAO,MAAMkB,iBAAiB,CAACJ;IAC9B,IAAI,CAACA,UAAU;QACd1B,OAAOiB,GAAG,CAAC;QACX,mDAAmD;QACnDf,QAAQ6B,IAAI,CAAC;IACd;IACA,OAAO;AACR,EAAE"}
1
+ {"version":3,"sources":["../src/utilities.ts"],"sourcesContent":["import { Logger } from \"@node-cli/logger\";\nimport fs from \"fs-extra\";\nimport inquirer from \"inquirer\";\n\nimport { decrypt, encrypt } from \"./lib.js\";\n\nexport const logger = new Logger({\n\tboring: process.env.NODE_ENV === \"test\",\n});\n\nconst UTF8 = \"utf8\";\nconst DEFAULT_FILE_ENCODING = UTF8;\n\n/**\n * Process a file with a given password. The file can be encoded or decoded\n * depending on the `encode` flag.\n * @param {Boolean} encode whether to encode or decode the file\n * @param {String} input the input file path\n * @param {String} [output] the output file path\n * @param {String} password the password to use\n * @return {Promise} a promise that resolves when\n * the file has been processed.\n */\nexport type ProcessFileOptions = {\n\tencode: boolean;\n\tinput: string;\n\toutput?: string;\n\tpassword: string;\n};\nexport const processFileWithPassword = async (\n\toptions: ProcessFileOptions,\n): Promise<void> => {\n\tconst { encode, input, output, password } = options;\n\tconst fileProcessor = encode ? encrypt : decrypt;\n\tconst data = await fs.readFile(input, DEFAULT_FILE_ENCODING);\n\n\tif (output) {\n\t\t// Save data to output file.\n\t\tawait fs.outputFile(output, fileProcessor(password, data));\n\t} else {\n\t\t// Print to stdout directly.\n\t\tlogger.log(fileProcessor(password, data));\n\t}\n};\n\n/* v8 ignore next 12 */\nexport const displayConfirmation = async (message: string) => {\n\tconst questions = {\n\t\tdefault: true,\n\t\tmessage: message || \"Do you want to continue?\",\n\t\tname: \"goodToGo\",\n\t\ttype: \"confirm\",\n\t};\n\tlogger.log();\n\tconst answers = await inquirer.prompt(questions);\n\treturn answers.goodToGo;\n};\n\n/* v8 ignore next 16 */\nexport const displayPromptWithPassword = async (message: string) => {\n\tconst questions = {\n\t\tmessage: message,\n\t\tname: \"password\",\n\t\ttype: \"password\",\n\t\tvalidate(value: string) {\n\t\t\tif (!value) {\n\t\t\t\treturn \"Password cannot be empty...\";\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\t};\n\tconst answers = await inquirer.prompt(questions);\n\treturn answers.password;\n};\n\n/* v8 ignore next 8 */\nexport const shouldContinue = (goodToGo: boolean) => {\n\tif (!goodToGo) {\n\t\tlogger.log(\"\\nBye then!\");\n\t\t// eslint-disable-next-line unicorn/no-process-exit\n\t\tprocess.exit(0);\n\t}\n\treturn true;\n};\n"],"names":["Logger","fs","inquirer","decrypt","encrypt","logger","boring","process","env","NODE_ENV","UTF8","DEFAULT_FILE_ENCODING","processFileWithPassword","options","encode","input","output","password","fileProcessor","data","readFile","outputFile","log","displayConfirmation","message","questions","default","name","type","answers","prompt","goodToGo","displayPromptWithPassword","validate","value","shouldContinue","exit"],"mappings":"AAAA,SAASA,MAAM,QAAQ,mBAAmB;AAC1C,OAAOC,QAAQ,WAAW;AAC1B,OAAOC,cAAc,WAAW;AAEhC,SAASC,OAAO,EAAEC,OAAO,QAAQ,WAAW;AAE5C,OAAO,MAAMC,SAAS,IAAIL,OAAO;IAChCM,QAAQC,QAAQC,GAAG,CAACC,QAAQ,KAAK;AAClC,GAAG;AAEH,MAAMC,OAAO;AACb,MAAMC,wBAAwBD;AAkB9B,OAAO,MAAME,0BAA0B,OACtCC;IAEA,MAAM,EAAEC,MAAM,EAAEC,KAAK,EAAEC,MAAM,EAAEC,QAAQ,EAAE,GAAGJ;IAC5C,MAAMK,gBAAgBJ,SAASV,UAAUD;IACzC,MAAMgB,OAAO,MAAMlB,GAAGmB,QAAQ,CAACL,OAAOJ;IAEtC,IAAIK,QAAQ;QACX,4BAA4B;QAC5B,MAAMf,GAAGoB,UAAU,CAACL,QAAQE,cAAcD,UAAUE;IACrD,OAAO;QACN,4BAA4B;QAC5Bd,OAAOiB,GAAG,CAACJ,cAAcD,UAAUE;IACpC;AACD,EAAE;AAEF,qBAAqB,GACrB,OAAO,MAAMI,sBAAsB,OAAOC;IACzC,MAAMC,YAAY;QACjBC,SAAS;QACTF,SAASA,WAAW;QACpBG,MAAM;QACNC,MAAM;IACP;IACAvB,OAAOiB,GAAG;IACV,MAAMO,UAAU,MAAM3B,SAAS4B,MAAM,CAACL;IACtC,OAAOI,QAAQE,QAAQ;AACxB,EAAE;AAEF,qBAAqB,GACrB,OAAO,MAAMC,4BAA4B,OAAOR;IAC/C,MAAMC,YAAY;QACjBD,SAASA;QACTG,MAAM;QACNC,MAAM;QACNK,UAASC,KAAa;YACrB,IAAI,CAACA,OAAO;gBACX,OAAO;YACR;YACA,OAAO;QACR;IACD;IACA,MAAML,UAAU,MAAM3B,SAAS4B,MAAM,CAACL;IACtC,OAAOI,QAAQZ,QAAQ;AACxB,EAAE;AAEF,oBAAoB,GACpB,OAAO,MAAMkB,iBAAiB,CAACJ;IAC9B,IAAI,CAACA,UAAU;QACd1B,OAAOiB,GAAG,CAAC;QACX,mDAAmD;QACnDf,QAAQ6B,IAAI,CAAC;IACd;IACA,OAAO;AACR,EAAE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node-cli/secret",
3
- "version": "1.2.4",
3
+ "version": "1.2.6",
4
4
  "license": "MIT",
5
5
  "author": "Arno Versini",
6
6
  "description": "Secret is a CLI tool that can encode or decode a file with a password",
@@ -9,7 +9,8 @@
9
9
  "exports": "./dist/lib.js",
10
10
  "bin": "dist/secret.js",
11
11
  "files": [
12
- "dist"
12
+ "dist",
13
+ "README.md"
13
14
  ],
14
15
  "node": ">=18",
15
16
  "scripts": {
@@ -18,24 +19,27 @@
18
19
  "build:js": "swc --strip-leading-paths --source-maps --out-dir dist src",
19
20
  "build:types": "tsc",
20
21
  "clean": "rimraf dist types coverage",
22
+ "comments:fix": "comments --merge-line-comments 'src/**/*.ts'",
21
23
  "lint": "biome lint src",
24
+ "lint:fix": "biome check src --write --no-errors-on-unmatched",
22
25
  "test": "vitest run --globals",
23
26
  "test:coverage": "vitest run --coverage --globals",
24
27
  "test:watch": "npm run test -- --watch",
25
28
  "watch": "swc --strip-leading-paths --watch --out-dir dist src"
26
29
  },
27
30
  "dependencies": {
28
- "@node-cli/logger": "1.3.1",
29
- "@node-cli/parser": "2.4.1",
30
- "fs-extra": "11.3.0",
31
+ "@node-cli/logger": "1.3.2",
32
+ "@node-cli/parser": "2.4.3",
33
+ "fs-extra": "11.3.1",
31
34
  "inquirer": "9.3.7"
32
35
  },
33
36
  "publishConfig": {
34
37
  "access": "public"
35
38
  },
36
39
  "devDependencies": {
40
+ "@node-cli/comments": "0.2.5",
37
41
  "@vitest/coverage-v8": "3.2.4",
38
42
  "vitest": "3.2.4"
39
43
  },
40
- "gitHead": "2cef8f88aa5316a1789caad2bd7327ca908ccb9f"
44
+ "gitHead": "cab44c95cf447b7c80af963e205be1d9459f4c42"
41
45
  }