⚠️ Oops! This page doesn't appear to define a type called _.

Build Status Coverage Status

bs-password

A password hashing libarary for ReasonML

How do I install it?

Inside of a BuckleScript project:

yarn add bs-password

Then add bs-password to your bs-dependencies in bsconfig.json

{
  "bs-dependencies": [ "bs-password" ]
}

Usage

Basic Callback based interface.

  1. Derive a hash
let password = "This is my password";
let algorithm = Password.Algorithm.Bcrypt;

Password.deriveKey(algorithm, password, (result) => {
  switch (result) {
  | Belt.Result.Error(e) => raise(e)
  | Belt.Result.Ok((salt, hash)) => Js.log3("Salt and Key", salt, hash)
  };
});
[@@@ocaml.ppx.context { cookies = [] }]
let password =
  (("This is my password")[@reason.raw_literal "This is my password"])
let algorithm = Password.Algorithm.Bcrypt
let _ =
  Password.deriveKey algorithm password
    (fun result  ->
       match result with
       | ((Belt.Result.Error (e))[@explicit_arity ]) -> raise e
       | ((Belt.Result.Ok ((salt,hash)))[@explicit_arity ]) ->
           Js.log3 (("Salt and Key")[@reason.raw_literal "Salt and Key"])
             salt hash)
Type Error: File "", line 10, characters 9-59: Error: The constructor Belt.Result.Ok expects 1 argument(s), but is applied here to 2 argument(s)
  1. Verify a hash against a password.
let password = "This is my passsword";
let algorithm = Password.Algorithm.Bcrypt;

Password.deriveKey(algorithm, password, (result) => {
  switch (result) {
  | Belt.Result.Error(e) => raise(e)
  | Belt.Result.Ok((_, hash)) =>
    Password.verify(algorithm, hash, password, (result2) => {
    switch (result) {
    | Belt.Result.Error(e) => raise(e)
    | Belt.Result.Ok(isValid) => Js.log2("isValid: ", isValid)
    }
    });
  };
});
[@@@ocaml.ppx.context { cookies = [] }]
let password =
  (("This is my passsword")[@reason.raw_literal "This is my passsword"])
let algorithm = Password.Algorithm.Bcrypt
let _ =
  Password.deriveKey algorithm password
    (fun result  ->
       match result with
       | ((Belt.Result.Error (e))[@explicit_arity ]) -> raise e
       | ((Belt.Result.Ok ((_,hash)))[@explicit_arity ]) ->
           Password.verify algorithm hash password
             (fun result2  ->
                match result with
                | ((Belt.Result.Error (e))[@explicit_arity ]) -> raise e
                | ((Belt.Result.Ok (isValid))[@explicit_arity ]) ->
                    Js.log2 (("isValid: ")[@reason.raw_literal "isValid: "])
                      isValid))
Type Error: File "", line 10, characters 9-56: Error: The constructor Belt.Result.Ok expects 1 argument(s), but is applied here to 2 argument(s)
  1. Generate a random token.
let algorithm = Password.Algorithm.Bcrypt;
let length = 8;

Password.token(algorithm, length, (result) => {
  switch(result) {
  | Belt.Result.Error(e) => raise(e)
  | Belt.Result.Ok(token) => Js.log2("Token: ", token)
  };
});
[@@@ocaml.ppx.context { cookies = [] }]
let algorithm = Password.Algorithm.Bcrypt
let length = 8
let _ =
  Password.token algorithm length
    (fun result  ->
       match result with
       | ((Belt.Result.Error (e))[@explicit_arity ]) -> raise e
       | ((Belt.Result.Ok (token))[@explicit_arity ]) ->
           Js.log2 (("Token: ")[@reason.raw_literal "Token: "]) token)

Future based interface.

  1. Derive a hash.
let password = "This is my password";
let algorithm = Password.Algorithm.Bcrypt;

Password.Future.deriveKey(algorithm, password)
|. Future.mapOk(((salt, hash)) => Js.log3("Salt and Key: ", salt, hash))
|. Future.mapError(raise);
[@@@ocaml.ppx.context { cookies = [] }]
let password =
  (("This is my password")[@reason.raw_literal "This is my password"])
let algorithm = Password.Algorithm.Bcrypt
let _ =
  ((Password.Future.deriveKey algorithm password) |.
     (Future.mapOk
        (fun (salt,hash)  ->
           Js.log3 (("Salt and Key: ")[@reason.raw_literal "Salt and Key: "])
             salt hash)))
    |. (Future.mapError raise)
  1. Verify a hash against a password.
let password = "This is my password";
let algo = Password.Algorithm.Bcrypt;

Password.Future.deriveKey(algo, password)
|. Future.flatMapOk(((_, hash)) => Password.Future.verify(algo, hash, password))
|. Future.mapOk(isValid => Js.log2("Is Valid: ", isValid))
|. Future.mapError(raise)
[@@@ocaml.ppx.context { cookies = [] }]
let password =
  (("This is my password")[@reason.raw_literal "This is my password"])
let algo = Password.Algorithm.Bcrypt
let _ =
  (((Password.Future.deriveKey algo password) |.
      (Future.flatMapOk
         (fun (_,hash)  -> Password.Future.verify algo hash password)))
     |.
     (Future.mapOk
        (fun isValid  ->
           Js.log2 (("Is Valid: ")[@reason.raw_literal "Is Valid: "]) isValid)))
    |. (Future.mapError raise)
  1. Generate a random token.
let algo = Password.Algorithm.Bcrypt;

Password.Future.token(algo, 16)
|. Future.mapOk(token => Js.log2("Token: ", token))
|. Future.mapError(raise)
[@@@ocaml.ppx.context { cookies = [] }]
let algo = Password.Algorithm.Bcrypt
let _ =
  ((Password.Future.token algo 16) |.
     (Future.mapOk
        (fun token  ->
           Js.log2 (("Token: ")[@reason.raw_literal "Token: "]) token)))
    |. (Future.mapError raise)

Promise based interface.

  1. Derive a hash.
let password = "This is my password";
let algorithm = Password.Algorithm.Bcrypt;

Password.Promise.deriveKey(algorithm, password)
|> Js.Promise.then_(result =>
  switch (result) {
  | Belt.Result.Error(e) => raise(e)
  | Belt.Result.Ok((salt, hash)) => Js.log3("Salt and key: ", salt, hash)
  }
  |> Js.Promise.resolve
)
[@@@ocaml.ppx.context { cookies = [] }]
let password =
  (("This is my password")[@reason.raw_literal "This is my password"])
let algorithm = Password.Algorithm.Bcrypt
let _ =
  (Password.Promise.deriveKey algorithm password) |>
    (Js.Promise.then_
       (fun result  ->
          (match result with
           | ((Belt.Result.Error (e))[@explicit_arity ]) -> raise e
           | ((Belt.Result.Ok ((salt,hash)))[@explicit_arity ]) ->
               Js.log3
                 (("Salt and key: ")[@reason.raw_literal "Salt and key: "])
                 salt hash)
            |> Js.Promise.resolve))
Type Error: File "", line 11, characters 13-63: Error: The constructor Belt.Result.Ok expects 1 argument(s), but is applied here to 2 argument(s)
  1. Verify a hash against a password.
let password = "This is my password";
let algo = Password.Algorithm.Bcrypt;

Password.Promise.deriveKey(algo, password)
|> Js.Promise.then_(result =>
  switch (result) {
  | Belt.Result.Error(e) => raise(e)
  | Belt.Result.Ok((_, hash)) => Js.Promise.resolve(hash)
  }
)
|> Js.Promise.then_(hash => Password.Promise.verify(algo, hash, password))
|> Js.Promise.then_(isValid =>
  Js.log2("Does Match: ", isValid) |> Js.Promise.resolve
) 
[@@@ocaml.ppx.context { cookies = [] }]
let password =
  (("This is my password")[@reason.raw_literal "This is my password"])
let algo = Password.Algorithm.Bcrypt
let _ =
  (((Password.Promise.deriveKey algo password) |>
      (Js.Promise.then_
         (fun result  ->
            match result with
            | ((Belt.Result.Error (e))[@explicit_arity ]) -> raise e
            | ((Belt.Result.Ok ((_,hash)))[@explicit_arity ]) ->
                Js.Promise.resolve hash)))
     |>
     (Js.Promise.then_
        (fun hash  -> Password.Promise.verify algo hash password)))
    |>
    (Js.Promise.then_
       (fun isValid  ->
          (Js.log2 (("Does Match: ")[@reason.raw_literal "Does Match: "])
             isValid)
            |> Js.Promise.resolve))
Type Error: File "", line 11, characters 14-61: Error: The constructor Belt.Result.Ok expects 1 argument(s), but is applied here to 2 argument(s)
  1. Generate a random token.
let algo = Password.Algorithm.Bcrypt;

Password.Promise.token(algo, 31)
|> Js.Promise.then_(token => Js.log2("Token: ", token) |> Js.Promise.resolve)
[@@@ocaml.ppx.context { cookies = [] }]
let algo = Password.Algorithm.Bcrypt
let _ =
  (Password.Promise.token algo 31) |>
    (Js.Promise.then_
       (fun token  ->
          (Js.log2 (("Token: ")[@reason.raw_literal "Token: "]) token) |>
            Js.Promise.resolve))