Skip to content

Commit 7a7f93e

Browse files
committed
first commit
1 parent df2d902 commit 7a7f93e

File tree

7 files changed

+2250
-1
lines changed

7 files changed

+2250
-1
lines changed

.eslintrc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"extends": ["eslint:recommended", "plugin:prettier/recommended"],
3+
"env": {
4+
"node": true,
5+
"es6": true
6+
},
7+
"parserOptions": {
8+
"ecmaVersion": 10,
9+
"sourceType": "module"
10+
}
11+
}

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.DS_Store
2+
.node-version
3+
node_modules

.prettierrc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"printWidth": 100,
3+
"tabWidth": 2,
4+
"useTabs": false,
5+
"semi": true,
6+
"singleQuote": true,
7+
"trailingComma": "all",
8+
"arrowParens": "avoid"
9+
}

README.md

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,46 @@
1-
# sequelize-bcrypt
1+
# sequelize-bcrypt
2+
3+
## Installation
4+
5+
```bash
6+
npm i sequelize-bcrypt
7+
```
8+
9+
## Setup
10+
11+
```javascript
12+
const { Sequelize, DataTypes } = require('sequelize');
13+
const SequelizeBcrypt = require('sequelize-bcrypt');
14+
15+
const database = new Sequelize({
16+
...sequelizeConnectionOptions,
17+
});
18+
19+
const User = database.define('User', {
20+
email: { type: DataTypes.STRING },
21+
password: { type: DataTypes.STRING },
22+
});
23+
24+
SequelizeBcrypt.useBcrypt(User, options);
25+
```
26+
27+
## Options
28+
29+
```javascript
30+
{
31+
field: 'password', // secret field to hash, default: 'password'
32+
rounds: 12, // used to generate bcrypt salt, default: 12
33+
compare: 'authenticate', // method used to compare secrets, default: 'authenticate'
34+
}
35+
```
36+
37+
## Usage
38+
39+
```javascript
40+
User.create({ email: '[email protected]', password: 'SuperSecret!' });
41+
// { id: 1, email: '[email protected]', password: '$2a$12$VtyL7j5xx6t/GmmAqy53ZuKJ1nwPox5kHLXDaottN9tIQBsEB3EsW' }
42+
43+
const user = await User.findOne({ where: { email: '[email protected]' } });
44+
user.authenticate('WrongPassword!'); // false
45+
user.authenticate('SuperSecret!'); // true
46+
```

index.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
const { ValidationError } = require('sequelize');
2+
const bcrypt = require('bcryptjs');
3+
4+
const DEFAULT_OPTIONS = {
5+
field: 'password',
6+
rounds: 12,
7+
compare: 'authenticate',
8+
};
9+
10+
class SequelizeBcrypt {
11+
static useBcrypt(Model, options = DEFAULT_OPTIONS) {
12+
const opts = { ...DEFAULT_OPTIONS, ...options };
13+
14+
const hashField = function (instance) {
15+
try {
16+
const changedKey = Array.from(instance._changed).find(key => key === opts.field);
17+
if (!changedKey) return;
18+
19+
const fieldDefinition = instance.rawAttributes[changedKey];
20+
if (!fieldDefinition) return;
21+
22+
const plainValue = instance[changedKey];
23+
if (!plainValue) return;
24+
25+
const salt = bcrypt.genSaltSync(opts.rounds);
26+
const hashedValue = bcrypt.hashSync(plainValue, salt);
27+
instance[changedKey] = hashedValue;
28+
} catch (err) {
29+
throw new ValidationError(err.message);
30+
}
31+
};
32+
33+
Model.prototype[opts.compare] = function (plainValue) {
34+
return bcrypt.compareSync(plainValue, this._previousDataValues[opts.field]);
35+
};
36+
37+
Model.addHook('beforeCreate', hashField);
38+
Model.addHook('beforeUpdate', hashField);
39+
}
40+
}
41+
42+
module.exports = SequelizeBcrypt;

0 commit comments

Comments
 (0)