Merge branch 'develop' into openapi/account
[akkoma] / lib / pleroma / web / twitter_api / twitter_api.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
6 alias Pleroma.Emails.Mailer
7 alias Pleroma.Emails.UserEmail
8 alias Pleroma.Repo
9 alias Pleroma.User
10 alias Pleroma.UserInviteToken
11
12 require Pleroma.Constants
13
14 def register_user(params, opts \\ []) do
15 params =
16 params
17 |> Map.take([
18 :nickname,
19 :password,
20 :captcha_solution,
21 :captcha_token,
22 :captcha_answer_data,
23 :token,
24 :email,
25 :trusted_app
26 ])
27 |> Map.put(:bio, User.parse_bio(params[:bio] || ""))
28 |> Map.put(:name, params.fullname)
29 |> Map.put(:password_confirmation, params[:confirm])
30
31 case validate_captcha(params) do
32 :ok ->
33 if Pleroma.Config.get([:instance, :registrations_open]) do
34 create_user(params, opts)
35 else
36 create_user_with_invite(params, opts)
37 end
38
39 {:error, error} ->
40 # I have no idea how this error handling works
41 {:error, %{error: Jason.encode!(%{captcha: [error]})}}
42 end
43 end
44
45 defp validate_captcha(params) do
46 if params[:trusted_app] || not Pleroma.Config.get([Pleroma.Captcha, :enabled]) do
47 :ok
48 else
49 Pleroma.Captcha.validate(
50 params.captcha_token,
51 params.captcha_solution,
52 params.captcha_answer_data
53 )
54 end
55 end
56
57 defp create_user_with_invite(params, opts) do
58 with %{token: token} when is_binary(token) <- params,
59 %UserInviteToken{} = invite <- Repo.get_by(UserInviteToken, %{token: token}),
60 true <- UserInviteToken.valid_invite?(invite) do
61 UserInviteToken.update_usage!(invite)
62 create_user(params, opts)
63 else
64 nil -> {:error, "Invalid token"}
65 _ -> {:error, "Expired token"}
66 end
67 end
68
69 defp create_user(params, opts) do
70 changeset = User.register_changeset(%User{}, params, opts)
71
72 case User.register(changeset) do
73 {:ok, user} ->
74 {:ok, user}
75
76 {:error, changeset} ->
77 errors =
78 Ecto.Changeset.traverse_errors(changeset, fn {msg, _opts} -> msg end)
79 |> Jason.encode!()
80
81 {:error, %{error: errors}}
82 end
83 end
84
85 def password_reset(nickname_or_email) do
86 with true <- is_binary(nickname_or_email),
87 %User{local: true, email: email} = user when not is_nil(email) <-
88 User.get_by_nickname_or_email(nickname_or_email),
89 {:ok, token_record} <- Pleroma.PasswordResetToken.create_token(user) do
90 user
91 |> UserEmail.password_reset_email(token_record.token)
92 |> Mailer.deliver_async()
93
94 {:ok, :enqueued}
95 else
96 false ->
97 {:error, "bad user identifier"}
98
99 %User{local: true, email: nil} ->
100 {:ok, :noop}
101
102 %User{local: false} ->
103 {:error, "remote user"}
104
105 nil ->
106 {:error, "unknown user"}
107 end
108 end
109 end