- Customer-service notes joined to the account by comparing encrypted phone
columns. Both notes tables now carry phone_key, written when a note is
saved, and the three joins match on it.
- The email_verifications join was comparing a plaintext column against an
encrypted one, so it never matched and `verified` was always NULL in both
passenger and driver sign-in. It is now resolved in PHP against the
decrypted address, which fixes a pre-existing bug rather than only
preparing for GCM.
- auth/sendVerifyEmail.php built all three of its statements by interpolating
the request values into SQL. Any caller could inject through the email or
token field. Now parameterised.
- serviceapp/register.php duplicate detection consults the users indexes and
writes them with the row.
Sweep confirms no join or lookup compares two encrypted columns any more.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Storing the verification phone as a keyed HMAC fixed OTP lookups but broke
every query that joined those tables back to the account, because
phone_verification*.phone_number no longer holds the same value as
driver.phone / passengers.phone. Six joins were affected, and four of them
feed the `verified` flag that the rider and driver apps check at sign-in — so
this was already failing under the current CBC mode, not only after a switch
to GCM.
Accounts now carry phone_key, computed exactly as otpPhoneKey() does, and the
joins match on it. It is written at registration for both apps and populated
for existing rows by the backfill.
The backfill also covers the columns added for the remaining lookups:
users.email_bidx/phone_bidx and driver.national_bidx, which were migrated but
never populated, and honours a per-field prefix so phone_key reproduces
otpPhoneKey's exact output.
Insert column/value counts verified with a paren-aware parser after editing.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>