node-scrypt-wrapper/README.md
2023-09-25 13:13:20 -04:00

2.2 KiB

Scrypt Wrapper

NodeJS's standard library's crypto module contains an scrypt function, which uses the Scrypt password-based key derivation function to create a hash which can be stored to later verify a password's validity. This library is a thin wrapper around that function which handles salting, serializing and deserializing hash metadata, and verification. It contains both asynchronous and synchronous versions of its functions, and is thoroughly tested.

Usage

const { hash, verify } = require('@techworkers/scrypt-wrapper')
const userEnteredPassword = 'some password'
const hashedPassword = await hash(userEnteredPassword)
if (await verify(hashedPassword, userEnteredPassword)) {
    // allowed!
}

Or, in a synchronous environment...

const { hashSync, verifySync } = require('@techworkers/scrypt-wrapper')
const userEnteredPassword = 'some password'
const hashedPassword = hashSync(userEnteredPassword)
if (verifySync(hashedPassword, userEnteredPassword)) {
    // allowed!
}

Async and sync versions can be used together. For example, Sequelize doesn't offer async setters:

const sequelize = require('sequelize')
const { Model } = sequelize
const { hashSync, verify } = require('@techworkers/scrypt-wrapper')
module.exports = (sequelize, DataTypes) => {
  class User extends Model {
    static async authenticated(name, password) {
      const user = await User.findOne({ where: { name } })
      if (!user) return null
      if (await verify(user.password, password)) return user
      else return null
    }
  }
  User.init(
    {
      name: DataTypes.STRING,
      password: {
        type: DataTypes.STRING,
        set(password) {
          if (!password) throw `invalid password <${password}>`
          this.setDataValue('password', hashSync(password))
          // We need to generate the hash ^^^ value synchronously here
        },
      },
    },
    {
      sequelize,
      tableName: 'Users',
      modelName: 'User',
      underscored: true,
    },
  )
  return User
}

// Creating a user
const user = await User.create({name: 'user', password: 'monkey'})
// Validating them
const reFetchedUser = await User.authenticated('user', 'monkey')

Tests

Run tests with yarn test.