diff --git a/lib/helper/crypto.ex b/lib/helper/crypto.ex index 8358d74..fe99294 100644 --- a/lib/helper/crypto.ex +++ b/lib/helper/crypto.ex @@ -1,10 +1,17 @@ defmodule MishkaDeveloperTools.Helper.Crypto do @moduledoc """ + In reality, this module serves as a support for other libraries in addition + to Erlang's built-in functions for encryption, hashing, and other topics that are associated + with the language. + It should be brought to your attention that certain functions necessitate the addition of their + dependencies to the primary project. Consequently, prior to making use of these functionalities, + establish the appropriate dependence within the project in accordance with your requirements. """ + alias Postgrex.Extensions.JSON @type based32_url :: <<_::64, _::_*8>> - @simple_hash_algs %{ + @hash_algs %{ "RS256" => %{"type" => :asymmetric, "hash_algorithm" => :sha256, "binary_size" => 16}, "RS384" => %{"type" => :asymmetric, "hash_algorithm" => :sha384, "binary_size" => 24}, "RS512" => %{"type" => :asymmetric, "hash_algorithm" => :sha512, "binary_size" => 32}, @@ -13,6 +20,8 @@ defmodule MishkaDeveloperTools.Helper.Crypto do "HS512" => %{"type" => :symmetric, "hash_algorithm" => :sha512, "binary_size" => 32} } + @hash_algs_keys Map.keys(@hash_algs) + @doc """ Generate a binary composed of random bytes. @@ -407,9 +416,52 @@ defmodule MishkaDeveloperTools.Helper.Crypto do - https://github.com/malach-it/boruta_auth/blob/master/lib/boruta/oauth/schemas/client.ex#L173 """ - def simple_hash(text, alg, truncated \\ nil) do - :crypto.hash(@simple_hash_algs[alg]["hash_algorithm"], text) - |> binary_part(0, truncated || @simple_hash_algs[alg]["binary_size"]) - |> Base.url_encode64(padding: false) + def simple_hash(text, alg, truncated \\ nil) when alg in @hash_algs_keys do + hashed = + :crypto.hash(@hash_algs[alg]["hash_algorithm"], text) + |> binary_part(0, truncated || @hash_algs[alg]["binary_size"]) + + {Base.url_encode64(hashed, padding: false), hashed} + end + + def simple_hash(rand_size \\ 32) do + token = :crypto.strong_rand_bytes(rand_size) + hashed = :crypto.hash(:sha256, token) + + {Base.url_encode64(token, padding: false), hashed} + end + + if Code.ensure_loaded?(JSON) and Code.ensure_loaded?(Joken) do + defmodule Token do + use Joken.Config + end + + def create_signer(alg, key) when alg in @hash_algs_keys do + Joken.Signer.create(alg, key) + end + + def generate_and_sign(extra_claims, signer \\ nil) do + if !is_nil(signer), + do: Token.generate_and_sign(extra_claims, signer), + else: Token.generate_and_sign(extra_claims) + end + + def generate_and_sign!(extra_claims, signer \\ nil) do + if !is_nil(signer), + do: Token.generate_and_sign!(extra_claims, signer), + else: Token.generate_and_sign!(extra_claims) + end + + def verify_and_validate(token, signer \\ nil) do + if !is_nil(signer), + do: Token.verify_and_validate(token, signer), + else: Token.verify_and_validate(token) + end + + def verify_and_validate!(token, signer \\ nil) do + if !is_nil(signer), + do: Token.verify_and_validate!(token, signer), + else: Token.verify_and_validate!(token) + end end end diff --git a/lib/helper/extra.ex b/lib/helper/extra.ex index c28819d..c65d6cb 100644 --- a/lib/helper/extra.ex +++ b/lib/helper/extra.ex @@ -66,4 +66,15 @@ defmodule MishkaDeveloperTools.Helper.Extra do |> String.to_charlist() |> Enum.all?(&(&1 in allowed_chars)) end + + def get_unix_time() do + DateTime.utc_now() |> DateTime.to_unix() + end + + def get_unix_time_with_shift(number, type \\ :second) + when type in [:day, :hour, :minute, :second] do + DateTime.utc_now() + |> DateTime.add(number, type) + |> DateTime.to_unix() + end end diff --git a/mix.exs b/mix.exs index 6f2bfc8..e553671 100644 --- a/mix.exs +++ b/mix.exs @@ -48,6 +48,8 @@ defmodule MishkaDeveloperTools.MixProject do {:ex_url, "~> 2.0", optional: true}, {:ex_phone_number, "~> 0.4.3", optional: true}, {:nimble_totp, "~> 1.0", optional: true}, + {:joken, "~> 2.6", optional: true}, + {:jason, "~> 1.4", optional: true}, # Make sure you have a C compiler installed. See the Comeonin wiki for details. # Wiki link: https://github.com/riverrun/comeonin/wiki/Requirements {:bcrypt_elixir, "~> 3.1", optional: true}, diff --git a/mix.lock b/mix.lock index 473d4ef..29a95d7 100644 --- a/mix.lock +++ b/mix.lock @@ -16,6 +16,9 @@ "ex_phone_number": {:hex, :ex_phone_number, "0.4.4", "8e994abe583496a3308cf56af013dca9b47a0424b0a9940af41cb0d66b848dd3", [:mix], [{:sweet_xml, "~> 0.7", [hex: :sweet_xml, repo: "hexpm", optional: false]}], "hexpm", "a59875692ec57b3392959a7740f3e9a5cb08da88bcaee4efd480c770f5bb0f2c"}, "ex_url": {:hex, :ex_url, "2.0.0", "c940f034895103fc493948ef0036c9473c396988dad3835531fb0c1476ba63c4", [:mix], [{:ex_cldr, "~> 2.18", [hex: :ex_cldr, repo: "hexpm", optional: true]}, {:ex_phone_number, "~> 0.1", [hex: :ex_phone_number, repo: "hexpm", optional: true]}, {:gettext, "~> 0.13", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "5bba73e551462f891a3cc47d7c1a42acff8dc0cb4dce02f03c937947db4f0d31"}, "html_sanitize_ex": {:hex, :html_sanitize_ex, "1.4.3", "67b3d9fa8691b727317e0cc96b9b3093be00ee45419ffb221cdeee88e75d1360", [:mix], [{:mochiweb, "~> 2.15 or ~> 3.1", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm", "87748d3c4afe949c7c6eb7150c958c2bcba43fc5b2a02686af30e636b74bccb7"}, + "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, + "joken": {:hex, :joken, "2.6.1", "2ca3d8d7f83bf7196296a3d9b2ecda421a404634bfc618159981a960020480a1", [:mix], [{:jose, "~> 1.11.9", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "ab26122c400b3d254ce7d86ed066d6afad27e70416df947cdcb01e13a7382e68"}, + "jose": {:hex, :jose, "1.11.9", "c861eb99d9e9f62acd071dc5a49ffbeab9014e44490cd85ea3e49e3d36184777", [:mix, :rebar3], [], "hexpm", "b5ccc3749d2e1638c26bed806259df5bc9e438797fe60dc71e9fa0716133899b"}, "makeup": {:hex, :makeup, "1.1.1", "fa0bc768698053b2b3869fa8a62616501ff9d11a562f3ce39580d60860c3a55e", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "5dc62fbdd0de44de194898b6710692490be74baa02d9d108bc29f007783b0b48"}, "makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"}, "makeup_erlang": {:hex, :makeup_erlang, "0.1.5", "e0ff5a7c708dda34311f7522a8758e23bfcd7d8d8068dc312b5eb41c6fd76eba", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "94d2e986428585a21516d7d7149781480013c56e30c6a233534bedf38867a59a"},