96 lines
2.6 KiB
PHP
96 lines
2.6 KiB
PHP
<?php
|
|
defined('BASEPATH') OR exit('No direct script access allowed');
|
|
|
|
/**
|
|
* User OTP Model
|
|
* Manages email-based one-time passwords for two-factor authentication
|
|
*/
|
|
class UserOtp_model extends MY_Model
|
|
{
|
|
protected $tablename = "user_otp_codes";
|
|
|
|
/**
|
|
* Generate and store a new OTP code for a user
|
|
* @param int $userId User ID
|
|
* @param int $expiryMinutes Expiry time in minutes (default 10)
|
|
* @return string The generated OTP code
|
|
*/
|
|
public function generateOTP($userId, $expiryMinutes = 10)
|
|
{
|
|
// Generate 6-digit OTP
|
|
$otpCode = str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT);
|
|
|
|
// Calculate expiry time
|
|
$expiresAt = date('Y-m-d H:i:s', strtotime("+{$expiryMinutes} minutes"));
|
|
|
|
// Store OTP in database
|
|
$data = [
|
|
'user_id' => $userId,
|
|
'otp_code' => $otpCode,
|
|
'expires_at' => $expiresAt,
|
|
'used' => 'F'
|
|
];
|
|
|
|
// Use direct insert since this table doesn't have audit columns
|
|
$this->db->insert($this->tablename, $data);
|
|
|
|
return $otpCode;
|
|
}
|
|
|
|
/**
|
|
* Verify an OTP code for a user
|
|
* @param int $userId User ID
|
|
* @param string $otpCode The OTP code to verify
|
|
* @return bool True if valid, false otherwise
|
|
*/
|
|
public function verifyOTP($userId, $otpCode)
|
|
{
|
|
// Get the most recent unused OTP for this user
|
|
$sql = "
|
|
SELECT * FROM {$this->tablename}
|
|
WHERE user_id = ?
|
|
AND otp_code = ?
|
|
AND used = 'F'
|
|
AND expires_at > NOW()
|
|
ORDER BY created_at DESC
|
|
LIMIT 1
|
|
";
|
|
|
|
$query = $this->db->query($sql, [$userId, $otpCode]);
|
|
|
|
if ($query->num_rows() == 0) {
|
|
return false;
|
|
}
|
|
|
|
$result = $query->row();
|
|
|
|
// Mark OTP as used (use direct update since this table doesn't have audit columns)
|
|
$this->db->where('id', $result->id);
|
|
$this->db->update($this->tablename, ['used' => 'T']);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Clean up expired OTP codes
|
|
* @return int Number of deleted records
|
|
*/
|
|
public function cleanupExpiredOTPs()
|
|
{
|
|
$this->sql = "DELETE FROM {$this->tablename} WHERE expires_at < NOW() OR used = 'T'";
|
|
$this->db->query($this->sql);
|
|
|
|
return $this->db->affected_rows();
|
|
}
|
|
|
|
/**
|
|
* Delete all OTP codes for a user
|
|
* @param int $userId User ID
|
|
*/
|
|
public function deleteUserOTPs($userId)
|
|
{
|
|
$this->db->where('user_id', $userId);
|
|
$this->db->delete($this->tablename);
|
|
}
|
|
}
|