encryption_key = $this->getEncryptionKey(); } public static function getInstance(): CredentialsManager { if (self::$instance === null) { self::$instance = new self(); } return self::$instance; } /** * Store encrypted credentials */ 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); } /** * Retrieve and decrypt credentials */ 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)) { 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) : []; } /** * Delete credentials */ public function deleteCredentials(string $service, ?int $userID = null): bool { if ($userID) { return $this->deleteUserCredentials($service, $userID); } return delete_option($this->option_prefix . $service); } public function deleteUserCredentials(string $service, int $userID): bool { return delete_user_meta($userID, $this->user_meta_prefix . $service); } /** * Check if credentials exist */ 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); } /** * Get or create encryption key */ private function getEncryptionKey(): string { $key = get_option('jvb_encryption_key'); if (!$key) { $key = base64_encode(random_bytes(32)); update_option('jvb_encryption_key', $key); } return base64_decode($key); } /** * Encrypt data */ private function encrypt(string $data): string { $iv = random_bytes(16); $encrypted = openssl_encrypt($data, 'AES-256-CBC', $this->encryption_key, 0, $iv); return base64_encode($iv . $encrypted); } /** * Decrypt data */ private function decrypt(string $data): ?string { $data = base64_decode($data); $iv = substr($data, 0, 16); $encrypted = substr($data, 16); return openssl_decrypt($encrypted, 'AES-256-CBC', $this->encryption_key, 0, $iv); } /** * Get all users with credentials for a service */ 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'); } }