@@ -341,6 +341,7 @@ defmodule MishkaDeveloperTools.Helper.Crypto do
341
341
verify_password(hash, "USER_HARD_PASSWORD", :argon2)
342
342
```
343
343
"""
344
+ @ spec create_hash_password ( String . t ( ) , :argon2 | :bcrypt | :pbkdf2 ) :: String . t ( )
344
345
if Code . ensure_loaded? ( Bcrypt ) do
345
346
def create_hash_password ( password , :bcrypt ) do
346
347
Bcrypt . hash_pwd_salt ( password )
@@ -362,6 +363,8 @@ defmodule MishkaDeveloperTools.Helper.Crypto do
362
363
@ doc """
363
364
For information See `create_hash_password/2`.
364
365
"""
366
+ @ spec verify_password ( binary ( ) , String . t ( ) , :argon2 | :bcrypt | :bcrypt_2b | :pbkdf2 ) ::
367
+ boolean ( )
365
368
if Code . ensure_loaded? ( Bcrypt ) do
366
369
def verify_password ( hash , password , :bcrypt ) do
367
370
Bcrypt . verify_pass ( password , hash )
@@ -386,6 +389,7 @@ defmodule MishkaDeveloperTools.Helper.Crypto do
386
389
end
387
390
388
391
if Code . ensure_loaded? ( Bcrypt ) do
392
+ @ spec no_user_verify_password ( String . t ( ) , :argon2 | :bcrypt | :pbkdf2 ) :: false
389
393
def no_user_verify_password ( password , :bcrypt ) do
390
394
Bcrypt . no_user_verify ( password: password )
391
395
end
@@ -406,7 +410,8 @@ defmodule MishkaDeveloperTools.Helper.Crypto do
406
410
@ doc """
407
411
This is a straightforward data hashing function that does not differentiate between
408
412
**`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.
410
415
411
416
> #### Security issue {: .warning}
412
417
>
@@ -415,7 +420,24 @@ defmodule MishkaDeveloperTools.Helper.Crypto do
415
420
##### I inspired the initial code from this path:
416
421
417
422
- 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
+ ```
418
439
"""
440
+ @ spec simple_hash ( String . t ( ) , String . t ( ) ) :: { binary ( ) , binary ( ) }
419
441
def simple_hash ( text , alg , truncated \\ nil ) when alg in @ hash_algs_keys do
420
442
hashed =
421
443
:crypto . hash ( @ hash_algs [ alg ] [ "hash_algorithm" ] , text )
@@ -424,6 +446,10 @@ defmodule MishkaDeveloperTools.Helper.Crypto do
424
446
{ Base . url_encode64 ( hashed , padding: false ) , hashed }
425
447
end
426
448
449
+ @ doc """
450
+ For information See `simple_hash/2` and `simple_hash/3`.
451
+ """
452
+ @ spec simple_hash ( ) :: { binary ( ) , binary ( ) }
427
453
def simple_hash ( rand_size \\ 32 ) do
428
454
token = :crypto . strong_rand_bytes ( rand_size )
429
455
hashed = :crypto . hash ( :sha256 , token )
@@ -436,28 +462,116 @@ defmodule MishkaDeveloperTools.Helper.Crypto do
436
462
use Joken.Config
437
463
end
438
464
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 ( )
439
490
def create_signer ( alg , key ) when alg in @ hash_algs_keys do
440
491
Joken.Signer . create ( alg , key )
441
492
end
442
493
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 ( ) } }
443
524
def generate_and_sign ( extra_claims , signer \\ nil ) do
444
525
if ! is_nil ( signer ) ,
445
526
do: Token . generate_and_sign ( extra_claims , signer ) ,
446
527
else: Token . generate_and_sign ( extra_claims )
447
528
end
448
529
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 ( )
449
534
def generate_and_sign! ( extra_claims , signer \\ nil ) do
450
535
if ! is_nil ( signer ) ,
451
536
do: Token . generate_and_sign! ( extra_claims , signer ) ,
452
537
else: Token . generate_and_sign! ( extra_claims )
453
538
end
454
539
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 ( ) } }
455
565
def verify_and_validate ( token , signer \\ nil ) do
456
566
if ! is_nil ( signer ) ,
457
567
do: Token . verify_and_validate ( token , signer ) ,
458
568
else: Token . verify_and_validate ( token )
459
569
end
460
570
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 ( ) }
461
575
def verify_and_validate! ( token , signer \\ nil ) do
462
576
if ! is_nil ( signer ) ,
463
577
do: Token . verify_and_validate! ( token , signer ) ,
0 commit comments