Skip to content

Commit 8520640

Browse files
committed
Add essential functions of comenion and joken module for password and jwt
1 parent 11d54ae commit 8520640

File tree

1 file changed

+115
-1
lines changed

1 file changed

+115
-1
lines changed

lib/helper/crypto.ex

+115-1
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ defmodule MishkaDeveloperTools.Helper.Crypto do
341341
verify_password(hash, "USER_HARD_PASSWORD", :argon2)
342342
```
343343
"""
344+
@spec create_hash_password(String.t(), :argon2 | :bcrypt | :pbkdf2) :: String.t()
344345
if Code.ensure_loaded?(Bcrypt) do
345346
def create_hash_password(password, :bcrypt) do
346347
Bcrypt.hash_pwd_salt(password)
@@ -362,6 +363,8 @@ defmodule MishkaDeveloperTools.Helper.Crypto do
362363
@doc """
363364
For information See `create_hash_password/2`.
364365
"""
366+
@spec verify_password(binary(), String.t(), :argon2 | :bcrypt | :bcrypt_2b | :pbkdf2) ::
367+
boolean()
365368
if Code.ensure_loaded?(Bcrypt) do
366369
def verify_password(hash, password, :bcrypt) do
367370
Bcrypt.verify_pass(password, hash)
@@ -386,6 +389,7 @@ defmodule MishkaDeveloperTools.Helper.Crypto do
386389
end
387390

388391
if Code.ensure_loaded?(Bcrypt) do
392+
@spec no_user_verify_password(String.t(), :argon2 | :bcrypt | :pbkdf2) :: false
389393
def no_user_verify_password(password, :bcrypt) do
390394
Bcrypt.no_user_verify(password: password)
391395
end
@@ -406,7 +410,8 @@ defmodule MishkaDeveloperTools.Helper.Crypto do
406410
@doc """
407411
This is a straightforward data hashing function that does not differentiate between
408412
**`symmetric`** and **`asymmetric`** functions according to their characteristics. Take, for instance,
409-
the use of **`checksums`** or codes associated with `nonce`, `c_hash`, `at_hash`, and other similar concepts.
413+
the use of **`checksums`** or codes associated with `nonce`, `c_hash`, `at_hash`,
414+
`short-lived Access Token`, and other similar concepts.
410415
411416
> #### Security issue {: .warning}
412417
>
@@ -415,7 +420,24 @@ defmodule MishkaDeveloperTools.Helper.Crypto do
415420
##### I inspired the initial code from this path:
416421
417422
- https://github.com/malach-it/boruta_auth/blob/master/lib/boruta/oauth/schemas/client.ex#L173
423+
424+
### Example:
425+
```elixir
426+
simple_hash("Your text", "RS512")
427+
simple_hash("Your text", "RS512", 32)
428+
429+
# OR
430+
simple_hash()
431+
simple_hash(32)
432+
```
433+
434+
> This function in all types of input and output is as follows
435+
436+
```elixir
437+
{URL Encode64, Binary}
438+
```
418439
"""
440+
@spec simple_hash(String.t(), String.t()) :: {binary(), binary()}
419441
def simple_hash(text, alg, truncated \\ nil) when alg in @hash_algs_keys do
420442
hashed =
421443
:crypto.hash(@hash_algs[alg]["hash_algorithm"], text)
@@ -424,6 +446,10 @@ defmodule MishkaDeveloperTools.Helper.Crypto do
424446
{Base.url_encode64(hashed, padding: false), hashed}
425447
end
426448

449+
@doc """
450+
For information See `simple_hash/2` and `simple_hash/3`.
451+
"""
452+
@spec simple_hash() :: {binary(), binary()}
427453
def simple_hash(rand_size \\ 32) do
428454
token = :crypto.strong_rand_bytes(rand_size)
429455
hashed = :crypto.hash(:sha256, token)
@@ -436,28 +462,116 @@ defmodule MishkaDeveloperTools.Helper.Crypto do
436462
use Joken.Config
437463
end
438464

465+
@doc """
466+
For your convenience, this function will generate a signature for you, allowing you to sign
467+
the data that you desire. It is necessary to create a signature before you can create a `JWT`.
468+
Pay a visit to the `Joken` library if you have certain requirements that you need to fulfill.
469+
470+
### Example:
471+
```elixir
472+
create_signer("HS384", "YOUR SECURE KEY")
473+
create_signer("RS512", %{"pem" => pem_file})
474+
// OR
475+
create_typed_signer("HS384", "YOUR SECURE KEY")
476+
create_typed_signer("RS512", %{"pem" => pem_file})
477+
```
478+
479+
For more information about `pem`:
480+
- https://hexdocs.pm/joken/signers.html#pem-privacy-enhanced-mail
481+
482+
483+
If you want to create `signer` with pem like RSA as an asymmetric, see `create_typed_signer/2`
484+
or `create_typed_signer/3`
485+
486+
See this issue:
487+
- https://github.com/joken-elixir/joken/issues/420
488+
"""
489+
@spec create_signer(String.t(), binary() | map()) :: Joken.Signer.t()
439490
def create_signer(alg, key) when alg in @hash_algs_keys do
440491
Joken.Signer.create(alg, key)
441492
end
442493

494+
@doc """
495+
For information See `create_signer/2`.
496+
"""
497+
@spec create_typed_signer(String.t(), binary(), binary() | nil) :: Joken.Signer.t()
498+
def create_typed_signer(alg, key, pem \\ nil) when alg in @hash_algs_keys do
499+
case @hash_algs[alg]["type"] do
500+
:asymmetric when not is_nil(pem) -> Joken.Signer.create(alg, %{"pem" => pem})
501+
_ -> create_signer(alg, key)
502+
end
503+
end
504+
505+
@doc """
506+
It is possible to use a signature that you have already made in order to sign a
507+
piece of data by utilizing this function. Take note that signing guarantees
508+
that no changes will be made to the data, and that all of your information will
509+
be entirely transparent.
510+
511+
### Example:
512+
```elixir
513+
signer = create_typed_signer("HS384", "YOUR SECURE KEY")
514+
generate_and_sign(extra_claims, signer)
515+
```
516+
517+
> If you do not send the signer, it will attempt to retrieve it from the config of
518+
> your `Joken` module.
519+
>
520+
> Generates claims with the given token configuration and merges them with the given extra claims.
521+
"""
522+
@spec generate_and_sign(map(), Joken.Signer.t() | nil) ::
523+
{:error, atom() | keyword()} | {:ok, binary(), %{optional(binary()) => any()}}
443524
def generate_and_sign(extra_claims, signer \\ nil) do
444525
if !is_nil(signer),
445526
do: Token.generate_and_sign(extra_claims, signer),
446527
else: Token.generate_and_sign(extra_claims)
447528
end
448529

530+
@doc """
531+
For information See `generate_and_sign/2` or `generate_and_sign/1`.
532+
"""
533+
@spec generate_and_sign!(map(), Joken.Signer.t() | nil) :: binary()
449534
def generate_and_sign!(extra_claims, signer \\ nil) do
450535
if !is_nil(signer),
451536
do: Token.generate_and_sign!(extra_claims, signer),
452537
else: Token.generate_and_sign!(extra_claims)
453538
end
454539

540+
@doc """
541+
It is like `generate_and_sign/2` or `generate_and_sign/1`, but it did not generate claims.
542+
"""
543+
@spec encode_and_sign(map(), Joken.Signer.t() | nil) ::
544+
{:error, atom() | keyword()} | {:ok, binary(), %{optional(binary()) => any()}}
545+
def encode_and_sign(extra_claims, signer \\ nil) do
546+
if !is_nil(signer),
547+
do: Token.encode_and_sign(extra_claims, signer),
548+
else: Token.encode_and_sign(extra_claims)
549+
end
550+
551+
@doc """
552+
Verifies a bearer_token using the given signer and executes hooks if any are given.
553+
554+
> If you do not send the signer, it will attempt to retrieve it from the config of
555+
> your `Joken` module.
556+
557+
### Example:
558+
```elixir
559+
signer = create_typed_signer("HS384", "YOUR SECURE KEY")
560+
verify_and_validate(token, signer)
561+
```
562+
"""
563+
@spec verify_and_validate(binary(), Joken.Signer.t() | nil) ::
564+
{:error, atom() | keyword()} | {:ok, %{optional(binary()) => any()}}
455565
def verify_and_validate(token, signer \\ nil) do
456566
if !is_nil(signer),
457567
do: Token.verify_and_validate(token, signer),
458568
else: Token.verify_and_validate(token)
459569
end
460570

571+
@doc """
572+
For information See `verify_and_validate/2` or `verify_and_validate/1`.
573+
"""
574+
@spec verify_and_validate!(binary(), Joken.Signer.t() | nil) :: %{optional(binary()) => any()}
461575
def verify_and_validate!(token, signer \\ nil) do
462576
if !is_nil(signer),
463577
do: Token.verify_and_validate!(token, signer),

0 commit comments

Comments
 (0)