diff --git a/lib/accounts/user.ex b/lib/accounts/user.ex index 53156b4..daf29ba 100644 --- a/lib/accounts/user.ex +++ b/lib/accounts/user.ex @@ -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 diff --git a/lib/mv_web/live/user_live/form.ex b/lib/mv_web/live/user_live/form.ex index dd78c0c..b599bc1 100644 --- a/lib/mv_web/live/user_live/form.ex +++ b/lib/mv_web/live/user_live/form.ex @@ -13,23 +13,81 @@ 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" /> - <%= if @user do %> -
- {gettext("Note")}: {gettext( - "Password can only be changed through authentication functions." - )} -
-- {gettext("Note")}: {gettext( - "Users created here will need to set their password through the authentication system." - )} -
-{gettext("Password requirements")}:
++ {gettext("Admin Note")}: {gettext( + "As an administrator, you can directly set a new password for this user using the same secure Ash Authentication system." + )} +
++ {gettext("Note")}: {gettext( + "Check 'Change Password' above to set a new password for this user." + )} +
++ {gettext("Note")}: {gettext( + "User will be created without a password. Check 'Set Password' to add one." + )} +
+