Skip to content

Commit 7807ac9

Browse files
authored
release: fixes
- Fixed charts using a database source saving the results of the previous query, so a saved chart no longer differs from the data shown in the editor. - Updated dependencies - Enhanced security — fixed unauthorized chart_data REST access.
2 parents 33ff44f + baf67a3 commit 7807ac9

20 files changed

Lines changed: 1009 additions & 46 deletions

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,6 @@ artifacts
1010
classes/Visualizer/Gutenberg/build
1111
classes/Visualizer/ChartBuilder/build
1212
classes/Visualizer/D3Renderer/build
13+
14+
# Local wp-env port pinning (per-checkout).
15+
.wp-env.override.json

.wp-env.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
],
77
"themes": [],
88
"mappings": {
9-
"wp-content/mu-plugins/visualizer-e2e-force-lazy-render.php": "./tests/e2e/config/force-lazy-render.php"
9+
"wp-content/mu-plugins": "./tests/e2e/config/mu-plugins"
1010
},
1111
"config": {
1212
"WP_DEBUG": true,

classes/Visualizer/Gutenberg/Block.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ public function register_rest_endpoints() {
276276
* Get Post Meta Fields
277277
*/
278278
public function get_visualizer_data( $post ) {
279-
if ( ! current_user_can( 'edit_posts' ) ) {
279+
if ( ! Visualizer_Module::can_edit_chart( $post['id'] ) ) {
280280
return false;
281281
}
282282

classes/Visualizer/Module.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ protected function get_inline_custom_css( $id, $settings ) {
650650
$class_name = $id . $name;
651651
$properties = implode( ' !important; ', array_filter( $attributes ) );
652652
if ( ! empty( $properties ) ) {
653-
$css .= '.' . $class_name . ' {' . $properties . ' !important;}';
653+
$css .= wp_strip_all_tags( '.' . $class_name . ' {' . $properties . ' !important;}' );
654654
$classes[ $name ] = $class_name;
655655
}
656656
}

classes/Visualizer/Module/AIBuilder.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ private function _verify_create_nonce(): void {
100100
* @param int $chart_id Chart ID.
101101
*/
102102
private function _verify_chart_access( $chart_id ): void {
103-
if ( ! current_user_can( 'edit_post', $chart_id ) ) {
103+
if ( ! self::can_edit_chart( $chart_id ) ) {
104104
wp_send_json_error( array( 'message' => __( 'Unauthorized.', 'visualizer' ) ), 403 );
105105
}
106106
}
@@ -369,7 +369,7 @@ public function uploadData(): void {
369369

370370
// ── Database query ────────────────────────────────────────────────
371371
case 'db_query':
372-
if ( ! current_user_can( 'manage_options' ) && ! is_super_admin() ) {
372+
if ( ! current_user_can( 'manage_options' ) || ! is_super_admin() || ! Visualizer_Module::is_pro() ) {
373373
wp_send_json_error( array( 'message' => __( 'Action not allowed for this user.', 'visualizer' ) ), 403 );
374374
}
375375
if ( empty( $_POST['db_query'] ) ) {
@@ -502,6 +502,10 @@ public function generateChart(): void {
502502
}
503503
}
504504

505+
if ( ! empty( $workflow_id ) ) {
506+
set_transient( 'viz_ai_wf_' . $workflow_id, get_current_user_id(), 6 * HOUR_IN_SECONDS );
507+
}
508+
505509
wp_send_json_success(
506510
array(
507511
'workflow_id' => $workflow_id,
@@ -524,6 +528,10 @@ public function chartStatus(): void {
524528
wp_send_json_error( array( 'message' => __( 'Missing workflow ID.', 'visualizer' ) ) );
525529
}
526530

531+
if ( (int) get_transient( 'viz_ai_wf_' . $workflow_id ) !== get_current_user_id() ) {
532+
wp_send_json_error( array( 'message' => __( 'Unauthorized.', 'visualizer' ) ), 403 );
533+
}
534+
527535
$agents_url = VISUALIZER_AGENTS_URL;
528536
$workflow_slug = $this->_get_workflow_slug();
529537
$headers = $this->_get_agents_headers();

classes/Visualizer/Module/Wizard.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,12 @@ public function visualizer_enqueue_setup_wizard_scripts() {
153153
* @return bool|void
154154
*/
155155
public function dismissWizard( $redirect_to_dashboard = true ) {
156+
if ( ! current_user_can( 'manage_options' ) ) {
157+
wp_die( esc_html__( 'You do not have permission to perform this action.', 'visualizer' ), '', array( 'response' => 403 ) );
158+
}
159+
if ( false !== $redirect_to_dashboard ) {
160+
check_admin_referer( 'visualizer_dismiss_wizard' );
161+
}
156162
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
157163
$status = isset( $_REQUEST['status'] ) ? (int) $_REQUEST['status'] : 0;
158164
update_option( 'visualizer_fresh_install', $status );
@@ -169,6 +175,9 @@ public function dismissWizard( $redirect_to_dashboard = true ) {
169175
*/
170176
public function visualizer_wizard_step_process() {
171177
check_ajax_referer( VISUALIZER_ABSPATH, 'security' );
178+
if ( ! current_user_can( 'manage_options' ) ) {
179+
wp_send_json( array( 'status' => 0 ), 403 );
180+
}
172181
$step = ! empty( $_POST['step'] ) ? sanitize_text_field( wp_unslash( $_POST['step'] ) ) : 1;
173182
switch ( $step ) {
174183
case 'step_2':

composer.lock

Lines changed: 45 additions & 34 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

js/frame.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,34 @@
479479

480480
init_db_import_component();
481481

482+
var settings_button = document.querySelector( '#settings-button' );
483+
if ( settings_button ) {
484+
settings_button.addEventListener( 'click', function( event ){
485+
$('body').trigger('visualizer:db:query:update', {});
486+
if( $( '#db-chart-button' ).attr( 'data-current' ) !== 'filter' || $( '.visualizer-db-query' ).val().length === 0 ){
487+
return;
488+
}
489+
490+
event.preventDefault();
491+
event.stopImmediatePropagation();
492+
493+
var query_saved = false;
494+
var resume_save = function(){
495+
query_saved = true;
496+
settings_button.click();
497+
};
498+
499+
$('body').one( 'visualizer:render:currentchart:update', resume_save );
500+
$( '#thehole' ).one( 'load', function(){
501+
$('body').off( 'visualizer:render:currentchart:update', resume_save );
502+
if ( ! query_saved ) {
503+
$( '#db-chart-button' ).trigger( 'click' );
504+
}
505+
} );
506+
$( '#db-chart-button' ).trigger( 'click' );
507+
}, true );
508+
}
509+
482510
$('#visualizer-query-fetch').on('click', function(e){
483511

484512
$('body').trigger('visualizer:db:query:update', {});

templates/setup-wizard.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@
66
* @package Templates
77
*/
88

9-
$dashboard_url = add_query_arg(
10-
array(
11-
'action' => 'visualizer_dismiss_wizard',
12-
'status' => 0,
9+
$dashboard_url = wp_nonce_url(
10+
add_query_arg(
11+
array(
12+
'action' => 'visualizer_dismiss_wizard',
13+
'status' => 0,
14+
),
15+
admin_url( 'admin.php' )
1316
),
14-
admin_url( 'admin.php' )
17+
'visualizer_dismiss_wizard'
1518
);
1619

1720
$chart_id = ! empty( $this->wizard_data['chart_id'] ) ? (int) $this->wizard_data['chart_id'] : '';
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
/**
3+
* Enable database-source E2E tests for requests carrying the test cookie.
4+
*/
5+
6+
if ( defined( 'TI_E2E_TESTING' ) && isset( $_COOKIE['visualizer_e2e_database_source'] ) ) {
7+
defined( 'VISUALIZER_PRO_VERSION' ) || define( 'VISUALIZER_PRO_VERSION', '2.0.1' );
8+
9+
if ( ! class_exists( 'Visualizer_Pro' ) ) {
10+
class Visualizer_Pro {
11+
const ACTION_FETCH_DATA = 'visualizer-fetch-data';
12+
const CF_PERMISSIONS = 'visualizer-permissions';
13+
}
14+
}
15+
16+
add_filter( 'visualizer_is_pro', '__return_true', PHP_INT_MAX );
17+
18+
add_filter(
19+
'visualizer_pro_upsell_class',
20+
function ( $class, $feature = '' ) {
21+
return 'db-query' === $feature ? '' : $class;
22+
},
23+
PHP_INT_MAX,
24+
2
25+
);
26+
}

0 commit comments

Comments
 (0)