Giter Club home page Giter Club logo

secure-password's Introduction

secure-password

Build Status Build status

Making Password storage safer for all

Features

  • State of the art password hashing algorithm (Argon2id)
  • Safe defaults for most applications
  • Future-proof so work factors and hashing algorithms can be easily upgraded
  • Buffers everywhere for safer memory management

Usage

var securePassword = require('secure-password')

// Initialise our password policy
var pwd = securePassword()

var userPassword = Buffer.from('my secret password')

// Register user
pwd.hash(userPassword, function (err, hash) {
  if (err) throw err

  // Save hash somewhere
  pwd.verify(userPassword, hash, function (err, result) {
    if (err) throw err
    
    switch (result) {
      case securePassword.INVALID_UNRECOGNIZED_HASH:
        return console.error('This hash was not made with secure-password. Attempt legacy algorithm')
      case securePassword.INVALID:
        return console.log('Invalid password')
      case securePassword.VALID:
        return console.log('Authenticated')
      case securePassword.VALID_NEEDS_REHASH:
        console.log('Yay you made it, wait for us to improve your safety')

        pwd.hash(userPassword, function (err, improvedHash) {
          if (err) console.error('You are authenticated, but we could not improve your safety this time around')

          // Save improvedHash somewhere
        })
        break
    }
  })
})

or with async await:

const securePassword = require('secure-password')

// Initialise our password policy
const pwd = securePassword()

const userPassword = Buffer.from('my secret password')

async function run () {
  // Register user
  const hash = await pwd.hash(userPassword)

  // Save hash somewhere
  const result = await pwd.verify(userPassword, hash)
  
  switch (result) {
    case securePassword.INVALID_UNRECOGNIZED_HASH:
      return console.error('This hash was not made with secure-password. Attempt legacy algorithm')
    case securePassword.INVALID:
      return console.log('Invalid password')
    case securePassword.VALID:
      return console.log('Authenticated')
    case securePassword.VALID_NEEDS_REHASH:
      console.log('Yay you made it, wait for us to improve your safety')

      try {
        const improvedHash = await pwd.hash(userPassword)
        // Save improvedHash somewhere
      } catch (err) {
        console.error('You are authenticated, but we could not improve your safety this time around')
      }
      break
  }
}

run()

API

var pwd = new SecurePassword(opts)

Make a new instance of SecurePassword which will contain your settings. You can view this as a password policy for your application. opts takes the following keys:

// Initialise our password policy (these are the defaults)
var pwd = securePassword({
  memlimit: securePassword.MEMLIMIT_DEFAULT,
  opslimit: securePassword.OPSLIMIT_DEFAULT
})

They're both constrained by the constants SecurePassword.MEMLIMIT_MIN - SecurePassword.MEMLIMIT_MAX and SecurePassword.OPSLIMIT_MIN - SecurePassword.OPSLIMIT_MAX. If not provided they will be given the default values SecurePassword.MEMLIMIT_DEFAULT and SecurePassword.OPSLIMIT_DEFAULT which should be fast enough for a general purpose web server without your users noticing too much of a load time. However your should set these as high as possible to make any kind of cracking as costly as possible. A load time of 1s seems reasonable for login, so test various settings in your production environment.

The settings can be easily increased at a later time as hardware most likely improves (Moore's law) and adversaries therefore get more powerful. If a hash is attempted verified with weaker parameters than your current settings, you get a special return code signalling that you need to rehash the plaintext password according to the updated policy. In contrast to other modules, this module will not increase these settings automatically as this can have ill effects on services that are not carefully monitored.

pwd.hash(password, [function (err, hash) {}])

Takes Buffer password and hashes it. You can call cancel to abort the hashing.

The hashing is done by a seperate worker as to not block the event loop, so normal execution and I/O can continue. The callback is invoked with a potential error, or the Buffer hash.

  • password must be a Buffer of length SecurePassword.PASSWORD_BYTES_MIN - SecurePassword.PASSWORD_BYTES_MAX.
  • hash will be a Buffer of length SecurePassword.HASH_BYTES.

If a callback is not specified, a Promise is returned.

var hash = pwd.hashSync(password)

Takes Buffer password and hashes it. The hashing is done on the same thread as the event loop, therefore normal execution and I/O will be blocked. The function may throw a potential error, but most likely return the Buffer hash.

password must be a Buffer of length SecurePassword.PASSWORD_BYTES_MIN - SecurePassword.PASSWORD_BYTES_MAX.
hash will be a Buffer of length SecurePassword.HASH_BYTES.

pwd.verify(password, hash, [function (err, enum) {}])

Takes Buffer password and hashes it and then safely compares it to the Buffer hash. The hashing is done by a seperate worker as to not block the event loop, so normal execution and I/O can continue. The callback is invoked with a potential error, or one of the symbols SecurePassword.INVALID, SecurePassword.VALID, SecurePassword.NEEDS_REHASH or SecurePassword.INVALID_UNRECOGNIZED_HASH. Check with strict equality for one the cases as in the example above.

If enum === SecurePassword.NEEDS_REHASH you should call pwd.hash with password and save the new hash for next time. Be careful not to introduce a bug where a user trying to login multiple times, successfully, in quick succession makes your server do unnecessary work.

password must be a Buffer of length SecurePassword.PASSWORD_BYTES_MIN - SecurePassword.PASSWORD_BYTES_MAX.
hash will be a Buffer of length SecurePassword.HASH_BYTES.

If a callback is not specified, a Promise is returned.

var enum = pwd.verifySync(password, hash)

Takes Buffer password and hashes it and then safely compares it to the Buffer hash. The hashing is done on the same thread as the event loop, therefore normal execution and I/O will be blocked. The function may throw a potential error, or return one of the symbols SecurePassword.VALID, SecurePassword.INVALID, SecurePassword.NEEDS_REHASH or SecurePassword.INVALID_UNRECOGNIZED_HASH. Check with strict equality for one the cases as in the example above.

SecurePassword.VALID

The password was verified and is valid

SecurePassword.INVALID

The password was invalid

SecurePassword.VALID_NEEDS_REHASH

The password was verified and is valid, but needs to be rehashed with new parameters

SecurePassword.INVALID_UNRECOGNIZED_HASH

The hash was unrecognized and therefore could not be verified. As an implementation detail it is currently very cheap to attempt verifying unrecognized hashes, since this only requires some lightweight pattern matching.

SecurePassword.HASH_BYTES

Size of the hash Buffer returned by hash and hashSync and used by verify and verifySync.

SecurePassword.PASSWORD_BYTES_MIN

Minimum length of the password Buffer.

SecurePassword.PASSWORD_BYTES_MAX

Maximum length of the password Buffer.

SecurePassword.MEMLIMIT_MIN

Minimum value for the opts.memlimit option.

SecurePassword.MEMLIMIT_MAX

Maximum value for the opts.memlimit option.

SecurePassword.OPSLIMIT_MIN

Minimum value for the opts.opslimit option.

SecurePassword.OPSLIMIT_MAX

Maximum value for the opts.opslimit option.

SecurePassword.MEMLIMIT_DEFAULT

Default value for the opts.memlimit option.

SecurePassword.OPSLIMIT_DEFAULT

Minimum value for the opts.opslimit option.

Install

npm install secure-password

Credits

I want to thank Tom Streller for donating the package name on npm. The <1.0.0 versions that he had written and published to npm can still be downloaded and the source is available in his scan/secure-password repository

License

ISC

secure-password's People

Contributors

alexaivars avatar emilbayes avatar jakechampion avatar marcbachmann avatar mcollina avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

secure-password's Issues

Would recommend updating ReadMe/docs to be more specific on how the algorithm is chosen.

Hi! The docs currently say that Argon2id is used, which roughly correct. But more precisely, it uses libsodium's current default password hashing algorithm, which may change in the future, but will always be backwards compatible.

I realize not everybody needs that level of precision, but because NPM has a lot of low-quality packages, I usually dig in a little when it's something important like crypto. My rough thought process:

  1. I need a library to do Argon2id. I found secure-password.
  2. Looks like it uses libsodium -- this is good because I know libsodium is optimized native code, which is very important for password hashing to make sure we're not giving the attacker an unnecessary CPU advantage. I avoided the NPM package that used the Argon2id reference implementation because I assumed (perhaps incorrectly) that the reference implementation might not be optimized as well as libsodium.
  3. Looks like it uses sodium.crypto_pwhash and not sodium.crypto_pwhash_argon2id. What if libsodium changes their default in the future? For example, will the crypto_pwhash_PASSWD_MIN constants change and cause incompatibilities in the future?
  4. I then read the libsodium docs which say that the crypto_pwhash will remain backwards compatible (link):

Sodium's high-level crypto_pwhash_* API currently leverages the Argon2id function on all platforms. This can change at any point in time, but it is guaranteed that a given version of libsodium can verify all hashes produced by all previous versions, from any platform. Applications don't have to worry about backward compatibility.

I think something like this at the top of the ReadMe and NPM docs would have saved me some effort:

Uses sodium-native package to call libsodium's optimized crypto_pwhash API, which currently defaults Argon2id. libsodium promises the crypto_pwhash API will remain backwards compatible, even if they change the default algorithm (search for "previous versions" or "backwards compatibility" in the libsodium pwhash docs).

Same password, same options, different verify result

Hi,

I'm running identical container Docker Swarm Mode stacks on two identical servers. On one of the servers, password verification always works fine. On the other, it keeps failing regardless of whether the input password is correct or not. When it fails, it seems to fail for all passwords.

To make sure it was a problem with Secure Password and not with my (and others) typing, I copied a stored password hash directly from one database to the other, checked that the stored values were identical and then attempted to log in to each instance of my software by copying and pasting the same password into each log in form. One passed verification, the other failed.

This also happened a couple of days ago. At that time, I found #10 and so changed the way I stored hashes to match:

const savedHash = Buffer.alloc(securePassword.HASH_BYTES);
savedHash.write(dbhashedvalue);

After deploying that change, everything worked fine for a couple of days. However, today I've noticed that password verification is failing again on the same server as before.

I don't understand how this issue can arise on one server but not the other. Neither has significant usage at the moment and they're running identical container stacks. One of the containers is a Node app which handles password hashing and verification via Secure Password. That container is currently limited to 150MB memory in each stack. I limit Secure Password to 64MB and have checked that the memory utilisation when not hashing passwords generally sits at 62MB, which leaves a little room for growth (not much, but this project is in early stages and for a small, fixed-size team of users, so trying to avoid increasing the cost of hosting).

I generate password hashes with the following function and save the resulting hash string to MongoDB (running in a separate container on the same stack):

const SecurePassword = require('secure-password');

const securePassword = SecurePassword({
	memlimit: 67108864 # 64Mb
});

function hashPassword(userPassword) {
	return new Promise((resolve, reject) => {
		console.debug('Hashing password');

		securePassword.hash(
			Buffer.from(userPassword),
			(error, hashBuffer) => {
				if (error) {
					reject(error);
				}

				resolve(hashBuffer.toString());
			}
		);
	});
}

I verify the passwords with this function:

function verifyPassword(userPassword, correctHash) {
	const passwordBuffer = Buffer.from(userPassword);
	const hashBuffer = Buffer.alloc(SecurePassword.HASH_BYTES);
	hashBuffer.write(correctHash);

	return new Promise((resolve, reject) => {
		securePassword.verify(passwordBuffer, hashBuffer, async (error, result) => {
			if (error) {
				reject(error);
			}

			switch (result) {
				case SecurePassword.INVALID_UNRECOGNIZED_HASH:
					reject({message: 'Unexpected error'});
					break;
				case SecurePassword.INVALID:
					reject({invalid: true, message: 'Invalid password'});
					break;
				case SecurePassword.VALID:
					resolve();
					break;
				case SecurePassword.VALID_NEEDS_REHASH:
					try {
						newHash = await hashPassword(userPassword);
						resolve(newHash);
					} catch (error) {
						resolve(); // Resolve because password verified correctly although failed to create new hash
					}
					break
				default:
					reject({message: 'Unexpected error'});
			}
		});
	});
}

On the failing server, it hits the SecurePassword.INVALID case every time.

Any ideas why this could be failing on one server and not the other?

Import fails when using node alpine docker image

I'm using the docker image node:alpine3.11 to build and deploy my application.

internal/modules/cjs/loader.js:1197
 return process.dlopen(module, path.toNamespacedPath(filename));

Error: Error loading shared library ld-linux-x86-64.so.2: No such file or directory (needed by /usr/app/node_modules/sodium-native/prebuilds/linux-x64/libsodium.so.23)
 at Object.Module._extensions..node (internal/modules/cjs/loader.js:1197:18)
 at Module.load (internal/modules/cjs/loader.js:996:32)
 at Function.Module._load (internal/modules/cjs/loader.js:896:14)
 at Module.require (internal/modules/cjs/loader.js:1036:19)
 at require (internal/modules/cjs/helpers.js:72:18)
 at load (/usr/app/node_modules/node-gyp-build/index.js:21:10)
 at Object.<anonymous> (/usr/app/node_modules/sodium-native/index.js:1:39)
 at Module._compile (internal/modules/cjs/loader.js:1147:30)
 at Object.Module._extensions..js (internal/modules/cjs/loader.js:1167:10)
 at Module.load (internal/modules/cjs/loader.js:996:32)

Client-size hash implementation

Edit: client-side* sorry for the typo

Would it be possible to make the hash function works on the client side with libsodium.js or something&

I'd like the server to send the salt and the client to compute the password before sending it back

Thanks!

PS I looked at many argon2 implementation in Node and this one is by far my favorite!

Can't install on High Sierra

checking build system type... x86_64-apple-darwin17.2.0
checking host system type... x86_64-apple-darwin17.2.0
checking for a BSD-compatible install... /usr/local/opt/coreutils/libexec/gnubin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/local/opt/coreutils/libexec/gnubin/mkdir -p
checking for gawk... no
checking for mawk... no
checking for nawk... no
checking for awk... awk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking whether UID '501' is supported by ustar format... yes
checking whether GID '20' is supported by ustar format... yes
checking how to create a ustar tar archive... gnutar
checking whether make supports nested variables... (cached) yes
checking whether to enable maintainer-specific portions of Makefiles... no
configure: error: The build directory contains whitespaces - This can cause tests/installation to fail due to limitations of some libtool versions

secure-password version < 1.0.0 is not available anymore

I was using secure-password version 0.1.2. However after the publish of version 2.0.0 for some reason npm is forcefully downloading version 2.0.0 despite my package.json asking for version 0.1.2. Below is a snippet from my package.json .

"secure-password": "0.1.2"

Because of the above, my current implementation is breaking. I can however move to the newer implementation but I am not confident if my old passwords will work with the library.

Request you to do the needful to restore the older version along with the newer version.

Using toString('hex') or toString('base64') on the resulting buffer always generates the same string

this library seems to return the same exact buffer when I hash a password:

> var secure = require('secure-password')
undefined
> var pwd = secure()
undefined
> pwd.hash(Buffer.from('foo'), (_, b) => console.log(b))
undefined
> <Buffer 24 61 72 67 6f 6e 32 69 24 76 3d 31 39 24 6d 3d 33 32 37 36 38 2c 74 3d 34 2c 70 3d 31 24 5a 6c 75 57 68 78 4c 75 54 71 6f 61 6c 75 58 5a 52 33 31 50 ... >
> pwd.hash(Buffer.from('foo'), (_, b) => console.log(b))
undefined
> <Buffer 24 61 72 67 6f 6e 32 69 24 76 3d 31 39 24 6d 3d 33 32 37 36 38 2c 74 3d 34 2c 70 3d 31 24 55 52 49 6e 6f 31 62 71 39 73 50 37 73 46 74 4f 4f 56 71 73 ... >
> pwd.hash(Buffer.from('asdsdsdsdsd'), (_, b) => console.log(b))
undefined
> <Buffer 24 61 72 67 6f 6e 32 69 24 76 3d 31 39 24 6d 3d 33 32 37 36 38 2c 74 3d 34 2c 70 3d 31 24 77 33 6e 6b 6c 48 54 4e 36 48 6c 6b 38 59 33 32 41 34 4a 47 ... >
> pwd.hash(Buffer.from('foobar'), (_, b) => console.log(b.toString('base64'))
> JGFyZ29uMmkkdj0xOSRtPTMyNzY4LHQ9NCxwPTEkTi9QbkZpN0M4Z3RlYUtha2hWbHNQdyRlaDd1WTc4dGlndHF2ZVlRWmlub1V4LytIMWZwaFNQdG1WMUs2bkpWWThzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
> pwd.hash(Buffer.from('foo'), (_, b) => console.log(b.toString('base64')))
undefined
> JGFyZ29uMmkkdj0xOSRtPTMyNzY4LHQ9NCxwPTEkMk9mam5DbFAvTHN1OExxVGJVWVpadyQyNjh0MXdnNkp5blhaM3RnUDZZR1JVeFdGYTZDditvbWJrR3B0eFNQb1U4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=

INVALID_UNRECOGNIZED_HASH and HASH_BYTES

Thank you for this great package, saved me a ton of headaches and I look forward to it saving me more in the future as new hashing algos come out.

If your hash is not HASH_BYTES, you never receive the expected securePassword.INVALID_UNRECOGNIZED_HASH result, instead you get hashBuf must be HASH_BYTES (128)

I would not expect securePassword to impose it's restrictions on the Buffer or password min/max length on hashes it does not recognize as it's own.

 Error: hashBuf must be HASH_BYTES (128)
              at assert (<my project>\node_modules\nanoassert\index.js:21:17)
              at SecurePassword.verify (<my project>\node_modules\secure-password\index.js:126:3)
              at <my project>\node_modules\secure-password\index.js:109:12
              at new Promise (<anonymous>)
              at SecurePassword.verify (<my project>\node_modules\secure-password\index.js:108:12)
              at Object.exports.passwordHashCompareString (<my project>\src\utils\password-hash.ts:37:14)
              at AuthResolver.login (<my project>\src\resolvers\auth-resolver.ts:120:25)
              at processTicksAndRejections (internal/process/task_queues.js:97:5)
              at Object.<anonymous> (<my project>\tests\auth-resolver\login.mutation.errors.test.ts:83:22) {
            locations: [Array],
            path: [Array]
          }

I can fix it by re-saving my old hashes with

const oldHash = Buffer.alloc(SecurePassword.HASH_BYTES)
oldHash.write(rawOldHash)

however this can cause problems with any legacy hashing algorithm so sometimes needs magic to undo it again too.

As an aside, if I want to test securePassword.VALID_NEEDS_REHASH works properly in my app, is there a way to generate an "older" hash with securePassword to trigger it? or am I stuck mocking out pwd.verify to return this code in my tests?

Consider using argon2 instead of sodium-native

DISCLAIMER: I am the author of argon2 package.

I see you use sodium-native, and I personally like the simplicity of libsodium, but since you only use it for Argon2 hashing, it might be better to use argon2 instead. After all, sodium-native ships 10 MB of files, while argon2 is only 184 KB and supports virtually everything this library requires.

The only issue I see is that we long ago dropped sync functions (it really does not make sense to run such a slow function synchronously, consider dropping too ๐Ÿ˜† ), other than that I'm more than happy to do whatever you need from the library.

Example on how to verify a password from database

I'm new to javascript so excuse me if this is trivial, it took me a while to figure it out so i think it should be good to include this in the example to save people some time.

To save the hash to db i need to convert it first to a string.
When a user logs in i need to create a new buffer with the saved hash in order to use the verify function.

Using Buffer.from returns the error
"Error: hashBuf must be HASH_BYTES (128)"
Because the buffer length is 96.

It should be something:

const savedHash = Buffer.alloc(securePassword.HASH_BYTES)
savedHash.write(dbhashedvalue)

Also from what i understand it's not possible to set the value of securePassword.HASH_BYTES right?

Thank you

Where to add the salt?

If I would ask when to put the salt, could be question of cooking receipt.
I was wondering, how secure this library might be, if you don't add a salt?

Or should I just add the salt along the password?

why assert on an async callback

using assert which throws an error if the data doesn't match the parameters feels a little odd for a library with an async callback -- why not call the callback with an error?

it feels very odd to protect myself from a crashing program with doing:

try {
  pwd.verify(pass, hash, cb) 
} catch (err) {
  cb(err)
}

Rather than just

pwd.verify(pass, has, cb)

Would you be open to a PR changing the async methods to call the callback instead of throwing an AssertionError?

Node 4 support?

Hi ๐Ÿ‘‹,
I'm using secure-password with node 7 and works great. I've defined some tests that are all passing locally, but are failling in travis for node 4. Is this module not supporting node 4 or am I doing something wrong? Here is the travis log: https://travis-ci.org/YerkoPalma/auth-example/builds/248086860

Seems like some assertion is throwing, but just for node 4.
Thanks :)

Error: opts.memlimit must be at least MEMLIMIT_MIN (undefined)

I'm having this error only in node 9. I've recently updated to node stable and a project using this module started to crash. Here is the full stacktrace of the error

/home/yerko/Dev/kids/node_modules/nanoassert/index.js:21
  if (!t) throw new Error(m || 'AssertionError')
          ^

Error: opts.memlimit must be at least MEMLIMIT_MIN (undefined)
    at assert (/home/yerko/Dev/kids/node_modules/nanoassert/index.js:21:17)
    at new SecurePassword (/home/yerko/Dev/kids/node_modules/secure-password/index.js:30:3)
    at SecurePassword (/home/yerko/Dev/kids/node_modules/secure-password/index.js:24:49)
    at Object.<anonymous> (/home/yerko/Dev/kids/routes/teachers/create.js:2:11)
    at Module._compile (module.js:641:30)
    at Object.Module._extensions..js (module.js:652:10)
    at Module.load (module.js:560:32)
    at tryModuleLoad (module.js:503:12)
    at Function.Module._load (module.js:495:3)
    at Module.require (module.js:585:17)

As you can see the error happens in line 30 and it seems to be beacause MEMLIMIT_MIN (sodium.crypto_pwhash_MEMLIMIT_MIN) is not defined in node 9

Docker with secure-password

Hi,
I use secure-password with docker, but when I run docker-compose up, I receive this error.

api_1    | > node-gyp-build "node preinstall.js" "node postinstall.js"
api_1    | 
api_1    | libtool is required, but wasn't found on this system
api_1    | ./configure: line 5: ./configure: not found
api_1    | /api/node_modules/secure-password/node_modules/sodium-native/preinstall.js:119
api_1    |     if (err) throw err
api_1    |              ^
api_1    | 
api_1    | Error: ./configure exited with 127
api_1    |     at ChildProcess.<anonymous> (/api/node_modules/secure-password/node_modules/sodium-native/preinstall.js:149:25)
api_1    |     at ChildProcess.emit (events.js:310:20)
api_1    |     at Process.ChildProcess._handle.onexit (internal/child_process.js:275:12)
api_1    | npm WARN [email protected] No repository field.
api_1    | npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/fsevents):
api_1    | npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
api_1    | 
api_1    | npm ERR! code ELIFECYCLE
api_1    | npm ERR! errno 1
api_1    | npm ERR! [email protected] install: `node-gyp-build "node preinstall.js" "node postinstall.js"`
api_1    | npm ERR! Exit status 1
api_1    | npm ERR! 
api_1    | npm ERR! Failed at the [email protected] install script.
api_1    | npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
api_1    | 
api_1    | npm ERR! A complete log of this run can be found in:
api_1    | npm ERR!     /root/.npm/_logs/2020-04-20T07_24_48_237Z-debug.log

This is my Dockerfile

FROM node:12-alpine
WORKDIR /api
COPY . .
ENTRYPOINT [ "sh", "/api/docker-api-cmd/api-cmd.sh" ]
CMD ["npm", "run", "dev"]

This is api-cmd.sh:

#!/bin/bash

npm install

#Some cmds here

Thanks for any helps

Adding support for promises

I'd like to request support for the Promise API. Your code example together with async / await would look like following then.

const securePassword = require('secure-password')

// Initialise our password policy
const pwd = securePassword()

const doHashingAndVerify = async function () {
  const userPassword = Buffer.from('my secret password')

  // Register user
  const hash = await pwd.hash(userPassword) 

  // Save hash somewhere
  const result = await pwd.verify(userPassword, hash)

  if (result === securePassword.INVALID) return console.log('Imma call the cops')
  if (result === securePassword.VALID) return console.log('Yay you made it')
  if (result === securePassword.VALID_NEEDS_REHASH) {
    console.log('Yay you made it, wait for us to improve your safety')

    const improvedHash = await pwd.hash(userPassword)
  }
}

doHashingAndVerify()
  .then(() => console.log('succesful'))
  .catch(err => throw err)

Really enjoyed your JSConf talk btw!

Support typescript ??

Could not find a declaration file for module 'secure-password'.
Try npm install @types/secure-password if it exists or add a new declaration (.d.ts) file containing declare module 'secure-password';

Unicode characters when hashing password

Hi, I don't really know if this is the expected behavior or not, but when I hash a password the result includes a bunch of unicode characters, like so:

$argon2id$v=19$m=65536,t=2,p=1$aG/+dVRNEcHrdTHLlGTdVg$85tZ6DCyYvZNDudIrLY8kqEBVoRQruSJItI/HR4dxX4\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000

Is this how it works or am I doing something wrong?

Migrate to WASM

By now libsodium supports an official wasm build.
Are you interested in getting a PR that completely replaces sodium-native with it?

One challenge would be async support without blocking the event loop.
It most likely needs a worker thread for production systems.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.