diff --git a/.env.testing b/.env.testing
index 0bf105f10e081da1df165fc1221a96d779f428e5..2e2439fb86e393d989f62a1adfeb989d7b8e8bc2 100644
--- a/.env.testing
+++ b/.env.testing
@@ -12,7 +12,7 @@ TEST_DB_PASSWORD="mysql"
 TEST_TABLE_PREFIX="wp_"
 TEST_SITE_WP_URL="http://${WOOTESTS_IP}"
 TEST_SITE_WP_DOMAIN="${WOOTESTS_IP}"
-TEST_SITE_ADMIN_EMAIL="grola@seostudio.pl"
+TEST_SITE_ADMIN_EMAIL="grola@octolize.dev"
 TEST_SITE_ADMIN_USERNAME="admin"
 TEST_SITE_ADMIN_PASSWORD="admin"
 SELENIUM_HOST="chrome"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9a60d64d33408087290e887d27ca1deb5066637e..325f248203dd8f5f0ee946b6fef3cee0dc648a25 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,11 @@
+## [3.2.4] - 2024-03-11
+### Fixed
+- permission check on notice dismiss action
+
 ## [3.2.3] - 2023-04-06
 ### Fixed
 - fatal error if get_current_screen function return null
+
 ## [3.2.2] - 2023-03-03
 ### Added
 - security nonce in permanent dismissible notice ajax action
diff --git a/src/WPDesk/Notice/AjaxHandler.php b/src/WPDesk/Notice/AjaxHandler.php
index 263e84b7ff630f977fdbd356c785ffc01792e152..64c9b7141b4bdc34ef6c2725831842ef26e3240a 100644
--- a/src/WPDesk/Notice/AjaxHandler.php
+++ b/src/WPDesk/Notice/AjaxHandler.php
@@ -78,25 +78,26 @@ class AjaxHandler implements HookablePluginDependant {
         if ( isset( $_POST[ self::POST_FIELD_NOTICE_NAME ] ) ) {
             $noticeName = sanitize_text_field( $_POST[ self::POST_FIELD_NOTICE_NAME ] );
 
+            $optionName = PermanentDismissibleNotice::OPTION_NAME_PREFIX . $noticeName;
+            check_ajax_referer( $optionName, self::POST_FIELD_SECURITY );
+
+            if ( ! current_user_can( 'edit_posts' ) ) {
+                wp_send_json_error();
+            }
+
             if ( isset( $_POST[ self::POST_FIELD_SOURCE ] ) ) {
                 $source = sanitize_text_field( $_POST[ self::POST_FIELD_SOURCE ] );
             } else {
                 $source = null;
             }
 
-            $security = $_POST[ self::POST_FIELD_SECURITY ] ?? '';
-
-            $option_name = PermanentDismissibleNotice::OPTION_NAME_PREFIX . $noticeName;
-
-            if ( wp_verify_nonce( $security, $option_name ) ) {
-                update_option(
-                    $option_name,
-                    PermanentDismissibleNotice::OPTION_VALUE_DISMISSED
-                );
-                do_action( 'wpdesk_notice_dismissed_notice', $noticeName, $source );
-                if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
-                    wp_send_json_success();
-                }
+            update_option(
+                $optionName,
+                PermanentDismissibleNotice::OPTION_VALUE_DISMISSED
+            );
+            do_action( 'wpdesk_notice_dismissed_notice', $noticeName, $source );
+            if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
+                wp_send_json_success();
             }
         }
         if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
@@ -105,4 +106,3 @@ class AjaxHandler implements HookablePluginDependant {
     }
 
 }
-
diff --git a/tests/codeception/tests/integration.suite.yml b/tests/codeception/tests/integration.suite.yml
index 25ef607c1f3de3ce2340ad644c5ee1059b6e602d..ea39b1159166f4b810620668f3c62e54e7c82768 100644
--- a/tests/codeception/tests/integration.suite.yml
+++ b/tests/codeception/tests/integration.suite.yml
@@ -30,7 +30,7 @@ modules:
             dbHost: "%TEST_SITE_DB_HOST%"
             dbUser: "%TEST_SITE_DB_USER%"
             dbPassword: "%TEST_SITE_DB_PASSWORD%"
-            isolatedInstall: false
+            isolatedInstall: true
             loadOnly: false
             tablePrefix: "%TEST_SITE_TABLE_PREFIX%"
             plugins: []
diff --git a/tests/codeception/tests/integration/AjaxHandlerTest.php b/tests/codeception/tests/integration/AjaxHandlerTest.php
index c0f40f9992362437d5efe3657ea9a396eef03657..486a60f273cc35bbe5f4fe5447854b858c0563f3 100644
--- a/tests/codeception/tests/integration/AjaxHandlerTest.php
+++ b/tests/codeception/tests/integration/AjaxHandlerTest.php
@@ -14,12 +14,22 @@ class AjaxHandlerTest extends WPTestCase {
 
     public function setUp() {
         parent::setUp();
+        add_filter( 'wp_doing_ajax', '__return_true' );
+        add_filter( 'wp_die_ajax_handler', array( $this, 'getDieHandler' ), 1, 1 );
     }
 
     public function tearDown() {
         parent::tearDown();
     }
 
+    public function getDieHandler( $handler ) {
+        return array( $this, 'dieHandler' );
+    }
+
+    public function dieHandler( $message, $title, $args ) {
+        throw new \Exception( $message );
+    }
+
 	public function testHooksWithAssetsURL() {
 		$ajaxHandler = new AjaxHandler( self::ASSETS_URL );
 		$ajaxHandler->hooks();
@@ -77,25 +87,40 @@ class AjaxHandlerTest extends WPTestCase {
 		$ajaxHandler->addScriptToAdminHead();
 	}
 
-	public function testProcessAjaxNoticeDismiss() {
-		$_POST[ AjaxHandler::POST_FIELD_NOTICE_NAME ] = self::NOTICE_NAME;
-        $_POST[ AjaxHandler::POST_FIELD_SECURITY ] = wp_create_nonce( PermanentDismissibleNotice::OPTION_NAME_PREFIX . sanitize_text_field( self::NOTICE_NAME ) );
+    public function testProcessAjaxNoticeDismiss() {
+        $user_name = 'test_user';
+        $random_password = wp_generate_password( $length = 12, $include_standard_special_chars = false );
+        $user_email = 'test@wpdesk.dev';
+        $user_id = wp_create_user( $user_name, $random_password, $user_email );
+        $user = new \WP_User( $user_id );
+        $user->set_role( 'administrator' );
+        $user->save();
+        wp_set_current_user( $user_id );
+
+        $_POST[ AjaxHandler::POST_FIELD_NOTICE_NAME ] = self::NOTICE_NAME;
+        $_REQUEST[ AjaxHandler::POST_FIELD_SECURITY ] = wp_create_nonce( PermanentDismissibleNotice::OPTION_NAME_PREFIX . sanitize_text_field( self::NOTICE_NAME ) );
 
         $ajaxHandler = new AjaxHandler( self::ASSETS_URL );
-		$ajaxHandler->processAjaxNoticeDismiss();
+        $ajaxHandler->processAjaxNoticeDismiss();
 
-		$this->assertEquals(
-			PermanentDismissibleNotice::OPTION_VALUE_DISMISSED,
-			get_option( PermanentDismissibleNotice::OPTION_NAME_PREFIX . self::NOTICE_NAME )
-		);
-	}
+        $this->assertEquals(
+            PermanentDismissibleNotice::OPTION_VALUE_DISMISSED,
+            get_option( PermanentDismissibleNotice::OPTION_NAME_PREFIX . self::NOTICE_NAME, '0' )
+        );
+
+        wp_delete_user( $user_id );
+    }
 
     public function testShoulfNotProcessAjaxNoticeDismissWhenInvalidNonce() {
         $_POST[ AjaxHandler::POST_FIELD_NOTICE_NAME ] = self::NOTICE_NAME;
-        $_POST[ AjaxHandler::POST_FIELD_SECURITY ] = wp_create_nonce();
+        $_REQUEST[ AjaxHandler::POST_FIELD_SECURITY ] = wp_create_nonce();
 
         $ajaxHandler = new AjaxHandler( self::ASSETS_URL );
-        $ajaxHandler->processAjaxNoticeDismiss();
+        try {
+            $ajaxHandler->processAjaxNoticeDismiss();
+        } catch ( \Exception $e ) {
+            $this->assertEquals('-1', $e->getMessage());
+        }
 
         $this->assertNotEquals(
             PermanentDismissibleNotice::OPTION_VALUE_DISMISSED,
diff --git a/tests/codeception/wpdesk.yml b/tests/codeception/wpdesk.yml
index 870a58cd2df9c7068dc7ac1101dc3c7d0c639a83..b0bbcb51c9122ff5fb21be7ac0cc2f5e9022771a 100644
--- a/tests/codeception/wpdesk.yml
+++ b/tests/codeception/wpdesk.yml
@@ -3,6 +3,7 @@ plugin-file: none
 plugin-title: none
 plugins:
   repository:
+    - woocommerce
   local:
   activate:
 prepare-database: