first commit
This commit is contained in:
155
includes/Token.php
Normal file
155
includes/Token.php
Normal file
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
namespace Formipay;
|
||||
use Exception;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
class Token {
|
||||
|
||||
private $table_name;
|
||||
|
||||
public function __construct() {
|
||||
|
||||
global $wpdb;
|
||||
$this->table_name = $wpdb->prefix . 'formipay_tokens';
|
||||
|
||||
add_action( 'init', [$this, 'create_db'] );
|
||||
// Setup cleanup hook
|
||||
add_action( 'formipay_daily_cleanup', [$this, 'cleanup_expired_tokens']);
|
||||
|
||||
if (!wp_next_scheduled('formipay_daily_cleanup')) {
|
||||
wp_schedule_event(time(), 'daily', 'formipay_daily_cleanup');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function create_db() {
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix . 'formipay_tokens';
|
||||
|
||||
$sql = "CREATE TABLE $table_name (
|
||||
token CHAR(64) NOT NULL,
|
||||
form_id BIGINT UNSIGNED NOT NULL,
|
||||
order_id BIGINT UNSIGNED NOT NULL,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
expires_at DATETIME NOT NULL,
|
||||
used TINYINT(1) NOT NULL DEFAULT 0,
|
||||
use_count INT NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (token),
|
||||
KEY expires_at_idx (expires_at),
|
||||
KEY order_id_idx (order_id)
|
||||
) {$wpdb->get_charset_collate()};";
|
||||
|
||||
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
|
||||
dbDelta($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate cryptographically secure token
|
||||
*
|
||||
* @param int $order_id
|
||||
* @param int $form_id
|
||||
* @param int $expires_in Seconds until expiration (default: 900 = 15 mins)
|
||||
* @return string
|
||||
*/
|
||||
public function generate(int $order_id, int $form_id, int $expires_in = 900): string {
|
||||
global $wpdb;
|
||||
|
||||
$token = bin2hex(random_bytes(32)); // 64-character token
|
||||
$expires_at = formipay_date('Y-m-d H:i:s', time() + $expires_in);
|
||||
|
||||
$wpdb->insert($this->table_name, [
|
||||
'token' => $token,
|
||||
'form_id' => $form_id,
|
||||
'order_id' => $order_id,
|
||||
'expires_at' => $expires_at,
|
||||
'created_at' => formipay_date('Y-m-d H:i:s')
|
||||
]);
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate token and retrieve order data
|
||||
*
|
||||
* @param string $token
|
||||
* @return array|false
|
||||
*/
|
||||
public function validate(string $token) {
|
||||
global $wpdb;
|
||||
|
||||
// Validate token format
|
||||
if (!preg_match('/^[a-f0-9]{64}$/', $token)) return false;
|
||||
|
||||
$query = $wpdb->prepare(
|
||||
"SELECT form_id, order_id
|
||||
FROM {$this->table_name}
|
||||
WHERE token = %s
|
||||
AND expires_at > NOW()
|
||||
AND used = 0",
|
||||
$token
|
||||
);
|
||||
|
||||
return $wpdb->get_row($query, ARRAY_A);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark token as used
|
||||
*
|
||||
* @param string $token
|
||||
* @return bool
|
||||
*/
|
||||
public function mark_used(string $token): bool {
|
||||
global $wpdb;
|
||||
return (bool) $wpdb->update(
|
||||
$this->table_name,
|
||||
['used' => 1],
|
||||
['token' => $token]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup expired tokens
|
||||
*/
|
||||
public function cleanup_expired_tokens() {
|
||||
global $wpdb;
|
||||
$wpdb->query("DELETE FROM {$this->table_name} WHERE expires_at < NOW()");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get token usage count
|
||||
*
|
||||
* @param string $token
|
||||
* @return int
|
||||
*/
|
||||
public function get_usage_count(string $token): int {
|
||||
global $wpdb;
|
||||
return (int) $wpdb->get_var($wpdb->prepare(
|
||||
"SELECT use_count FROM {$this->table_name} WHERE token = %s",
|
||||
$token
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment token usage
|
||||
*
|
||||
* @param string $token
|
||||
* @param int $max_uses
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function increment_usage(string $token, int $max_uses = 5): bool {
|
||||
global $wpdb;
|
||||
|
||||
$current_count = $this->get_usage_count($token);
|
||||
if ($current_count >= $max_uses) {
|
||||
throw new Exception('Token usage limit reached');
|
||||
}
|
||||
|
||||
return (bool) $wpdb->update(
|
||||
$this->table_name,
|
||||
['use_count' => $current_count + 1],
|
||||
['token' => $token]
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user