PluginProbe
SureCookie – GDPR Cookie Consent Banner, Cookie Scanner & Script Blocking / trunk
SureCookie – GDPR Cookie Consent Banner, Cookie Scanner & Script Blocking vtrunk
1.5.0 1.4.0 1.3.0 1.3.1 trunk 0.0.0-alpha.1 0.0.0-alpha.2 0.0.0-alpha.3 0.0.1-beta.1 0.0.1-beta.2 0.0.1-beta.3 0.0.1-beta.4 1.0.0 1.1.0 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4
surecookie / inc / modules / auth / api.php

api.php in SureCookie – GDPR Cookie Consent Banner, Cookie Scanner & Script Blocking trunk, at inc/modules/auth/api.php

122 lines 3.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Auth API class
4 *
5 * Handles authentication related REST API endpoints + the admin-post handler
6 * that receives the inbound POST form from the billing portal popup.
7 *
8 * @package SureCookie\Inc\Modules\Auth
9 * @since 0.0.1-beta.3
10 */
11
12 namespace SureCookie\Inc\Modules\Auth;
13
14 use SureCookie\Inc\API\Base;
15 use SureCookie\Inc\Functions\SendJson;
16 use SureCookie\Inc\Traits\GetInstance;
17 use WP_REST_Request;
18 use WP_REST_Server;
19
20 if ( ! defined( 'ABSPATH' ) ) {
21 exit; // Exit if accessed directly.
22 }
23
24 /**
25 * Class Api
26 *
27 * Handles authentication related REST API endpoints.
28 */
29 class Api extends Base {
30 use GetInstance;
31
32 /**
33 * Admin-post.php action slug for the inbound auth callback (issue #466).
34 */
35 public const CALLBACK_ACTION = 'surecookie_auth_callback';
36
37 /**
38 * Register REST routes.
39 *
40 * @since 0.0.1-beta.3
41 * @return void
42 */
43 public function register_routes(): void {
44 register_rest_route(
45 $this->get_api_namespace(),
46 '/auth',
47 [
48 'methods' => WP_REST_Server::READABLE,
49 'callback' => [ $this, 'get_auth_payload' ],
50 'permission_callback' => [ $this, 'validate_permission' ],
51 ]
52 );
53 }
54
55 /**
56 * GET /surecookie/v1/auth - returns the form payload the frontend POSTs
57 * to the billing portal (issue #466). Replaces the URL-string response.
58 *
59 * @since 0.0.1-beta.3
60 * @param WP_REST_Request<array<string, mixed>> $request Request object.
61 * @return void
62 */
63 public function get_auth_payload( $request ): void {
64 $controller = Controller::get_instance();
65
66 if ( $controller->get_auth_status() ) {
67 SendJson::success(
68 [
69 'is_authenticated' => true,
70 'email' => $controller->get_auth_email(),
71 'message' => __( 'Authentication is already completed.', 'surecookie' ),
72 ]
73 );
74 return;
75 }
76
77 $payload = $controller->get_auth_payload();
78
79 if ( is_wp_error( $payload ) ) {
80 SendJson::error( [ 'message' => $payload->get_error_message() ] );
81 return;
82 }
83
84 SendJson::success( $payload );
85 }
86
87 /**
88 * Handle the inbound POST form from the billing portal popup (issue #466).
89 *
90 * Receives `{action, flow_id, access_key}` as form fields, runs save_auth,
91 * and redirects the popup to /wp-admin/admin.php?page=surecookie with a
92 * benign `?auth=success|fail` query - the ciphertext never lands in the
93 * post-OAuth URL.
94 *
95 * @since 0.0.1-beta.3
96 */
97 public function handle_inbound_callback(): void {
98 // Cast to string up front - array-typed $_POST values would trigger
99 // sanitize_text_field warnings. flow_id is then validated as UUID v4
100 // inside save_auth(); access_key is base64-URL-safe ciphertext that
101 // sanitization would corrupt, validated by decrypt.
102 // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Replay protection is via one-time transient in save_auth. flow_id validated as UUID v4 downstream.
103 $flow_raw = isset( $_POST['flow_id'] ) && is_string( $_POST['flow_id'] ) ? wp_unslash( $_POST['flow_id'] ) : '';
104 $flow_id = sanitize_text_field( (string) $flow_raw );
105 // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash -- ciphertext is base64 URL-safe; sanitization would corrupt it. Validated by save_auth.
106 $access_key = isset( $_POST['access_key'] ) && is_string( $_POST['access_key'] ) ? (string) wp_unslash( $_POST['access_key'] ) : '';
107
108 $redirect_base = admin_url( 'admin.php?page=surecookie' );
109
110 if ( $access_key === '' || $flow_id === '' ) {
111 wp_safe_redirect( add_query_arg( 'auth', 'fail', $redirect_base ) );
112 exit;
113 }
114
115 $result = Controller::get_instance()->save_auth( $access_key, $flow_id );
116
117 $status = is_wp_error( $result ) ? 'fail' : 'success';
118 wp_safe_redirect( add_query_arg( 'auth', $status, $redirect_base ) );
119 exit;
120 }
121 }
122