forked from AkkomaGang/akkoma
Merge branch '114_email_confirmation' into 'develop'
[#114] Email confirmation See merge request pleroma/pleroma!546
This commit is contained in:
commit
2e2030ada8
21 changed files with 398 additions and 24 deletions
|
@ -69,6 +69,7 @@ config :pleroma, Pleroma.Mailer,
|
|||
* `banner_upload_limit`: File size limit of user’s profile banners
|
||||
* `registrations_open`: Enable registrations for anyone, invitations can be enabled when false.
|
||||
* `invites_enabled`: Enable user invitations for admins (depends on `registrations_open: false`).
|
||||
* `account_activation_required`: Require users to confirm their emails before signing in.
|
||||
* `federating`: Enable federation with other instances
|
||||
* `allow_relay`: Enable Pleroma’s Relay, which makes it possible to follow a whole instance
|
||||
* `rewrite_policy`: Message Rewrite Policy, either one or a list. Here are the ones available by default:
|
||||
|
|
|
@ -103,8 +103,8 @@ def run(["new", nickname, email | rest]) do
|
|||
bio: bio
|
||||
}
|
||||
|
||||
user = User.register_changeset(%User{}, params)
|
||||
Repo.insert!(user)
|
||||
changeset = User.register_changeset(%User{}, params, confirmed: true)
|
||||
{:ok, _user} = User.register(changeset)
|
||||
|
||||
Mix.shell().info("User #{nickname} created")
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ defp sender do
|
|||
|
||||
defp recipient(email, nil), do: email
|
||||
defp recipient(email, name), do: {name, email}
|
||||
defp recipient(%Pleroma.User{} = user), do: recipient(user.email, user.name)
|
||||
|
||||
def password_reset_email(user, password_reset_token) when is_binary(password_reset_token) do
|
||||
password_reset_url =
|
||||
|
@ -32,7 +33,7 @@ def password_reset_email(user, password_reset_token) when is_binary(password_res
|
|||
"""
|
||||
|
||||
new()
|
||||
|> to(recipient(user.email, user.name))
|
||||
|> to(recipient(user))
|
||||
|> from(sender())
|
||||
|> subject("Password reset")
|
||||
|> html_body(html_body)
|
||||
|
@ -63,4 +64,26 @@ def user_invitation_email(
|
|||
|> subject("Invitation to #{instance_name()}")
|
||||
|> html_body(html_body)
|
||||
end
|
||||
|
||||
def account_confirmation_email(user) do
|
||||
confirmation_url =
|
||||
Router.Helpers.confirm_email_url(
|
||||
Endpoint,
|
||||
:confirm_email,
|
||||
user.id,
|
||||
to_string(user.info.confirmation_token)
|
||||
)
|
||||
|
||||
html_body = """
|
||||
<h3>Welcome to #{instance_name()}!</h3>
|
||||
<p>Email confirmation is required to activate the account.</p>
|
||||
<p>Click the following link to proceed: <a href="#{confirmation_url}">activate your account</a>.</p>
|
||||
"""
|
||||
|
||||
new()
|
||||
|> to(recipient(user))
|
||||
|> from(sender())
|
||||
|> subject("#{instance_name()} account confirmation")
|
||||
|> html_body(html_body)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -38,6 +38,13 @@ defmodule Pleroma.User do
|
|||
timestamps()
|
||||
end
|
||||
|
||||
def auth_active?(%User{} = user) do
|
||||
(user.info && !user.info.confirmation_pending) ||
|
||||
!Pleroma.Config.get([:instance, :account_activation_required])
|
||||
end
|
||||
|
||||
def superuser?(%User{} = user), do: user.info && User.Info.superuser?(user.info)
|
||||
|
||||
def avatar_url(user) do
|
||||
case user.avatar do
|
||||
%{"url" => [%{"href" => href} | _]} -> href
|
||||
|
@ -78,6 +85,7 @@ def user_info(%User{} = user) do
|
|||
note_count: user.info.note_count,
|
||||
follower_count: user.info.follower_count,
|
||||
locked: user.info.locked,
|
||||
confirmation_pending: user.info.confirmation_pending,
|
||||
default_scope: user.info.default_scope
|
||||
}
|
||||
end
|
||||
|
@ -168,7 +176,16 @@ def reset_password(user, data) do
|
|||
update_and_set_cache(password_update_changeset(user, data))
|
||||
end
|
||||
|
||||
def register_changeset(struct, params \\ %{}) do
|
||||
def register_changeset(struct, params \\ %{}, opts \\ []) do
|
||||
confirmation_status =
|
||||
if opts[:confirmed] || !Pleroma.Config.get([:instance, :account_activation_required]) do
|
||||
:confirmed
|
||||
else
|
||||
:unconfirmed
|
||||
end
|
||||
|
||||
info_change = User.Info.confirmation_changeset(%User.Info{}, confirmation_status)
|
||||
|
||||
changeset =
|
||||
struct
|
||||
|> cast(params, [:bio, :email, :name, :nickname, :password, :password_confirmation])
|
||||
|
@ -180,7 +197,7 @@ def register_changeset(struct, params \\ %{}) do
|
|||
|> validate_format(:email, @email_regex)
|
||||
|> validate_length(:bio, max: 1000)
|
||||
|> validate_length(:name, min: 1, max: 100)
|
||||
|> put_change(:info, %Pleroma.User.Info{})
|
||||
|> put_change(:info, info_change)
|
||||
|
||||
if changeset.valid? do
|
||||
hashed = Pbkdf2.hashpwsalt(changeset.changes[:password])
|
||||
|
@ -197,6 +214,25 @@ def register_changeset(struct, params \\ %{}) do
|
|||
end
|
||||
end
|
||||
|
||||
@doc "Inserts provided changeset, performs post-registration actions (confirmation email sending etc.)"
|
||||
def register(%Ecto.Changeset{} = changeset) do
|
||||
with {:ok, user} <- Repo.insert(changeset),
|
||||
{:ok, _} = try_send_confirmation_email(user) do
|
||||
{:ok, user}
|
||||
end
|
||||
end
|
||||
|
||||
def try_send_confirmation_email(%User{} = user) do
|
||||
if user.info.confirmation_pending &&
|
||||
Pleroma.Config.get([:instance, :account_activation_required]) do
|
||||
user
|
||||
|> Pleroma.UserEmail.account_confirmation_email()
|
||||
|> Pleroma.Mailer.deliver()
|
||||
else
|
||||
{:ok, :noop}
|
||||
end
|
||||
end
|
||||
|
||||
def needs_update?(%User{local: true}), do: false
|
||||
|
||||
def needs_update?(%User{local: false, last_refreshed_at: nil}), do: true
|
||||
|
|
|
@ -9,6 +9,8 @@ defmodule Pleroma.User.Info do
|
|||
field(:note_count, :integer, default: 0)
|
||||
field(:follower_count, :integer, default: 0)
|
||||
field(:locked, :boolean, default: false)
|
||||
field(:confirmation_pending, :boolean, default: false)
|
||||
field(:confirmation_token, :string, default: nil)
|
||||
field(:default_scope, :string, default: "public")
|
||||
field(:blocks, {:array, :string}, default: [])
|
||||
field(:domain_blocks, {:array, :string}, default: [])
|
||||
|
@ -35,6 +37,8 @@ defmodule Pleroma.User.Info do
|
|||
# subject _> Where is this used?
|
||||
end
|
||||
|
||||
def superuser?(info), do: info.is_admin || info.is_moderator
|
||||
|
||||
def set_activation_status(info, deactivated) do
|
||||
params = %{deactivated: deactivated}
|
||||
|
||||
|
@ -141,6 +145,24 @@ def profile_update(info, params) do
|
|||
])
|
||||
end
|
||||
|
||||
def confirmation_changeset(info, :confirmed) do
|
||||
confirmation_changeset(info, %{
|
||||
confirmation_pending: false,
|
||||
confirmation_token: nil
|
||||
})
|
||||
end
|
||||
|
||||
def confirmation_changeset(info, :unconfirmed) do
|
||||
confirmation_changeset(info, %{
|
||||
confirmation_pending: true,
|
||||
confirmation_token: :crypto.strong_rand_bytes(32) |> Base.url_encode64()
|
||||
})
|
||||
end
|
||||
|
||||
def confirmation_changeset(info, params) do
|
||||
cast(info, params, [:confirmation_pending, :confirmation_token])
|
||||
end
|
||||
|
||||
def mastodon_profile_update(info, params) do
|
||||
info
|
||||
|> cast(params, [
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
||||
use Pleroma.Web, :controller
|
||||
alias Pleroma.{User, Repo}
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.Relay
|
||||
|
||||
import Pleroma.Web.ControllerHelper, only: [json_response: 3]
|
||||
|
@ -26,7 +26,7 @@ def user_create(
|
|||
conn,
|
||||
%{"nickname" => nickname, "email" => email, "password" => password}
|
||||
) do
|
||||
new_user = %{
|
||||
user_data = %{
|
||||
nickname: nickname,
|
||||
name: nickname,
|
||||
email: email,
|
||||
|
@ -35,11 +35,11 @@ def user_create(
|
|||
bio: "."
|
||||
}
|
||||
|
||||
User.register_changeset(%User{}, new_user)
|
||||
|> Repo.insert!()
|
||||
changeset = User.register_changeset(%User{}, user_data, confirmed: true)
|
||||
{:ok, user} = User.register(changeset)
|
||||
|
||||
conn
|
||||
|> json(new_user.nickname)
|
||||
|> json(user.nickname)
|
||||
end
|
||||
|
||||
def tag_users(conn, %{"nicknames" => nicknames, "tags" => tags}) do
|
||||
|
|
|
@ -110,7 +110,8 @@ def verify_credentials(%{assigns: %{user: user}} = conn, _) do
|
|||
end
|
||||
|
||||
def user(%{assigns: %{user: for_user}} = conn, %{"id" => id}) do
|
||||
with %User{} = user <- Repo.get(User, id) do
|
||||
with %User{} = user <- Repo.get(User, id),
|
||||
true <- User.auth_active?(user) || user.id == for_user.id || User.superuser?(for_user) do
|
||||
account = AccountView.render("account.json", %{user: user, for: for_user})
|
||||
json(conn, account)
|
||||
else
|
||||
|
|
|
@ -62,6 +62,7 @@ def render("account.json", %{user: user} = opts) do
|
|||
|
||||
# Pleroma extension
|
||||
pleroma: %{
|
||||
confirmation_pending: user_info.confirmation_pending,
|
||||
tags: user.tags
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,6 +132,7 @@ def nodeinfo(conn, %{"version" => "2.0"}) do
|
|||
banner: Keyword.get(instance, :banner_upload_limit),
|
||||
background: Keyword.get(instance, :background_upload_limit)
|
||||
},
|
||||
accountActivationRequired: Keyword.get(instance, :account_activation_required, false),
|
||||
invitesEnabled: Keyword.get(instance, :invites_enabled, false),
|
||||
features: features
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ def create_authorization(conn, %{
|
|||
}) do
|
||||
with %User{} = user <- User.get_by_nickname_or_email(name),
|
||||
true <- Pbkdf2.checkpw(password, user.password_hash),
|
||||
{:auth_active, true} <- {:auth_active, User.auth_active?(user)},
|
||||
%App{} = app <- Repo.get_by(App, client_id: client_id),
|
||||
{:ok, auth} <- Authorization.create_authorization(app, user) do
|
||||
# Special case: Local MastodonFE.
|
||||
|
@ -63,6 +64,15 @@ def create_authorization(conn, %{
|
|||
|
||||
redirect(conn, external: url)
|
||||
end
|
||||
else
|
||||
{:auth_active, false} ->
|
||||
conn
|
||||
|> put_flash(:error, "Account confirmation pending")
|
||||
|> put_status(:forbidden)
|
||||
|> authorize(params)
|
||||
|
||||
error ->
|
||||
error
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -101,6 +111,7 @@ def token_exchange(
|
|||
with %App{} = app <- get_app_from_request(conn, params),
|
||||
%User{} = user <- User.get_by_nickname_or_email(name),
|
||||
true <- Pbkdf2.checkpw(password, user.password_hash),
|
||||
{:auth_active, true} <- {:auth_active, User.auth_active?(user)},
|
||||
{:ok, auth} <- Authorization.create_authorization(app, user),
|
||||
{:ok, token} <- Token.exchange_token(app, auth) do
|
||||
response = %{
|
||||
|
@ -113,6 +124,11 @@ def token_exchange(
|
|||
|
||||
json(conn, response)
|
||||
else
|
||||
{:auth_active, false} ->
|
||||
conn
|
||||
|> put_status(:forbidden)
|
||||
|> json(%{error: "Account confirmation pending"})
|
||||
|
||||
_error ->
|
||||
put_status(conn, 400)
|
||||
|> json(%{error: "Invalid credentials"})
|
||||
|
|
|
@ -283,6 +283,15 @@ defmodule Pleroma.Web.Router do
|
|||
post("/account/register", TwitterAPI.Controller, :register)
|
||||
post("/account/password_reset", TwitterAPI.Controller, :password_reset)
|
||||
|
||||
get(
|
||||
"/account/confirm_email/:user_id/:token",
|
||||
TwitterAPI.Controller,
|
||||
:confirm_email,
|
||||
as: :confirm_email
|
||||
)
|
||||
|
||||
post("/account/resend_confirmation_email", TwitterAPI.Controller, :resend_confirmation_email)
|
||||
|
||||
get("/search", TwitterAPI.Controller, :search)
|
||||
get("/statusnet/tags/timeline/:tag", TwitterAPI.Controller, :public_and_external_timeline)
|
||||
end
|
||||
|
|
|
@ -174,6 +174,8 @@ def config(conn, _params) do
|
|||
closed: if(Keyword.get(instance, :registrations_open), do: "0", else: "1"),
|
||||
private: if(Keyword.get(instance, :public, true), do: "0", else: "1"),
|
||||
vapidPublicKey: vapid_public_key,
|
||||
accountActivationRequired:
|
||||
if(Keyword.get(instance, :account_activation_required, false), do: "1", else: "0"),
|
||||
invitesEnabled: if(Keyword.get(instance, :invites_enabled, false), do: "1", else: "0")
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
|
||||
alias Pleroma.{UserInviteToken, User, Activity, Repo, Object}
|
||||
alias Pleroma.{UserEmail, Mailer}
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.TwitterAPI.UserView
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
import Ecto.Query
|
||||
|
||||
def create_status(%User{} = user, %{"status" => _} = data) do
|
||||
|
@ -161,10 +163,11 @@ def register_user(params) do
|
|||
|
||||
cond do
|
||||
registrations_open || (!is_nil(token) && !token.used) ->
|
||||
changeset = User.register_changeset(%User{info: %{}}, params)
|
||||
changeset = User.register_changeset(%User{}, params)
|
||||
|
||||
with {:ok, user} <- Repo.insert(changeset) do
|
||||
with {:ok, user} <- User.register(changeset) do
|
||||
!registrations_open && UserInviteToken.mark_as_used(token.token)
|
||||
|
||||
{:ok, user}
|
||||
else
|
||||
{:error, changeset} ->
|
||||
|
@ -189,8 +192,8 @@ def password_reset(nickname_or_email) do
|
|||
%User{local: true} = user <- User.get_by_nickname_or_email(nickname_or_email),
|
||||
{:ok, token_record} <- Pleroma.PasswordResetToken.create_token(user) do
|
||||
user
|
||||
|> Pleroma.UserEmail.password_reset_email(token_record.token)
|
||||
|> Pleroma.Mailer.deliver()
|
||||
|> UserEmail.password_reset_email(token_record.token)
|
||||
|> Mailer.deliver()
|
||||
else
|
||||
false ->
|
||||
{:error, "bad user identifier"}
|
||||
|
|
|
@ -96,10 +96,15 @@ def friends_timeline(%{assigns: %{user: user}} = conn, params) do
|
|||
end
|
||||
|
||||
def show_user(conn, params) do
|
||||
with {:ok, shown} <- TwitterAPI.get_user(params) do
|
||||
for_user = conn.assigns.user
|
||||
|
||||
with {:ok, shown} <- TwitterAPI.get_user(params),
|
||||
true <-
|
||||
User.auth_active?(shown) ||
|
||||
(for_user && (for_user.id == shown.id || User.superuser?(for_user))) do
|
||||
params =
|
||||
if user = conn.assigns.user do
|
||||
%{user: shown, for: user}
|
||||
if for_user do
|
||||
%{user: shown, for: for_user}
|
||||
else
|
||||
%{user: shown}
|
||||
end
|
||||
|
@ -110,6 +115,11 @@ def show_user(conn, params) do
|
|||
else
|
||||
{:error, msg} ->
|
||||
bad_request_reply(conn, msg)
|
||||
|
||||
false ->
|
||||
conn
|
||||
|> put_status(404)
|
||||
|> json(%{error: "Unconfirmed user"})
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -372,6 +382,29 @@ def password_reset(conn, params) do
|
|||
end
|
||||
end
|
||||
|
||||
def confirm_email(conn, %{"user_id" => uid, "token" => token}) do
|
||||
with %User{} = user <- Repo.get(User, uid),
|
||||
true <- user.local,
|
||||
true <- user.info.confirmation_pending,
|
||||
true <- user.info.confirmation_token == token,
|
||||
info_change <- User.Info.confirmation_changeset(user.info, :confirmed),
|
||||
changeset <- Changeset.change(user) |> Changeset.put_embed(:info, info_change),
|
||||
{:ok, _} <- User.update_and_set_cache(changeset) do
|
||||
conn
|
||||
|> redirect(to: "/")
|
||||
end
|
||||
end
|
||||
|
||||
def resend_confirmation_email(conn, params) do
|
||||
nickname_or_email = params["email"] || params["nickname"]
|
||||
|
||||
with %User{} = user <- User.get_by_nickname_or_email(nickname_or_email),
|
||||
{:ok, _} <- User.try_send_confirmation_email(user) do
|
||||
conn
|
||||
|> json_response(:no_content, "")
|
||||
end
|
||||
end
|
||||
|
||||
def update_avatar(%{assigns: %{user: user}} = conn, params) do
|
||||
{:ok, object} = ActivityPub.upload(params, type: :avatar)
|
||||
change = Changeset.change(user, %{avatar: object.data})
|
||||
|
|
|
@ -81,6 +81,7 @@ def render("user.json", %{user: user = %User{}} = assigns) do
|
|||
|
||||
# Pleroma extension
|
||||
"pleroma" => %{
|
||||
"confirmation_pending" => user_info.confirmation_pending,
|
||||
"tags" => user.tags
|
||||
}
|
||||
}
|
||||
|
|
|
@ -177,6 +177,48 @@ test "it ensures info is not nil" do
|
|||
end
|
||||
end
|
||||
|
||||
describe "user registration, with :account_activation_required" do
|
||||
@full_user_data %{
|
||||
bio: "A guy",
|
||||
name: "my name",
|
||||
nickname: "nick",
|
||||
password: "test",
|
||||
password_confirmation: "test",
|
||||
email: "email@example.com"
|
||||
}
|
||||
|
||||
setup do
|
||||
setting = Pleroma.Config.get([:instance, :account_activation_required])
|
||||
|
||||
unless setting do
|
||||
Pleroma.Config.put([:instance, :account_activation_required], true)
|
||||
on_exit(fn -> Pleroma.Config.put([:instance, :account_activation_required], setting) end)
|
||||
end
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
test "it creates unconfirmed user" do
|
||||
changeset = User.register_changeset(%User{}, @full_user_data)
|
||||
assert changeset.valid?
|
||||
|
||||
{:ok, user} = Repo.insert(changeset)
|
||||
|
||||
assert user.info.confirmation_pending
|
||||
assert user.info.confirmation_token
|
||||
end
|
||||
|
||||
test "it creates confirmed user if :confirmed option is given" do
|
||||
changeset = User.register_changeset(%User{}, @full_user_data, confirmed: true)
|
||||
assert changeset.valid?
|
||||
|
||||
{:ok, user} = Repo.insert(changeset)
|
||||
|
||||
refute user.info.confirmation_pending
|
||||
refute user.info.confirmation_token
|
||||
end
|
||||
end
|
||||
|
||||
describe "get_or_fetch/1" do
|
||||
test "gets an existing user by nickname" do
|
||||
user = insert(:user)
|
||||
|
|
|
@ -55,7 +55,10 @@ test "Represent a user account" do
|
|||
privacy: "public",
|
||||
sensitive: false
|
||||
},
|
||||
pleroma: %{tags: []}
|
||||
pleroma: %{
|
||||
confirmation_pending: false,
|
||||
tags: []
|
||||
}
|
||||
}
|
||||
|
||||
assert expected == AccountView.render("account.json", %{user: user})
|
||||
|
@ -93,7 +96,10 @@ test "Represent a Service(bot) account" do
|
|||
privacy: "public",
|
||||
sensitive: false
|
||||
},
|
||||
pleroma: %{tags: []}
|
||||
pleroma: %{
|
||||
confirmation_pending: false,
|
||||
tags: []
|
||||
}
|
||||
}
|
||||
|
||||
assert expected == AccountView.render("account.json", %{user: user})
|
||||
|
|
|
@ -50,6 +50,26 @@ test "issues a token for an all-body request" do
|
|||
assert Repo.get_by(Token, token: token)
|
||||
end
|
||||
|
||||
test "issues a token for `password` grant_type with valid credentials" do
|
||||
password = "testpassword"
|
||||
user = insert(:user, password_hash: Comeonin.Pbkdf2.hashpwsalt(password))
|
||||
|
||||
app = insert(:oauth_app)
|
||||
|
||||
conn =
|
||||
build_conn()
|
||||
|> post("/oauth/token", %{
|
||||
"grant_type" => "password",
|
||||
"username" => user.nickname,
|
||||
"password" => password,
|
||||
"client_id" => app.client_id,
|
||||
"client_secret" => app.client_secret
|
||||
})
|
||||
|
||||
assert %{"access_token" => token} = json_response(conn, 200)
|
||||
assert Repo.get_by(Token, token: token)
|
||||
end
|
||||
|
||||
test "issues a token for request with HTTP basic auth client credentials" do
|
||||
user = insert(:user)
|
||||
app = insert(:oauth_app)
|
||||
|
@ -93,6 +113,43 @@ test "rejects token exchange with invalid client credentials" do
|
|||
refute Map.has_key?(resp, "access_token")
|
||||
end
|
||||
|
||||
test "rejects token exchange for valid credentials belonging to unconfirmed user and confirmation is required" do
|
||||
setting = Pleroma.Config.get([:instance, :account_activation_required])
|
||||
|
||||
unless setting do
|
||||
Pleroma.Config.put([:instance, :account_activation_required], true)
|
||||
on_exit(fn -> Pleroma.Config.put([:instance, :account_activation_required], setting) end)
|
||||
end
|
||||
|
||||
password = "testpassword"
|
||||
user = insert(:user, password_hash: Comeonin.Pbkdf2.hashpwsalt(password))
|
||||
info_change = Pleroma.User.Info.confirmation_changeset(user.info, :unconfirmed)
|
||||
|
||||
{:ok, user} =
|
||||
user
|
||||
|> Ecto.Changeset.change()
|
||||
|> Ecto.Changeset.put_embed(:info, info_change)
|
||||
|> Repo.update()
|
||||
|
||||
refute Pleroma.User.auth_active?(user)
|
||||
|
||||
app = insert(:oauth_app)
|
||||
|
||||
conn =
|
||||
build_conn()
|
||||
|> post("/oauth/token", %{
|
||||
"grant_type" => "password",
|
||||
"username" => user.nickname,
|
||||
"password" => password,
|
||||
"client_id" => app.client_id,
|
||||
"client_secret" => app.client_secret
|
||||
})
|
||||
|
||||
assert resp = json_response(conn, 403)
|
||||
assert %{"error" => _} = resp
|
||||
refute Map.has_key?(resp, "access_token")
|
||||
end
|
||||
|
||||
test "rejects an invalid authorization code" do
|
||||
app = insert(:oauth_app)
|
||||
|
||||
|
|
|
@ -873,6 +873,89 @@ test "it returns 500 when user is not local", %{conn: conn, user: user} do
|
|||
end
|
||||
end
|
||||
|
||||
describe "GET /api/account/confirm_email/:id/:token" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
info_change = User.Info.confirmation_changeset(user.info, :unconfirmed)
|
||||
|
||||
{:ok, user} =
|
||||
user
|
||||
|> Changeset.change()
|
||||
|> Changeset.put_embed(:info, info_change)
|
||||
|> Repo.update()
|
||||
|
||||
assert user.info.confirmation_pending
|
||||
|
||||
[user: user]
|
||||
end
|
||||
|
||||
test "it redirects to root url", %{conn: conn, user: user} do
|
||||
conn = get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
|
||||
|
||||
assert 302 == conn.status
|
||||
end
|
||||
|
||||
test "it confirms the user account", %{conn: conn, user: user} do
|
||||
get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
|
||||
|
||||
user = Repo.get(User, user.id)
|
||||
|
||||
refute user.info.confirmation_pending
|
||||
refute user.info.confirmation_token
|
||||
end
|
||||
|
||||
test "it returns 500 if user cannot be found by id", %{conn: conn, user: user} do
|
||||
conn = get(conn, "/api/account/confirm_email/0/#{user.info.confirmation_token}")
|
||||
|
||||
assert 500 == conn.status
|
||||
end
|
||||
|
||||
test "it returns 500 if token is invalid", %{conn: conn, user: user} do
|
||||
conn = get(conn, "/api/account/confirm_email/#{user.id}/wrong_token")
|
||||
|
||||
assert 500 == conn.status
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /api/account/resend_confirmation_email" do
|
||||
setup do
|
||||
setting = Pleroma.Config.get([:instance, :account_activation_required])
|
||||
|
||||
unless setting do
|
||||
Pleroma.Config.put([:instance, :account_activation_required], true)
|
||||
on_exit(fn -> Pleroma.Config.put([:instance, :account_activation_required], setting) end)
|
||||
end
|
||||
|
||||
user = insert(:user)
|
||||
info_change = User.Info.confirmation_changeset(user.info, :unconfirmed)
|
||||
|
||||
{:ok, user} =
|
||||
user
|
||||
|> Changeset.change()
|
||||
|> Changeset.put_embed(:info, info_change)
|
||||
|> Repo.update()
|
||||
|
||||
assert user.info.confirmation_pending
|
||||
|
||||
[user: user]
|
||||
end
|
||||
|
||||
test "it returns 204 No Content", %{conn: conn, user: user} do
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> post("/api/account/resend_confirmation_email?email=#{user.email}")
|
||||
|> json_response(:no_content)
|
||||
end
|
||||
|
||||
test "it sends confirmation email", %{conn: conn, user: user} do
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> post("/api/account/resend_confirmation_email?email=#{user.email}")
|
||||
|
||||
Swoosh.TestAssertions.assert_email_sent(Pleroma.UserEmail.account_confirmation_email(user))
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /api/externalprofile/show" do
|
||||
test "it returns the user", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
|
|
@ -275,6 +275,31 @@ test "it registers a new user with empty string in bio and returns the user." do
|
|||
UserView.render("show.json", %{user: fetched_user})
|
||||
end
|
||||
|
||||
@moduletag skip: "needs 'account_activation_required: true' in config"
|
||||
test "it sends confirmation email if :account_activation_required is specified in instance config" do
|
||||
setting = Pleroma.Config.get([:instance, :account_activation_required])
|
||||
|
||||
unless setting do
|
||||
Pleroma.Config.put([:instance, :account_activation_required], true)
|
||||
on_exit(fn -> Pleroma.Config.put([:instance, :account_activation_required], setting) end)
|
||||
end
|
||||
|
||||
data = %{
|
||||
"nickname" => "lain",
|
||||
"email" => "lain@wired.jp",
|
||||
"fullname" => "lain iwakura",
|
||||
"bio" => "",
|
||||
"password" => "bear",
|
||||
"confirm" => "bear"
|
||||
}
|
||||
|
||||
{:ok, user} = TwitterAPI.register_user(data)
|
||||
|
||||
assert user.info.confirmation_pending
|
||||
|
||||
Swoosh.TestAssertions.assert_email_sent(Pleroma.UserEmail.account_confirmation_email(user))
|
||||
end
|
||||
|
||||
test "it registers a new user and parses mentions in the bio" do
|
||||
data1 = %{
|
||||
"nickname" => "john",
|
||||
|
|
|
@ -96,7 +96,10 @@ test "A user" do
|
|||
"default_scope" => "public",
|
||||
"no_rich_text" => false,
|
||||
"fields" => [],
|
||||
"pleroma" => %{"tags" => []}
|
||||
"pleroma" => %{
|
||||
"confirmation_pending" => false,
|
||||
"tags" => []
|
||||
}
|
||||
}
|
||||
|
||||
assert represented == UserView.render("show.json", %{user: user})
|
||||
|
@ -138,7 +141,10 @@ test "A user for a given other follower", %{user: user} do
|
|||
"default_scope" => "public",
|
||||
"no_rich_text" => false,
|
||||
"fields" => [],
|
||||
"pleroma" => %{"tags" => []}
|
||||
"pleroma" => %{
|
||||
"confirmation_pending" => false,
|
||||
"tags" => []
|
||||
}
|
||||
}
|
||||
|
||||
assert represented == UserView.render("show.json", %{user: user, for: follower})
|
||||
|
@ -181,7 +187,10 @@ test "A user that follows you", %{user: user} do
|
|||
"default_scope" => "public",
|
||||
"no_rich_text" => false,
|
||||
"fields" => [],
|
||||
"pleroma" => %{"tags" => []}
|
||||
"pleroma" => %{
|
||||
"confirmation_pending" => false,
|
||||
"tags" => []
|
||||
}
|
||||
}
|
||||
|
||||
assert represented == UserView.render("show.json", %{user: follower, for: user})
|
||||
|
@ -231,7 +240,10 @@ test "A blocked user for the blocker" do
|
|||
"default_scope" => "public",
|
||||
"no_rich_text" => false,
|
||||
"fields" => [],
|
||||
"pleroma" => %{"tags" => []}
|
||||
"pleroma" => %{
|
||||
"confirmation_pending" => false,
|
||||
"tags" => []
|
||||
}
|
||||
}
|
||||
|
||||
blocker = Repo.get(User, blocker.id)
|
||||
|
|
Loading…
Reference in a new issue