{"id":15364655,"url":"https://github.com/venables/bookshelf-secure-password","last_synced_at":"2025-04-15T07:30:57.221Z","repository":{"id":35434218,"uuid":"39700362","full_name":"venables/bookshelf-secure-password","owner":"venables","description":"A Bookshelf.js plugin for handling secure passwords","archived":false,"fork":false,"pushed_at":"2023-01-11T01:48:07.000Z","size":547,"stargazers_count":24,"open_issues_count":12,"forks_count":14,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-28T18:12:12.422Z","etag":null,"topics":["bcrypt","bookshelf","bookshelf-plugin","hash","password","secure","secure-by-default","secure-password","security"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/venables.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-07-25T19:37:45.000Z","updated_at":"2022-05-26T05:28:39.000Z","dependencies_parsed_at":"2023-01-15T21:08:35.887Z","dependency_job_id":null,"html_url":"https://github.com/venables/bookshelf-secure-password","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/venables%2Fbookshelf-secure-password","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/venables%2Fbookshelf-secure-password/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/venables%2Fbookshelf-secure-password/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/venables%2Fbookshelf-secure-password/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/venables","download_url":"https://codeload.github.com/venables/bookshelf-secure-password/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248590086,"owners_count":21129747,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bcrypt","bookshelf","bookshelf-plugin","hash","password","secure","secure-by-default","secure-password","security"],"created_at":"2024-10-01T13:12:59.154Z","updated_at":"2025-04-15T07:30:56.868Z","avatar_url":"https://github.com/venables.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bookshelf-secure-password\n\n[![Version](https://img.shields.io/npm/v/bookshelf-secure-password.svg)](https://www.npmjs.com/package/bookshelf-secure-password)\n[![Build Status](https://img.shields.io/travis/venables/bookshelf-secure-password/master.svg)](https://travis-ci.org/venables/bookshelf-secure-password)\n[![Coverage Status](https://img.shields.io/coveralls/venables/bookshelf-secure-password.svg)](https://coveralls.io/github/venables/bookshelf-secure-password)\n[![Dependency Status](https://david-dm.org/venables/bookshelf-secure-password.png)](https://david-dm.org/venables/bookshelf-secure-password)\n[![Standard - JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](http://standardjs.com/)\n[![License](https://img.shields.io/npm/l/bookshelf-secure-password.svg)](https://github.com/venables/bookshelf-secure-password/blob/master/LICENSE.txt)\n[![Downloads](https://img.shields.io/npm/dm/bookshelf-secure-password.svg)](https://www.npmjs.com/package/bookshelf-secure-password)\n\nA Bookshelf.js plugin for securely handling passwords.\n\n## Features\n\n* Securely store passwords in the database using BCrypt with ease.\n* Minimal setup required: just install the module, and make a `password_digest` column in the database!\n* Follows the latest security guidelines, using a BCrypt cost of 12\n* Inspired by and similar to [has_secure_password](http://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html) in Ruby on Rails.\n\n## Installation\n\n```\nyarn add bookshelf-secure-password\n```\n\nor\n\n```\nnpm install bookshelf-secure-password --save\n```\n\n## Usage\n\n1. Enable the plugin in your Bookshelf setup\n\n  ```javascript\n  const bookshelf = require('bookshelf')(knex)\n  const securePassword = require('bookshelf-secure-password')\n\n  bookshelf.plugin(securePassword)\n  ```\n\n2. Add `hasSecurePassword` to the model(s) which require a secure password\n\n  ```javascript\n  const User = bookshelf.Model.extend({\n    tableName: 'users',\n    hasSecurePassword: true\n  })\n  ```\n\n  By default, this will use the database column named `password_digest`. To use a different column, simply change `true` to be the column name. For example:\n\n  ```javascript\n  const User = bookshelf.Model.extend({\n    tableName: 'users',\n    hasSecurePassword: 'custom_password_digest_field'\n  })\n  ```\n\n3. Now, when you set a password and save the record, it will be hashed as `password_digest`:\n\n  ```javascript\n  user = new User({ password: 'testing' })\n  user.get('password') // =\u003e undefined\n  user.get('password_digest') // =\u003e undefined\n\n  user.save().then(function () {\n    user.get('password') // =\u003e undefined\n    user.get('password_digest') // =\u003e '$2a$12$SzUDit15feMdVCtfSzopc.0LuqeHlJInqq/1Ol8uxCC5QydHpVWFy'\n  })\n  ```\n\n4. To authenticate against the password, simply call the instance method `authenticate`, which returns a `Promise` resolving to the authenticated Model.\n\n  ```javascript\n  user.authenticate('some-password').then(function (user) {\n    // do something with the authenticated user\n  }, function (err) {\n    // invalid password.\n    // `err` will be of type `PasswordMismatchError`, which extends the `Error` class\n  })\n  ```\n\n## Example\n\n```javascript\nconst User = require('./models/User')\n\n/**\n * Sign up a new user.\n *\n * @returns {Promise.\u003cUser\u003e} A promise resolving to the newly registered User, or rejected with an error.\n */\nfunction signUp (email, password) {\n  let user = new User({ email: email, password: password })\n\n  return user.save()\n}\n\n/**\n * Sign in with a given email, password combination\n *\n * @returns {Promise.\u003cUser\u003e} A promise resolving to the authenticated User, or rejected with a `PasswordMismatchError`.\n */\nfunction signIn (email, password) {\n  return User.forge({ email: email })\n    .fetch()\n    .then(function (user) {\n      return user.authenticate(password)\n    })\n}\n```\n\n## Notes\n\n* BCrypt requires that passwords are 72 characters maximum (it ignores characters after 72).\n* This library enables the `bookshelf-virtuals-plugin` plugin on Bookshelf for the virtual `password` field.\n* Passing a `null` value to the password will clear the `password_digest`.\n* Passing `undefined` or a zero-length string to the password will leave the `password_digest` as-is\n\n## Testing\n\nTo run the tests locally, simply run `yarn test` or `npm test`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvenables%2Fbookshelf-secure-password","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvenables%2Fbookshelf-secure-password","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvenables%2Fbookshelf-secure-password/lists"}