fix(canSendEmailOtp): use a query to find whitelist match, rather than fetching the whole table #1296
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
We have a whitelist of domains and specific allowed emails in DB. Before we allow a OTP to be sent to an email, we check against the whitelist if the input email is allowed.
The way this is done is to fetch the entire table content (with a slight filter for expiry) and do a match in code 😑
It would be much more efficient to use the database query capabilities to run the match on the DB directly. We can expect that to be both faster and transfer much less data.
Solution
Run a raw efficient query to return an easy yes/no state on whether an email matches an entry in the whitelist.
We can not use the ORM capability because we are not matching a cell value to some input. Instead we are matching the input against the cell value with a
endsWith
behaviour. This is done by using the<input> like concat ('%', field)
syntax.As we want the query to exit as early as possible (any match is enough), we run the query to return 1 on match and limit 1.
While DB engine do not offer guarantees of early exit, in principle, this can exit on the first match found and is thus as efficient as it can be made.
For email which do not match, there will be a full traversal of the table, which is about the same as the previous code, which was also doing a full table scan.
We return the whitelist entry that matched so we can log and verify