PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / 1.10.16
WCPOS – Point of Sale (POS) plugin for WooCommerce v1.10.16
1.10.18 1.10.17 1.10.16 1.10.15 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 All 162 releases
woocommerce-pos / includes / Sync / Cors.php

Cors.php in WCPOS – Point of Sale (POS) plugin for WooCommerce 1.10.16, at includes/Sync/Cors.php

82 lines 3.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * WCPOS sync CORS allow-list.
4 *
5 * @package WCPOS\WooCommercePOS\Sync
6 */
7
8 namespace WCPOS\WooCommercePOS\Sync;
9
10 /**
11 * The single registration point for the request headers the v2 sync lane
12 * sends, so CORS preflight lets them through.
13 *
14 * ## Why this exists
15 *
16 * Any cross-origin web client (standalone connect mode, a localhost dev
17 * server) preflights every engine request: Authorization and the custom
18 * WCPOS headers make each one non-simple. The preflight is an OPTIONS
19 * request that cannot carry the headers themselves (so it cannot be gated
20 * by the WCPOS marker), and a header missing from
21 * `Access-Control-Allow-Headers` does not merely lose its feature — the
22 * browser refuses the ACTUAL request outright, taking the whole v2 lane
23 * down for that client.
24 *
25 * ONE writer publishes the allow-list — {@see \WCPOS\WooCommercePOS\Rest_Cors},
26 * which owns both the `rest_allowed_cors_headers` filter and the preflight
27 * response. This class stays as its data collaborator: it is where the sync
28 * lane declares the headers it sends, beside {@see Header_Mirror::HEADERS}
29 * and {@see Store_Scope::HEADER}, rather than a second publisher. Kept as
30 * two hand-maintained lists these headers drifted apart twice — first
31 * `X-WCPOS-Store` (pro#425 fallout, 23bcdb47), then
32 * `X-WCPOS-Idempotency-Key` (118a091f) — each time failing every
33 * cross-origin request that carried them at preflight. That is the split
34 * the single owner exists to make impossible.
35 */
36 final class Cors {
37 /**
38 * POS-client request headers beyond WP core's CORS defaults.
39 *
40 * FROZEN as the compatibility floor (free#1763): Rest_Cors pre-authorizes
41 * new client headers through preflight reflection, so adding a name only
42 * masks a reflection bug, while removing one narrows the degradation floor
43 * used when announcements are stripped and by old preflight caches.
44 * `X-WCPOS-Protocol` and `X-WCPOS-Client` (free#1760) are the last additions.
45 *
46 * - `Idempotency-Key` / `If-Match` — the v2 write path's standard-header
47 * mirror ({@see Header_Mirror::HEADERS}).
48 * - `If-None-Match` — conditional sequence-log polling (304s).
49 * - `X-WCPOS-Idempotency-Key` — the checkout/refund lane's idempotency
50 * key (v1-shaped, predates the ADR 0011 mirror).
51 * - `X-WCPOS-Store` — the till's store scope ({@see Store_Scope::HEADER},
52 * pro#425).
53 * - `X-WCPOS-Protocol` — protocol signal (wcpos/woocommerce-pos#1752).
54 * - `X-WCPOS-Client` — client platform signal (wcpos/woocommerce-pos#1752).
55 *
56 * @return string[] Header names in their canonical (sent) casing.
57 */
58 public static function headers(): array {
59 return array_merge(
60 Header_Mirror::HEADERS,
61 array(
62 'If-None-Match',
63 'X-WCPOS-Idempotency-Key',
64 Store_Scope::HEADER,
65 'X-WCPOS-Protocol',
66 'X-WCPOS-Client',
67 )
68 );
69 }
70
71 /**
72 * Merge the sync-lane header set into a CORS allow-list.
73 *
74 * @param string[] $allow_headers The allow-list under construction.
75 *
76 * @return string[] The allow-list with the sync-lane headers, deduplicated.
77 */
78 public static function allow_headers( array $allow_headers ): array {
79 return array_values( array_unique( array_merge( $allow_headers, self::headers() ) ) );
80 }
81 }
82