logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://hacktivis.me/git/pleroma.git

password_reset_token.ex (1609B)


  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.PasswordResetToken do
  5. use Ecto.Schema
  6. import Ecto.Changeset
  7. alias Pleroma.PasswordResetToken
  8. alias Pleroma.Repo
  9. alias Pleroma.User
  10. schema "password_reset_tokens" do
  11. belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
  12. field(:token, :string)
  13. field(:used, :boolean, default: false)
  14. timestamps()
  15. end
  16. def create_token(%User{} = user) do
  17. token = :crypto.strong_rand_bytes(32) |> Base.url_encode64()
  18. token = %PasswordResetToken{
  19. user_id: user.id,
  20. used: false,
  21. token: token
  22. }
  23. Repo.insert(token)
  24. end
  25. def used_changeset(struct) do
  26. struct
  27. |> cast(%{}, [])
  28. |> put_change(:used, true)
  29. end
  30. @spec reset_password(binary(), map()) :: {:ok, User.t()} | {:error, binary()}
  31. def reset_password(token, data) do
  32. with %{used: false} = token <- Repo.get_by(PasswordResetToken, %{token: token}),
  33. false <- expired?(token),
  34. %User{} = user <- User.get_cached_by_id(token.user_id),
  35. {:ok, _user} <- User.reset_password(user, data),
  36. {:ok, token} <- Repo.update(used_changeset(token)) do
  37. {:ok, token}
  38. else
  39. _e -> {:error, token}
  40. end
  41. end
  42. def expired?(%__MODULE__{inserted_at: inserted_at}) do
  43. validity = Pleroma.Config.get([:instance, :password_reset_token_validity], 0)
  44. now = NaiveDateTime.utc_now()
  45. difference = NaiveDateTime.diff(now, inserted_at)
  46. difference > validity
  47. end
  48. end