Merge branch 'develop' into oembed_provider
authorraeno <just.raeno@gmail.com>
Tue, 18 Dec 2018 13:59:32 +0000 (14:59 +0100)
committerraeno <just.raeno@gmail.com>
Tue, 18 Dec 2018 13:59:32 +0000 (14:59 +0100)
1  2 
config/config.exs
lib/pleroma/formatter.ex
lib/pleroma/user.ex
lib/pleroma/web/router.ex
mix.exs
mix.lock

diff --combined config/config.exs
index 5477c0c0e8418426685d54ea9bdfe23bd6014307,e4b31bf8132765fff620542a1ab27440487ee518..73242e4ffa52a351675020c74d8ab4687e7fae2e
@@@ -10,6 -10,13 +10,13 @@@ config :pleroma, ecto_repos: [Pleroma.R
  
  config :pleroma, Pleroma.Repo, types: Pleroma.PostgresTypes
  
+ config :pleroma, Pleroma.Captcha,
+   enabled: false,
+   seconds_retained: 180,
+   method: Pleroma.Captcha.Kocaptcha
+ config :pleroma, Pleroma.Captcha.Kocaptcha, endpoint: "https://captcha.kotobank.ch"
  # Upload configuration
  config :pleroma, Pleroma.Upload,
    uploader: Pleroma.Uploaders.Local,
@@@ -50,6 -57,15 +57,15 @@@ config :pleroma, :uri_schemes
  # Configures the endpoint
  config :pleroma, Pleroma.Web.Endpoint,
    url: [host: "localhost"],
+   http: [
+     dispatch: [
+       {:_,
+        [
+          {"/api/v1/streaming", Elixir.Pleroma.Web.MastodonAPI.WebsocketHandler, []},
+          {:_, Plug.Adapters.Cowboy.Handler, {Pleroma.Web.Endpoint, []}}
+        ]}
+     ]
+   ],
    protocol: "https",
    secret_key_base: "aK4Abxf29xU9TTDKre9coZPUgevcVCFQJe/5xP/7Lt4BEif6idBIbjupVbOrbKxl",
    signing_salt: "CqaoopA2",
@@@ -65,6 -81,7 +81,7 @@@ config :logger, :console
  config :mime, :types, %{
    "application/xml" => ["xml"],
    "application/xrd+xml" => ["xrd+xml"],
+   "application/jrd+json" => ["jrd+json"],
    "application/activity+json" => ["activity+json"],
    "application/ld+json" => ["activity+json"]
  }
@@@ -93,6 -110,7 +110,7 @@@ config :pleroma, :instance
    public: true,
    quarantined_instances: [],
    managed_config: true,
+   static_dir: "instance/static/",
    allowed_post_formats: [
      "text/plain",
      "text/html",
@@@ -171,8 -189,6 +189,8 @@@ config :pleroma, :gopher
    ip: {0, 0, 0, 0},
    port: 9999
  
 +config :pleroma, :metadata, opengraph: true
 +
  config :pleroma, :suggestions,
    enabled: false,
    third_party_engine:
diff --combined lib/pleroma/formatter.ex
index 1d5dc0c99c7411e88a36e3b83940cde8f3809f84,46d0d926a814b2177c4aeefff7cc79e37b8f74e6..8024d97c2dc716454592cd5fc8e739d1962f4765
@@@ -5,6 -5,8 +5,8 @@@ defmodule Pleroma.Formatter d
    alias Pleroma.Emoji
  
    @tag_regex ~r/\#\w+/u
+   @markdown_characters_regex ~r/(`|\*|_|{|}|[|]|\(|\)|#|\+|-|\.|!)/
    def parse_tags(text, data \\ %{}) do
      Regex.scan(@tag_regex, text)
      |> Enum.map(fn ["#" <> tag = full_tag] -> {full_tag, String.downcase(tag)} end)
      |> Enum.join("")
    end
  
+   @doc """
+   Escapes a special characters in mention names.
+   """
+   @spec mentions_escape(String.t(), list({String.t(), any()})) :: String.t()
+   def mentions_escape(text, mentions) do
+     mentions
+     |> Enum.reduce(text, fn {name, _}, acc ->
+       escape_name = String.replace(name, @markdown_characters_regex, "\\\\\\1")
+       String.replace(acc, name, escape_name)
+     end)
+   end
    @doc "changes scheme:... urls to html links"
    def add_links({subs, text}) do
      links =
        String.replace(result_text, uuid, replacement)
      end)
    end
 +
 +  def truncate(text, opts \\ []) do
 +    max_length = opts[:max_length] || 200
 +    omission = opts[:omission] || "..."
 +
 +    cond do
 +      not String.valid?(text) ->
 +        text
 +
 +      String.length(text) < max_length ->
 +        text
 +
 +      true ->
 +        length_with_omission = max_length - String.length(omission)
 +
 +        "#{String.slice(text, 0, length_with_omission)}#{omission}"
 +    end
 +  end
  end
diff --combined lib/pleroma/user.ex
index 28ff08a39f01ba1fdcf1cba223a9a33b674340ff,3ad1ab87a69347c775e9fa7f2081414d53e814d6..c86ad4afee38238172ef9bd32935eaa051d8cfe1
@@@ -294,10 -294,6 +294,10 @@@ defmodule Pleroma.User d
      user.info.locked || false
    end
  
 +  def get_by_id(id) do
 +    Repo.get_by(User, id: id)
 +  end
 +
    def get_by_ap_id(ap_id) do
      Repo.get_by(User, ap_id: ap_id)
    end
      Cachex.fetch!(:user_cache, key, fn _ -> get_by_ap_id(ap_id) end)
    end
  
 +  def get_cached_by_id(id) do
 +    key = "id:#{id}"
 +    Cachex.fetch!(:user_cache, key, fn _ -> get_by_id(id) end)
 +  end
 +
    def get_cached_by_nickname(nickname) do
      key = "nickname:#{nickname}"
      Cachex.fetch!(:user_cache, key, fn _ -> get_or_fetch_by_nickname(nickname) end)
    end
  
 +  def get_cached_by_nickname_or_id(nickname_or_id) do
 +    get_cached_by_nickname(nickname_or_id) || get_cached_by_id(nickname_or_id)
 +  end
 +
    def get_by_nickname(nickname) do
      Repo.get_by(User, nickname: nickname)
    end
      do: tag(User.get_by_nickname(nickname), tags)
  
    def tag(%User{} = user, tags),
-     do: update_tags(user, Enum.uniq(user.tags ++ normalize_tags(tags)))
+     do: update_tags(user, Enum.uniq((user.tags || []) ++ normalize_tags(tags)))
  
    def untag(user_identifiers, tags) when is_list(user_identifiers) do
      Repo.transaction(fn ->
    def untag(nickname, tags) when is_binary(nickname),
      do: untag(User.get_by_nickname(nickname), tags)
  
-   def untag(%User{} = user, tags), do: update_tags(user, user.tags -- normalize_tags(tags))
+   def untag(%User{} = user, tags),
+     do: update_tags(user, (user.tags || []) -- normalize_tags(tags))
  
    defp update_tags(%User{} = user, new_tags) do
      {:ok, updated_user} =
index 751624e80cc381adee8e85b8f0380521be369263,dd1985d6ee1b91a16e0c88517f0edc9fa1e49f27..49b007422a9390c4444ca2c0ee360ed8d5ab4ce9
@@@ -99,6 -99,7 +99,7 @@@ defmodule Pleroma.Web.Router d
      get("/password_reset/:token", UtilController, :show_password_reset)
      post("/password_reset", UtilController, :password_reset)
      get("/emoji", UtilController, :emoji)
+     get("/captcha", UtilController, :captcha)
    end
  
    scope "/api/pleroma/admin", Pleroma.Web.AdminAPI do
      delete("/relay", AdminAPIController, :relay_unfollow)
  
      get("/invite_token", AdminAPIController, :get_invite_token)
+     post("/email_invite", AdminAPIController, :email_invite)
      get("/password_reset", AdminAPIController, :get_password_reset)
    end
  
    end
  
    pipeline :ostatus do
 -    plug(:accepts, ["xml", "atom", "html", "activity+json"])
 +    plug(:accepts, ["html", "xml", "atom", "activity+json"])
 +  end
 +
 +  pipeline :oembed do
 +    plug(:accepts, ["json", "xml"])
    end
  
    scope "/", Pleroma.Web do
      post("/push/subscriptions/:id", Websub.WebsubController, :websub_incoming)
    end
  
 +  scope "/", Pleroma.Web do
 +    pipe_through(:oembed)
 +
 +    get("/oembed", OEmbed.OEmbedController, :url)
 +  end
 +
    pipeline :activitypub do
      plug(:accepts, ["activity+json"])
      plug(Pleroma.Web.Plugs.HTTPSignaturePlug)
@@@ -462,26 -455,11 +465,26 @@@ en
  
  defmodule Fallback.RedirectController do
    use Pleroma.Web, :controller
 +  alias Pleroma.Web.Metadata
  
    def redirector(conn, _params) do
      conn
      |> put_resp_content_type("text/html")
 -    |> send_file(200, Pleroma.Plugs.InstanceStatic.file_path("index.html"))
 +    |> send_file(200, index_file_path())
 +  end
 +
 +  def redirector_with_meta(conn, params) do
 +    {:ok, index_content} = File.read(index_file_path())
 +    tags = Metadata.build_tags(params)
 +    response = String.replace(index_content, "<!--server-generated-meta-->", tags)
 +
 +    conn
 +    |> put_resp_content_type("text/html")
 +    |> send_resp(200, response)
 +  end
 +
 +  def index_file_path do
-     Application.app_dir(:pleroma, "priv/static/index.html")
++    Pleroma.Plugs.InstanceStatic.file_path("index.html"))
    end
  
    def registration_page(conn, params) do
diff --combined mix.exs
index e5fb654dd52ccf082b985cec75fa2df500932ad8,e9705bcf90c1877ca3d6e78bc08e8d44340d6b68..31ebcc5f3cfb7b0f1ecfea0c2edcab2b37f60311
+++ b/mix.exs
@@@ -8,12 -8,7 +8,7 @@@ defmodule Pleroma.Mixfile d
        elixir: "~> 1.4",
        elixirc_paths: elixirc_paths(Mix.env()),
        compilers: [:phoenix, :gettext] ++ Mix.compilers(),
-       elixirc_options:
-         if Mix.env() == :test do
-           []
-         else
-           [warnings_as_errors: true]
-         end,
+       elixirc_options: [warnings_as_errors: true],
        start_permanent: Mix.env() == :prod,
        aliases: aliases(),
        deps: deps(),
    # Type `mix help deps` for examples and options.
    defp deps do
      [
-       {:phoenix, "~> 1.3.3"},
-       {:phoenix_pubsub, "~> 1.0.2"},
+       # Until Phoenix 1.4.1 is released
+       {:phoenix, github: "phoenixframework/phoenix", branch: "v1.4"},
+       {:plug_cowboy, "~> 1.0"},
+       {:phoenix_pubsub, "~> 1.1"},
        {:phoenix_ecto, "~> 3.3"},
        {:postgrex, ">= 0.13.5"},
        {:gettext, "~> 0.15"},
-       {:cowboy, "~> 1.1.2", override: true},
        {:comeonin, "~> 4.1.1"},
        {:pbkdf2_elixir, "~> 0.12.3"},
        {:trailing_format_plug, "~> 0.0.7"},
        {:html_sanitize_ex, "~> 1.3.0"},
 +      {:html_entities, "~> 0.4"},
        {:phoenix_html, "~> 2.10"},
        {:calendar, "~> 0.17.4"},
        {:cachex, "~> 3.0.2"},
@@@ -68,7 -63,7 +64,7 @@@
        {:mogrify, "~> 0.6.1"},
        {:ex_aws, "~> 2.0"},
        {:ex_aws_s3, "~> 2.0"},
-       {:earmark, "~> 1.2"},
+       {:earmark, "~> 1.3"},
        {:ex_machina, "~> 2.2", only: :test},
        {:credo, "~> 0.9.3", only: [:dev, :test]},
        {:mock, "~> 0.3.1", only: :test},
@@@ -78,7 -73,8 +74,8 @@@
        {:ex_doc, "> 0.18.3 and < 0.20.0", only: :dev, runtime: false},
        {:web_push_encryption, "~> 0.2.1"},
        {:swoosh, "~> 0.20"},
-       {:gen_smtp, "~> 0.13"}
+       {:gen_smtp, "~> 0.13"},
+       {:websocket_client, git: "https://github.com/jeremyong/websocket_client.git", only: :test}
      ]
    end
  
diff --combined mix.lock
index 007079652577c53345b79eef4afd925e337e319a,dddb04aadac97f312a6e097529a5bff31db767c9..3521f82bbf928726daefa8ff97ddff84c0db111d
+++ b/mix.lock
@@@ -13,7 -13,7 +13,7 @@@
    "crypt": {:git, "https://github.com/msantos/crypt", "1f2b58927ab57e72910191a7ebaeff984382a1d3", [ref: "1f2b58927ab57e72910191a7ebaeff984382a1d3"]},
    "db_connection": {:hex, :db_connection, "1.1.3", "89b30ca1ef0a3b469b1c779579590688561d586694a3ce8792985d4d7e575a61", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
    "decimal": {:hex, :decimal, "1.5.0", "b0433a36d0e2430e3d50291b1c65f53c37d56f83665b43d79963684865beab68", [:mix], [], "hexpm"},
-   "earmark": {:hex, :earmark, "1.2.6", "b6da42b3831458d3ecc57314dff3051b080b9b2be88c2e5aa41cd642a5b044ed", [:mix], [], "hexpm"},
+   "earmark": {:hex, :earmark, "1.3.0", "17f0c38eaafb4800f746b457313af4b2442a8c2405b49c645768680f900be603", [:mix], [], "hexpm"},
    "ecto": {:hex, :ecto, "2.2.10", "e7366dc82f48f8dd78fcbf3ab50985ceeb11cb3dc93435147c6e13f2cda0992e", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
    "eternal": {:hex, :eternal, "1.2.0", "e2a6b6ce3b8c248f7dc31451aefca57e3bdf0e48d73ae5043229380a67614c41", [:mix], [], "hexpm"},
    "ex_aws": {:hex, :ex_aws, "2.1.0", "b92651527d6c09c479f9013caa9c7331f19cba38a650590d82ebf2c6c16a1d8a", [:mix], [{:configparser_ex, "~> 2.0", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "1.6.3 or 1.6.5 or 1.7.1 or 1.8.6 or ~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jsx, "~> 2.8", [hex: :jsx, repo: "hexpm", optional: true]}, {:poison, ">= 1.2.0", [hex: :poison, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}, {:xml_builder, "~> 0.1.0", [hex: :xml_builder, repo: "hexpm", optional: true]}], "hexpm"},
@@@ -23,7 -23,6 +23,7 @@@
    "gen_smtp": {:hex, :gen_smtp, "0.13.0", "11f08504c4bdd831dc520b8f84a1dce5ce624474a797394e7aafd3c29f5dcd25", [:rebar3], [], "hexpm"},
    "gettext": {:hex, :gettext, "0.15.0", "40a2b8ce33a80ced7727e36768499fc9286881c43ebafccae6bab731e2b2b8ce", [:mix], [], "hexpm"},
    "hackney": {:hex, :hackney, "1.13.0", "24edc8cd2b28e1c652593833862435c80661834f6c9344e84b6a2255e7aeef03", [:rebar3], [{:certifi, "2.3.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
 +  "html_entities": {:hex, :html_entities, "0.4.0", "f2fee876858cf6aaa9db608820a3209e45a087c5177332799592142b50e89a6b", [:mix], [], "hexpm"},
    "html_sanitize_ex": {:hex, :html_sanitize_ex, "1.3.0", "f005ad692b717691203f940c686208aa3d8ffd9dd4bb3699240096a51fa9564e", [:mix], [{:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"},
    "httpoison": {:hex, :httpoison, "1.2.0", "2702ed3da5fd7a8130fc34b11965c8cfa21ade2f232c00b42d96d4967c39a3a3", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
    "idna": {:hex, :idna, "5.1.2", "e21cb58a09f0228a9e0b95eaa1217f1bcfc31a1aaa6e1fdf2f53a33f7dbd9494", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
@@@ -33,7 -32,7 +33,7 @@@
    "makeup_elixir": {:hex, :makeup_elixir, "0.10.0", "0f09c2ddf352887a956d84f8f7e702111122ca32fbbc84c2f0569b8b65cbf7fa", [:mix], [{:makeup, "~> 0.5.5", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"},
    "meck": {:hex, :meck, "0.8.9", "64c5c0bd8bcca3a180b44196265c8ed7594e16bcc845d0698ec6b4e577f48188", [:rebar3], [], "hexpm"},
    "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
-   "mime": {:hex, :mime, "1.3.0", "5e8d45a39e95c650900d03f897fbf99ae04f60ab1daa4a34c7a20a5151b7a5fe", [:mix], [], "hexpm"},
+   "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"},
    "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"},
    "mochiweb": {:hex, :mochiweb, "2.15.0", "e1daac474df07651e5d17cc1e642c4069c7850dc4508d3db7263a0651330aacc", [:rebar3], [], "hexpm"},
    "mock": {:hex, :mock, "0.3.1", "994f00150f79a0ea50dc9d86134cd9ebd0d177ad60bd04d1e46336cdfdb98ff9", [:mix], [{:meck, "~> 0.8.8", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"},
    "nimble_parsec": {:hex, :nimble_parsec, "0.4.0", "ee261bb53214943679422be70f1658fff573c5d0b0a1ecd0f18738944f818efe", [:mix], [], "hexpm"},
    "parse_trans": {:hex, :parse_trans, "3.2.0", "2adfa4daf80c14dc36f522cf190eb5c4ee3e28008fc6394397c16f62a26258c2", [:rebar3], [], "hexpm"},
    "pbkdf2_elixir": {:hex, :pbkdf2_elixir, "0.12.3", "6706a148809a29c306062862c803406e88f048277f6e85b68faf73291e820b84", [:mix], [], "hexpm"},
-   "phoenix": {:hex, :phoenix, "1.3.4", "aaa1b55e5523083a877bcbe9886d9ee180bf2c8754905323493c2ac325903dc5", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.3 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
+   "phoenix": {:git, "https://github.com/phoenixframework/phoenix.git", "ea22dc50b574178a300ecd19253443960407df93", [branch: "v1.4"]},
    "phoenix_ecto": {:hex, :phoenix_ecto, "3.3.0", "702f6e164512853d29f9d20763493f2b3bcfcb44f118af2bc37bb95d0801b480", [:mix], [{:ecto, "~> 2.1", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
    "phoenix_html": {:hex, :phoenix_html, "2.11.2", "86ebd768258ba60a27f5578bec83095bdb93485d646fc4111db8844c316602d6", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
-   "phoenix_pubsub": {:hex, :phoenix_pubsub, "1.0.2", "bfa7fd52788b5eaa09cb51ff9fcad1d9edfeb68251add458523f839392f034c1", [:mix], [], "hexpm"},
-   "plug": {:hex, :plug, "1.6.2", "e06a7bd2bb6de5145da0dd950070110dce88045351224bd98e84edfdaaf5ffee", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"},
+   "phoenix_pubsub": {:hex, :phoenix_pubsub, "1.1.1", "6668d787e602981f24f17a5fbb69cc98f8ab085114ebfac6cc36e10a90c8e93c", [:mix], [], "hexpm"},
+   "plug": {:hex, :plug, "1.7.1", "8516d565fb84a6a8b2ca722e74e2cd25ca0fc9d64f364ec9dbec09d33eb78ccd", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}], "hexpm"},
+   "plug_cowboy": {:hex, :plug_cowboy, "1.0.0", "2e2a7d3409746d335f451218b8bb0858301c3de6d668c3052716c909936eb57a", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
+   "plug_crypto": {:hex, :plug_crypto, "1.0.0", "18e49317d3fa343f24620ed22795ec29d4a5e602d52d1513ccea0b07d8ea7d4d", [:mix], [], "hexpm"},
    "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
    "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"},
    "postgrex": {:hex, :postgrex, "0.13.5", "3d931aba29363e1443da167a4b12f06dcd171103c424de15e5f3fc2ba3e6d9c5", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"},
@@@ -58,4 -59,5 +60,5 @@@
    "unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"},
    "unsafe": {:hex, :unsafe, "1.0.0", "7c21742cd05380c7875546b023481d3a26f52df8e5dfedcb9f958f322baae305", [:mix], [], "hexpm"},
    "web_push_encryption": {:hex, :web_push_encryption, "0.2.1", "d42cecf73420d9dc0053ba3299cc8c8d6ff2be2487d67ca2a57265868e4d9a98", [:mix], [{:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}, {:poison, "~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
+   "websocket_client": {:git, "https://github.com/jeremyong/websocket_client.git", "9a6f65d05ebf2725d62fb19262b21f1805a59fbf", []},
  }