// ========================================================================= // MYCODEBLOCK - HEADLESS REACT API INTEGRATION // ========================================================================= // 1. ENABLE STRICT CORS (Allows store.mycodeblock.com to talk to account.mycodeblock.com) add_action('init', function() { $allowed_origins = [ 'https://store.mycodeblock.com', 'http://localhost:5173', // For local Vite development 'http://localhost:5002' // For local Vite production preview ]; if (isset($_SERVER['HTTP_ORIGIN']) && in_array($_SERVER['HTTP_ORIGIN'], $allowed_origins)) { header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']); header("Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE"); header("Access-Control-Allow-Credentials: true"); header("Access-Control-Allow-Headers: Authorization, Content-Type, X-Requested-With"); } if ('OPTIONS' == $_SERVER['REQUEST_METHOD']) { status_header(200); exit(); } }); define('MCB_JWT_SECRET', defined('AUTH_KEY') ? AUTH_KEY : 'mycodeblock-super-secret-key-2024!'); // 2. JWT GENERATOR function mcb_generate_jwt($user_id) { $header = json_encode(['typ' => 'JWT', 'alg' => 'HS256']); $payload = json_encode(['user_id' => $user_id, 'exp' => time() + (86400 * 7)]); // 7 days valid $base64UrlHeader = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($header)); $base64UrlPayload = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($payload)); $signature = hash_hmac('sha256', $base64UrlHeader . "." . $base64UrlPayload, MCB_JWT_SECRET, true); $base64UrlSignature = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($signature)); return $base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature; } // 3. REGISTER API ROUTES add_action('rest_api_init', function () { register_rest_route('mcb/v1', '/auth/login', [ 'methods' => 'POST', 'callback' => 'mcb_api_login', 'permission_callback' => '__return_true' ]); register_rest_route('mcb/v1', '/auth/register', [ 'methods' => 'POST', 'callback' => 'mcb_api_register', 'permission_callback' => '__return_true' ]); register_rest_route('mcb/v1', '/users/me', [ 'methods' => 'GET', 'callback' => 'mcb_api_get_me', 'permission_callback' => '__return_true' ]); }); // 4. API CALLBACK FUNCTIONS function mcb_api_login($request) { $params = $request->get_json_params(); $user = wp_authenticate($params['email'], $params['password']); if (is_wp_error($user)) { return new WP_REST_Response(['detail' => 'Invalid email or password.'], 401); } return new WP_REST_Response([ 'access_token' => mcb_generate_jwt($user->ID), 'token_type' => 'bearer' ], 200); } function mcb_api_register($request) { $params = $request->get_json_params(); if (email_exists($params['email'])) { return new WP_REST_Response(['detail' => 'Email is already registered.'], 400); } $user_id = wp_insert_user([ 'user_login' => $params['email'], 'user_pass' => $params['password'], 'user_email' => $params['email'], 'first_name' => sanitize_text_field($params['first_name']), 'last_name' => sanitize_text_field($params['last_name']), 'role' => 'customer' ]); if (is_wp_error($user_id)) { return new WP_REST_Response(['detail' => $user_id->get_error_message()], 400); } return new WP_REST_Response([ 'access_token' => mcb_generate_jwt($user_id), 'token_type' => 'bearer' ], 200); } function mcb_api_get_me($request) { $auth_header = $request->get_header('authorization'); if (!$auth_header) return new WP_REST_Response(['detail' => 'No token provided'], 401); $token = str_replace('Bearer ', '', $auth_header); $parts = explode('.', $token); if (count($parts) !== 3) return new WP_REST_Response(['detail' => 'Invalid token format'], 401); $payload = json_decode(base64_decode(str_replace(['-', '_'], ['+', '/'], $parts[1])), true); if (!$payload || $payload['exp'] < time()) return new WP_REST_Response(['detail' => 'Token expired'], 401); $user = get_userdata($payload['user_id']); if (!$user) return new WP_REST_Response(['detail' => 'User not found'], 404); return new WP_REST_Response([ 'id' => $user->ID, 'email' => $user->user_email, 'first_name' => $user->first_name, 'last_name' => $user->last_name, 'name' => $user->first_name . ' ' . $user->last_name, 'role' => in_array('administrator', $user->roles) ? 'admin' : 'vip' ], 200); } MyCodeBlock.store