create($data); } /** * Update an existing contact with encryption */ public function updateSecure(int $id, array $data) { if (isset($data['phone'])) { $data['phone_hash'] = Security::blindIndex($data['phone']); $data['phone'] = Security::encrypt($data['phone']); } if (isset($data['email'])) { $data['email_hash'] = Security::blindIndex($data['email']); $data['email'] = Security::encrypt($data['email']); } if (isset($data['notes'])) { $data['notes'] = Security::encrypt($data['notes']); } return $this->update($id, $data); } /** * Find a contact by decrypted phone number within a company */ public function findByPhone(int $companyId, string $phone) { $hash = Security::blindIndex($phone); $contact = $this->db->query( "SELECT * FROM {$this->table} WHERE company_id = ? AND phone_hash = ? LIMIT 1", [$companyId, $hash] )->fetch(); return $this->decryptContact($contact); } /** * Retrieve all contacts for a company */ public function findAllByCompany(int $companyId) { $contacts = $this->db->query( "SELECT * FROM {$this->table} WHERE company_id = ? ORDER BY id DESC", [$companyId] )->fetchAll(); foreach ($contacts as &$contact) { $contact = $this->decryptContact($contact); } return $contacts; } /** * Helper to decrypt sensitive fields */ private function decryptContact($contact) { if ($contact) { $contact['phone'] = !empty($contact['phone']) ? Security::decrypt($contact['phone']) : null; $contact['email'] = !empty($contact['email']) ? Security::decrypt($contact['email']) : null; $contact['notes'] = !empty($contact['notes']) ? Security::decrypt($contact['notes']) : null; // Remove hashes from response unset($contact['phone_hash'], $contact['email_hash']); } return $contact; } }