1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Web.TwitterAPI.PasswordControllerTest do
6 use Pleroma.Web.ConnCase
9 alias Pleroma.PasswordResetToken
11 alias Pleroma.Tests.ObanHelpers
13 alias Pleroma.Web.OAuth.Token
14 import Pleroma.Factory
15 import Swoosh.TestAssertions
17 describe "GET /api/pleroma/password_reset/token" do
18 test "it returns error when token invalid", %{conn: conn} do
21 |> get("/api/pleroma/password_reset/token")
24 assert response =~ "<h2>Invalid Token</h2>"
27 test "it shows password reset form", %{conn: conn} do
29 {:ok, token} = PasswordResetToken.create_token(user)
33 |> get("/api/pleroma/password_reset/#{token.token}")
36 assert response =~ "<h2>Password Reset for #{user.nickname}</h2>"
39 test "it returns an error when the token has expired", %{conn: conn} do
40 clear_config([:instance, :password_reset_token_validity], 0)
43 {:ok, token} = PasswordResetToken.create_token(user)
44 {:ok, token} = time_travel(token, -2)
48 |> get("/api/pleroma/password_reset/#{token.token}")
51 assert response =~ "<h2>Invalid Token</h2>"
55 describe "POST /api/pleroma/password_reset" do
56 test "it fails for an expired token", %{conn: conn} do
57 clear_config([:instance, :password_reset_token_validity], 0)
60 {:ok, token} = PasswordResetToken.create_token(user)
61 {:ok, token} = time_travel(token, -2)
62 {:ok, _access_token} = Token.create(insert(:oauth_app), user, %{})
66 password_confirmation: "test",
72 |> assign(:user, user)
73 |> post("/api/pleroma/password_reset", %{data: params})
76 refute response =~ "<h2>Password changed!</h2>"
79 test "it returns HTTP 200", %{conn: conn} do
81 {:ok, token} = PasswordResetToken.create_token(user)
82 {:ok, _access_token} = Token.create(insert(:oauth_app), user, %{})
86 password_confirmation: "test",
92 |> assign(:user, user)
93 |> post("/api/pleroma/password_reset", %{data: params})
96 assert response =~ "<h2>Password changed!</h2>"
98 user = refresh_record(user)
99 assert Pleroma.Password.Pbkdf2.verify_pass("test", user.password_hash)
100 assert Enum.empty?(Token.get_user_tokens(user))
103 test "it sets password_reset_pending to false", %{conn: conn} do
104 user = insert(:user, password_reset_pending: true)
106 {:ok, token} = PasswordResetToken.create_token(user)
107 {:ok, _access_token} = Token.create(insert(:oauth_app), user, %{})
110 "password" => "test",
111 password_confirmation: "test",
116 |> assign(:user, user)
117 |> post("/api/pleroma/password_reset", %{data: params})
118 |> html_response(:ok)
120 assert User.get_by_id(user.id).password_reset_pending == false
124 describe "POST /auth/password, with valid parameters" do
125 setup %{conn: conn} do
127 conn = post(conn, "/auth/password?email=#{user.email}")
128 %{conn: conn, user: user}
131 test "it returns 204", %{conn: conn} do
132 assert empty_json_response(conn)
135 test "it creates a PasswordResetToken record for user", %{user: user} do
136 token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
140 test "it sends an email to user", %{user: user} do
141 ObanHelpers.perform_all()
142 token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
144 email = Pleroma.Emails.UserEmail.password_reset_email(user, token_record.token)
145 notify_email = Config.get([:instance, :notify_email])
146 instance_name = Config.get([:instance, :name])
149 from: {instance_name, notify_email},
150 to: {user.name, user.email},
151 html_body: email.html_body
156 describe "POST /auth/password, with nickname" do
157 test "it returns 204", %{conn: conn} do
161 |> post("/auth/password?nickname=#{user.nickname}")
162 |> empty_json_response()
164 ObanHelpers.perform_all()
165 token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
167 email = Pleroma.Emails.UserEmail.password_reset_email(user, token_record.token)
168 notify_email = Config.get([:instance, :notify_email])
169 instance_name = Config.get([:instance, :name])
172 from: {instance_name, notify_email},
173 to: {user.name, user.email},
174 html_body: email.html_body
178 test "it doesn't fail when a user has no email", %{conn: conn} do
179 user = insert(:user, %{email: nil})
182 |> post("/auth/password?nickname=#{user.nickname}")
183 |> empty_json_response()
187 describe "POST /auth/password, with invalid parameters" do
193 test "it returns 204 when user is not found", %{conn: conn, user: user} do
194 conn = post(conn, "/auth/password?email=nonexisting_#{user.email}")
196 assert empty_json_response(conn)
199 test "it returns 204 when user is not local", %{conn: conn, user: user} do
200 {:ok, user} = Repo.update(Ecto.Changeset.change(user, local: false))
201 conn = post(conn, "/auth/password?email=#{user.email}")
203 assert empty_json_response(conn)
206 test "it returns 204 when user is deactivated", %{conn: conn, user: user} do
207 {:ok, user} = Repo.update(Ecto.Changeset.change(user, is_active: false, local: true))
208 conn = post(conn, "/auth/password?email=#{user.email}")
210 assert empty_json_response(conn)