defmodule GlificWeb.API.V1.SessionController do @moduledoc """ The Pow User Session Controller """ use GlificWeb, :controller require Logger alias Glific.{Repo, Users.User} alias GlificWeb.APIAuthPlug alias Plug.Conn @doc false @spec create(Conn.t(), map()) :: Conn.t() def create(conn, %{"user" => user_params}) do user_params = Map.put(user_params, "organization_id", conn.assigns[:organization_id]) conn |> Pow.Plug.authenticate_user(user_params) |> case do {:ok, conn} -> Logger.info("Logged in user: user_id: '#{conn.assigns[:current_user].id}'") update_last_login(conn.assigns[:current_user], conn) json(conn, %{ data: %{ access_token: conn.private[:api_access_token], token_expiry_time: conn.private[:api_token_expiry_time], renewal_token: conn.private[:api_renewal_token] } }) {:error, conn} -> Logger.error("Logged in user failure: user_phone: '#{user_params["phone"]}'") conn |> put_status(401) |> json(%{error: %{status: 401, message: "Invalid phone or password"}}) end end defp update_last_login(user, conn) do remote_ip = GlificWeb.Tenants.remote_ip(conn) Logger.info("Updating user login timestamp, user_phone: #{user.phone}, ip: #{remote_ip}") user # we are not using update_user call here, since it destroys all tokens |> User.update_fields_changeset(%{ last_login_at: DateTime.utc_now(), last_login_from: remote_ip }) |> Repo.update() end @doc false @spec renew(Conn.t(), map()) :: Conn.t() def renew(conn, _params) do config = Pow.Plug.fetch_config(conn) conn |> APIAuthPlug.renew(config) |> case do {conn, nil} -> conn |> put_status(401) |> json(%{error: %{status: 401, message: "Invalid token"}}) {conn, _user} -> json(conn, %{ data: %{ access_token: conn.private[:api_access_token], token_expiry_time: conn.private[:api_token_expiry_time], renewal_token: conn.private[:api_renewal_token] } }) end end @doc false @spec delete(Conn.t(), map()) :: Conn.t() def delete(conn, _params) do conn |> Pow.Plug.delete() |> json(%{data: %{}}) end end