bluesky-Connector/includes/bluesky-auth.php

214 lines
8.4 KiB
PHP
Raw Permalink Normal View History

2024-11-21 09:05:37 +00:00
<?php
class Bluesky_Auth {
private $identifier;
private $password;
private $api_domain;
public function __construct($identifier, $password) {
$this->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
));
2024-11-21 09:05:37 +00:00
}
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
2024-11-21 09:05:37 +00:00
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');
}
2024-11-21 09:05:37 +00:00
}
$token_url = $this->api_domain . 'xrpc/com.atproto.server.createSession';
$this->log_debug('Attempting connection', array('url' => $token_url));
2024-11-21 09:05:37 +00:00
$headers = array(
'Content-Type' => 'application/json',
);
$body = wp_json_encode(array(
2024-11-21 09:05:37 +00:00
'identifier' => $this->identifier,
'password' => $this->password,
));
$this->log_debug('Request prepared', array('body' => str_replace($this->password, '[REDACTED]', $body)));
2024-11-21 09:05:37 +00:00
$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,
2024-11-21 09:05:37 +00:00
));
if (is_wp_error($response)) {
$error_message = $response->get_error_message();
$this->log_debug('Auth Error', array('error' => $error_message));
2024-11-21 09:05:37 +00:00
return array('error' => $error_message);
}
// Log response details
2024-11-21 09:05:37 +00:00
$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
));
2024-11-21 09:05:37 +00:00
$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));
2024-11-21 09:05:37 +00:00
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']));
2024-11-21 09:05:37 +00:00
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));
2024-11-21 09:05:37 +00:00
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));
2024-11-21 09:05:37 +00:00
$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));
2024-11-21 09:05:37 +00:00
return array('error' => $error_message);
}
$data = json_decode(wp_remote_retrieve_body($response), true);
2024-11-21 09:05:37 +00:00
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');
2024-11-21 09:05:37 +00:00
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));
2024-11-21 09:05:37 +00:00
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);
}
}
2024-11-21 09:05:37 +00:00
}