service auth | | Add encrypted to passwords.json | Search

This code provides functions to retrieve and decrypt credentials stored in a JSON file, allowing access to them based on a hostname. It uses AES-256 encryption and retrieves a decryption password from either an environment variable or a local file.

Run example

npm run import -- "Decrypt passwords.json"

Decrypt passwords.json

var path = require('path');
var fs = require('fs');
var crypto = require('crypto');
var path = require('path');

var PROFILE_PATH = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE || '';
var PASS_FILE = path.join(PROFILE_PATH, '.credentials', 'password.txt');
var PASSWORDS_FILE = path.join(PROFILE_PATH, '.credentials', 'passwords.json');

function decrypt(text) {
    var pass = process.env.SELENIUM_PASS || fs.readFileSync(PASS_FILE).toString();
    var decipher = crypto.createDecipher('aes-256-ctr', pass);
    var dec = decipher.update(text, 'hex', 'binary');
    dec += decipher.final('binary');
    return dec;
}

function getCredentials(name) {
    var resultSet = {};
    var passwords = JSON.parse(fs.readFileSync(PASSWORDS_FILE).toString());
    var set = passwords.filter(el => el.host == name)[0] || {};
    for (var i in set) {
        if (set.hasOwnProperty(i)) {
            if (i == 'added' || i == 'host') {
                resultSet[i] = set[i];
                continue;
            }
            resultSet[i] = decrypt(set[i]);
        }
    }
    return resultSet;
};
module.exports = getCredentials;
getCredentials;

What the code could have been:

const fs = require('fs');
const path = require('path');
const crypto = require('crypto');

// Environment variables for profile path and credential files
const PROFILE_PATH = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE || '';
const PASS_FILE = path.join(PROFILE_PATH, '.credentials', 'password.txt');
const PASSWORDS_FILE = path.join(PROFILE_PATH, '.credentials', 'passwords.json');

/**
 * Decrypts a given text using a provided password.
 * @param {string} text - The text to be decrypted.
 * @param {string} password - The password used for decryption.
 * @returns {string} The decrypted text.
 */
function decrypt(text, password) {
    try {
        const decipher = crypto.createDecipher('aes-256-ctr', password);
        const dec = decipher.update(text, 'hex', 'binary');
        dec += decipher.final('binary');
        return dec;
    } catch (error) {
        // Handle decryption errors
        console.error('Error decrypting text:', error);
        return null;
    }
}

/**
 * Retrieves credentials associated with a given host.
 * @param {string} name - The host name.
 * @returns {object} An object containing the host credentials.
 */
function getCredentials(name) {
    try {
        const passwords = JSON.parse(fs.readFileSync(PASSWORDS_FILE, 'utf8'));
        const credentials = passwords.filter((el) => el.host === name)[0] || {};
        const decryptedCredentials = {};

        for (const key in credentials) {
            if (Object.prototype.hasOwnProperty.call(credentials, key)) {
                if (key === 'added' || key === 'host') {
                    decryptedCredentials[key] = credentials[key];
                } else {
                    decryptedCredentials[key] = decrypt(credentials[key], process.env.SELENIUM_PASS || fs.readFileSync(PASS_FILE, 'utf8'));
                }
            }
        }

        return decryptedCredentials;
    } catch (error) {
        // Handle file read or JSON parse errors
        console.error('Error reading credentials file or parsing JSON:', error);
        return null;
    }
}

module.exports = getCredentials;

This code snippet defines functions for decrypting credentials and retrieving them based on a hostname.

Here's a breakdown:

  1. Dependencies:

  2. Configuration:

  3. decrypt Function:

  4. getCredentials Function:

  5. Module Export: