PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / trunk
WCPOS – Point of Sale (POS) plugin for WooCommerce vtrunk
1.10.13 1.10.14 1.10.12 1.10.11 1.10.10 1.10.9 1.10.8 untagged-3d9b7ccddc54df87c672 1.10.7 1.10.6 1.10.5 1.10.3 1.10.4 1.10.2 1.10.1 1.10.0 1.9.17 1.9.15 1.9.16 1.9.14 1.9.13 1.9.12 1.9.11 1.9.10 1.9.9 All 158 releases
woocommerce-pos / includes / API / V2 / Echo_Probe.php

Echo_Probe.php in WCPOS – Point of Sale (POS) plugin for WooCommerce trunk, at includes/API/V2/Echo_Probe.php

89 lines 3.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Public request-header echo probe REST API controller.
4 *
5 * @package WCPOS\WooCommercePOS\API\V2
6 */
7
8 namespace WCPOS\WooCommercePOS\API\V2;
9
10 use WCPOS\WooCommercePOS\Sync\Cors;
11 use WP_REST_Request;
12 use WP_REST_Response;
13
14 /** Reports which POS client headers reached the normal REST stack. */
15 final class Echo_Probe {
16 /** Register the public echo probe route. */
17 public function register_routes(): void {
18 register_rest_route(
19 'wcpos/v2',
20 '/echo',
21 array(
22 'methods' => 'GET',
23 'callback' => array( $this, 'get_echo' ),
24 'permission_callback' => '__return_true',
25 )
26 );
27 }
28
29 /**
30 * Classify the probe as public for the central permission gate.
31 *
32 * @return array<string, string[]>
33 */
34 public function wcpos_route_classifications(): array {
35 return array( 'public' => array( '/wcpos/v2/echo' ) );
36 }
37
38 /**
39 * Return header and fallback-parameter presence without exposing values.
40 *
41 * @param WP_REST_Request $request Request to inspect.
42 */
43 public function get_echo( WP_REST_Request $request ): WP_REST_Response {
44 $headers = array();
45
46 foreach ( array_merge( array( 'Authorization', 'Content-Type', 'X-WCPOS' ), Cors::headers() ) as $name ) {
47 $key = strtolower( $name );
48 // get_header() returns null when absent — normalize, or an absent
49 // header reads as received (the exact case this probe detects).
50 $value = (string) ( $request->get_header( $name ) ?? '' );
51
52 if ( 'authorization' === $key && '' === $value && ! empty( $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ) && \is_string( $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ) ) {
53 $value = $_SERVER['REDIRECT_HTTP_AUTHORIZATION']; // phpcs:ignore -- Raw byte length only; the value is never returned.
54 }
55
56 $headers[ $key ] = array(
57 'received' => '' !== $value,
58 'length' => \strlen( $value ),
59 );
60 }
61 $params = $request->get_query_params();
62
63 return new WP_REST_Response(
64 array(
65 // Stays 1: shipped clients hard-gate on `v === 1` and read a
66 // mismatch as "not the echo route" (hydration-steps.ts), so an
67 // additive field must not bump it.
68 'v' => 1,
69 'headers' => $headers,
70 'params' => array(
71 'authorization' => isset( $params['authorization'] ) && '' !== $params['authorization'],
72 'wcpos' => isset( $params['wcpos'] ) && '' !== $params['wcpos'],
73 'store_id' => isset( $params['store_id'] ) && '' !== $params['store_id'],
74 'wcpos_protocol' => isset( $params['wcpos_protocol'] ) && '' !== $params['wcpos_protocol'],
75 'wcpos_client' => isset( $params['wcpos_client'] ) && '' !== $params['wcpos_client'],
76 ),
77 // Means: this SERVER reflects announced x-wcpos-* names at
78 // preflight ({@see \WCPOS\WooCommercePOS\Rest_Cors}). It does
79 // NOT prove this store's preflights reach PHP — an edge that
80 // answers OPTIONS itself still blocks new headers, so a client
81 // must confirm the path with one cross-origin request carrying
82 // a throwaway x-wcpos-* header before trusting header transport.
83 'cors' => array( 'reflects_request_headers' => true ),
84 ),
85 200
86 );
87 }
88 }
89