'string', 'sanitize_callback' => [self::class, 'sanitize_url'], 'default' => Defaults::merchant_api_base_url(), ]); register_setting('agenized_chat_widget', Options::OPT_WIDGET_API_BASE_URL, [ 'type' => 'string', 'sanitize_callback' => [self::class, 'sanitize_url'], 'default' => Defaults::widget_api_base_url(), ]); register_setting('agenized_chat_widget', Options::OPT_PORTAL_BASE_URL, [ 'type' => 'string', 'sanitize_callback' => [self::class, 'sanitize_url'], 'default' => Defaults::merchant_portal_base_url(), ]); register_setting('agenized_chat_widget', Options::OPT_WIDGET_SCRIPT_URL, [ 'type' => 'string', 'sanitize_callback' => [self::class, 'sanitize_url'], 'default' => Defaults::widget_script_url(), ]); register_setting('agenized_chat_widget', Options::OPT_OAUTH_CLIENT_ID, [ 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => Defaults::oauth_client_id(), ]); register_setting('agenized_chat_widget', Options::OPT_OAUTH_CLIENT_SECRET, [ 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '', ]); register_setting('agenized_chat_widget', Options::OPT_OAUTH_SCOPES, [ 'type' => 'string', 'sanitize_callback' => [self::class, 'sanitize_scopes'], 'default' => Defaults::oauth_scopes(), ]); register_setting('agenized_chat_widget', Options::OPT_CHANNEL_ID, [ 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '', ]); } public static function sanitize_url(string $val): string { $val = trim($val); if ($val === '') { return ''; } $val = esc_url_raw($val); return rtrim($val, '/'); } public static function sanitize_scopes(string $val): string { $val = sanitize_text_field($val); $parts = preg_split('/\s+/', $val, -1, PREG_SPLIT_NO_EMPTY); $out = []; foreach ($parts as $part) { $part = sanitize_text_field((string) $part); if ($part === '') { continue; } // Allow typical OAuth scope tokens only (e.g. read:conversations). if (!preg_match('/^[a-z][a-z0-9:_\/.\-]*$/i', $part)) { continue; } $out[] = $part; } return implode(' ', $out); } public static function render(): void { if (!current_user_can('manage_options')) { return; } // Handle OAuth callback if present. $oauth_result = OAuth::handle_callback_if_present(); // Handle actions. $notice = null; if (isset($_POST['agenized_chat_widget_action'])) { check_admin_referer('agenized_chat_widget_actions'); $action = sanitize_text_field(wp_unslash($_POST['agenized_chat_widget_action'])); if ($action === 'disconnect') { OAuth::disconnect(); $notice = ['type' => 'success', 'text' => 'Disconnected.']; } if ($action === 'save_channel') { $channel_id = isset($_POST['agenized_chat_widget_channel_id']) ? sanitize_text_field(wp_unslash($_POST['agenized_chat_widget_channel_id'])) : ''; if ($channel_id === '') { Options::delete(Options::OPT_CHANNEL_ID); Options::delete(Options::OPT_CHANNEL_PUBLIC_KEY); $notice = ['type' => 'success', 'text' => 'Channel selection cleared.']; } else { $ch = AgenizedApi::get_channel($channel_id); if (!$ch['ok']) { $notice = ['type' => 'error', 'text' => 'Failed to fetch channel: ' . ($ch['message'] ?? '')]; } else { $channel = $ch['channel'] ?? []; $public_key = is_array($channel) && isset($channel['public_key']) ? (string) $channel['public_key'] : ''; if ($public_key === '') { $notice = ['type' => 'error', 'text' => 'Channel has no public_key. Make sure it is a chat_widget channel.']; } else { Options::update_string(Options::OPT_CHANNEL_ID, $channel_id); Options::update_string(Options::OPT_CHANNEL_PUBLIC_KEY, $public_key); $notice = ['type' => 'success', 'text' => 'Channel saved.']; } } } } } if (is_array($oauth_result)) { $notice = ['type' => ($oauth_result['ok'] ? 'success' : 'error'), 'text' => $oauth_result['message']]; } $is_connected = OAuth::is_connected(); $channels = null; if ($is_connected) { $list = AgenizedApi::list_chat_widget_channels(); if ($list['ok']) { $channels = $list['channels']; } else { $notice = $notice ?: ['type' => 'error', 'text' => 'Failed to load channels: ' . ($list['message'] ?? '')]; } } $selected_channel_id = Options::get_string(Options::OPT_CHANNEL_ID, ''); $selected_public_key = Options::get_string(Options::OPT_CHANNEL_PUBLIC_KEY, ''); $connect_url = OAuth::begin_auth_url(); ?>
Status: Connected
Status: Not connected
Please set the OAuth Client ID and save settings first.
Redirect URI to whitelist on the OAuth client:
Connect via OAuth first.