PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.2
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.2
6.2.2 6.2.1 6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 All 155 releases
mainwp / class / class-mainwp-credential-render.php

class-mainwp-credential-render.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 6.2.2, at class/class-mainwp-credential-render.php

75 lines 3.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Credential render helpers for sentinel-based form rendering.
4 *
5 * @package MainWP\Dashboard
6 * @since 6.0.12
7 */
8
9 namespace MainWP\Dashboard;
10
11 /**
12 * Class MainWP_Credential_Render
13 *
14 * Settings pages that render credential-shaped values into HTML inputs
15 * (third-party API keys, master license keys, HTTP Basic Auth passwords)
16 * leak the live value into the rendered DOM. The sentinel pattern fixes
17 * the leak while preserving the "value already set" admin signal:
18 *
19 * - On render, if a value is set the input shows a fixed placeholder
20 * ('••••••••') instead of the actual value. If unset, the input is
21 * empty.
22 * - On save, the corresponding storage handler checks for the sentinel
23 * and short-circuits without modifying the stored value, so a form
24 * submission that did not change the field preserves the existing
25 * value rather than overwriting it with the sentinel.
26 *
27 * Used by MWP-1543 (3rd-party API Backups settings), MWP-1547 (master
28 * license key), MWP-1546 (per-extension license keys), and MWP-1548
29 * (HTTP Basic Auth password on the Edit Site form).
30 */
31 class MainWP_Credential_Render {
32
33 /**
34 * The placeholder rendered into a credential input when a value is
35 * already stored. Visually obvious to admins, recognizable to the
36 * matching save handler, and intentionally a string no real key
37 * generator would produce.
38 *
39 * @var string
40 */
41 const SENTINEL = '••••••••';
42
43 /**
44 * Return the value to write into an `<input value="...">` attribute
45 * for a credential field. Empty string when nothing is stored, the
46 * sentinel placeholder when something is stored.
47 *
48 * @param bool $has_value Whether a value is currently stored.
49 * @param string $sentinel Override the placeholder (rare; mostly for tests).
50 * @return string Sentinel placeholder or empty string.
51 */
52 public static function value_for_input( $has_value, $sentinel = self::SENTINEL ) {
53 return $has_value ? $sentinel : '';
54 }
55
56 /**
57 * Detect whether a submitted form value is the unchanged-sentinel.
58 * Save handlers that get true here MUST short-circuit and leave the
59 * existing storage untouched.
60 *
61 * Callers MUST pass the raw `wp_unslash()`-ed value. Do not chain
62 * `sanitize_text_field()`, `wp_kses*()`, `mb_convert_encoding()`, or
63 * any other byte-altering filter before the check, or the multi-byte
64 * bullet bytes get stripped/normalized and the comparison fails open
65 * (the sentinel becomes a real submission and overwrites storage).
66 *
67 * @param mixed $submitted Submitted form value (typically from $_POST).
68 * @param string $sentinel Override the placeholder (rare; mostly for tests).
69 * @return bool True if the submitted value equals the sentinel.
70 */
71 public static function is_sentinel( $submitted, $sentinel = self::SENTINEL ) {
72 return is_string( $submitted ) && $submitted === $sentinel;
73 }
74 }
75