Twofactor authentication and strong password
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user