javascriptnode.jsvue.jsdotenvnedb

nodejs - save account information inside .env file or in client side database


I've created a simple nodejs app that will use express to do some file processing operations. I will pack the final app using pkg this mean that the app will access the packaged resources in readonly mode. Since I want to implement a login system and a one time account creation, what's the best way to proceed? The app will open a browser tab that will run the a vuejs app for the UI. I'm thinking to use nedb-promises by implementing it in the vue app but the data stored inside it are accessible to all so the login will become insecure. Is there a way to encrypt/decrypt stored data inside nedb-promises?

Another solution I'm thinking to use is to run the one time account creation and to store the created account info inside a .env file that will be created inside the folder where te app will run. With this method how I can hash password and account data and when the app is launched check them with the credential that the user will input?


Solution

  • NeDB have two functions called beforeDeserialization and afterSerialization. These can be used for encrypting and decrypting data when reading and writing from your database using the crypto module.

    const crypto    = require('crypto');
    const Datastore = require('nedb-promises');
    
    const ALGORITHM = 'aes-256-cbc'
    const BLOCK_SIZE = 16
    const SECRET = 'SECRET'
    
    const database = new Datastore({
        filename: 'database.db', 
        autoload: true,
        afterSerialization (plaintext) {
            // Encryption
    
            const iv = crypto.randomBytes(BLOCK_SIZE);
            const cipher = crypto.createCipheriv(ALGORITHM, SECRET, iv);
            const ciphertext = Buffer.concat([iv, cipher.update(plaintext), cipher.final()]);
            return ciphertext.toString('base64');
        },
        beforeDeserialization (ciphertext) {
            // Decryption
    
            const ciphertextBytes = Buffer.from(ciphertext, 'base64');
            const iv = ciphertextBytes.slice(0, BLOCK_SIZE);
            const data = ciphertextBytes.slice(BLOCK_SIZE);
            const decipher = crypto.createDecipheriv(ALGORITHM, SECRET, iv);
            const plaintextBytes = Buffer.concat([decipher.update(data), decipher.final()]);
            return plaintextBytes.toString('utf8');
        },
    });
    

    You would want to your SECRET variable to be a random generated string stored in a .env file