Sync your WordPress posts to standard.site records on your PDS
7
fork

Configure Feed

Select the types of activity you want to include in your feed.

hardening

+220 -29
+6 -6
assets/js/meta-box.js
··· 58 58 attachment.sizes && attachment.sizes.thumbnail 59 59 ? attachment.sizes.thumbnail.url 60 60 : attachment.url; 61 - document.getElementById( 62 - "wireservice-custom-image-preview" 63 - ).innerHTML = 64 - '<img src="' + 65 - thumbUrl + 66 - '" style="max-width:150px;height:auto;display:block;margin-bottom:8px;" />'; 61 + var previewEl = document.getElementById("wireservice-custom-image-preview"); 62 + previewEl.innerHTML = ""; 63 + var img = document.createElement("img"); 64 + img.src = thumbUrl; 65 + img.style.cssText = "max-width:150px;height:auto;display:block;margin-bottom:8px;"; 66 + previewEl.appendChild(img); 67 67 document.getElementById("wireservice-remove-image").style.display = 68 68 ""; 69 69 });
+12 -2
assets/js/records.js
··· 7 7 return div.innerHTML; 8 8 } 9 9 10 + function safeUrl(url) { 11 + if (!url || typeof url !== "string") return "#"; 12 + return /^https?:\/\//i.test(url) ? url : "#"; 13 + } 14 + 15 + function safeInt(val) { 16 + var n = parseInt(val, 10); 17 + return isFinite(n) ? n : 0; 18 + } 19 + 10 20 function formatDate(isoString) { 11 21 if (!isoString) return "\u2014"; 12 22 var d = new Date(isoString); ··· 33 43 html += fieldRow( 34 44 "URL", 35 45 '<a href="' + 36 - escapeHtml(val.url) + 46 + escapeHtml(safeUrl(val.url)) + 37 47 '" target="_blank">' + 38 48 escapeHtml(val.url) + 39 49 "</a>" ··· 58 68 for (var i = 0; i < colors.length; i++) { 59 69 var c = theme[colors[i]]; 60 70 if (c) { 61 - var rgb = "rgb(" + c.r + ", " + c.g + ", " + c.b + ")"; 71 + var rgb = "rgb(" + safeInt(c.r) + ", " + safeInt(c.g) + ", " + safeInt(c.b) + ")"; 62 72 html += fieldRow( 63 73 "Theme: " + colors[i], 64 74 '<span class="wireservice-color-swatch" style="background:' +
+6 -4
assets/js/settings.js
··· 92 92 attachment.sizes && attachment.sizes.thumbnail 93 93 ? attachment.sizes.thumbnail.url 94 94 : attachment.url; 95 - customPreview.innerHTML = 96 - '<img src="' + 97 - thumbUrl + 98 - '" alt="" style="width: 64px; height: 64px; object-fit: cover; border-radius: 4px;">'; 95 + customPreview.innerHTML = ""; 96 + var img = document.createElement("img"); 97 + img.src = thumbUrl; 98 + img.alt = ""; 99 + img.style.cssText = "width: 64px; height: 64px; object-fit: cover; border-radius: 4px;"; 100 + customPreview.appendChild(img); 99 101 removeBtn.style.display = ""; 100 102 }); 101 103
+45 -17
includes/Admin.php
··· 219 219 220 220 return [ 221 221 "name_source" => isset($value["name_source"]) 222 - ? sanitize_text_field($value["name_source"]) 222 + ? SourceOptions::validate_pub_name_key( 223 + sanitize_text_field($value["name_source"]), 224 + ) 223 225 : "wordpress_title", 224 226 "description_source" => isset($value["description_source"]) 225 - ? sanitize_text_field($value["description_source"]) 227 + ? SourceOptions::validate_pub_desc_key( 228 + sanitize_text_field($value["description_source"]), 229 + ) 226 230 : "wordpress_tagline", 227 231 "custom_name" => isset($value["custom_name"]) 228 232 ? sanitize_text_field($value["custom_name"]) ··· 231 235 ? sanitize_textarea_field($value["custom_description"]) 232 236 : "", 233 237 "icon_source" => isset($value["icon_source"]) 234 - ? sanitize_text_field($value["icon_source"]) 238 + ? SourceOptions::validate_pub_icon_key( 239 + sanitize_text_field($value["icon_source"]), 240 + ) 235 241 : "none", 236 242 "custom_icon_id" => isset($value["custom_icon_id"]) 237 243 ? absint($value["custom_icon_id"]) ··· 271 277 ? sanitize_text_field($value["enabled"]) 272 278 : "0", 273 279 "title_source" => isset($value["title_source"]) 274 - ? sanitize_text_field($value["title_source"]) 280 + ? SourceOptions::validate_doc_title_key( 281 + sanitize_text_field($value["title_source"]), 282 + ) 275 283 : "wordpress_title", 276 284 "description_source" => isset($value["description_source"]) 277 - ? sanitize_text_field($value["description_source"]) 285 + ? SourceOptions::validate_doc_desc_key( 286 + sanitize_text_field($value["description_source"]), 287 + ) 278 288 : "wordpress_excerpt", 279 289 "image_source" => isset($value["image_source"]) 280 - ? sanitize_text_field($value["image_source"]) 290 + ? SourceOptions::validate_doc_image_key( 291 + sanitize_text_field($value["image_source"]), 292 + ) 281 293 : "wordpress_featured", 282 294 "include_content" => isset($value["include_content"]) 283 295 ? sanitize_text_field($value["include_content"]) ··· 425 437 $pub = SourceOptions::get_pub_settings(); 426 438 427 439 $pub["name_source"] = isset($_POST["wireservice_pub_name_source"]) 428 - ? sanitize_text_field(wp_unslash($_POST["wireservice_pub_name_source"])) 440 + ? SourceOptions::validate_pub_name_key( 441 + sanitize_text_field(wp_unslash($_POST["wireservice_pub_name_source"])), 442 + ) 429 443 : $pub["name_source"]; 430 444 $pub["description_source"] = isset( 431 445 $_POST["wireservice_pub_description_source"], 432 446 ) 433 - ? sanitize_text_field( 434 - wp_unslash($_POST["wireservice_pub_description_source"]), 447 + ? SourceOptions::validate_pub_desc_key( 448 + sanitize_text_field( 449 + wp_unslash($_POST["wireservice_pub_description_source"]), 450 + ), 435 451 ) 436 452 : $pub["description_source"]; 437 453 ··· 447 463 } 448 464 449 465 $pub["icon_source"] = isset($_POST["wireservice_pub_icon_source"]) 450 - ? sanitize_text_field( 451 - wp_unslash($_POST["wireservice_pub_icon_source"]), 466 + ? SourceOptions::validate_pub_icon_key( 467 + sanitize_text_field( 468 + wp_unslash($_POST["wireservice_pub_icon_source"]), 469 + ), 452 470 ) 453 471 : $pub["icon_source"]; 454 472 $pub["custom_icon_id"] = isset($_POST["wireservice_pub_custom_icon_id"]) ··· 676 694 { 677 695 if (!current_user_can("manage_options")) { 678 696 wp_send_json_error("Unauthorized.", 403); 697 + return; 679 698 } 680 699 681 700 check_ajax_referer("wireservice_backfill", "nonce"); ··· 713 732 { 714 733 if (!current_user_can("manage_options")) { 715 734 wp_send_json_error("Unauthorized.", 403); 735 + return; 716 736 } 717 737 718 738 check_ajax_referer("wireservice_backfill", "nonce"); ··· 782 802 $doc["enabled"] = isset($_POST["wireservice_doc_enabled"]) ? "1" : "0"; 783 803 784 804 if (isset($_POST["wireservice_doc_title_source"])) { 785 - $doc["title_source"] = sanitize_text_field( 786 - wp_unslash($_POST["wireservice_doc_title_source"]), 805 + $doc["title_source"] = SourceOptions::validate_doc_title_key( 806 + sanitize_text_field( 807 + wp_unslash($_POST["wireservice_doc_title_source"]), 808 + ), 787 809 ); 788 810 } 789 811 790 812 if (isset($_POST["wireservice_doc_description_source"])) { 791 - $doc["description_source"] = sanitize_text_field( 792 - wp_unslash($_POST["wireservice_doc_description_source"]), 813 + $doc["description_source"] = SourceOptions::validate_doc_desc_key( 814 + sanitize_text_field( 815 + wp_unslash($_POST["wireservice_doc_description_source"]), 816 + ), 793 817 ); 794 818 } 795 819 796 820 if (isset($_POST["wireservice_doc_image_source"])) { 797 - $doc["image_source"] = sanitize_text_field( 798 - wp_unslash($_POST["wireservice_doc_image_source"]), 821 + $doc["image_source"] = SourceOptions::validate_doc_image_key( 822 + sanitize_text_field( 823 + wp_unslash($_POST["wireservice_doc_image_source"]), 824 + ), 799 825 ); 800 826 } 801 827 ··· 829 855 { 830 856 if (!current_user_can("manage_options")) { 831 857 wp_send_json_error("Unauthorized.", 403); 858 + return; 832 859 } 833 860 834 861 check_ajax_referer("wireservice_records", "nonce"); ··· 858 885 { 859 886 if (!current_user_can("manage_options")) { 860 887 wp_send_json_error("Unauthorized.", 403); 888 + return; 861 889 } 862 890 863 891 check_ajax_referer("wireservice_records", "nonce");
+151
includes/SourceOptions.php
··· 43 43 ]; 44 44 45 45 /** 46 + * All valid publication name source keys. 47 + * 48 + * @var string[] 49 + */ 50 + private const VALID_PUB_NAME_KEYS = [ 51 + "wordpress_title", 52 + "yoast_organization", 53 + "yoast_website", 54 + "custom", 55 + ]; 56 + 57 + /** 58 + * All valid publication description source keys. 59 + * 60 + * @var string[] 61 + */ 62 + private const VALID_PUB_DESC_KEYS = [ 63 + "wordpress_tagline", 64 + "yoast_homepage", 65 + "custom", 66 + ]; 67 + 68 + /** 69 + * All valid publication icon source keys. 70 + * 71 + * @var string[] 72 + */ 73 + private const VALID_PUB_ICON_KEYS = [ 74 + "none", 75 + "wordpress_site_icon", 76 + "custom", 77 + ]; 78 + 79 + /** 80 + * All valid document title source keys. 81 + * 82 + * @var string[] 83 + */ 84 + private const VALID_DOC_TITLE_KEYS = [ 85 + "wordpress_title", 86 + "yoast_title", 87 + "yoast_social_title", 88 + "yoast_x_title", 89 + "custom", 90 + ]; 91 + 92 + /** 93 + * All valid document description source keys. 94 + * 95 + * @var string[] 96 + */ 97 + private const VALID_DOC_DESC_KEYS = [ 98 + "wordpress_excerpt", 99 + "yoast_description", 100 + "yoast_social_description", 101 + "yoast_x_description", 102 + "custom", 103 + ]; 104 + 105 + /** 106 + * All valid document image source keys. 107 + * 108 + * @var string[] 109 + */ 110 + private const VALID_DOC_IMAGE_KEYS = [ 111 + "none", 112 + "wordpress_featured", 113 + "yoast_social_image", 114 + "yoast_x_image", 115 + "custom", 116 + ]; 117 + 118 + /** 119 + * Validate a publication name source key, returning the default if invalid. 120 + * 121 + * @param string $key The source key to validate. 122 + * @return string The validated key. 123 + */ 124 + public static function validate_pub_name_key(string $key): string 125 + { 126 + return in_array($key, self::VALID_PUB_NAME_KEYS, true) 127 + ? $key 128 + : self::PUB_DEFAULTS["name_source"]; 129 + } 130 + 131 + /** 132 + * Validate a publication description source key, returning the default if invalid. 133 + * 134 + * @param string $key The source key to validate. 135 + * @return string The validated key. 136 + */ 137 + public static function validate_pub_desc_key(string $key): string 138 + { 139 + return in_array($key, self::VALID_PUB_DESC_KEYS, true) 140 + ? $key 141 + : self::PUB_DEFAULTS["description_source"]; 142 + } 143 + 144 + /** 145 + * Validate a publication icon source key, returning the default if invalid. 146 + * 147 + * @param string $key The source key to validate. 148 + * @return string The validated key. 149 + */ 150 + public static function validate_pub_icon_key(string $key): string 151 + { 152 + return in_array($key, self::VALID_PUB_ICON_KEYS, true) 153 + ? $key 154 + : self::PUB_DEFAULTS["icon_source"]; 155 + } 156 + 157 + /** 158 + * Validate a document title source key, returning the default if invalid. 159 + * 160 + * @param string $key The source key to validate. 161 + * @return string The validated key. 162 + */ 163 + public static function validate_doc_title_key(string $key): string 164 + { 165 + return in_array($key, self::VALID_DOC_TITLE_KEYS, true) 166 + ? $key 167 + : self::DOC_DEFAULTS["title_source"]; 168 + } 169 + 170 + /** 171 + * Validate a document description source key, returning the default if invalid. 172 + * 173 + * @param string $key The source key to validate. 174 + * @return string The validated key. 175 + */ 176 + public static function validate_doc_desc_key(string $key): string 177 + { 178 + return in_array($key, self::VALID_DOC_DESC_KEYS, true) 179 + ? $key 180 + : self::DOC_DEFAULTS["description_source"]; 181 + } 182 + 183 + /** 184 + * Validate a document image source key, returning the default if invalid. 185 + * 186 + * @param string $key The source key to validate. 187 + * @return string The validated key. 188 + */ 189 + public static function validate_doc_image_key(string $key): string 190 + { 191 + return in_array($key, self::VALID_DOC_IMAGE_KEYS, true) 192 + ? $key 193 + : self::DOC_DEFAULTS["image_source"]; 194 + } 195 + 196 + /** 46 197 * Get publication settings merged with defaults. 47 198 * 48 199 * @return array