edwinofdawn
edwinofdawn
AEAsh Elixir
Created by edwinofdawn on 7/18/2023 in #support
Calculatated fields and AshGraphQL
How can I query calculated fields in when graphql . the fields are virtual they don't exist as attributes. ?
3 replies
AEAsh Elixir
Created by edwinofdawn on 6/13/2023 in #support
Policies Usage
I am guessing policies always get evaluated before the action is called. Can I set an argument based on the results of a policies evaluation ?
9 replies
AEAsh Elixir
Created by edwinofdawn on 6/2/2023 in #support
Intergrating Gaurdian Plugs into AshGraphql
I want implement JWT validation checking using Guardian. Is there an example I could checkout . For context this is for AshGraphQL and I want the check done only when certain actions are called not all. eg I have elixir

update :update_customer_registration do
accept [
:contact_name,
:organization_name,
:organization_abbreviation,
:location_city,
:location_state,
:customer_note
]

change fn changeset, struct ->
changeset
|> Ash.Changeset.after_action(fn changeset, customer ->
# send email to support

{:ok, customer}
end)
end
end
end
.....
policies do
policy action_type([:update_customer_registration]) do
forbid_if expr(confirmed_at == nil)
end
end

update :update_customer_registration do
accept [
:contact_name,
:organization_name,
:organization_abbreviation,
:location_city,
:location_state,
:customer_note
]

change fn changeset, struct ->
changeset
|> Ash.Changeset.after_action(fn changeset, customer ->
# send email to support

{:ok, customer}
end)
end
end
end
.....
policies do
policy action_type([:update_customer_registration]) do
forbid_if expr(confirmed_at == nil)
end
end
above is the action I want to protect by putting it behind a valid session. how do I use a Guardian plug that validates valid token to protect this action.
5 replies
AEAsh Elixir
Created by edwinofdawn on 5/24/2023 in #support
Returns type
I have a actions likes this elixir

update :update_user, :update_user do
read_action :get_by_token
identity false
end
....

update :update_user do
change fn changeset, struct ->
changeset
|> Ash.Changeset.change_attribute(
:confirmed_at,
Dates.now()
)
|> Ash.Changeset.change_attribute(
:status,
:confirmed
)
|> Ash.Changeset.after_action(fn changeset, customer ->
#generate token
{:ok, %{user: user, token: token}}
end)
end

update :update_user, :update_user do
read_action :get_by_token
identity false
end
....

update :update_user do
change fn changeset, struct ->
changeset
|> Ash.Changeset.change_attribute(
:confirmed_at,
Dates.now()
)
|> Ash.Changeset.change_attribute(
:status,
:confirmed
)
|> Ash.Changeset.after_action(fn changeset, customer ->
#generate token
{:ok, %{user: user, token: token}}
end)
end
I want to override the default return type which defaults to the resource . and instead return a map type with fields user of type user resource and token of type string.
16 replies
AEAsh Elixir
Created by edwinofdawn on 5/23/2023 in #support
Intercept Identities Behaviour
I have this code elixir
identities do
identity :email, [:email]
identity :confirmation_token, [:confirmation_token]
eager_check_with: Ash.API
end
...

change fn changeset, _struct ->
token = Utils.generate_token()

changeset
|> Ash.Changeset.change_attribute(
:confirmation_token,
Utils.hash_token(token) |> Base.encode64()
)
|> Ash.Changeset.change_attribute(
:expires_at,
NaiveDateTime.add(Dates.now(), @token_expiry_in_seconds)
)
|> Ash.Changeset.after_action(fn changeset, customer ->
#send email here

{:ok, customer}
end)
end
identities do
identity :email, [:email]
identity :confirmation_token, [:confirmation_token]
eager_check_with: Ash.API
end
...

change fn changeset, _struct ->
token = Utils.generate_token()

changeset
|> Ash.Changeset.change_attribute(
:confirmation_token,
Utils.hash_token(token) |> Base.encode64()
)
|> Ash.Changeset.change_attribute(
:expires_at,
NaiveDateTime.add(Dates.now(), @token_expiry_in_seconds)
)
|> Ash.Changeset.after_action(fn changeset, customer ->
#send email here

{:ok, customer}
end)
end
Incase of a unique error by email found using eager_check_with. rerun change again and upsert the record raising the error ? so that the API never errors out.
26 replies
AEAsh Elixir
Created by edwinofdawn on 5/16/2023 in #support
Ecto.Multi Usage
I saw only one post about how to use Ecto.Multi it directed me to Ash.Flow what I didn't find an example usage. For context I have a record I want fetch using token provided its valid, after I get the record successfully I want to update a field on it and finally on success issue a JWT or on error just return the error. How will this look like in the update function ?. Is this a candidate for to consider using ManualActions ?
41 replies
AEAsh Elixir
Created by edwinofdawn on 4/27/2023 in #support
undefined root_level_errors? true
Hello, small problem here. I am doing something like this
change fn changeset, _struct ->
changeset
|> Ash.Changeset.change_attribute(
:confirmation_token,
Utils.hash_token(token) |> Base.encode64()
)
|> case do
%Ash.Changeset{valid?: true} = changeset ->
Ash.Changeset.after_action(changeset, fn _changeset, customer ->
# enqueue job to send email here

})
{:ok, customer}
end)

changeset ->

{:error, changeset}
end
end
change fn changeset, _struct ->
changeset
|> Ash.Changeset.change_attribute(
:confirmation_token,
Utils.hash_token(token) |> Base.encode64()
)
|> case do
%Ash.Changeset{valid?: true} = changeset ->
Ash.Changeset.after_action(changeset, fn _changeset, customer ->
# enqueue job to send email here

})
{:ok, customer}
end)

changeset ->

{:error, changeset}
end
end
where I return {: error, changeset} I want the errors to bubble up and be returned by the graphql layer but root_level_errors? seems to be undefined. right now when you enter an invalid email the error returned is a generic something went wrong.
6 replies
AEAsh Elixir
Created by edwinofdawn on 4/17/2023 in #support
Ash Query filter function
For background information I have binary field in my datalayer called token when I call this the following function:
%{id: id} = user = insert(:user)

assert {:ok, %My_App.Ash.User{id: ^id} = _user} =
User
|> Ash.Query.filter(token == user.token)
|> My_App.Ash.read_one()
%{id: id} = user = insert(:user)

assert {:ok, %My_App.Ash.User{id: ^id} = _user} =
User
|> Ash.Query.filter(token == user.token)
|> My_App.Ash.read_one()
but I keep running into the same error highlighted below after inspection.
#Ash.Query<
resource: My_App.Ash.User,
errors: [
%Ash.Error.Unknown.UnknownError{
error: "filter: Invalid reference user.confirmation_token at relationship_path [:user]",
field: nil,
changeset: nil,
query: nil,
error_context: [],
vars: [],
path: [:filter],
stacktrace: #Stacktrace<>,
class: :unknown
}
]
>
#Ash.Query<
resource: My_App.Ash.User,
errors: [
%Ash.Error.Unknown.UnknownError{
error: "filter: Invalid reference user.confirmation_token at relationship_path [:user]",
field: nil,
changeset: nil,
query: nil,
error_context: [],
vars: [],
path: [:filter],
stacktrace: #Stacktrace<>,
class: :unknown
}
]
>
token exists on resource user , I don't know what the problem is ?
22 replies
AEAsh Elixir
Created by edwinofdawn on 4/13/2023 in #support
Casting Binary from Ash.Type.Binary to GraphQL type
Hello, I Have field with type :binary in my resource user which just represents a token generate using :crypto but I get this error Could not determine graphql field type for Ash.Type.Binary any ideas on how to solve this?
3 replies