'POST', 'callback' => array(__CLASS__, 'activate_plugin'), 'permission_callback' => array(__CLASS__, 'check_activate_permission'), )); register_rest_route('presslearn/v1', '/status', array( 'methods' => 'GET', 'callback' => array(__CLASS__, 'check_status'), 'permission_callback' => array(__CLASS__, 'check_permission'), )); register_rest_route('presslearn/v1', '/banner', array( 'methods' => 'GET', 'callback' => array(__CLASS__, 'get_banner'), 'permission_callback' => array(__CLASS__, 'check_permission'), )); } public static function check_permission($request) { if (current_user_can('manage_options')) { return true; } $site_host = wp_parse_url(site_url(), PHP_URL_HOST); $origin = get_http_origin(); $origin_host = $origin ? wp_parse_url($origin, PHP_URL_HOST) : ''; if ($origin_host && $origin_host === $site_host) { return true; } $current_host = isset($_SERVER['HTTP_HOST']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST'])) : ''; if ($current_host === $site_host) { return true; } return false; } public static function check_admin_permission($request) { return self::check_permission($request); } public static function check_activate_permission($request) { $origin = get_http_origin(); $allowed_domains = array('qa.ledu.kr', 'api.qa.ledu.kr', 'presslearn.co.kr'); if (!empty($origin)) { $origin_host = wp_parse_url($origin, PHP_URL_HOST); if ($origin_host && in_array($origin_host, $allowed_domains, true)) { return true; } } return false; } public static function activate_plugin($request) { $key = $request->get_param('key'); if (empty($key)) { return new WP_Error( 'invalid_key', '유효하지 않은 키입니다.', array('status' => 400) ); } $is_valid = self::validate_key($key); if (!$is_valid) { return new WP_Error( 'invalid_key', '키가 유효하지 않습니다.', array('status' => 400) ); } update_option('presslearn_plugin_key', $key); self::perform_activation_tasks($key); return array( 'success' => true, 'message' => 'Successfully activated.', 'timestamp' => current_time('timestamp') ); } public static function check_status($request) { $key = get_option('presslearn_plugin_key', ''); $is_active = !empty($key); $activated_time = get_option('presslearn_plugin_activated_time', 0); return array( 'is_active' => $is_active, 'activated_time' => $activated_time, 'message' => $is_active ? '플러그인이 활성화되었습니다.' : '플러그인이 비활성화 상태입니다.' ); } private static function validate_key($key) { $start_time = microtime(true); $is_empty = empty($key); $is_short = strlen($key ?: '') < 32; $server_valid = self::mock_validate_with_presslearn_server($key ?: ''); $is_valid = !$is_empty && !$is_short && $server_valid; $min_execution_time = 0.1; $elapsed = microtime(true) - $start_time; if ($elapsed < $min_execution_time) { usleep(($min_execution_time - $elapsed) * 1000000); } return $is_valid; } private static function mock_validate_with_presslearn_server($key) { return true; } private static function perform_activation_tasks($key) { update_option('presslearn_plugin_activated_time', time()); self::log_activation_event($key); } private static function log_activation_event($key) { $masked_key = substr($key, 0, 4) . '...' . substr($key, -4); $remote_addr = isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'])) : ''; $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : ''; $log_data = array( 'time' => current_time('mysql'), 'key' => $masked_key, 'ip' => $remote_addr, 'user_agent' => $user_agent ); $activation_logs = get_option('presslearn_activation_logs', array()); $activation_logs[] = $log_data; if (count($activation_logs) > 10) { $activation_logs = array_slice($activation_logs, -10); } update_option('presslearn_activation_logs', $activation_logs); } public static function get_banner($request) { $supabase_url = 'https://odkponsvhcfajgoetubm.supabase.co'; $supabase_key = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im9ka3BvbnN2aGNmYWpnb2V0dWJtIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDU4OTIxMjMsImV4cCI6MjA2MTQ2ODEyM30.yR08gaJeSy4kagAT3PZl1i8uAC6aEEnZSfQ4sSbqOYk'; $response = wp_remote_get( $supabase_url . '/rest/v1/banner_table?id=eq.1', array( 'headers' => array( 'apikey' => $supabase_key, 'Authorization' => 'Bearer ' . $supabase_key, 'Content-Type' => 'application/json' ) ) ); if (is_wp_error($response)) { return new WP_Error( 'banner_fetch_error', '배너 데이터를 가져오는데 실패했습니다.', array('status' => 500) ); } $body = wp_remote_retrieve_body($response); $data = json_decode($body, true); if (empty($data)) { return new WP_Error( 'no_banner', '배너 데이터가 없습니다.', array('status' => 404) ); } return array( 'success' => true, 'data' => $data[0] ); } } PressLearn_API::init();