Hey @Georges_Jamous,
This is actually a known issue that existed prior to the Rules migration, when permissions in Flexible Sync were used in a non-sync context, so the migration itself shouldn’t have introduced a regression here. We have a ticket to fix this issue.
In the meantime, I would suggest doing one of the following:
- Create an app for Flexible Sync and an app for non-sync requests
The flexible sync app would use the permissions as you have defined above, and the non-sync app would use a nearly identical rule but using the %%root
operator like this:
{
"collection": "MyCollection",
"database": "MyDatabase",
"roles": [
{
"name": "my_role_name",
"apply_when": {},
"document_filters": {
"write": false,
"read": {
"$or": [
{ "%%root.taskId": { $in: "%%user.custom_data.ownedTasks" }},
{ "%%root.taskId": { $in: "%%user.custom_data.tempTasks" }},
]
}
},
"read": true,
"write": true,
"insert": true,
"delete": true,
"search": true
}
]
}
Note that the reason we can’t use this rule in a flexible sync app is because the %%root
expansion is unsupported.
- Define a role for non-sync requests, and one for sync requests
{
"collection": "MyCollection",
"database": "MyDatabase",
"roles": [
{
"name": "nonSyncRole",
"apply_when": { "_id": { $exists: true } },
"document_filters": {
"write": false,
"read": {
"$or": [
{ "%%root.taskId": { $in: "%%user.custom_data.ownedTasks" }},
{ "%%root.taskId": { $in: "%%user.custom_data.tempTasks" }},
]
}
},
"read": true,
"write": true,
"insert": true,
"delete": true,
"search": true
},
{
"name": "my_role_name",
"apply_when": {},
"document_filters": {
"write": false,
"read": {
"$or": [
{ "taskId": { $in: "%%user.custom_data.ownedTasks" }},
{ "taskId": { $in: "%%user.custom_data.tempTasks" }},
]
}
},
"read": true,
"write": true,
"insert": true,
"delete": true,
"search": true
}
]
}
This takes advantage of the idea that apply_when
expressions referencing document fields in Flexible Sync doesn’t work, but does work for non-sync requests; this is because roles are applied per-document in non-sync requests, whereas they are applied per-sync-session on flexible sync requests (at session start, no documents have been queried for yet). Hence, the first role above will always apply on non-sync requests, and the latter will always apply on Flexible Sync requests.
Note that the first role is sync incompatible because it references the %%root
expansion, and will be reported as such in the UI with warning banners / modals (trying to set a sync incompatible role would actually result in an error in the CLI, but is tolerated in the UI – so this change would have to be done through the UI). This should be fine because the first role will never actually get used in flexible sync requests.
If you don’t want to deal with sync incompatible roles, then another option would be to capture the $or
in the apply_when
expression of a role, and then have a “catch-all” role for non-sync requests like:
{
"collection": "MyCollection",
"database": "MyDatabase",
"roles": [
{
"name": "nonSyncRole",
"apply_when": { "$or": [
{ "%%root.taskId": { $in: "%%user.custom_data.ownedTasks" }},
{ "%%root.taskId": { $in: "%%user.custom_data.tempTasks" }},
] },
"document_filters": {
"write": false,
"read": true
},
"read": true,
"write": true,
"insert": true,
"delete": true,
"search": true
},
{
"name": "catchAllForNonSyncRequestsRole",
"apply_when": { "_id": { $exists: true } },
"document_filters": {
"write": false,
"read": false
},
"read": false,
"write": false,
"insert": false,
"delete": false,
"search": false
},
{
"name": "my_role_name",
"apply_when": {},
"document_filters": {
"write": false,
"read": {
"$or": [
{ "taskId": { $in: "%%user.custom_data.ownedTasks" }},
{ "taskId": { $in: "%%user.custom_data.tempTasks" }},
]
}
},
"read": true,
"write": true,
"insert": true,
"delete": true,
"search": true
}
]
}
Under this configuration, the third role would apply to sync requests, whereas the first two will apply to non-sync requests.
Let me know if any of those options work for you,
Jonathan