Commit Graph
13 Commits
Author SHA1 Message Date
Hamza-AyedandClaude Opus 5 a1c19b052d Make OTP verification independent of the encryption mode
The verification tables (token_verification*, phone_verification*) use the
phone number as a lookup key: written when the code is sent, read when it is
checked. Storing it encrypted worked only because encryptData() is
deterministic — under AES-GCM the two sides would produce different
ciphertexts and no code would ever verify, locking every user out of
registration and OTP sign-in.

otpPhoneKey() stores a keyed HMAC of the normalised number instead. No schema
change is needed since the column is textual, local and international formats
now resolve to the same key, and the value cannot be reversed without the
pepper. It falls back to the previous behaviour when no pepper is configured.

Applied to both sides of every affected flow — request/verify, and the driver
and passenger send/verify pairs — including the OTP value itself where it is
compared by equality rather than decrypted. auth/otp/verify.php already
decrypts the token before comparing, so it needed no change there.

Also adds ENCRYPTION_MODE to EncryptionHelper: encryptData() writes GCM when
set to 'gcm', CBC otherwise. Verified in both directions — rows written under
CBC stay readable after switching, and rows written under GCM stay readable
after rolling back — so the switch is reversible by an environment variable.

The admin console's own OTP is unaffected: it keys the table by the stored
ciphertext read from adminUser, identical on both sides.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-25 16:18:16 +03:00
Hamza-AyedandClaude Opus 5 6802026dbd Add blind-index search layer; fix captain detail 200-with-empty-body
Searching encrypted columns currently works only because encryptData() is
AES-CBC with a fixed IV, i.e. deterministic. That determinism is what leaks
equality and shared prefixes, and it is why moving storage to AES-GCM would
break every lookup. This separates the two concerns.

- core/Security/BlindIndex.php: HMAC-SHA256 over a normalised value, keyed by
  a secret pepper. Phone numbers have a small keyspace, so a bare SHA-256
  would be reversible by enumeration; the pepper lives in the environment, not
  the database. The scope string includes table and field so the same number
  does not produce a matching index across tables.
  Normalisation unifies local/international phone forms, lowercases emails and
  folds Arabic alef/ya/ta-marbuta and diacritics for names.
- migrations/: nullable *_bidx columns plus indexes, and the missing
  adminUser.status/approved_by/approved_at columns that admin approvals need.
- scripts/backfill_blind_index.php: restartable, batched, --dry-run capable,
  touches only index columns.
- Admin lookups by phone/email now match the index, keeping the old ciphertext
  comparison in the same query so search keeps working until the backfill runs.
  bootstrap exposes $blindIndex as null when no pepper is configured.

Also: AdminCaptain/getCaptainDetailsById.php selected driver.education, a
column absent from this schema. The PDOException was uncaught, so the client
received an empty body with HTTP 200 — the "non-JSON response" seen when
opening a captain. It now omits the column, catches the error, reports it as
JSON, and requires an admin role.

Console: opening any sidebar section refetches its data instead of showing
what was loaded when the console started.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-25 15:16:09 +03:00
Hamza-Ayed 1e785061ec Fix decryptData null type error and live analytics overflow 2026-07-23 20:42:48 +03:00
Hamza-Ayed b9efba3787 Update: 2026-07-22 18:32:11 2026-07-22 18:32:11 +03:00
Hamza-Ayed 55fbe22f8e Update: 2026-07-22 18:23:10 2026-07-22 18:23:10 +03:00
Hamza-Ayed 085b180bdb feat: implement secure OTP-based payout workflow with dynamic fee calculation and improved authentication checks 2026-07-19 01:51:39 +03:00
Hamza-Ayed ae723a75f6 Update: 2026-06-30 21:59:55 2026-06-30 21:59:55 +03:00
Hamza-Ayed 1dc5ccc11d Restore legacy decrypt fallback for prepended random IV in EncryptionHelper 2026-06-30 21:54:31 +03:00
Hamza-Ayed 2ee3a14c6d Fix OTP verification success response payload and restore deterministic encryptData 2026-06-24 23:11:24 +03:00
Hamza-Ayed 7b0283473e Fix timezone bug in request.php using MySQL DATE_ADD and clean up EncryptionHelper 2026-06-24 23:03:45 +03:00
Hamza-Ayed 12dfb25629 Update: 2026-06-24 22:56:39 2026-06-24 22:56:39 +03:00
Hamza-Ayed 0ceb67ee56 fix(security): fix SQL injection in updatePaymetToPaid, OTP random_int, static IV encryption, storage mismatch 2026-06-17 06:31:13 +03:00
Hamza-Ayed d8901e1a87 first commit 2026-06-09 08:40:31 +03:00