id ) { return; } delete_transient( $key ); echo '

' . esc_html__( 'Koppel met LTN', 'ltn-chatbot' ) . '

'; } public static function allow_dashboard_host( $hosts ) { $hosts[] = wp_parse_url( self::dashboard_url(), PHP_URL_HOST ); return $hosts; } private static function redirect_to_dashboard( $url ) { // Only the configured LTN host is temporarily allowed for these explicit handoffs. add_filter( 'allowed_redirect_hosts', array( __CLASS__, 'allow_dashboard_host' ) ); wp_safe_redirect( $url, 302, 'LTN Chatbot' ); remove_filter( 'allowed_redirect_hosts', array( __CLASS__, 'allow_dashboard_host' ) ); exit; } public static function menu() { add_options_page( 'LTN Chatbot', 'LTN Chatbot', 'manage_options', 'ltn-chatbot', array( __CLASS__, 'settings' ) ); } public static function settings_link( $links ) { array_unshift( $links, '' . esc_html__( 'Instellingen', 'ltn-chatbot' ) . '' ); return $links; } private static function require_admin() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'Je hebt geen toestemming om deze koppeling te beheren.', 'ltn-chatbot' ), '', array( 'response' => 403 ) ); } } public static function settings() { self::require_admin(); $connection = get_option( self::OPTION, array() ); $connected = ! empty( $connection['widget_id'] ); ?>

LTN Chatbot

$verifier, 'site_url' => site_url(), 'home_url' => home_url() ), 10 * MINUTE_IN_SECONDS ); $url = add_query_arg( array( 'site_url' => site_url(), 'home_url' => home_url(), 'state' => $state, 'code_challenge' => $challenge, 'plugin_version' => self::VERSION, 'callback_nonce' => wp_create_nonce( 'ltn_chatbot_callback' ) ), self::dashboard_url() . '/connect/wordpress' ); nocache_headers(); header( 'Referrer-Policy: no-referrer' ); self::redirect_to_dashboard( $url ); } public static function callback() { self::require_admin(); check_admin_referer( 'ltn_chatbot_callback' ); nocache_headers(); header( 'Referrer-Policy: no-referrer' ); $state = isset( $_GET['state'] ) && is_string( $_GET['state'] ) ? sanitize_text_field( wp_unslash( $_GET['state'] ) ) : ''; $code = isset( $_GET['code'] ) && is_string( $_GET['code'] ) ? sanitize_text_field( wp_unslash( $_GET['code'] ) ) : ''; if ( ! preg_match( '/^[a-f0-9]{64}$/D', $state ) || ! preg_match( '/^[A-Za-z0-9_-]{43}$/D', $code ) ) { self::failed(); } $key = 'ltn_chatbot_oauth_' . get_current_user_id() . '_' . hash( 'sha256', $state ); $request = get_transient( $key ); delete_transient( $key ); if ( ! is_array( $request ) || $request['site_url'] !== site_url() || $request['home_url'] !== home_url() ) { self::failed(); } $response = wp_remote_post( self::dashboard_url() . '/api/integrations/wordpress/exchange', array( 'headers' => array( 'Content-Type' => 'application/json', 'Accept' => 'application/json' ), 'body' => wp_json_encode( array( 'code' => $code, 'code_verifier' => $request['verifier'] ) ), 'timeout' => 20, 'redirection' => 0, 'sslverify' => true, 'limit_response_size' => 8192 ) ); if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { self::failed(); } $result = json_decode( wp_remote_retrieve_body( $response ), true ); if ( ! is_array( $result ) || ! isset( $result['widget_id'], $result['dashboard_return_url'] ) || ! is_string( $result['widget_id'] ) || ! is_string( $result['dashboard_return_url'] ) || ! preg_match( '/^wgt_[A-Za-z0-9_-]{32}$/D', $result['widget_id'] ) ) { self::failed(); } $return = wp_parse_url( $result['dashboard_return_url'] ); $base = wp_parse_url( self::dashboard_url() ); if ( ! is_array( $return ) || $return['scheme'] !== $base['scheme'] || $return['host'] !== $base['host'] || ( $return['port'] ?? null ) !== ( $base['port'] ?? null ) || isset( $return['user'] ) || isset( $return['pass'] ) || ! preg_match( '#^/app/[a-f0-9-]{36}/products/[a-f0-9-]{36}/installation$#iD', $return['path'] ?? '' ) ) { self::failed(); } update_option( self::OPTION, array( 'widget_id' => $result['widget_id'] ), false ); self::redirect_to_dashboard( $result['dashboard_return_url'] ); } private static function failed() { wp_die( esc_html__( 'Koppelen is niet gelukt of de koppeling is verlopen. Start opnieuw vanuit Installatie in het LTN-dashboard.', 'ltn-chatbot' ), esc_html__( 'LTN Chatbot', 'ltn-chatbot' ), array( 'response' => 400, 'back_link' => true ) ); } public static function disconnect() { self::require_admin(); check_admin_referer( 'ltn_chatbot_disconnect' ); delete_option( self::OPTION ); wp_safe_redirect( admin_url( 'options-general.php?page=ltn-chatbot' ) ); exit; } public static function enqueue() { if ( is_admin() || is_preview() || is_customize_preview() || is_feed() || is_embed() ) { return; } $connection = get_option( self::OPTION, array() ); if ( empty( $connection['widget_id'] ) || ! preg_match( '/^wgt_[A-Za-z0-9_-]{32}$/D', $connection['widget_id'] ) ) { return; } wp_enqueue_script( 'ltn-chatbot-widget', self::SCRIPT_URL, array(), self::VERSION, array( 'strategy' => 'defer', 'in_footer' => true ) ); } public static function script_tag( $tag, $handle ) { if ( 'ltn-chatbot-widget' !== $handle ) { return $tag; } $connection = get_option( self::OPTION, array() ); if ( empty( $connection['widget_id'] ) || ! preg_match( '/^wgt_[A-Za-z0-9_-]{32}$/D', $connection['widget_id'] ) ) { return ''; } return str_replace( '