Skip to content

Commit

Permalink
Merge pull request #2 from daveminer/pow-impl
Browse files Browse the repository at this point in the history
Pow impl
  • Loading branch information
daveminer authored Nov 1, 2023
2 parents 7a30878 + ede3bbe commit 740c7a7
Show file tree
Hide file tree
Showing 21 changed files with 359 additions and 2 deletions.
8 changes: 8 additions & 0 deletions config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ config :logger, :console,
# Use Jason for JSON parsing in Phoenix
config :phoenix, :json_library, Jason

config :basket, :pow,
web_mailer_module: BasketWeb,
user: Basket.Users.User,
repo: Basket.Repo,
extensions: [PowResetPassword, PowEmailConfirmation],
controller_callbacks: Pow.Extension.Phoenix.ControllerCallbacks,
mailer: MyAppWeb.Pow.Mailer

# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
import_config "#{config_env()}.exs"
21 changes: 21 additions & 0 deletions lib/basket/users/user.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
defmodule Basket.Users.User do
@moduledoc false

use Ecto.Schema
use Pow.Ecto.Schema

use Pow.Extension.Ecto.Schema,
extensions: [PowResetPassword, PowEmailConfirmation]

def changeset(user_or_changeset, attrs) do
user_or_changeset
|> pow_changeset(attrs)
|> pow_extension_changeset(attrs)
end

schema "users" do
pow_user_fields()

timestamps()
end
end
8 changes: 8 additions & 0 deletions lib/basket_web.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ defmodule BasketWeb do

def static_paths, do: ~w(assets fonts images favicon.ico robots.txt)

def mail do
quote do
use Pow.Phoenix.Mailer.Component

unquote(html_helpers())
end
end

def router do
quote do
use Phoenix.Router, helpers: false
Expand Down
5 changes: 5 additions & 0 deletions lib/basket_web/controllers/pow_invitation/invitation_html.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
defmodule BasketWeb.PowInvitation.InvitationHTML do
use BasketWeb, :html

embed_templates "invitation_html/*"
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<div class="mx-auto max-w-sm">
<.header class="text-center">
Register
<:subtitle>
Already have an account?
<.link
navigate={Pow.Phoenix.Routes.path_for(@conn, Pow.Phoenix.SessionController, :new)}
class="font-semibold text-brand hover:underline"
>
Sign in
</.link>
now.
</:subtitle>
</.header>

<.simple_form :let={f} for={@changeset} as={:user} action={@action} phx-update="ignore">
<.error :if={@changeset.action}>
Oops, something went wrong! Please check the errors below.
</.error>
<.input
field={f[Pow.Ecto.Schema.user_id_field(@changeset)]}
type={(Pow.Ecto.Schema.user_id_field(@changeset) == :email && "email") || "text"}
label={Phoenix.Naming.humanize(Pow.Ecto.Schema.user_id_field(@changeset))}
required
/>
<.input field={f[:password]} type="password" label="Password" required />
<.input field={f[:password_confirmation]} type="password" label="Confirm password" required />

<:actions>
<.button phx-disable-with="Submitting..." class="w-full">
Submit <span aria-hidden="true">→</span>
</.button>
</:actions>
</.simple_form>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<div class="mx-auto max-w-sm">
<.header class="text-center">
Invite
</.header>

<.simple_form :let={f} for={@changeset} as={:user} action={@action} phx-update="ignore">
<.error :if={@changeset.action}>
Oops, something went wrong! Please check the errors below.
</.error>
<.input
field={f[Pow.Ecto.Schema.user_id_field(@changeset)]}
type={(Pow.Ecto.Schema.user_id_field(@changeset) == :email && "email") || "text"}
label={Phoenix.Naming.humanize(Pow.Ecto.Schema.user_id_field(@changeset))}
required
/>

<:actions>
<.button phx-disable-with="Submitting..." class="w-full">
Submit <span aria-hidden="true">→</span>
</.button>
</:actions>
</.simple_form>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<div class="mx-auto max-w-sm">
<.header class="text-center">
Invitation URL
<:subtitle>
Please send the following URL to the invitee.
</:subtitle>
</.header>

<div class="space-y-8 bg-white mt-10">
<div class="flex items-center gap-1 text-sm leading-6 text-zinc-600">
<.input name="invite-url" type="text" id="invite-url" value={@url} class="mt-0" readonly />
<.button
phx-click={JS.dispatch("phx:share", to: "#invite-url")}
aria-label="Share"
class="mt-2"
>
<.icon name="hero-arrow-up-on-square" class="w-6 h-6" />
</.button>
</div>
</div>
</div>
<script type="text/javascript">
window.addEventListener("phx:share", (event) => {
let url = event.target.value;
navigator.clipboard.writeText(url).then(
() => {
/* clipboard successfully set */
},
() => {
/* clipboard write failed */
});
navigator.share({url: url}).then(
() => {
/* share succeeded */
},
() => {
/* share failed */
});
})
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
defmodule BasketWeb.PowResetPassword.ResetPasswordHTML do
use BasketWeb, :html

embed_templates "reset_password_html/*"
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<div class="mx-auto max-w-sm">
<.header class="text-center">
Reset password
<:subtitle>
Know your password?
<.link
navigate={Pow.Phoenix.Routes.path_for(@conn, Pow.Phoenix.SessionController, :new)}
class="font-semibold text-brand hover:underline"
>
Sign in
</.link>
now.
</:subtitle>
</.header>

<.simple_form :let={f} for={@changeset} as={:user} action={@action} phx-update="ignore">
<.error :if={@changeset.action}>
Oops, something went wrong! Please check the errors below.
</.error>
<.input field={f[:password]} type="password" label="New password" required />
<.input
field={f[:password_confirmation]}
type="password"
label="Confirm new password"
required
/>

<:actions>
<.button phx-disable-with="Submitting..." class="w-full">
Submit <span aria-hidden="true">→</span>
</.button>
</:actions>
</.simple_form>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<div class="mx-auto max-w-sm">
<.header class="text-center">
Reset password
<:subtitle>
Know your password?
<.link
navigate={Pow.Phoenix.Routes.path_for(@conn, Pow.Phoenix.SessionController, :new)}
class="font-semibold text-brand hover:underline"
>
Sign in
</.link>
now.
</:subtitle>
</.header>

<.simple_form :let={f} for={@changeset} as={:user} action={@action} phx-update="ignore">
<.error :if={@changeset.action}>
Oops, something went wrong! Please check the errors below.
</.error>
<.input field={f[:email]} type="email" label="Email" required />

<:actions>
<.button phx-disable-with="Submitting..." class="w-full">
Submit <span aria-hidden="true">→</span>
</.button>
</:actions>
</.simple_form>
</div>
1 change: 1 addition & 0 deletions lib/basket_web/endpoint.ex
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,6 @@ defmodule BasketWeb.Endpoint do
plug Plug.MethodOverride
plug Plug.Head
plug Plug.Session, @session_options
plug Pow.Plug.Session, otp_app: :basket
plug BasketWeb.Router
end
20 changes: 20 additions & 0 deletions lib/basket_web/mails/pow/mailer.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
defmodule MyAppWeb.Pow.Mailer do
@moduledoc """
Stub mailer implementation for initial Pow config
"""

use Pow.Phoenix.Mailer
require Logger

def cast(%{user: user, subject: subject, text: text, html: html, assigns: _assigns}) do
# Build email struct to be used in `process/1`

%{to: user.email, subject: subject, text: text, html: html}
end

def process(email) do
# Send email

Logger.debug("E-mail sent: #{inspect(email)}")
end
end
23 changes: 23 additions & 0 deletions lib/basket_web/mails/pow_email_confirmation_mail.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
defmodule BasketWeb.PowEmailConfirmationMail do
@moduledoc false

use BasketWeb, :mail

def email_confirmation(assigns) do
%Pow.Phoenix.Mailer.Template{
subject: "Confirm your email address",
html: ~H"""
<h3>Hi</h3>
<p>Please use the following link to confirm your e-mail address:</p>
<p><a href="{@url}">{@url}</a></p>
""",
text: ~P"""
Hi,
Please use the following link to confirm your e-mail address:
<%= @url %>
"""
}
end
end
25 changes: 25 additions & 0 deletions lib/basket_web/mails/pow_invitation_mail.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
defmodule BasketWeb.PowInvitationMail do
@moduledoc false

use BasketWeb, :mail

def invitation(assigns) do
%Pow.Phoenix.Mailer.Template{
subject: "You've been invited",
html: ~H"""
<h3>Hi,</h3>
<p>
You've been invited by <strong><%= @invited_by_user_id %></strong>. Please use the following link to accept your invitation:
</p>
<p><a href="{@url}">{@url}</a></p>
""",
text: ~P"""
Hi,
You've been invited by <%= @invited_by_user_id %>. Please use the following link to accept your invitation:
{@url}
"""
}
end
end
26 changes: 26 additions & 0 deletions lib/basket_web/mails/pow_reset_password_mail.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
defmodule BasketWeb.PowResetPasswordMail do
@moduledoc false

use BasketWeb, :mail

def reset_password(assigns) do
%Pow.Phoenix.Mailer.Template{
subject: "Reset password link",
html: ~H"""
<h3>Hi,</h3>
<p>Please use the following link to reset your password:</p>
<p><a href="{@url}"><%= @url %></a></p>
<p>You can disregard this email if you didn't request a password reset.</p>
""",
text: ~P"""
Hi,
Please use the following link to reset your password:
<%= @url %>
You can disregard this email if you didn't request a password reset.
"""
}
end
end
11 changes: 11 additions & 0 deletions lib/basket_web/router.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
defmodule BasketWeb.Router do
use BasketWeb, :router
use Pow.Phoenix.Router

use Pow.Extension.Phoenix.Router,
extensions: [PowResetPassword, PowEmailConfirmation, PowInvitation, PowPersistentSession]

import Surface.Catalogue.Router

Expand All @@ -16,6 +20,13 @@ defmodule BasketWeb.Router do
plug :accepts, ["json"]
end

scope "/" do
pipe_through :browser

pow_routes()
pow_extension_routes()
end

scope "/", BasketWeb do
pipe_through :browser

Expand Down
5 changes: 3 additions & 2 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,15 @@ defmodule Basket.MixProject do
{:dns_cluster, "~> 0.1.1"},
{:plug_cowboy, "~> 2.5"},
{:surface, "~> 0.11.0"},
# for surface.init
# for surface.init; possible to remove.
{:sourceror, "~> 0.12.0"},
{:surface_catalogue, "~> 0.6.0"},
{:excoveralls, "~> 0.18", only: :test},
{:sobelow, "~> 0.13.0", only: [:dev, :test], runtime: false},
{:credo, "~> 1.7.1", only: [:dev, :test], runtime: false},
{:dialyxir, "~> 1.4.2", runtime: false},
{:mix_audit, "~> 2.1.1", runtime: false}
{:mix_audit, "~> 2.1.1", runtime: false},
{:pow, "~> 1.0.34"}
]
end

Expand Down
1 change: 1 addition & 0 deletions mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"plug_cowboy": {:hex, :plug_cowboy, "2.6.1", "9a3bbfceeb65eff5f39dab529e5cd79137ac36e913c02067dba3963a26efe9b2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "de36e1a21f451a18b790f37765db198075c25875c64834bcc82d90b309eb6613"},
"plug_crypto": {:hex, :plug_crypto, "2.0.0", "77515cc10af06645abbfb5e6ad7a3e9714f805ae118fa1a70205f80d2d70fe73", [:mix], [], "hexpm", "53695bae57cc4e54566d993eb01074e4d894b65a3766f1c43e2c61a1b0f45ea9"},
"postgrex": {:hex, :postgrex, "0.17.3", "c92cda8de2033a7585dae8c61b1d420a1a1322421df84da9a82a6764580c503d", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "946cf46935a4fdca7a81448be76ba3503cff082df42c6ec1ff16a4bdfbfb098d"},
"pow": {:hex, :pow, "1.0.34", "51999e624475a4c75d9e5d04fcf7e38b3c5a1f8d09f37c1311d7bef43962aafa", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix, ">= 1.3.0 and < 1.8.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, ">= 2.0.0 and < 4.0.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_live_view, ">= 0.18.0", [hex: :phoenix_live_view, repo: "hexpm", optional: true]}, {:plug, ">= 1.5.0 and < 2.0.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "63a5e3b5197a39ac0320224526fb555b2b009852d878d29efc4362537393080b"},
"ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
"sobelow": {:hex, :sobelow, "0.13.0", "218afe9075904793f5c64b8837cc356e493d88fddde126a463839351870b8d1e", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "cd6e9026b85fc35d7529da14f95e85a078d9dd1907a9097b3ba6ac7ebbe34a0d"},
"sourceror": {:hex, :sourceror, "0.12.3", "a2ad3a1a4554b486d8a113ae7adad5646f938cad99bf8bfcef26dc0c88e8fade", [:mix], [], "hexpm", "4d4e78010ca046524e8194ffc4683422f34a96f6b82901abbb45acc79ace0316"},
Expand Down
Loading

0 comments on commit 740c7a7

Please sign in to comment.