PluginProbe
CryptX / 3.5.2
CryptX v3.5.2
4.2.1 4.2.0 4.1.1 trunk 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.9 2.0 2.1 2.2 2.3 2.3.1 2.3.2 2.3.3 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 All 93 releases
← All changes | classes/Config.php +5 -149 4.1.13.5.2 View file →
@@ -2,56 +2,8 @@
2 2
3 3 namespace CryptX;
4 4
5 5 final class Config {
6 - /**
7 - * Default configuration options for the application.
8 - *
9 - * This array provides the default settings and values for various
10 - * features and behaviors of the application. These options can be
11 - * customized to suit specific implementation requirements.
12 - *
13 - * Keys and their purposes:
14 - * - 'version': The version of the application (default: null).
15 - * - 'at': Replacement string for the "@" symbol (default: ' [at] ').
16 - * - 'dot': Replacement string for the "." symbol (default: ' [dot] ').
17 - * - 'css_id': CSS ID to use for specific elements (default: '').
18 - * - 'css_class': CSS class to use for specific elements (default: '').
19 - * - 'the_content': Flag to enable processing on content (default: 1).
20 - * On block themes this filter is swapped for 'render_block'
21 - * at runtime, see CryptX::initializePluginFilters(). There is
22 - * no separate option for it.
23 - * - 'the_meta_key': Flag to enable processing on meta keys (default: 1).
24 - * - 'the_excerpt': Flag to enable processing on excerpts (default: 1).
25 - * - 'comment_text': Flag to enable processing on comments (default: 1).
26 - * - 'widget_text': Flag to enable processing in widgets (default: 1).
27 - * - 'java': Flag indicating JavaScript-related configurations (default: 1).
28 - * - 'load_java': Flag to enable JavaScript loading (default: 1).
29 - * - 'opt_linktext': Option for link text settings (default: 0).
30 - * - 'autolink': Flag to enable auto-linking of content (default: 1).
31 - * - 'alt_linktext': Alternative text for links (default: '').
32 - * - 'alt_linkimage': Alternative image for links (default: '').
33 - * - 'http_linkimage_title': Link image title with HTTP reference (default: '').
34 - * - 'alt_linkimage_title': Alternative title for the link image (default: '').
35 - * - 'excludedIDs': IDs to exclude from processing (default: '').
36 - * - 'metaBox': Flag to enable or disable meta box features (default: 1).
37 - * - 'alt_uploadedimage': Alternative uploaded image setting (default: '0').
38 - * - 'c2i_font': Custom font setting (default: null).
39 - * - 'c2i_fontSize': Font size for configuration (default: 10).
40 - * - 'c2i_fontRGB': Font color in RGB format (default: '#000000').
41 - * - 'echo': Flag to enable output directly to the browser (default: 1).
42 - * - 'whiteList': Comma-separated string of allowed file extensions (default: 'jpeg,jpg,png,gif').
43 - * - 'disable_rss': Flag to disable CryptX in RSS feeds by default (default: 1).
44 - * - 'encryption_mode': Encryption mode setting (default: 'secure').
45 - * - 'encryption_password': Password for encryption; a random secret is generated
46 - * on first use if null and then kept forever (default: null).
47 - * - 'use_secure_encryption': Flag to enable secure encryption by default (default: 1).
48 - * - 'iterations': PBKDF2 iteration count for the secure mode (default: 10000).
49 - * - 'link_mode': How the encrypted link is delivered -- 'data' puts the payload
50 - * into data attributes and lets a delegated click handler take
51 - * over (survives a Content-Security-Policy), 'js' is the historical
52 - * "javascript:" URI (default: 'data').
53 - */
54 6 private const DEFAULT_OPTIONS = [
55 7 'version' => null,
56 8 'at' => ' [at] ',
57 9 'dot' => ' [dot] ',
@@ -76,31 +28,13 @@
76 28 'c2i_font' => null,
77 29 'c2i_fontSize' => 10,
78 30 'c2i_fontRGB' => '#000000',
79 31 'echo' => 1,
32 + 'filter' => ['the_content', 'the_meta_key', 'the_excerpt', 'comment_text', 'widget_text'],
80 33 'whiteList' => 'jpeg,jpg,png,gif',
81 - 'disable_rss' => 1,
82 - 'encryption_mode' => 'secure',
83 - 'encryption_password' => null,
84 - 'use_secure_encryption' => 1,
85 - 'iterations' => 10000,
86 - 'link_mode' => 'data',
34 + 'disable_rss' => 1, // Disable CryptX in RSS feeds by default
87 35 ];
88 36
89 - /**
90 - * An array of filter names used within the application.
91 - * These filters are commonly applied to various types of content,
92 - * including posts, comments, and widgets.
93 - */
94 - private const FILTERS = ['the_content', 'the_meta_key', 'the_excerpt', 'comment_text', 'widget_text'];
95 -
96 - // Define the actual widget filters that will be used when widget_text is enabled
97 - private const WIDGET_FILTERS = [
98 - 'widget_text', // Legacy text widget (pre-4.9)
99 - 'widget_text_content', // Modern text widget (4.9+)
100 - 'widget_custom_html_content' // Custom HTML widget (4.8.1+)
101 - ];
102 -
103 37 private array $options;
104 38 private array $originalOptions;
105 39
106 40 public function __construct(array $options = []) {
@@ -108,9 +42,9 @@
108 42 $this->originalOptions = $this->options;
109 43 }
110 44
111 45 public function getActiveFilters(): array {
112 - return array_filter(self::FILTERS, fn($filter) =>
46 + return array_filter($this->options['filter'], fn($filter) =>
113 47 isset($this->options[$filter]) && $this->options[$filter]
114 48 );
115 49 }
116 50
@@ -165,17 +99,8 @@
165 99 public function getVersion(): ?string {
166 100 return $this->options['version'];
167 101 }
168 102
169 - /**
170 - * Get the actual widget filters to be applied
171 - *
172 - * @return array
173 - */
174 - public function getWidgetFilters(): array {
175 - return self::WIDGET_FILTERS;
176 - }
177 -
178 103 public function updateFromShortcode(array $attributes, string $tag): void {
179 104 $this->originalOptions = $this->options;
180 105 $shortcodeOptions = shortcode_atts(
181 106 $this->options,
@@ -196,9 +121,9 @@
196 121 public function update(array $newOptions): void
197 122 {
198 123 // Convert checkbox values to integers
199 124 foreach (['the_content', 'the_meta_key', 'the_excerpt', 'comment_text',
200 - 'widget_text', 'autolink', 'metaBox', 'disable_rss', 'use_secure_encryption'] as $key) {
125 + 'widget_text', 'autolink', 'metaBox', 'disable_rss'] as $key) {
201 126 if (isset($newOptions[$key])) {
202 127 $newOptions[$key] = (int)$newOptions[$key];
203 128 }
204 129 }
@@ -219,19 +144,10 @@
219 144 return $this->options;
220 145 }
221 146
222 147 /**
223 - * Resets all options to their default values.
148 + * Resets all options to their default values
224 149 *
225 - * Careful before wiring this up again: it has had no caller since 4.1.0,
226 - * because the settings screen resets through SettingsSchema instead. This
227 - * method sets the whole array to DEFAULT_OPTIONS, in which
228 - * encryption_password is null -- and then saves. That discards the secret
229 - * every already delivered link was encrypted with, so those links stop
230 - * resolving until the pages are regenerated. SettingsSchema::defaults()
231 - * covers only the editable options and leaves the secret alone, which is
232 - * why the REST route uses it.
233 - *
234 150 * @return void
235 151 */
236 152 public function reset(): void
237 153 {
@@ -246,66 +162,6 @@
246 162 $this->options['c2i_font'] = basename($fontFiles[0]);
247 163 }
248 164
249 165 $this->save();
250 - }
251 -
252 - /**
253 - * Retrieves the encryption mode configured in the options.
254 - *
255 - * @return string Returns the encryption mode as a string. Defaults to 'secure' if not set.
256 - */
257 - public function getEncryptionMode(): string
258 - {
259 - return $this->options['encryption_mode'] ?? 'secure';
260 - }
261 -
262 - /**
263 - * Checks if secure encryption is enabled in the options.
264 - *
265 - * @return bool Returns true if secure encryption is enabled, false otherwise.
266 - */
267 - public function isSecureEncryptionEnabled(): bool
268 - {
269 - return (bool) ($this->options['use_secure_encryption'] ?? true);
270 - }
271 -
272 - /**
273 - * Retrieves the encryption password configured in the options or generates a secure password if not set.
274 - *
275 - * @return string Returns the encryption password as a string.
276 - */
277 - public function getEncryptionPassword(): string
278 - {
279 - // A stored password is returned untouched and is NEVER regenerated.
280 - // The password is baked into every link this plugin has ever emitted,
281 - // so a new one would turn all already delivered and cached pages into
282 - // undecryptable garbage. Only a missing (or empty) value is filled in.
283 - if (empty($this->options['encryption_password'])) {
284 - // Random secret instead of a value derived from the WordPress keys.
285 - // Rationale: this password is published. It is handed to the browser
286 - // as the second argument of the generated
287 - // javascript:secureDecryptAndNavigate(...) link and therefore sits
288 - // in the HTML of every page in clear text. Deriving it from AUTH_KEY
289 - // and SECURE_AUTH_KEY was not reversible, but there is no reason to
290 - // publish anything at all that is a function of the site's secrets.
291 - //
292 - // bin2hex(random_bytes(32)) is the choice because random_bytes() is
293 - // the platform CSPRNG (always available on the required PHP 8.1+,
294 - // not filterable by other plugins) and hex output is pure [0-9a-f]:
295 - // it survives every escaping stage on the way into the JavaScript
296 - // string literal and into the option row unchanged. 32 bytes = 256
297 - // bits, matching the AES-256 key later derived from it via PBKDF2.
298 - try {
299 - $this->options['encryption_password'] = bin2hex(random_bytes(32));
300 - } catch (\Throwable $e) {
301 - // random_bytes() throws when the system has no usable source of
302 - // randomness. wp_generate_password() then provides the fallback;
303 - // 64 chars without special characters keeps the value safe to
304 - // embed unescaped.
305 - $this->options['encryption_password'] = wp_generate_password(64, false, false);
306 - }
307 - $this->save();
308 - }
309 - return $this->options['encryption_password'];
310 166 }
311 167 }