Search code examples
javascriptnode.jsnpmcryptojs

crypto: var keyWords = key.words: TypeError: Cannot read property 'words' of undefined


having an issue using crypto. i'm pretty sure my issue is on line 75 in the saveAccounts function. I believe at this point the accounts var will consist of an empty [] as assigned in the getAccounts function (since there is nothing to 'getItemSync' from 'accounts' in 'storage'. I have a feeling the problem has something to do with the format of the data i'm trying to encrypt but i can't wrap my head around it. been trouble shooting for some time now. days. full-error report at below my code.

console.log('starting password manager');
var crypto = require("crypto-js");
var storage = require('node-persist');
storage.initSync();

var argv = require('yargs')
    .command('create', 'Create a new account', function(yargs){
        yargs.options({
            name: {
                demand: true,
                alias: 'n',
                description: "Account name (eg: Github, SnapChat).",
                type: 'string'
            },
            username: {
                demand: true,
                alias: 'u',
                description: "Please provide a username for your account.",
                type: 'string'
            },
            password: {
                demand: true,
                alias: 'p',
                description: "Please provide a password for your account.",
                type: 'string'
            },
            masterPassword: {
                demand: true,
                alias: 'm',
                description: "Please provide a MASTER password.",
                type: 'string'
            }
        }).help('help');
    })
    .command('get', 'Get an existing account', function(yargs){
        yargs.options({
            name: {
                demand: true,
                alias: 'n',
                description: "Account name (eg: Github, SnapChat).",
                type: 'string'
            },
            masterPassword: {
                demand: true,
                alias: 'm',
                description: "Please provide a MASTER password.",
                type: 'string'
            }
        }).help('help');
    })
    .help('help')
    .argv;


var command = argv._[0];


function getAccounts (masterPassword){
    console.log("function getAccounts has been run");
    var encryptedAccount = storage.getItemSync('accounts');
    var accounts = [];
    // decrypt
    if (typeof encryptedAccount !== 'undefined') {
        var bytes = crypto.AES.decrypt(encryptedAccount, masterPassword);
        accounts = JSON.parse(bytes.toString(crypto.enc.Utf8));
    }

    // return accoutns array
    return accounts;
}

function saveAccounts (accounts, masterPassword){
    console.log("function saveAccounts has been run");
    // encrypt accounts
    var encryptedAccounts = crypto.AES.encrypt(JSON.stringify(accounts), masterPassword);
    // setItemSync
    storage.setItemSync('accounts', encryptedAccounts.toString());
    // return accounts
    return accounts;
}


function createAccount(account, masterPassword){
    var accounts = getAccounts(masterPassword);

    accounts.push(account);
    console.log("back to function createAccount");
    saveAccounts(account, masterPassword);
}


function getAccount(accountName, masterPassword){
    var accounts = getAccounts(masterPassword);
    var matchedAccount;

    accounts.forEach(function(account){
        if (account.name === accountName) {
            matchedAccount = account;
        }
    });

    return matchedAccount;
}




if (command === "create") {
    var createdAccount = createAccount({
        name: argv.name,
        username: argv.username,
        password: argv.password
    }, argv.masterPassword);
    console.log('Account created!');
    console.log(createdAccount);
} else if (command === "get") {
    if (masterPassword !== argv.m || typeof masterPassword === undefined) {
        console.log("Your password was incorrect.");
    } else {
    var accountReturned = getAccount(argv.name, argv.masterPassword);
        if(typeof(accountReturned) === undefined){
            console.log("This account doesn't exist.");
        } else {
        console.log("Your account info:");
        console.log(accountReturned);
        }
    }
}

the full error code looks like this

starting password manager
function getAccounts has been run
back to function createAccount
function saveAccounts has been run
/media/david/08053ee9-7733-4986-97be-f5cac7a80746/david/Projects/Node-Password-Manager/node_modules/crypto-js/aes.js:96
                var keyWords = key.words;
                                  ^

TypeError: Cannot read property 'words' of undefined
    at Object.C_algo.AES.BlockCipher.extend._doReset (/media/david/08053ee9-7733-4986-97be-f5cac7a80746/david/Projects/Node-Password-Manager/node_modules/crypto-js/aes.js:96:32)
    at Object.CryptoJS.lib.Cipher.C_lib.Cipher.BufferedBlockAlgorithm.extend.reset (/media/david/08053ee9-7733-4986-97be-f5cac7a80746/david/Projects/Node-Password-Manager/node_modules/crypto-js/cipher-core.js:119:19)
    at Object.CryptoJS.lib.Cipher.C_lib.BlockCipher.Cipher.extend.reset (/media/david/08053ee9-7733-4986-97be-f5cac7a80746/david/Projects/Node-Password-Manager/node_modules/crypto-js/cipher-core.js:457:27)
    at Object.CryptoJS.lib.Cipher.C_lib.Cipher.BufferedBlockAlgorithm.extend.init (/media/david/08053ee9-7733-4986-97be-f5cac7a80746/david/Projects/Node-Password-Manager/node_modules/crypto-js/cipher-core.js:104:19)
    at Object.subtype.init (/media/david/08053ee9-7733-4986-97be-f5cac7a80746/david/Projects/Node-Password-Manager/node_modules/crypto-js/core.js:68:46)
    at Object.subtype.init (/media/david/08053ee9-7733-4986-97be-f5cac7a80746/david/Projects/Node-Password-Manager/node_modules/crypto-js/core.js:68:46)
    at Object.subtype.init (/media/david/08053ee9-7733-4986-97be-f5cac7a80746/david/Projects/Node-Password-Manager/node_modules/crypto-js/core.js:68:46)
    at Object.C_lib.Base.create (/media/david/08053ee9-7733-4986-97be-f5cac7a80746/david/Projects/Node-Password-Manager/node_modules/crypto-js/core.js:95:32)
    at Object.CryptoJS.lib.Cipher.C_lib.Cipher.BufferedBlockAlgorithm.extend.createEncryptor (/media/david/08053ee9-7733-4986-97be-f5cac7a80746/david/Projects/Node-Password-Manager/node_modules/crypto-js/cipher-core.js:63:26)
    at Object.CryptoJS.lib.Cipher.C_lib.SerializableCipher.Base.extend.encrypt (/media/david/08053ee9-7733-4986-97be-f5cac7a80746/david/Projects/Node-Password-Manager/node_modules/crypto-js/cipher-core.js:669:37)

Solution

  • You should compare typeof to the string — 'undefined'. See typeof docs

    else if (command === "get") {
    if (masterPassword !== argv.m || typeof masterPassword === 'undefined') {
        console.log("Your password was incorrect.");
    } else {
    var accountReturned = getAccount(argv.name, argv.masterPassword);
        if(typeof(accountReturned) === 'undefined'){
            console.log("This account doesn't exist.");
        } else {
        console.log("Your account info:");
        console.log(accountReturned);
        }
    }
    

    I am working on the same Udemy course I think. Good luck!