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.
- 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)
- 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)
- 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.
- 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)
- 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)
- 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.
- 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)
- 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)
- 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))