mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 10:18:54 +00:00
Seems to be working
This commit is contained in:
@@ -17,7 +17,7 @@ defmodule FgHttp.Devices.Device do
|
||||
has_many :rules, Rule
|
||||
belongs_to :user, User
|
||||
|
||||
timestamps()
|
||||
timestamps(type: :utc_datetime_usec)
|
||||
end
|
||||
|
||||
@doc false
|
||||
|
||||
@@ -3,13 +3,14 @@ defmodule FgHttp.Email do
|
||||
Handles Email for the app
|
||||
"""
|
||||
|
||||
import Bamboo.{Email, Phoenix}
|
||||
use Bamboo.Phoenix, view: FgHttpWeb.EmailView
|
||||
alias FgHttp.Users.PasswordReset
|
||||
|
||||
@from "noreply@#{Application.get_env(:fg_http, FgHttpWeb.Endpoint)[:url][:host]}"
|
||||
|
||||
defp base_email(to) do
|
||||
new_email()
|
||||
|> put_html_layout({FgHttpWeb.LayoutView, "email.html"})
|
||||
|> from(@from)
|
||||
|> to(to)
|
||||
end
|
||||
@@ -17,6 +18,7 @@ defmodule FgHttp.Email do
|
||||
def password_reset(%PasswordReset{} = password_reset) do
|
||||
base_email(password_reset.email)
|
||||
|> subject("FireGuard password reset")
|
||||
|> put_html_layout({FgHttpWeb.LayoutView, "email.html.eex"})
|
||||
|> assign(:reset_token, password_reset.reset_token)
|
||||
|> render(:password_reset)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -17,7 +17,7 @@ defmodule FgHttp.PasswordResets do
|
||||
|
||||
def get_password_reset!(reset_token: reset_token) do
|
||||
validity_secs = -1 * PasswordReset.token_validity_secs()
|
||||
now = DateTime.truncate(DateTime.utc_now(), :second)
|
||||
now = DateTime.utc_now()
|
||||
|
||||
query =
|
||||
from p in PasswordReset,
|
||||
|
||||
@@ -18,7 +18,7 @@ defmodule FgHttp.Rules.Rule do
|
||||
|
||||
belongs_to :device, Device
|
||||
|
||||
timestamps()
|
||||
timestamps(type: :utc_datetime_usec)
|
||||
end
|
||||
|
||||
@doc false
|
||||
|
||||
@@ -37,8 +37,8 @@ defmodule FgHttp.Sessions do
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def create_session(%{email: email} = attrs) do
|
||||
get_session!(email: email)
|
||||
def create_session(%Session{} = session, %{} = attrs) do
|
||||
session
|
||||
|> Session.create_changeset(attrs)
|
||||
|> Repo.update()
|
||||
end
|
||||
|
||||
@@ -12,7 +12,7 @@ defmodule FgHttp.Users.PasswordReset do
|
||||
@token_validity_secs 86_400
|
||||
|
||||
schema "users" do
|
||||
field :reset_sent_at, :utc_datetime
|
||||
field :reset_sent_at, :utc_datetime_usec
|
||||
field :password_hash, :string
|
||||
field :password, :string, virtual: true
|
||||
field :password_confirmation, :string, virtual: true
|
||||
@@ -40,6 +40,8 @@ defmodule FgHttp.Users.PasswordReset do
|
||||
|> generate_reset_token()
|
||||
|> validate_required([:reset_token])
|
||||
|> unique_constraint(:reset_token)
|
||||
|> set_reset_sent_at()
|
||||
|> validate_required([:reset_sent_at])
|
||||
end
|
||||
|
||||
@doc false
|
||||
@@ -80,4 +82,11 @@ defmodule FgHttp.Users.PasswordReset do
|
||||
end
|
||||
|
||||
defp clear_token_fields(changeset), do: changeset
|
||||
|
||||
defp set_reset_sent_at(%Ecto.Changeset{valid?: true} = changeset) do
|
||||
changeset
|
||||
|> put_change(:reset_sent_at, DateTime.utc_now())
|
||||
end
|
||||
|
||||
defp set_reset_sent_at(changeset), do: changeset
|
||||
end
|
||||
|
||||
@@ -11,7 +11,7 @@ defmodule FgHttp.Users.Session do
|
||||
schema "users" do
|
||||
field :email, :string
|
||||
field :password, :string, virtual: true
|
||||
field :last_signed_in_at, :utc_datetime
|
||||
field :last_signed_in_at, :utc_datetime_usec
|
||||
end
|
||||
|
||||
def create_changeset(session, attrs \\ %{}) do
|
||||
@@ -23,7 +23,7 @@ defmodule FgHttp.Users.Session do
|
||||
end
|
||||
|
||||
defp set_last_signed_in_at(%Ecto.Changeset{valid?: true} = changeset) do
|
||||
last_signed_in_at = DateTime.truncate(DateTime.utc_now(), :second)
|
||||
last_signed_in_at = DateTime.utc_now()
|
||||
change(changeset, last_signed_in_at: last_signed_in_at)
|
||||
end
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@ defmodule FgHttp.Users.User do
|
||||
|
||||
schema "users" do
|
||||
field :email, :string
|
||||
field :confirmed_at, :utc_datetime
|
||||
field :last_signed_in_at, :utc_datetime
|
||||
field :confirmed_at, :utc_datetime_usec
|
||||
field :last_signed_in_at, :utc_datetime_usec
|
||||
field :password_hash, :string
|
||||
|
||||
# VIRTUAL FIELDS
|
||||
@@ -22,7 +22,7 @@ defmodule FgHttp.Users.User do
|
||||
|
||||
has_many :devices, Device, on_delete: :delete_all
|
||||
|
||||
timestamps()
|
||||
timestamps(type: :utc_datetime_usec)
|
||||
end
|
||||
|
||||
@doc false
|
||||
|
||||
@@ -3,7 +3,7 @@ defmodule FgHttpWeb.SessionController do
|
||||
Implements the CRUD for a Session
|
||||
"""
|
||||
|
||||
alias FgHttp.Sessions
|
||||
alias FgHttp.{Sessions, Users.Session}
|
||||
use FgHttpWeb, :controller
|
||||
|
||||
plug FgHttpWeb.Plugs.RedirectAuthenticated when action in [:new]
|
||||
@@ -15,22 +15,30 @@ defmodule FgHttpWeb.SessionController do
|
||||
end
|
||||
|
||||
# POST /sessions
|
||||
def create(conn, %{"session" => session_params}) do
|
||||
case Sessions.create_session(session_params) do
|
||||
{:ok, session} ->
|
||||
conn
|
||||
|> clear_session()
|
||||
|> put_session(:user_id, session.id)
|
||||
|> assign(:session, session)
|
||||
|> put_flash(:info, "Session created successfully")
|
||||
|> redirect(to: Routes.device_path(conn, :index))
|
||||
def create(conn, %{"session" => %{"email" => email} = session_params}) do
|
||||
case Sessions.get_session!(email: email) do
|
||||
%Session{} = session ->
|
||||
case Sessions.create_session(session, session_params) do
|
||||
{:ok, session} ->
|
||||
conn
|
||||
|> clear_session()
|
||||
|> put_session(:user_id, session.id)
|
||||
|> assign(:session, session)
|
||||
|> put_flash(:info, "Session created successfully")
|
||||
|> redirect(to: Routes.device_path(conn, :index))
|
||||
|
||||
{:error, changeset} ->
|
||||
{:error, changeset} ->
|
||||
conn
|
||||
|> clear_session()
|
||||
|> assign(:session, nil)
|
||||
|> put_flash(:error, "Error creating session.")
|
||||
|> render("new.html", changeset: changeset)
|
||||
end
|
||||
|
||||
nil ->
|
||||
conn
|
||||
|> clear_session()
|
||||
|> assign(:session, nil)
|
||||
|> put_flash(:error, "Error creating session.")
|
||||
|> render("new.html", changeset: changeset)
|
||||
|> put_flash(:error, "Email not found.")
|
||||
|> render("new.html")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -32,8 +32,7 @@ defmodule FgHttpWeb.Plugs.SessionLoader do
|
||||
|
||||
defp unauthed(conn) do
|
||||
conn
|
||||
|> clear_session()
|
||||
|> put_flash(:error, "There was an error loading your session. Please sign in again")
|
||||
|> put_flash(:error, "Please sign in to access that page.")
|
||||
|> redirect(to: Routes.session_path(conn, :new))
|
||||
|> halt()
|
||||
end
|
||||
|
||||
@@ -25,7 +25,8 @@ defmodule FgHttpWeb.Router do
|
||||
scope "/", FgHttpWeb do
|
||||
pipe_through :browser
|
||||
|
||||
resources "/password_resets", PasswordResetController, only: [:edit, :update, :new, :create]
|
||||
resources "/password_resets", PasswordResetController, only: [:update, :new, :create]
|
||||
get "/password_resets/:reset_token", PasswordResetController, :edit
|
||||
|
||||
resources "/user", UserController, singleton: true, only: [:show, :edit, :update, :delete]
|
||||
resources "/users", UserController, only: [:new, :create]
|
||||
@@ -38,7 +39,7 @@ defmodule FgHttpWeb.Router do
|
||||
|
||||
resources "/sessions", SessionController, only: [:new, :create, :delete]
|
||||
|
||||
get "/", DeviceController, :index
|
||||
get "/", SessionController, :new
|
||||
end
|
||||
|
||||
# Other scopes may use custom stacks.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
<p>
|
||||
<%= password_reset_url(@password_reset) %>
|
||||
</p>
|
||||
<%= link(
|
||||
"Click here to reset your password.",
|
||||
to: Routes.password_reset_url(FgHttpWeb.Endpoint, :edit, @reset_token)
|
||||
)
|
||||
%>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
Copy and paste the following URL into your browser to reset your password:
|
||||
|
||||
<%= Routes.password_reset_url(FgHttpWeb.Endpoint, :edit, @reset_token) %>
|
||||
@@ -1,8 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="<%= Routes.static_path(FgHttp.Endpoint, "/css/email.css") %>">
|
||||
<link rel="stylesheet" href="<%= Routes.static_path(FgHttpWeb.Endpoint, "/css/email.css") %>">
|
||||
</head>
|
||||
<body>
|
||||
<%= render @view_module, @view_template, assigns %>
|
||||
<%= @inner_content %>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
<%= submit "Sign in", class: "b ph3 pv2 input-reset ba b--black bg-transparent grow pointer f6 dib" %>
|
||||
</div>
|
||||
<div class="lh-copy mt3">
|
||||
<%= link("Sign up", to: Routes.user_path(@conn, :new), class: "f6 link dim black") %>
|
||||
<%= link("Forgot your password?", to: Routes.password_reset_path(@conn, :new), class: "f6 link dim black") %>
|
||||
<%= link("Sign up", to: Routes.user_path(@conn, :new), class: "f6 link dim black fl") %>
|
||||
<%= link("Forgot your password?", to: Routes.password_reset_path(@conn, :new), class: "f6 link dim black fr") %>
|
||||
</div>
|
||||
<% end) %>
|
||||
</main>
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
defmodule FgHttpWeb.EmailView do
|
||||
use FgHttpWeb, :view
|
||||
|
||||
def password_reset_url(password_reset) do
|
||||
link(
|
||||
"Click here to reset your password.",
|
||||
Routes.password_reset_path(:update, password_reset.reset_token)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,9 +4,9 @@ defmodule FgHttpWeb.LayoutView do
|
||||
def render_flash(conn) do
|
||||
~E"""
|
||||
<section id="flash">
|
||||
<%= if get_flash(conn, :error) do %>
|
||||
<div id="flash-error">
|
||||
<%= get_flash(conn, :error) %>
|
||||
<%= if get_flash(conn, :info) do %>
|
||||
<div id="flash-info">
|
||||
<%= get_flash(conn, :info) %>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= if get_flash(conn, :error) do %>
|
||||
|
||||
@@ -4,13 +4,13 @@ defmodule FgHttp.Repo.Migrations.CreateUsers do
|
||||
def change do
|
||||
create table(:users) do
|
||||
add :email, :string
|
||||
add :confirmed_at, :utc_datetime
|
||||
add :confirmed_at, :utc_datetime_usec
|
||||
add :password_hash, :string
|
||||
add :last_signed_in_at, :utc_datetime
|
||||
add :last_signed_in_at, :utc_datetime_usec
|
||||
add :reset_token, :string
|
||||
add :reset_sent_at, :utc_datetime
|
||||
add :reset_sent_at, :utc_datetime_usec
|
||||
|
||||
timestamps()
|
||||
timestamps(type: :utc_datetime_usec)
|
||||
end
|
||||
|
||||
create unique_index(:users, [:email])
|
||||
|
||||
@@ -9,7 +9,7 @@ defmodule FgHttp.Repo.Migrations.CreateDevices do
|
||||
add :last_ip, :inet
|
||||
add :user_id, references(:users, on_delete: :delete_all), null: false
|
||||
|
||||
timestamps()
|
||||
timestamps(type: :utc_datetime_usec)
|
||||
end
|
||||
|
||||
create index(:devices, [:user_id])
|
||||
|
||||
@@ -14,7 +14,7 @@ defmodule FgHttp.Repo.Migrations.CreateRules do
|
||||
add :port, :string
|
||||
add :device_id, references(:devices, on_delete: :delete_all), null: false
|
||||
|
||||
timestamps()
|
||||
timestamps(type: :utc_datetime_usec)
|
||||
end
|
||||
|
||||
create index(:rules, [:device_id])
|
||||
|
||||
@@ -22,7 +22,7 @@ defmodule FgHttp.PasswordResetsTest do
|
||||
PasswordResets.create_password_reset(Fixtures.password_reset(), @valid_attrs)
|
||||
|
||||
# reset_sent_at should be nil after creation
|
||||
assert is_nil(password_reset.reset_sent_at)
|
||||
assert !is_nil(password_reset.reset_sent_at)
|
||||
|
||||
assert password_reset.reset_token
|
||||
assert password_reset.email == email
|
||||
|
||||
@@ -36,13 +36,11 @@ defmodule FgHttpWeb.PasswordResetControllerTest do
|
||||
describe "edit password_reset" do
|
||||
setup [:create_password_reset]
|
||||
|
||||
test "renders password change form", %{unauthed_conn: conn, password_reset: password_reset} do
|
||||
params = [{:reset_token, password_reset.reset_token}]
|
||||
|
||||
test "renders form", %{unauthed_conn: conn, password_reset: password_reset} do
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
Routes.password_reset_path(conn, :edit, password_reset.id, params)
|
||||
Routes.password_reset_path(conn, :edit, password_reset.reset_token)
|
||||
)
|
||||
|
||||
assert html_response(conn, 200) =~ "Edit Password"
|
||||
|
||||
@@ -30,7 +30,10 @@ defmodule FgHttp.Fixtures do
|
||||
end
|
||||
|
||||
def session(_attrs \\ %{}) do
|
||||
{:ok, session} = Sessions.create_session(%{email: user().email, password: "test"})
|
||||
email = user().email
|
||||
record = Sessions.get_session!(email: email)
|
||||
create_params = %{email: email, password: "test"}
|
||||
{:ok, session} = Sessions.create_session(record, create_params)
|
||||
session
|
||||
end
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ config :fg_http, FgHttp.Mailer, adapter: Bamboo.LocalAdapter
|
||||
# watchers to your application. For example, we use it
|
||||
# with webpack to recompile .js and .css sources.
|
||||
config :fg_http, FgHttpWeb.Endpoint,
|
||||
http: [host: "localhost", port: 4000],
|
||||
http: [port: 4000],
|
||||
debug_errors: true,
|
||||
code_reloader: true,
|
||||
check_origin: false,
|
||||
|
||||
Reference in New Issue
Block a user