<?php
|
namespace JVBase\rest\routes;
|
|
use JVBase\rest\RestRouteManager;
|
use WP_REST_Request;
|
use WP_REST_Response;
|
use Exception;
|
|
if (!defined('ABSPATH')) {
|
exit; // Exit if accessed directly
|
}
|
|
class IntegrationsRoutes extends RestRouteManager
|
{
|
|
/**
|
* Register REST routes
|
*/
|
public function registerRoutes(): void
|
{
|
register_rest_route($this->namespace, '/integrations', [
|
'methods' => 'POST',
|
'callback' => [$this, 'handleAction'],
|
'permission_callback' => [$this, 'checkPermission'],
|
'args' => [
|
'service' => [
|
'required' => true,
|
'type' => 'string',
|
'enum' => JVB()->getAvailableServices()
|
],
|
'action' => [
|
'required' => true,
|
'sanitize_callback' => 'sanitize_text_field',
|
],
|
'user_id' => [
|
'required' => false,
|
'sanitize_callback' => 'absint',
|
],
|
'context' => [
|
'required' => false,
|
'default' => 'user',
|
'sanitize_callback' => 'sanitize_text_field',
|
'validate_callback' => function($param) {
|
return in_array($param, ['admin', 'user']);
|
}
|
],
|
'data' => [
|
'required' => false,
|
'default' => [],
|
]
|
]
|
]);
|
|
// register_rest_route($this->namespace, '/oauth/callback', [
|
// 'methods' => 'GET',
|
// 'callback' => [$this, 'handleOAuthCallback'],
|
// 'permission_callback' => '__return_true', // External service callback
|
// 'args' => [
|
// 'service' => [
|
// 'required' => true,
|
// 'sanitize_callback' => 'sanitize_text_field',
|
// ],
|
// 'code' => [
|
// 'required' => false,
|
// 'sanitize_callback' => 'sanitize_text_field',
|
// ],
|
// 'state' => [
|
// 'required' => false,
|
// 'sanitize_callback' => 'sanitize_text_field',
|
// ],
|
// 'error' => [
|
// 'required' => false,
|
// 'sanitize_callback' => 'sanitize_text_field',
|
// ]
|
// ]
|
// ]);
|
|
// Add OAuth initiation route (for AJAX calls)
|
register_rest_route($this->namespace, '/oauth/connect', [
|
'methods' => 'POST',
|
'callback' => [$this, 'initiateOAuth'],
|
'permission_callback' => [$this, 'checkPermissions'],
|
'args' => [
|
'service' => [
|
'required' => true,
|
'sanitize_callback' => 'sanitize_text_field',
|
],
|
'user_id' => [
|
'required' => false,
|
'sanitize_callback' => 'absint',
|
],
|
'return_url' => [
|
'required' => false,
|
'sanitize_callback' => 'esc_url_raw',
|
]
|
]
|
]);
|
}
|
|
/**
|
* Check permissions based on context
|
*/
|
public function checkPermission(\WP_REST_Request $request): bool
|
{
|
parent::checkPermission($request);
|
$context = $request->get_param('context') ?? 'user';
|
$user_id = $request->get_param('user_id');
|
|
// Admin context requires manage_options
|
if ($context === 'admin') {
|
return current_user_can('manage_options');
|
}
|
|
// User context
|
if (!is_user_logged_in()) {
|
return false;
|
}
|
|
$current_user_id = get_current_user_id();
|
|
// If user_id provided, verify it matches current user
|
// OR current user is admin
|
if ($user_id && $user_id != $current_user_id) {
|
return current_user_can('manage_options');
|
}
|
|
return true;
|
}
|
|
/**
|
* Handle integration actions
|
*/
|
public function handleAction(WP_REST_Request $request): WP_REST_Response
|
{
|
error_log('[IntegrationsRoutes] handleAction request:'.print_r($request->get_params(), true));
|
$service = $request->get_param('service');
|
$action = $request->get_param('action');
|
|
// Get the integration instance
|
$userID = absint($request->get_param('user_id'));
|
if (!$this->userCheck($userID)) {
|
return new WP_REST_Response([
|
'success' => false,
|
'message' => 'Invalid User'
|
]);
|
}
|
|
$theUserID = (user_can($userID, 'manage_options')) ? null : $userID;
|
$integration = JVB()->connect($service, $theUserID);
|
|
if (!$integration) {
|
return new WP_REST_Response([
|
'success' => false,
|
'message' => 'Service not found'
|
], 404);
|
}
|
|
|
$integration->getCredentials();
|
|
// Handle the action
|
try {
|
// Get data parameter - DON'T convert empty array to null
|
$data = $request->get_param('data');
|
|
// Only set to null if it's truly empty or not provided
|
if (!is_array($data) && empty($data)) {
|
$data = null;
|
}
|
|
error_log('[IntegrationsRoutes] Calling processAction with data: ' . print_r($data, true));
|
|
$result = $integration->processAction($action, $data);
|
|
return new WP_REST_Response($result, 200);
|
|
} catch (Exception $e) {
|
return new WP_REST_Response([
|
'success' => false,
|
'message' => $e->getMessage()
|
], 400);
|
}
|
}
|
|
public function initiateOAuth(WP_REST_Request $request): WP_REST_Response
|
{
|
$service = $request->get_param('service');
|
$user_id = $request->get_param('user_id') ?: get_current_user_id();
|
$return_url = $request->get_param('return_url');
|
|
$integration = JVB()->connect($service, $user_id);
|
|
if (!$integration || !$integration->isOAuthService) {
|
return new WP_REST_Response([
|
'success' => false,
|
'message' => 'Invalid OAuth service'
|
], 400);
|
}
|
|
$auth_url = $integration->getOAuthUrl($return_url);
|
|
if ($auth_url) {
|
return new WP_REST_Response([
|
'success' => true,
|
'auth_url' => $auth_url,
|
'popup' => true
|
], 200);
|
}
|
|
return new WP_REST_Response([
|
'success' => false,
|
'message' => 'Failed to generate authorization URL'
|
], 400);
|
}
|
|
/**
|
* Handle OAuth callback from external service
|
*/
|
public function handleOAuthCallback(WP_REST_Request $request): WP_REST_Response
|
{
|
$service = $request->get_param('service');
|
$code = $request->get_param('code');
|
$state = $request->get_param('state');
|
$error = $request->get_param('error');
|
|
error_log('OAuth Callback - Service: ' . $request->get_param('service'));
|
error_log('OAuth Callback - Code: ' . $request->get_param('code'));
|
error_log('OAuth Callback - State: ' . $request->get_param('state'));
|
error_log('OAuth Callback - Error: ' . $request->get_param('error'));
|
|
|
$state_parts = explode('|', $state);
|
$state_key = $state_parts[0] ?? '';
|
$user_id = intval($state_parts[1] ?? 0);
|
$user_id = ($user_id === 0) ? null : $user_id;
|
$return_url = isset($state_parts[2]) ? base64_decode($state_parts[2]) : admin_url('admin.php?page=jvb-integrations');
|
|
|
$state_data = get_transient('oauth_state_' . $state_key);
|
error_log('State Data: '.print_r($state_data, true));
|
if (!$state_data || $state_data['service'] !== $service) {
|
wp_die('Invalid state parameter', 'OAuth Error');
|
}
|
|
// Delete the transient to prevent reuse
|
delete_transient('oauth_state_' . $state_key);
|
error_log('Return URL: '.print_r($return_url, true));
|
// Handle error from OAuth provider
|
if ($error) {
|
$error_description = $request->get_param('error_description') ?? 'Authorization denied';
|
|
wp_redirect(add_query_arg([
|
'page' => 'jvb-integrations',
|
'error' => 'OAuth authorization denied: ' . $error_description
|
], $return_url));
|
exit;
|
}
|
|
// Get integration instance
|
error_log('User ID: '.print_r($user_id, true));
|
error_log('Service: '.print_r($service, true));
|
$integration = JVB()->connect($service, $user_id);
|
|
if (!$integration) {
|
wp_die('Invalid service: ' . esc_html($service), 'OAuth Error');
|
}
|
|
|
// Exchange code for tokens
|
$result = $integration->handleOAuthCode($code, $state);
|
|
// Redirect back with result
|
if ($result['success']) {
|
wp_redirect(add_query_arg([
|
'page' => 'jvb-integrations',
|
'success' => 'Successfully connected to ' . $integration->title
|
], $return_url));
|
} else {
|
// Handle failure
|
$error_message = $result['message'] ?? 'Failed to complete OAuth authorization';
|
|
wp_redirect(add_query_arg([
|
'page' => 'jvb-integrations',
|
'error' => $error_message
|
], $return_url));
|
}
|
exit;
|
}
|
}
|