I'm writing a user search method that is supposed to search for users by their phone number, email and username. The thing is that users are allowed to hide their phone number and email. So, if they do hide it in their privacy settings of the application then they should not be listed in the search result.
I'm using typeorm to build this search query and here's what would be my attempt to do this if that requirement with the hiding personal info were not there:
const whereClause = `
(
"user".phone ILIKE :searchTerm
OR "user".username ILIKE :searchTerm
OR "user".profile_email ILIKE :searchTerm
) AND "user".id != :userId
`;
const users = await this.userRepository.createQueryBuilder('user')
.where(whereClause, filters)
.leftJoinAndSelect('user.subscription', 'subscription')
.leftJoinAndSelect('user.profilePrivacyPermissions', 'perms')
.limit(ESearchResponseLimit.USERS)
.getMany();
The profile privacy table looks as follows:
Screen type 1 corresponds to phone number and 2 corresponds to email. For now we only consider two possible states: isEverybody
and isNobody
(that's we don't consider contacts). So, e.g., if a user decided to hide his phone number then the isNobody
value will be equal to true, others will be set to false.
What I need is to somehow take these privacy settings into account in that search query I'm building. It should be something like this:
const whereClause = `
(
("user".phone ILIKE :searchTerm IF (perms.screenType = ${EScreenType.PHONE_NUMBER} AND perms.isEverybody))
OR "user".username ILIKE :searchTerm
OR ("user".profile_email ILIKE :searchTerm IF (perms.screenType = ${EScreenType.EMAIL} AND perms.isEverybody))
) AND "user".id != :userId
`;
The problem is that there's no such an operator as IF
but the idea is that I need to search by phone if it is not hidden, I need to search by email if it is not hidden either. I can't come up with even a remote idea on how to implement this in a query.
If it's possible to do with a raw query, it would be also good.
I've found out that there's the IF
operator in PostgreSQL but I don't see how I would use it here.
EDIT:
If I search by phone when email is hidden (which means that for the email screen perms.isEverybody = false
) the profilePrivacyPermissions field of the user object looks as follows:
"profilePrivacyPermissions": [
{
"screenType": 1,
"isEverybody": true,
"isContacts": false,
"isNobody": false
}
]
But it should look as follows:
"profilePrivacyPermissions": [
{
"screenType": 1,
"isEverybody": true,
"isContacts": false,
"isNobody": false
},
{
"screenType": 2,
"isEverybody": false,
"isContacts": false,
"isNobody": true
},
{
"screenType": 4,
"isEverybody": true,
"isContacts": false,
"isNobody": false
},
{
"screenType": 5,
"isEverybody": true,
"isContacts": false,
"isNobody": false
},
{
"screenType": 3,
"isEverybody": true,
"isContacts": false,
"isNobody": false
}
]
I understand it happens because of the perms
conditions in the where clause of the query.