I made my own authentication forms using ash_authentication as basis so I have more flexibility especially when it comes to styling. It works for almost everything only the validations does not work for :request_password_reset_with_password. I set up my form like:
form =
AshPhoenix.Form.for_action(User, :request_password_reset_with_password,
api: Account,
as: "user",
context: %{private: %{ash_authentication?: true}}
)
|> to_form()
And it does enter my validate form:
def handle_event("validate", %{"user" => params}, socket) do
%{form: form} = socket.assigns
form = AshPhoenix.Form.validate(form, params)
{:noreply, assign(socket, form: form)}
end
where user has a validation on email:
validations do
validate match(:email, ~r/(^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$)/) do
message "must be a valid email address"
end
end
And which also works for the registration form so Im not sure what Im doing wrong. Only resource I found was a discord archived support page where it was said to use:
context: %{private: %{ash_authentication?: true}}
. But all of the examples of what Im trying to do can just use the validate and it seems to work, although using a bit of a different setup so if more information is needed let me know.
Interesting
. I don’t think you’ll want to use that context
thing, thats kind of a hack (and likely would have no effect in this case). When you say it doesn’t work do you mean the validation is not applied? Can you show the output of Ash.Resource.Info.action(User, :request_password_reset_with_password)
?
That would be:
%Ash.Resource.Actions.Read{
arguments: [
%Ash.Resource.Actions.Argument{
allow_nil?: false,
type: Ash.Type.CiString,
name: :email,
default: nil,
private?: false,
sensitive?: false,
description: "The proposed identity to send reset instructions to.",
constraints: [casing: nil, allow_empty?: false, trim?: true]
}
],
description: "Send password reset instructions to a user if they exist.",
filter: nil,
get_by: [],
get?: false,
manual: nil,
metadata: [],
modify_query: nil,
name: :request_password_reset_with_password,
pagination: false,
preparations: [
%Ash.Resource.Preparation{
preparation: {AshAuthentication.Strategy.Password.RequestPasswordResetPreparation,
[]}
}
],
primary?: false,
touches_resources: [],
timeout: nil,
transaction?: false,
type: :read
}
Ah, okay, right. So, unfortunately, validations don’t work on read actions. I’ve been meaning to add a compatibility layer for this to allow validations to support queries in addition to change sets (essentially operating only on arguments). In the meantime, what you will need to do to work around this is add a preparation.
preparations do
prepare ValidateEmail, where: [action_is(:request_password_reset_with_password)]
end
That ValidateEmail
would be a standard hand-written preparation.
This is a pretty clear thing we can improve in the framework, and I hope to address this soon to make it a better experience.
1 Like