| | |
| | | <?php |
| | | namespace JVBase\integrations; |
| | | |
| | | use JVBase\managers\CustomTable; |
| | | |
| | | if (!defined('ABSPATH')) { |
| | | exit; |
| | | } |
| | |
| | | { |
| | | private static ?CredentialsManager $instance = null; |
| | | private string $encryption_key; |
| | | private string $option_prefix = 'jvb_integration_'; |
| | | private string $user_meta_prefix = 'jvb_integration_'; |
| | | private CustomTable $table; |
| | | |
| | | private function __construct() |
| | | { |
| | | $this->encryption_key = $this->getEncryptionKey(); |
| | | $this->getEncryptionKey(); |
| | | $this->defineTable(); |
| | | } |
| | | |
| | | protected function defineTable():void |
| | | { |
| | | $table = CustomTable::for('integrations'); |
| | | $table->setColumns([ |
| | | 'id' => 'bigint(20) unsigned NOT NULL AUTO_INCREMENT', |
| | | 'user_id' => $table->getUserIDType().' NOT NULL', |
| | | 'integration' => "ENUM('bluesky','cloudflare','facebook','google-maps','gmb','helcim','instagram','postmark','square','umami') NOT NULL", |
| | | 'credentials' => 'varchar(255) DEFAULT NULL', |
| | | 'created_at' => 'datetime DEFAULT CURRENT_TIMESTAMP', |
| | | 'updated_at' => 'datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP' |
| | | ]); |
| | | |
| | | $table->setKeys([ |
| | | ['key' => 'PRIMARY', 'value' => '(`id`)'], |
| | | ['key' => 'UNIQUE', 'value' => '`user_integration` (`user_id`, `integration`)'], |
| | | '`user` (`user_id`)', |
| | | ]); |
| | | |
| | | $base = BASE; |
| | | $table->setConstraints([ |
| | | "CONSTRAINT `{$base}integrations_user` FOREIGN KEY (`user_id`) |
| | | REFERENCES `{$table->getUserTable()}` (`ID`) ON DELETE CASCADE" |
| | | ]); |
| | | $table->defineTable(); |
| | | $this->table = $table; |
| | | } |
| | | |
| | | public static function getInstance(): CredentialsManager |
| | |
| | | */ |
| | | public function storeCredentials(string $service, array $credentials, ?int $userID = null): bool |
| | | { |
| | | $credentials['updated_at'] = time(); |
| | | if ($userID) { |
| | | return $this->storeUserCredentials($service, $credentials, $userID); |
| | | } |
| | | $encrypted_data = $this->encrypt(json_encode($credentials)); |
| | | return update_option($this->option_prefix . $service, $encrypted_data); |
| | | } |
| | | |
| | | public function storeUserCredentials(string $service, array $credentials, int $userID): bool |
| | | { |
| | | $encrypted_data = $this->encrypt(json_encode($credentials)); |
| | | return update_user_meta($userID, $this->user_meta_prefix . $service, $encrypted_data); |
| | | $find = $this->findBy($service, $userID); |
| | | $update = [ |
| | | 'credentials' => $this->encrypt(json_encode($credentials)) |
| | | ]; |
| | | return (bool)$this->table->findOrCreate($find, $update); |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | public function getCredentials(string $service, ?int $userID = null): array |
| | | { |
| | | if ($userID) { |
| | | return $this->getUserCredentials($service, $userID); |
| | | } |
| | | |
| | | $encrypted_data = get_option($this->option_prefix . $service, ''); |
| | | |
| | | if (empty($encrypted_data)) { |
| | | $find = $this->findBy($service, $userID); |
| | | $credentials = $this->table->pluck('credentials', $find); |
| | | if (empty($credentials)) { |
| | | return []; |
| | | } |
| | | |
| | | $decrypted_data = $this->decrypt($encrypted_data); |
| | | return $decrypted_data ? json_decode($decrypted_data, true) : []; |
| | | } |
| | | |
| | | public function getUserCredentials(string $service, int $userID): array |
| | | { |
| | | $encrypted_data = get_user_meta($userID, $this->user_meta_prefix . $service, true); |
| | | |
| | | if (empty($encrypted_data)) { |
| | | return []; |
| | | } |
| | | |
| | | $decrypted_data = $this->decrypt($encrypted_data); |
| | | return $decrypted_data ? json_decode($decrypted_data, true) : []; |
| | | $decrypted_data = $this->decrypt($credentials[0]); |
| | | return empty($decrypted_data) ? [] : json_decode($decrypted_data, true); |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | public function deleteCredentials(string $service, ?int $userID = null): bool |
| | | { |
| | | |
| | | if ($userID) { |
| | | return $this->deleteUserCredentials($service, $userID); |
| | | } |
| | | return delete_option($this->option_prefix . $service); |
| | | $find = $this->findBy($service, $userID); |
| | | return $this->table->delete($find); |
| | | } |
| | | |
| | | public function deleteUserCredentials(string $service, int $userID): bool |
| | | protected function findBy(string $service, ?int $userID = null):array |
| | | { |
| | | return delete_user_meta($userID, $this->user_meta_prefix . $service); |
| | | return [ |
| | | 'user_id' => is_null($userID) ? 0 : $userID, |
| | | 'integration'=> $service |
| | | ]; |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | public function hasCredentials(string $service, ?int $userID = null): bool |
| | | { |
| | | if ($userID) { |
| | | return $this->hasUserCredentials($service, $userID); |
| | | } |
| | | return !empty(get_option($this->option_prefix . $service, '')); |
| | | } |
| | | |
| | | public function hasUserCredentials(string $service, int $userID): bool |
| | | { |
| | | $encrypted_data = get_user_meta($userID, $this->user_meta_prefix . $service, true); |
| | | return !empty($encrypted_data); |
| | | return !empty($this->getCredentials($service, $userID)); |
| | | } |
| | | |
| | | /** |
| | | * Get or create encryption key |
| | | */ |
| | | private function getEncryptionKey(): string |
| | | private function getEncryptionKey():void |
| | | { |
| | | $key = get_option('jvb_encryption_key'); |
| | | |
| | | if (!$key) { |
| | | $key = base64_encode(random_bytes(32)); |
| | | update_option('jvb_encryption_key', $key); |
| | | } |
| | | |
| | | return base64_decode($key); |
| | | $this->encryption_key = JVB_KEY; |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | public function getUsersWithCredentials(string $service): array |
| | | { |
| | | global $wpdb; |
| | | |
| | | $meta_key = $this->user_meta_prefix . $service; |
| | | $results = $wpdb->get_results($wpdb->prepare( |
| | | "SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key = %s", |
| | | $meta_key |
| | | )); |
| | | |
| | | return wp_list_pluck($results, 'user_id'); |
| | | return $this->table->pluck('user_id', ['integration' => $service]); |
| | | } |
| | | } |