node-scrypt-wrapper/README.md

78 lines
2.2 KiB
Markdown
Raw Normal View History

2023-09-25 13:13:20 -04:00
# 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
```javascript
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...
```javascript
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:
```javascript
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`.