identifier = $identifier; $this->password = $password; // Get domain with fallback and force https:// $domain = get_option('bluesky_domain', 'https://bsky.social'); if (empty($domain)) { $domain = 'https://bsky.social'; } if (strpos($domain, 'https://') !== 0) { $domain = 'https://' . $domain; } // Ensure proper URL format $this->api_domain = rtrim($domain, '/') . '/'; // Log configuration details if debugging is enabled $this->log_debug('Auth Configuration', array( 'domain_setting' => get_option('bluesky_domain'), 'processed_domain' => $this->api_domain, 'identifier' => $this->identifier )); } public function get_access_token() { // First check if we have a valid access token $access_token = get_option('bluesky_access_jwt'); $token_created = get_option('bluesky_token_created'); if (!empty($access_token) && $token_created > (time() - 7200)) { $this->log_debug('Using existing valid token'); return $access_token; } // If we have a refresh token, try to use it if ($this->should_refresh_token()) { $refresh_result = $this->refresh_access_token(); if (!isset($refresh_result['error'])) { return $refresh_result; } } // If we got here, we need to create a new session if (empty($this->identifier) || empty($this->password)) { // Try to get credentials from settings if not provided $settings = get_option('bluesky_connector_settings', array()); if (!empty($settings['identifier'])) { $this->identifier = $settings['identifier']; } if (!empty($settings['password'])) { $this->password = $settings['password']; } // If still empty, try individual options if (empty($this->identifier)) { $this->identifier = get_option('bluesky_identifier'); } if (empty($this->password)) { $this->password = get_option('bluesky_password'); } if (empty($this->identifier) || empty($this->password)) { $this->log_debug('Missing credentials', array( 'has_identifier' => !empty($this->identifier), 'has_password' => !empty($this->password) )); return array('error' => 'Missing credentials - please check settings'); } } $token_url = $this->api_domain . 'xrpc/com.atproto.server.createSession'; $this->log_debug('Attempting connection', array('url' => $token_url)); $headers = array( 'Content-Type' => 'application/json', ); $body = wp_json_encode(array( 'identifier' => $this->identifier, 'password' => $this->password, )); $this->log_debug('Request prepared', array('body' => str_replace($this->password, '[REDACTED]', $body))); $wp_version = get_bloginfo('version'); $user_agent = apply_filters('http_headers_useragent', 'WordPress/' . $wp_version . '; ' . get_bloginfo('url')); $response = wp_remote_post($token_url, array( 'headers' => $headers, 'user-agent' => "$user_agent; Bluesky Connector", 'body' => $body, 'timeout' => 30, )); if (is_wp_error($response)) { $error_message = $response->get_error_message(); $this->log_debug('Auth Error', array('error' => $error_message)); return array('error' => $error_message); } // Log response details $status_code = wp_remote_retrieve_response_code($response); $response_body = wp_remote_retrieve_body($response); $this->log_debug('Response received', array( 'status' => $status_code, 'body' => $response_body )); $data = json_decode($response_body, true); if (!empty($data['accessJwt']) && !empty($data['refreshJwt']) && !empty($data['did'])) { // Save credentials in both locations $settings = get_option('bluesky_connector_settings', array()); $settings['identifier'] = $this->identifier; update_option('bluesky_connector_settings', $settings); // Save all necessary tokens and details update_option('bluesky_identifier', sanitize_text_field($this->identifier)); update_option('bluesky_access_jwt', sanitize_text_field($data['accessJwt'])); update_option('bluesky_refresh_jwt', sanitize_text_field($data['refreshJwt'])); update_option('bluesky_did', sanitize_text_field($data['did'])); update_option('bluesky_token_created', time()); // Store password for reauth update_option('bluesky_password', $this->password); $this->log_debug('Authentication successful', array('did' => $data['did'])); return $data['accessJwt']; } $error_message = isset($data['error']) ? $data['error'] : 'Failed to get access token'; if (isset($data['message'])) { $error_message .= ' - ' . $data['message']; } $this->log_debug('Auth Failed', array('error' => $error_message)); return array('error' => $error_message); } private function should_refresh_token() { $token_created = get_option('bluesky_token_created'); $refresh_token = get_option('bluesky_refresh_jwt'); return !empty($refresh_token) && ($token_created < (time() - 82800)); } private function refresh_access_token() { $refresh_token = get_option('bluesky_refresh_jwt'); if (empty($refresh_token)) { return array('error' => 'No refresh token available'); } $refresh_url = $this->api_domain . 'xrpc/com.atproto.server.refreshSession'; $this->log_debug('Token refresh attempt', array('url' => $refresh_url)); $wp_version = get_bloginfo('version'); $user_agent = apply_filters('http_headers_useragent', 'WordPress/' . $wp_version . '; ' . get_bloginfo('url')); $response = wp_remote_post($refresh_url, array( 'headers' => array( 'Authorization' => 'Bearer ' . $refresh_token, 'Content-Type' => 'application/json', ), 'user-agent' => "$user_agent; Bluesky Connector", 'timeout' => 30, )); if (is_wp_error($response)) { $error_message = $response->get_error_message(); $this->log_debug('Token Refresh Error', array('error' => $error_message)); return array('error' => $error_message); } $data = json_decode(wp_remote_retrieve_body($response), true); if (!empty($data['accessJwt']) && !empty($data['refreshJwt'])) { update_option('bluesky_access_jwt', sanitize_text_field($data['accessJwt'])); update_option('bluesky_refresh_jwt', sanitize_text_field($data['refreshJwt'])); update_option('bluesky_token_created', time()); $this->log_debug('Token refresh successful'); return $data['accessJwt']; } $error_message = isset($data['error']) ? $data['error'] : 'Failed to refresh token'; if (isset($data['message'])) { $error_message .= ' - ' . $data['message']; } $this->log_debug('Token Refresh Failed', array('error' => $error_message)); return array('error' => $error_message); } private function log_debug($message, $data = array()) { if (defined('WP_DEBUG') && WP_DEBUG) { $log_message = sprintf( '[Bluesky Connector] %s | Data: %s', $message, wp_json_encode($data, JSON_PRETTY_PRINT) ); if (defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) { error_log($log_message); } do_action('bluesky_connector_debug', $message, $data); } } }