Skip to content

using $or in ?s ignores auth filter #815

@matan1905

Description

@matan1905

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

repo

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions