PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 28.4
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v28.4
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
wordpress-seo / src / myyoast-client / domain / auth-flow-state.php

auth-flow-state.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 28.4, at src/myyoast-client/domain/auth-flow-state.php

196 lines 5.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Yoast\WP\SEO\MyYoast_Client\Domain;
4
5 use InvalidArgumentException;
6
7 /**
8 * Immutable value object representing the state of an in-progress authorization code flow.
9 *
10 * Stores the PKCE code verifier, CSRF state, nonce, redirect URI, and optional
11 * return URL for post-authorization redirect.
12 */
13 class Auth_Flow_State {
14
15 /**
16 * The PKCE code verifier.
17 *
18 * @var string
19 */
20 private $code_verifier;
21
22 /**
23 * The CSRF state parameter.
24 *
25 * @var string
26 */
27 private $state;
28
29 /**
30 * The nonce for ID token replay protection (only set when openid scope is requested).
31 *
32 * @var string|null
33 */
34 private $nonce;
35
36 /**
37 * The callback redirect URI.
38 *
39 * @var string
40 */
41 private $redirect_uri;
42
43 /**
44 * The URL to return the user to after authorization completes.
45 *
46 * @var string|null
47 */
48 private $return_url;
49
50 /**
51 * The RFC 8707 resource indicator this flow targets.
52 *
53 * @var Resource_Indicator
54 */
55 private $resource_indicator;
56
57 /**
58 * Auth_Flow_State constructor.
59 *
60 * @param string $code_verifier The PKCE code verifier.
61 * @param string $state The CSRF state parameter.
62 * @param string|null $nonce The nonce for ID token validation (only when openid scope is requested).
63 * @param string $redirect_uri The callback redirect URI.
64 * @param string|null $return_url The URL to return the user to after authorization.
65 * @param Resource_Indicator $resource_indicator The resource indicator (RFC 8707) this flow targets. Use Resource_Indicator::default() for the default resource.
66 *
67 * @throws InvalidArgumentException If required fields are empty.
68 */
69 public function __construct(
70 string $code_verifier,
71 string $state,
72 ?string $nonce,
73 string $redirect_uri,
74 ?string $return_url,
75 Resource_Indicator $resource_indicator
76 ) {
77 if ( $code_verifier === '' || $state === '' || $redirect_uri === '' ) {
78 throw new InvalidArgumentException( 'Auth_Flow_State requires non-empty code_verifier, state, and redirect_uri.' );
79 }
80
81 $this->code_verifier = $code_verifier;
82 $this->state = $state;
83 $this->nonce = $nonce;
84 $this->redirect_uri = $redirect_uri;
85 $this->return_url = $return_url;
86 $this->resource_indicator = $resource_indicator;
87 }
88
89 /**
90 * Returns the PKCE code verifier.
91 *
92 * @return string
93 */
94 public function get_code_verifier(): string {
95 return $this->code_verifier;
96 }
97
98 /**
99 * Returns the CSRF state parameter.
100 *
101 * @return string
102 */
103 public function get_state(): string {
104 return $this->state;
105 }
106
107 /**
108 * Returns the nonce.
109 *
110 * @return string|null
111 */
112 public function get_nonce(): ?string {
113 return $this->nonce;
114 }
115
116 /**
117 * Returns the callback redirect URI.
118 *
119 * @return string
120 */
121 public function get_redirect_uri(): string {
122 return $this->redirect_uri;
123 }
124
125 /**
126 * Returns the post-authorization return URL.
127 *
128 * @return string|null
129 */
130 public function get_return_url(): ?string {
131 return $this->return_url;
132 }
133
134 /**
135 * Returns the RFC 8707 resource indicator this flow targets.
136 *
137 * @return Resource_Indicator
138 */
139 public function get_resource_indicator(): Resource_Indicator {
140 return $this->resource_indicator;
141 }
142
143 /**
144 * Converts the state to an associative array for storage.
145 *
146 * @return array<string, string|null>
147 */
148 public function to_array(): array {
149 return [
150 'code_verifier' => $this->code_verifier,
151 'state' => $this->state,
152 'nonce' => $this->nonce,
153 'redirect_uri' => $this->redirect_uri,
154 'return_url' => $this->return_url,
155 'resource_indicator' => $this->resource_indicator->value(),
156 ];
157 }
158
159 /**
160 * Creates an Auth_Flow_State from a stored array.
161 *
162 * @param array<string, string|null> $data The stored array data.
163 *
164 * @return self
165 *
166 * @throws InvalidArgumentException If required fields are missing or have invalid types.
167 */
168 public static function from_array( array $data ): self {
169 $required = [ 'code_verifier', 'state', 'redirect_uri' ];
170 foreach ( $required as $key ) {
171 if ( ! isset( $data[ $key ] ) || ! \is_string( $data[ $key ] ) ) {
172 // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Internal exception message.
173 throw new InvalidArgumentException( "Auth_Flow_State::from_array() requires a string value for '{$key}'." );
174 }
175 }
176 $optional_strings = [ 'nonce', 'return_url', 'resource_indicator' ];
177 foreach ( $optional_strings as $key ) {
178 if ( isset( $data[ $key ] ) && ! \is_string( $data[ $key ] ) ) {
179 // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Internal exception message.
180 throw new InvalidArgumentException( "Auth_Flow_State::from_array() requires '{$key}' to be a string or null." );
181 }
182 }
183
184 $stored_indicator = ( $data['resource_indicator'] ?? null );
185
186 return new self(
187 $data['code_verifier'],
188 $data['state'],
189 ( $data['nonce'] ?? null ),
190 $data['redirect_uri'],
191 ( $data['return_url'] ?? null ),
192 new Resource_Indicator( ( \is_string( $stored_indicator ) && $stored_indicator !== '' ) ? $stored_indicator : null ),
193 );
194 }
195 }
196