2.2 KiB
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
.