using $or in ?s ignores auth filter
matan1905 opened this issue · 2 comments
matan1905 commented
Bug Report
Current behavior
When I use the following search query, I receive results from all userId's, despite setting a filter for userId:
{
"tip.type": {
"$or": [
"Connection",
"Info"
]
}
}
for your convenience, a Curl:
curl --request GET \
--url 'http://127.0.0.1:3000/user-tips?s=%7B%0A%09%09%09%22tip.type%22%3A%20%7B%0A%09%09%09%09%22%24or%22%3A%20%5B%0A%09%09%09%09%09%22Connection%22%2C%0A%09%09%09%09%09%22Info%22%0A%09%09%09%09%5D%0A%09%09%09%7D%0A%09%09%7D'
Input Code
Controller:
@Crud({
model: { type:UserTip },
routes:{
only:[]
},
query:{
join:{
tip:{eager:true},
}
}
})
@CrudAuth({
filter:(req)=>{
return {'userId':req?.auth?.id}
},
persist: (req: any) => {
return {
userId: req?.auth?.id ?? undefined
};
}
})
@Controller("user-tips")
export class UserTipsController implements CrudController<UserTip>{
constructor(public service: UserTipsService) {
}
get base(): CrudController<UserTip> {
return this;
}
@Override()
async getMany(
@ParsedRequest() req: CrudRequest,
) {
// todo - figure out why search = tip.type:{or:[1,2] gives away all tips, and remove the filter fix
const result= (await this.base.getManyBase(req))
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return { tips: result?.filter(tip=>tip.userId == req.parsed.authPersist.userId) };
}
}
UserTip Entity:
@Entity()
export class UserTip extends CommonEntity{
@ManyToOne(()=>Tip,)
tip:Tip;
@Column()
userId:string;
@Column()
isLiked:boolean;
}
Tip entity:
enum TipType {
Info = "Info",
Activity = "Activity",
Resource = "Resource",
Inspiration = "Inspiration",
Connection = "Connection",
}
@Entity()
export class Tip extends CommonEntity {
@Column({type:'enum',enum:TipType, default:TipType.Info})
type: TipType;
@Column()
content: string;
}
The generated SQL:
"UserTip_id", "UserTip"."id" AS "UserTip_id", "UserTip"."createdAt" AS "UserTip_createdAt", "UserTip"."userId" AS "UserTip_userId", "UserTip"."isLiked" AS "UserTip_isLiked", "tip"."id" AS "tip_id", "tip"."id" AS "tip_id", "tip"."createdAt" AS "tip_createdAt", "tip"."type" AS "tip_type", "tip"."content" AS "tip_content", "UserTip"."tipId" FROM "user_tip" "UserTip" LEFT JOIN "tip" "tip" ON "tip"."id"="UserTip"."tipId" WHERE ("UserTip"."userId" = $1 OR ("tip"."type" = $3 OR "tip"."type" = $4)
Expected behavior
I would expect to only receive entities with the specified userId. (WHERE ("UserTip"."userId" = $1 AND ("tip"."type" = $3 OR "tip"."type" = $4))
Possible Solution
Environment
Package version: tried both 4.6.2 and 5.0.0-alpha.3
For Tooling issues:
- Node version: v16.17.0
- Platform: Mac
- Database: PostgreSQL 15.0 (Debian 15.0-1.pgdg110+1) on aarch64-unknown-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
Repository with minimal reproduction
imnotjames commented
I'm using 4.6.2 and postgres and cannot replicate this. Commenting and subscribing for when the minimal repo is up!
matan1905 commented
@imnotjames Sorry, completely forgot about it, I added it now.