| 1 |
<?php |
| 2 |
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure. |
| 3 |
|
| 4 |
namespace Yoast\WP\SEO\MyYoast_Client\Infrastructure\OIDC; |
| 5 |
|
| 6 |
/** |
| 7 |
* Provides the MyYoast issuer URL, software statement, and initial access token. |
| 8 |
* |
| 9 |
* All values are filterable for development/staging environments. |
| 10 |
* |
| 11 |
* The `SOFTWARE_STATEMENT` and `INITIAL_ACCESS_TOKEN` constants below may |
| 12 |
* appear committed with real, valid values. This is intentional and safe — both |
| 13 |
* values are public by design, not leaked secrets. The full rationale lives in |
| 14 |
* the doc block at the top of `config/grunt/custom-tasks/update-myyoast-credentials.js`. |
| 15 |
* |
| 16 |
* ┌─────────────────────────────────────────────────────────────────────┐ |
| 17 |
* │ *** PLEASE DO NOT FILE A SECURITY REPORT ON THE SOLE GROUNDS *** │ |
| 18 |
* │ *** THAT THESE CREDENTIALS ARE PUBLICLY ACCESSIBLE. *** │ |
| 19 |
* └─────────────────────────────────────────────────────────────────────┘ |
| 20 |
* |
| 21 |
* That is by design and the linked doc block explains why. If, having read |
| 22 |
* that rationale, you still believe something here is wrong, please do file |
| 23 |
* a security report through the project's normal disclosure channel; |
| 24 |
* reports about anything else are always welcome. |
| 25 |
*/ |
| 26 |
class Issuer_Config { |
| 27 |
|
| 28 |
/** |
| 29 |
* The default production issuer URL. |
| 30 |
* |
| 31 |
* @var string |
| 32 |
*/ |
| 33 |
private const DEFAULT_ISSUER_URL = 'https://my.yoast.com'; |
| 34 |
|
| 35 |
/** |
| 36 |
* Software statement JWT for Dynamic Client Registration. |
| 37 |
* |
| 38 |
* Populated by the `update-myyoast-credentials` Grunt task as part of the |
| 39 |
* `artifact` alias on every build. The task fetches a fresh, version-bound |
| 40 |
* software statement from MyYoast when a service-account token is available |
| 41 |
* and falls back to a public version-zero software statement otherwise. |
| 42 |
* |
| 43 |
* The value committed in source may reflect the most recently shipped |
| 44 |
* release or be empty on dev branches; this is intentional. At runtime, |
| 45 |
* non-production environments override this via the |
| 46 |
* `wpseo_myyoast_software_statement` filter (see `get_software_statement()`). |
| 47 |
* |
| 48 |
* Public-by-design — see the class doc block above. |
| 49 |
* |
| 50 |
* @var string |
| 51 |
*/ |
| 52 |
private const SOFTWARE_STATEMENT = 'eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCIsImtpZCI6IjMwNTI3ZTlhLWZhMWYtNDhkZS05ZjIzLWUyZGE5MzY0NDE3NiJ9.eyJzb2Z0d2FyZV9pZCI6InlvYXN0L3dvcmRwcmVzcy1zZW8iLCJjbGllbnRfbmFtZSI6IllvYXN0IFNFTyIsImxvZ29fdXJpIjoiaHR0cHM6Ly95b2FzdC5jb20vYXBwL3VwbG9hZHMvMjAyNS8xMS9wcmVtaXVtLnN2ZyIsImNsaWVudF91cmkiOiJodHRwczovL3lvYXN0LmNvbS93b3JkcHJlc3MvcGx1Z2lucy9zZW8vIiwidG9zX3VyaSI6Imh0dHBzOi8veW9hc3QuY29tL3Rlcm1zLW9mLXNlcnZpY2UvIiwicG9saWN5X3VyaSI6Imh0dHBzOi8veW9hc3QuY29tL3ByaXZhY3ktcG9saWN5LyIsImNvbnRhY3RzIjpbInN1cHBvcnRAeW9hc3QuY29tIl0sInNvZnR3YXJlX3ZlcnNpb24iOiIyOC4xIiwiY2xlYW51cF93aGVuX2luYWN0aXZlIjp0cnVlLCJ0b2tlbl9lbmRwb2ludF9hdXRoX21ldGhvZCI6InByaXZhdGVfa2V5X2p3dCIsImlzcyI6Imh0dHBzOi8vbXkueW9hc3QuY29tIiwiYXVkIjoiaHR0cHM6Ly9teS55b2FzdC5jb20iLCJqdGkiOiJiNjE5MDFkOC01NzU1LTRlNDEtYmY2Yi0wOWRmNzk1YzllNTIiLCJpYXQiOjE3ODQ2MDk1NTJ9.nbv9HGD9qv5fabUAmkziNCt-xByDOAL2QGLdcNcIP3Czl5zmNKRwDo7Uve8olD0Bl3-GyD8_4esM7NlVOhN1BQ'; |
| 53 |
|
| 54 |
/** |
| 55 |
* Initial access token for Dynamic Client Registration. |
| 56 |
* |
| 57 |
* Populated by the `update-myyoast-credentials` Grunt task as part of the |
| 58 |
* `artifact` alias on every build. The task fetches a fresh, initial access |
| 59 |
* token from MyYoast when a service-account token is available and falls |
| 60 |
* back to a public version-zero token otherwise. |
| 61 |
* |
| 62 |
* The value committed in source may reflect the most recently shipped |
| 63 |
* release or be empty or v0 on dev branches; this is intentional. At |
| 64 |
* runtime, non-production environments override this via the |
| 65 |
* `wpseo_myyoast_initial_access_token` filter (see |
| 66 |
* `get_initial_access_token()`). |
| 67 |
* |
| 68 |
* Public-by-design — see the class doc block above. |
| 69 |
* |
| 70 |
* @var string |
| 71 |
*/ |
| 72 |
private const INITIAL_ACCESS_TOKEN = '_gcNzfLiOkllzZkdB1LzCM5KDUgvXQp043bJh5jBFIJ'; |
| 73 |
|
| 74 |
/** |
| 75 |
* Returns the MyYoast issuer URL. |
| 76 |
* |
| 77 |
* @return string The issuer URL (without trailing slash). |
| 78 |
*/ |
| 79 |
public function get_issuer_url(): string { |
| 80 |
/** |
| 81 |
* Filters the MyYoast issuer URL. |
| 82 |
* |
| 83 |
* @internal |
| 84 |
* |
| 85 |
* @param string $issuer_url The issuer URL. |
| 86 |
*/ |
| 87 |
return \rtrim( \apply_filters( 'wpseo_myyoast_issuer_url', self::DEFAULT_ISSUER_URL ), '/' ); |
| 88 |
} |
| 89 |
|
| 90 |
/** |
| 91 |
* Returns the software statement JWT. |
| 92 |
* |
| 93 |
* @return string The signed software statement JWT. |
| 94 |
*/ |
| 95 |
public function get_software_statement(): string { |
| 96 |
/** |
| 97 |
* Filters the MyYoast software statement JWT. |
| 98 |
* |
| 99 |
* @internal |
| 100 |
* |
| 101 |
* @param string $software_statement The software statement JWT. |
| 102 |
*/ |
| 103 |
return \apply_filters( 'wpseo_myyoast_software_statement', self::SOFTWARE_STATEMENT ); |
| 104 |
} |
| 105 |
|
| 106 |
/** |
| 107 |
* Returns the initial access token for Dynamic Client Registration. |
| 108 |
* |
| 109 |
* @return string The initial access token. |
| 110 |
*/ |
| 111 |
public function get_initial_access_token(): string { |
| 112 |
/** |
| 113 |
* Filters the MyYoast initial access token. |
| 114 |
* |
| 115 |
* @internal |
| 116 |
* |
| 117 |
* @param string $initial_access_token The initial access token. |
| 118 |
*/ |
| 119 |
return \apply_filters( 'wpseo_myyoast_initial_access_token', self::INITIAL_ACCESS_TOKEN ); |
| 120 |
} |
| 121 |
|
| 122 |
/** |
| 123 |
* Returns a short hash suffix derived from the issuer URL. |
| 124 |
* |
| 125 |
* Used to scope storage keys (options, transients, user meta) to the |
| 126 |
* current issuer, so that switching issuers isolates all stored data. |
| 127 |
* |
| 128 |
* @return string An 8-character hex string. |
| 129 |
*/ |
| 130 |
public function get_issuer_key(): string { |
| 131 |
return \substr( \md5( $this->get_issuer_url() ), 0, 8 ); |
| 132 |
} |
| 133 |
|
| 134 |
/** |
| 135 |
* Returns the OIDC discovery document URL. |
| 136 |
* |
| 137 |
* @return string The discovery URL. |
| 138 |
*/ |
| 139 |
public function get_discovery_url(): string { |
| 140 |
return $this->get_issuer_url() . '/.well-known/openid-configuration'; |
| 141 |
} |
| 142 |
} |
| 143 |
|