Plugin Directory

Changeset 3355610


Ignore:
Timestamp:
09/03/2025 06:31:34 PM (7 months ago)
Author:
ganddser
Message:

IMPORTANT! Update immediately. Fixed a security issue that could allow certain unauthorized users to make unwanted changes to schedules. This issue only affects v6.0.4 but we encourage all users to upgrade to 6.0.5 to ensure they're running the most up to date version.

Location:
joan/trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • joan/trunk/assets/js/joan.js

    r3350615 r3355610  
    902902               </div>
    903903            `);
     904                // Hide the element symbol and tooltip if the setting is disabled
     905                {
     906                    const showDayEmoji = (typeof joan_ajax !== 'undefined' && joan_ajax.settings && joan_ajax.settings.joan_show_day_emoji === '1');
     907                    if (!showDayEmoji) {
     908                        const headerElem = $daySection.find('.joan-schedule-day-header');
     909                        headerElem.removeAttr('title');
     910                        // Replace the content with just "Day Schedule"
     911                        headerElem.text(`${day} Schedule`);
     912                    }
     913                }
    904914               
    905915                if (dayShows.length > 0) {
  • joan/trunk/assets/js/schedule-admin.js

    r3343873 r3355610  
    212212            url: ajaxurl,
    213213            type: 'POST',
    214             data: { action: 'joan_schedule_read' },
     214            // Include nonce when requesting the schedule so that the server can validate
     215            data: { action: 'joan_schedule_read', nonce: (typeof joan_admin_ajax !== 'undefined' ? joan_admin_ajax.nonce : '') },
    215216            timeout: 15000,
    216217            beforeSend: function() {
     
    385386        const data = {
    386387            action: 'joan_schedule_create',
     388            nonce: (typeof joan_admin_ajax !== 'undefined' ? joan_admin_ajax.nonce : ''),
    387389            show_name: showName,
    388390            start_day: startDay,
     
    468470        const data = {
    469471            action: 'joan_schedule_update',
     472            nonce: (typeof joan_admin_ajax !== 'undefined' ? joan_admin_ajax.nonce : ''),
    470473            id: id,
    471474            show_name: row.find('.edit-show-name').val().trim(),
     
    533536            url: ajaxurl,
    534537            type: 'POST',
    535             data: { action: 'joan_schedule_delete', id: id },
     538            data: { action: 'joan_schedule_delete', nonce: (typeof joan_admin_ajax !== 'undefined' ? joan_admin_ajax.nonce : ''), id: id },
    536539            timeout: 15000
    537540        })
     
    629632            data: {
    630633                action: 'joan_schedule_save_all',
     634                nonce: (typeof joan_admin_ajax !== 'undefined' ? joan_admin_ajax.nonce : ''),
    631635                changes: changes
    632636            },
  • joan/trunk/includes/admin-menu.php

    r3348419 r3355610  
    412412    $dark_mode_setting = get_option('joan_dark_mode', 'auto');
    413413    $dark_mode_override = get_option('joan_dark_mode_override', '0');
     414
     415    // NEW: Option to toggle the display of day element symbols like [Hg]
     416    // Default to "0" (off) to ensure backwards‑compatibility.  This value is
     417    // sanitized and saved via joan_handle_settings_save().
     418    $show_day_emoji = get_option('joan_show_day_emoji', '0');
    414419   
    415420    ?>
     
    506511                            <strong>Override:</strong> Shows a toggle button for manual control
    507512                        </p>
     513                    </td>
     514                </tr>
     515                <!-- NEW: Option to toggle day element symbols -->
     516                <tr>
     517                    <th scope="row">Day Element Symbols</th>
     518                    <td>
     519                        <fieldset>
     520                            <label>
     521                                <input type="checkbox" name="show_day_emoji" <?php checked($show_day_emoji, '1'); ?> >
     522                                Display chemical element symbols before each day (e.g. [Hg] for Wednesday)
     523                            </label>
     524                        </fieldset>
     525                        <p class="description">Enable to add a small element symbol prefix on each day header of the schedule.</p>
    508526                    </td>
    509527                </tr>
     
    956974            update_option('joan_custom_widget_title', sanitize_text_field($_POST['custom_widget_title']));
    957975            update_option('joan_jock_only_mode', isset($_POST['jock_only_mode']) ? '1' : '0');
     976
     977            // NEW: Save option for showing day element symbols (e.g. [Hg])
     978            update_option('joan_show_day_emoji', isset($_POST['show_day_emoji']) ? '1' : '0');
    958979           
    959980            // NEW: Save dark mode settings
     
    10261047add_action('wp_ajax_joan_schedule_read', function() {
    10271048    global $wpdb;
     1049    // Enforce capability check and nonce verification for reading the schedule.
     1050    // Even though reading is less sensitive than writing, it still performs a privileged
     1051    // database query and should not be accessible to unauthorized users or via CSRF.
     1052    if ( ! current_user_can('manage_joan_schedule') ) {
     1053        wp_send_json_error('Insufficient permissions');
     1054        return;
     1055    }
     1056    if ( ! isset($_POST['nonce']) || ! wp_verify_nonce($_POST['nonce'], 'joan_admin_nonce') ) {
     1057        wp_send_json_error('Invalid nonce');
     1058        return;
     1059    }
    10281060    $table = $wpdb->prefix . 'joan_schedule';
    1029     $results = $wpdb->get_results("SELECT * FROM $table ORDER BY FIELD(start_day, 'Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'), start_time", ARRAY_A);
     1061    $results = $wpdb->get_results(
     1062        "SELECT * FROM $table ORDER BY FIELD(start_day, 'Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'), start_time",
     1063        ARRAY_A
     1064    );
    10301065    wp_send_json($results);
    10311066});
     
    10331068add_action('wp_ajax_joan_schedule_create', function() {
    10341069    global $wpdb;
     1070    // Only allow users with the manage_joan_schedule capability to create shows.
     1071    if ( ! current_user_can('manage_joan_schedule') ) {
     1072        wp_send_json_error('Insufficient permissions');
     1073        return;
     1074    }
     1075    // Validate the nonce to mitigate CSRF attacks.
     1076    if ( ! isset($_POST['nonce']) || ! wp_verify_nonce($_POST['nonce'], 'joan_admin_nonce') ) {
     1077        wp_send_json_error('Invalid nonce');
     1078        return;
     1079    }
    10351080    $table = $wpdb->prefix . 'joan_schedule';
    1036    
    10371081    $data = [
    10381082        'show_name' => sanitize_text_field($_POST['show_name']),
     
    10441088        'link_url' => esc_url_raw($_POST['link_url'])
    10451089    ];
    1046    
    10471090    $result = $wpdb->insert($table, $data);
    1048    
    10491091    if ($result !== false) {
    10501092        wp_send_json_success('Show added successfully');
     
    10561098add_action('wp_ajax_joan_schedule_update', function() {
    10571099    global $wpdb;
     1100    // Restrict update to authorized users.
     1101    if ( ! current_user_can('manage_joan_schedule') ) {
     1102        wp_send_json_error('Insufficient permissions');
     1103        return;
     1104    }
     1105    // Check nonce for CSRF protection.
     1106    if ( ! isset($_POST['nonce']) || ! wp_verify_nonce($_POST['nonce'], 'joan_admin_nonce') ) {
     1107        wp_send_json_error('Invalid nonce');
     1108        return;
     1109    }
    10581110    $table = $wpdb->prefix . 'joan_schedule';
    1059    
    10601111    $id = intval($_POST['id']);
    10611112    $data = [
     
    10681119        'link_url' => esc_url_raw($_POST['link_url'])
    10691120    ];
    1070    
    10711121    $result = $wpdb->update($table, $data, ['id' => $id]);
    1072    
    10731122    if ($result !== false) {
    10741123        wp_send_json_success('Show updated successfully');
     
    10801129add_action('wp_ajax_joan_schedule_delete', function() {
    10811130    global $wpdb;
     1131    // Restrict deletion to authorized users and validate nonce.
     1132    if ( ! current_user_can('manage_joan_schedule') ) {
     1133        wp_send_json_error('Insufficient permissions');
     1134        return;
     1135    }
     1136    if ( ! isset($_POST['nonce']) || ! wp_verify_nonce($_POST['nonce'], 'joan_admin_nonce') ) {
     1137        wp_send_json_error('Invalid nonce');
     1138        return;
     1139    }
    10821140    $table = $wpdb->prefix . 'joan_schedule';
    1083    
    10841141    $id = intval($_POST['id']);
    10851142    $result = $wpdb->delete($table, ['id' => $id]);
    1086    
    10871143    if ($result !== false) {
    10881144        wp_send_json_success('Show deleted successfully');
     
    10941150add_action('wp_ajax_joan_schedule_save_all', function() {
    10951151    global $wpdb;
     1152    // Restrict bulk updates to authorized users and check nonce.
     1153    if ( ! current_user_can('manage_joan_schedule') ) {
     1154        wp_send_json_error('Insufficient permissions');
     1155        return;
     1156    }
     1157    if ( ! isset($_POST['nonce']) || ! wp_verify_nonce($_POST['nonce'], 'joan_admin_nonce') ) {
     1158        wp_send_json_error('Invalid nonce');
     1159        return;
     1160    }
    10961161    $table = $wpdb->prefix . 'joan_schedule';
    1097    
    10981162    $changes = $_POST['changes'];
    1099     if (!is_array($changes)) {
     1163    if ( ! is_array($changes) ) {
    11001164        wp_send_json_error('Invalid data format');
    11011165        return;
    11021166    }
    1103    
    11041167    $updated = 0;
    11051168    $failed = 0;
    1106    
    11071169    foreach ($changes as $change) {
    11081170        $id = intval($change['id']);
     
    11161178            'link_url' => esc_url_raw($change['link_url'])
    11171179        ];
    1118        
    11191180        $result = $wpdb->update($table, $data, ['id' => $id]);
    1120        
    1121         if ($result !== false) {
     1181        if ( $result !== false ) {
    11221182            $updated++;
    11231183        } else {
     
    11251185        }
    11261186    }
    1127    
    1128     if ($failed === 0) {
     1187    if ( $failed === 0 ) {
    11291188        wp_send_json_success("All $updated shows updated successfully");
    11301189    } else {
  • joan/trunk/includes/crud.php

    r3348419 r3355610  
    260260        // NEW: Dark mode settings
    261261        'joan_dark_mode' => get_option('joan_dark_mode', 'auto'),
    262         'joan_dark_mode_override' => get_option('joan_dark_mode_override', '0')
     262        'joan_dark_mode_override' => get_option('joan_dark_mode_override', '0'),
     263        // NEW: show day element symbols setting (chemical symbols like [Hg])
     264        'joan_show_day_emoji' => get_option('joan_show_day_emoji', '0')
    263265    );
    264266}
  • joan/trunk/joan.php

    r3350615 r3355610  
    55 * Description: Display your station's current and upcoming on-air schedule in real-time with timezone awareness, Elementor and Visual Composer/WPBakery Page Builder integration support. Your site visitors can keep track of your on air schedule and their favorite shows.
    66 * Author: G &amp; D Enterprises, Inc.
    7  * Version: 6.0.4
     7 * Version: 6.0.5
    88 * Author URI: https://www.gandenterprisesinc.com
    99 * Text Domain: joan
     
    231231            'widget_max_width' => get_option('joan_widget_max_width', '300'),
    232232            'joan_dark_mode' => get_option('joan_dark_mode', 'auto'),
    233             'joan_dark_mode_override' => get_option('joan_dark_mode_override', '0')
     233            'joan_dark_mode_override' => get_option('joan_dark_mode_override', '0'),
     234            // NEW: show day element symbols setting
     235            'joan_show_day_emoji' => get_option('joan_show_day_emoji', '0')
    234236        ]
    235237    ]);
  • joan/trunk/readme.txt

    r3350615 r3355610  
    66Tested up to: 6.8 
    77Requires PHP: 7.2 
    8 Stable tag: 6.0.4 
     8Stable tag: 6.0.5 
    99License: GPLv2 or later 
    1010License URI: https://www.gnu.org/licenses/gpl-2.0.html 
     
    140140
    141141== Changelog ==
     142
     143
     144=6.0.5 - 2025-9-3 =
     145* **Fixed a security issue that could allow certain unauthorized users to make unwanted changes to schedules. Update immediately.
    142146
    143147= 6.0.4 - 2025-08-26 =
Note: See TracChangeset for help on using the changeset viewer.