( query: any, isMaster: boolean, isMaintenance: boolean, update: boolean, options: ?ParseServerOptions, _depth: number = 0 )
| 110 | }; |
| 111 | |
| 112 | const validateQuery = ( |
| 113 | query: any, |
| 114 | isMaster: boolean, |
| 115 | isMaintenance: boolean, |
| 116 | update: boolean, |
| 117 | options: ?ParseServerOptions, |
| 118 | _depth: number = 0 |
| 119 | ): void => { |
| 120 | if (isMaintenance) { |
| 121 | isMaster = true; |
| 122 | } |
| 123 | const rc = options?.requestComplexity; |
| 124 | if (!isMaster && rc && rc.queryDepth !== -1 && _depth > rc.queryDepth) { |
| 125 | throw new Parse.Error( |
| 126 | Parse.Error.INVALID_QUERY, |
| 127 | `Query condition nesting depth exceeds maximum allowed depth of ${rc.queryDepth}` |
| 128 | ); |
| 129 | } |
| 130 | if (query.ACL) { |
| 131 | throw new Parse.Error(Parse.Error.INVALID_QUERY, 'Cannot query on ACL.'); |
| 132 | } |
| 133 | |
| 134 | if (query.$or) { |
| 135 | if (Array.isArray(query.$or)) { |
| 136 | query.$or.forEach(value => validateQuery(value, isMaster, isMaintenance, update, options, _depth + 1)); |
| 137 | } else { |
| 138 | throw new Parse.Error(Parse.Error.INVALID_QUERY, 'Bad $or format - use an array value.'); |
| 139 | } |
| 140 | } |
| 141 | |
| 142 | if (query.$and) { |
| 143 | if (Array.isArray(query.$and)) { |
| 144 | query.$and.forEach(value => validateQuery(value, isMaster, isMaintenance, update, options, _depth + 1)); |
| 145 | } else { |
| 146 | throw new Parse.Error(Parse.Error.INVALID_QUERY, 'Bad $and format - use an array value.'); |
| 147 | } |
| 148 | } |
| 149 | |
| 150 | if (query.$nor) { |
| 151 | if (Array.isArray(query.$nor) && query.$nor.length > 0) { |
| 152 | query.$nor.forEach(value => validateQuery(value, isMaster, isMaintenance, update, options, _depth + 1)); |
| 153 | } else { |
| 154 | throw new Parse.Error( |
| 155 | Parse.Error.INVALID_QUERY, |
| 156 | 'Bad $nor format - use an array of at least 1 value.' |
| 157 | ); |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | Object.keys(query).forEach(key => { |
| 162 | if (query && query[key] && query[key].$regex !== undefined) { |
| 163 | if (!isMaster && rc && rc.allowRegex === false) { |
| 164 | throw new Parse.Error(Parse.Error.INVALID_QUERY, '$regex operator is not allowed'); |
| 165 | } |
| 166 | if (typeof query[key].$regex !== 'string') { |
| 167 | throw new Parse.Error(Parse.Error.INVALID_QUERY, '$regex value must be a string'); |
| 168 | } |
| 169 | if (query[key].$options !== undefined && typeof query[key].$options !== 'string') { |
no test coverage detected