* Which Category is your question related to? *
ElasticSearch, Cognito
* What AWS Services are you utilizing? *
ElasticSearch, Cognito
* Provide additional details e.g. code snippets *
I have an app, that logged in user can create items by submitting forms. I configure the model to be searchable with auth:
type Item @model @searchable @auth(rules: [{allow: owner}]) {
id: ID!
name: String!
}
To search items by name:
const searchItemsQuery = `query($searchValue: String){
searchItems(filter:{name:{match:$searchValue}}){
items{
id
name
}
}
}`;
API.graphql(graphqlOperation(searchItemsQuery, {{ searchValue: searchValue }})).then(...)
I want to allow only the logged in user to search his/her own items, however, the @auth seems to apply to only CRUDL, but not search. And search is not mentioned in doc too.
Is this possible?
Yes, this can be done but I think the way to do it would be to update your request mapping template to access the $context.identity.sub (or some unique identifier off of the identity, maybe even username).
This means you should also have the $context.identity.sub stored when you create a mutation.
This way you have the identity available in the resolver without having to pass it in as an argument.
Can you please show a code snippet on how to
have the $context.identity.sub stored when you create a mutation
@YikSanChan Sure. In the request mapping template of the mutation where you would like to store user information, you could add aline before the putItem operation that looks something like this:
$util.qr($context.args.input.put("userId", $context.identity.sub))
Thank you very much! Finally, I am able to solve this problem by editing the response template mapping of searchItems resolver.
Before:
#set( $items = [] )
#foreach( $entry in $context.result.hits.hits )
#if( !$foreach.hasNext )
#set( $nextToken = "$entry.sort.get(0)" )
#end
$util.qr($items.add($entry.get("_source")))
#end
$util.toJson({
"items": $items,
"total": $ctx.result.hits.total,
"nextToken": $nextToken
})
After:
#set( $items = [] )
#foreach( $entry in $context.result.hits.hits )
#if( !$foreach.hasNext )
#set( $nextToken = "$entry.sort.get(0)" )
#end
#set ( $item = $entry.get("_source") )
#if( $item.owner == $context.identity.username )
$util.qr($items.add($item))
#end
#end
$util.toJson({
"items": $items,
"total": $ctx.result.hits.total,
"nextToken": $nextToken
})
Most helpful comment
Thank you very much! Finally, I am able to solve this problem by editing the response template mapping of
searchItemsresolver.Before:
After: