feat: set password for new and for existing user
This commit is contained in:
parent
2e256a0206
commit
662e80cc74
4 changed files with 218 additions and 21 deletions
|
|
@ -71,6 +71,19 @@ defmodule Mv.Accounts.User do
|
|||
accept [:email]
|
||||
end
|
||||
|
||||
# Admin action for direct password changes in admin panel
|
||||
# Uses the official Ash Authentication HashPasswordChange with correct context
|
||||
update :admin_set_password do
|
||||
accept [:email]
|
||||
argument :password, :string, allow_nil?: false, sensitive?: true
|
||||
|
||||
# Set the strategy context that HashPasswordChange expects
|
||||
change set_context(%{strategy_name: :password})
|
||||
|
||||
# Use the official Ash Authentication password change
|
||||
change AshAuthentication.Strategy.Password.HashPasswordChange
|
||||
end
|
||||
|
||||
read :get_by_subject do
|
||||
description "Get a user by the subject claim in a JWT"
|
||||
argument :subject, :string, allow_nil?: false
|
||||
|
|
@ -121,6 +134,14 @@ defmodule Mv.Accounts.User do
|
|||
identity :unique_oidc_id, [:oidc_id]
|
||||
end
|
||||
|
||||
# Global validations - applied to all relevant actions
|
||||
validations do
|
||||
# Password strength policy: minimum 8 characters for all password-related actions
|
||||
validate string_length(:password, min: 8) do
|
||||
where action_is([:register_with_password, :admin_set_password])
|
||||
end
|
||||
end
|
||||
|
||||
# You can customize this if you wish, but this is a safe default that
|
||||
# only allows user data to be interacted with via AshAuthentication.
|
||||
# policies do
|
||||
|
|
|
|||
|
|
@ -13,11 +13,67 @@ defmodule MvWeb.UserLive.Form do
|
|||
<.form for={@form} id="user-form" phx-change="validate" phx-submit="save">
|
||||
<.input field={@form[:email]} label={gettext("Email")} required type="email" />
|
||||
|
||||
<!-- Password Section -->
|
||||
<div class="mt-6">
|
||||
<label class="flex items-center space-x-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="set_password"
|
||||
phx-click="toggle_password_section"
|
||||
checked={@show_password_fields}
|
||||
class="checkbox checkbox-sm"
|
||||
/>
|
||||
<span class="text-sm font-medium">
|
||||
{if @user, do: gettext("Change Password"), else: gettext("Set Password")}
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<%= if @show_password_fields do %>
|
||||
<div class="mt-4 space-y-4 p-4 bg-gray-50 rounded-lg">
|
||||
<.input
|
||||
field={@form[:password]}
|
||||
label={gettext("Password")}
|
||||
type="password"
|
||||
required
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
|
||||
<!-- Only show password confirmation for new users (register_with_password) -->
|
||||
<%= if !@user do %>
|
||||
<.input
|
||||
field={@form[:password_confirmation]}
|
||||
label={gettext("Confirm Password")}
|
||||
type="password"
|
||||
required
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
<% end %>
|
||||
|
||||
<div class="text-sm text-gray-600">
|
||||
<p><strong>{gettext("Password requirements")}:</strong></p>
|
||||
<ul class="list-disc list-inside text-xs mt-1 space-y-1">
|
||||
<li>{gettext("At least 8 characters")}</li>
|
||||
<li>{gettext("Include both letters and numbers")}</li>
|
||||
<li>{gettext("Consider using special characters")}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<%= if @user do %>
|
||||
<div class="mt-3 p-3 bg-orange-50 border border-orange-200 rounded">
|
||||
<p class="text-sm text-orange-800">
|
||||
<strong>{gettext("Admin Note")}:</strong> {gettext(
|
||||
"As an administrator, you can directly set a new password for this user using the same secure Ash Authentication system."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% else %>
|
||||
<%= if @user do %>
|
||||
<div class="mt-4 p-4 bg-blue-50 rounded-lg">
|
||||
<p class="text-sm text-blue-800">
|
||||
<strong>{gettext("Note")}:</strong> {gettext(
|
||||
"Password can only be changed through authentication functions."
|
||||
"Check 'Change Password' above to set a new password for this user."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -25,11 +81,13 @@ defmodule MvWeb.UserLive.Form do
|
|||
<div class="mt-4 p-4 bg-yellow-50 rounded-lg">
|
||||
<p class="text-sm text-yellow-800">
|
||||
<strong>{gettext("Note")}:</strong> {gettext(
|
||||
"Users created here will need to set their password through the authentication system."
|
||||
"User will be created without a password. Check 'Set Password' to add one."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<.button phx-disable-with={gettext("Saving...")} variant="primary">
|
||||
{gettext("Save User")}
|
||||
|
|
@ -56,6 +114,7 @@ defmodule MvWeb.UserLive.Form do
|
|||
|> assign(:return_to, return_to(params["return_to"]))
|
||||
|> assign(user: user)
|
||||
|> assign(:page_title, page_title)
|
||||
|> assign(:show_password_fields, false)
|
||||
|> assign_form()}
|
||||
end
|
||||
|
||||
|
|
@ -63,6 +122,19 @@ defmodule MvWeb.UserLive.Form do
|
|||
defp return_to(_), do: "index"
|
||||
|
||||
@impl true
|
||||
def handle_event("toggle_password_section", _params, socket) do
|
||||
show_password_fields = !socket.assigns.show_password_fields
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(:show_password_fields, show_password_fields)
|
||||
|> assign_form()
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
|
||||
|
||||
def handle_event("validate", %{"user" => user_params}, socket) do
|
||||
{:noreply, assign(socket, form: AshPhoenix.Form.validate(socket.assigns.form, user_params))}
|
||||
end
|
||||
|
|
@ -86,12 +158,16 @@ defmodule MvWeb.UserLive.Form do
|
|||
|
||||
defp notify_parent(msg), do: send(self(), {__MODULE__, msg})
|
||||
|
||||
defp assign_form(%{assigns: %{user: user}} = socket) do
|
||||
defp assign_form(%{assigns: %{user: user, show_password_fields: show_password_fields}} = socket) do
|
||||
form =
|
||||
if user do
|
||||
AshPhoenix.Form.for_update(user, :update_user, domain: Mv.Accounts, as: "user")
|
||||
# For existing users, use admin password action if password fields are shown
|
||||
action = if show_password_fields, do: :admin_set_password, else: :update_user
|
||||
AshPhoenix.Form.for_update(user, action, domain: Mv.Accounts, as: "user")
|
||||
else
|
||||
AshPhoenix.Form.for_create(Mv.Accounts.User, :create_user,
|
||||
# For new users, use password registration if password fields are shown
|
||||
action = if show_password_fields, do: :register_with_password, else: :create_user
|
||||
AshPhoenix.Form.for_create(Mv.Accounts.User, action,
|
||||
domain: Mv.Accounts,
|
||||
as: "user"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -502,3 +502,53 @@ msgstr "Alle Benutzer auswählen"
|
|||
#, elixir-autogen, elixir-format
|
||||
msgid "Select user"
|
||||
msgstr "Benutzer auswählen"
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex:23
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Set Password"
|
||||
msgstr "Passwort setzen"
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex:35
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Password"
|
||||
msgstr "Passwort"
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex:42
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Confirm Password"
|
||||
msgstr "Passwort bestätigen"
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex:48
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Password requirements"
|
||||
msgstr "Passwort-Anforderungen"
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex:50
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "At least 8 characters"
|
||||
msgstr "Mindestens 8 Zeichen"
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex:51
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Include both letters and numbers"
|
||||
msgstr "Buchstaben und Zahlen verwenden"
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex:52
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Consider using special characters"
|
||||
msgstr "Sonderzeichen empfohlen"
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex:57
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "User will be created without a password. Check 'Set Password' to add one."
|
||||
msgstr "Benutzer wird ohne Passwort erstellt. Aktivieren Sie 'Passwort setzen', um eines hinzuzufügen."
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex:75
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "As an administrator, you can directly set a new password for this user using the same secure Ash Authentication system."
|
||||
msgstr "Als Administrator können Sie direkt ein neues Passwort für diesen Benutzer setzen, wobei das gleiche sichere Ash Authentication System verwendet wird."
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex:85
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Check 'Change Password' above to set a new password for this user."
|
||||
msgstr "Aktivieren Sie 'Passwort ändern' oben, um ein neues Passwort für diesen Benutzer zu setzen."
|
||||
|
|
|
|||
|
|
@ -492,4 +492,54 @@ msgstr ""
|
|||
#: lib/mv_web/live/user_live/form.ex:27
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Users created here will need to set their password through the authentication system."
|
||||
msgstr ""
|
||||
msgstr "Users created here will need to set their password through the authentication system."
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex:23
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Set Password"
|
||||
msgstr "Set Password"
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex:35
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Password"
|
||||
msgstr "Password"
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex:42
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Confirm Password"
|
||||
msgstr "Confirm Password"
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex:48
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Password requirements"
|
||||
msgstr "Password requirements"
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex:50
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "At least 8 characters"
|
||||
msgstr "At least 8 characters"
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex:51
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Include both letters and numbers"
|
||||
msgstr "Include both letters and numbers"
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex:52
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Consider using special characters"
|
||||
msgstr "Consider using special characters"
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex:57
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "User will be created without a password. Check 'Set Password' to add one."
|
||||
msgstr "User will be created without a password. Check 'Set Password' to add one."
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex:75
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "As an administrator, you can directly set a new password for this user using the same secure Ash Authentication system."
|
||||
msgstr "As an administrator, you can directly set a new password for this user using the same secure Ash Authentication system."
|
||||
|
||||
#: lib/mv_web/live/user_live/form.ex:85
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Check 'Change Password' above to set a new password for this user."
|
||||
msgstr "Check 'Change Password' above to set a new password for this user."
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue