VYPR
High severityNVD Advisory· Published Aug 22, 2025· Updated Aug 22, 2025

unopim/unopim allows unauthorized product deletion via mass-delete endpoint

CVE-2025-55741

Description

UnoPim is an open-source Product Information Management (PIM) system built on the Laravel framework. In versions 0.3.0 and earlier, users without the Delete privilege for products are unable to delete individual products via the standard endpoint, as expected. However, these users can bypass intended access controls by issuing requests to the mass-delete endpoint, allowing them to delete products without proper authorization. This vulnerability allows unauthorized product deletion, leading to potential data loss and business disruption. The issue is fixed in version 0.3.1. No known workarounds exist.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

In UnoPim <=0.3.0, users lacking the Delete privilege can delete products by using the mass-delete endpoint instead of the individual delete endpoint.

UnoPim is an open-source Product Information Management (PIM) system built on the Laravel framework. In version 0.3.0 and earlier, the application implements access control checks for the standard product delete endpoint (admin.catalog.products.delete), preventing users without the Delete privilege from deleting individual products. However, the mass-delete endpoint (admin.catalog.products.mass_delete) lacks a corresponding access control check, allowing users to bypass the intended authorization [1].

To exploit this vulnerability, an authenticated user who possesses a role without the explicit "Delete" permission for products can send a request directly to the mass-delete endpoint. The application does not verify whether the user has the appropriate privilege for mass deletion, enabling the unauthorized removal of products [3].

The impact of this vulnerability is that an attacker with a low-privileged account can delete products from the system, leading to potential data loss and business disruption [1]. This could compromise product catalogs and affect downstream operations that rely on accurate product data.

The vulnerability is fixed in version 0.3.1. The fix introduces dedicated ACL keys for mass actions, including catalog.products.mass_delete, ensuring that access controls are properly enforced on the mass-delete endpoint [3]. No known workarounds exist [1].

AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
unopim/unopimPackagist
< 0.3.10.3.1

Affected products

2
  • UnoPim/UnoPimllm-create
    Range: <=0.3.0
  • unopim/unopimv5
    Range: < 0.3.1

Patches

2
f49fa630afd3

Merge pull request #194 from kunal-webkul/master

https://github.com/unopim/unopimNavneet WebkulAug 22, 2025via ghsa
3 files changed · +5 11
  • .github/workflows/playwright_test.yml+1 1 modified
    @@ -75,7 +75,7 @@ jobs:
               cd tests/e2e-pw
               npm install
               npx playwright install --with-deps
    -          npx playwright test
    +          npx playwright test --reporter=list
     
           - name: Upload Playwright report
             if: always()
    
  • tests/e2e-pw/tests/catalog/category.spec.js+2 8 modified
    @@ -55,7 +55,9 @@ test('Create Categories with all field', async ({ page }) => {
       await page.locator('#name').type('Television');
       await page.waitForTimeout(100);
       await page.getByRole('button', { name: 'Save Category' }).click();
    +  await page.waitForTimeout(500);
       await expect(page.getByText(/Category created successfully/i)).toBeVisible();
    +  await page.waitForTimeout(500);
     });
     
     test('should allow category search', async ({ page }) => {
    @@ -116,14 +118,6 @@ test('Update Categories', async ({ page }) => {
       await expect(page.getByText(/Category updated successfully/i)).toBeVisible();
     });
     
    -test('Delete Category', async ({ page }) => {
    -  await page.getByRole('link', { name: ' Catalog' }).click();
    -  await page.getByRole('link', { name: 'Categories' }).click();
    -  await page.getByText('LG TelevisionLG Televisiontest1').getByTitle('Delete').click();
    -  await page.getByRole('button', { name: 'Delete' }).click();
    -  await expect(page.getByText(/The category has been successfully deleted/i)).toBeVisible();
    -});
    -
     test('Delete Root Category', async ({ page }) => {
       await page.getByRole('link', { name: ' Catalog' }).click();
       await page.getByRole('link', { name: 'Categories' }).click();
    
  • tests/e2e-pw/tests/settings/role.spec.js+2 2 modified
    @@ -1,7 +1,7 @@
     import { test, expect } from '@playwright/test';
     test.describe('UnoPim Test cases(Administrator Role)', () => {
     test.beforeEach(async ({ page }) => {
    -   await page.goto('http://127.0.0.1:8000/admin/login');
    +  await page.goto('http://127.0.0.1:8000/admin/login');
       await page.getByRole('textbox', { name: 'Email Address' }).fill('admin@example.com');
       await page.getByRole('textbox', { name: 'Password' }).fill('admin123');
       await page.getByRole('button', { name: 'Sign In' }).click();
    @@ -137,7 +137,7 @@ test('Update Custom Roles', async ({ page }) => {
       await page.getByRole('link', { name: 'Roles' }).click();
       const itemRow = page.locator('div', { hasText: 'Catalog Manager' });
       await itemRow.locator('span[title="Edit"]').first().click();
    -  await page.locator('div').filter({ hasText: /^CategoriesCreateEditDelete$/ }).locator('span').nth(3).click();
    +  await page.locator('label').filter({ hasText: 'Categories' }).locator('span').click();
       await page.getByRole('button', { name: 'Save Role' }).click();
       await expect(page.getByText(/Roles is updated successfully./i).first()).toBeVisible();
     });
    
c14eebe653aa

Merge pull request #191 from devansh-pal-webkul/bugfix/missingacl-permissions

https://github.com/unopim/unopimNavneet KumarAug 18, 2025via ghsa
50 files changed · +439 29
  • packages/Webkul/Admin/src/Config/acl.php+51 1 modified
    @@ -55,6 +55,16 @@
             'name'  => 'admin::app.acl.delete',
             'route' => 'admin.catalog.products.delete',
             'sort'  => 4,
    +    ], [
    +        'key'   => 'catalog.products.mass_update',
    +        'name'  => 'admin::app.acl.mass-update',
    +        'route' => 'admin.catalog.products.mass_update',
    +        'sort'  => 5,
    +    ], [
    +        'key'   => 'catalog.products.mass_delete',
    +        'name'  => 'admin::app.acl.mass-delete',
    +        'route' => 'admin.catalog.products.mass_delete',
    +        'sort'  => 6,
         ], [
             'key'   => 'catalog.categories',
             'name'  => 'admin::app.acl.categories',
    @@ -75,6 +85,11 @@
             'name'  => 'admin::app.acl.delete',
             'route' => 'admin.catalog.categories.delete',
             'sort'  => 3,
    +    ], [
    +        'key'   => 'catalog.categories.mass_delete',
    +        'name'  => 'admin::app.acl.mass-delete',
    +        'route' => 'admin.catalog.categories.mass_delete',
    +        'sort'  => 4,
         ], [
             'key'   => 'catalog.category_fields',
             'name'  => 'admin::app.acl.category_fields',
    @@ -95,6 +110,16 @@
             'name'  => 'admin::app.acl.delete',
             'route' => 'admin.catalog.category_fields.delete',
             'sort'  => 3,
    +    ], [
    +        'key'   => 'catalog.category_fields.mass_update',
    +        'name'  => 'admin::app.acl.mass-update',
    +        'route' => 'admin.catalog.category_fields.mass_update',
    +        'sort'  => 4,
    +    ], [
    +        'key'   => 'catalog.category_fields.mass_delete',
    +        'name'  => 'admin::app.acl.mass-delete',
    +        'route' => 'admin.catalog.category_fields.mass_delete',
    +        'sort'  => 5,
         ], [
             'key'   => 'catalog.attributes',
             'name'  => 'admin::app.acl.attributes',
    @@ -115,6 +140,11 @@
             'name'  => 'admin::app.acl.delete',
             'route' => 'admin.catalog.attributes.delete',
             'sort'  => 3,
    +    ], [
    +        'key'   => 'catalog.attributes.mass_delete',
    +        'name'  => 'admin::app.acl.mass-delete',
    +        'route' => 'admin.catalog.attributes.mass_delete',
    +        'sort'  => 4,
         ], [
             'key'   => 'catalog.attribute_groups',
             'name'  => 'admin::app.acl.attribute-groups',
    @@ -275,6 +305,16 @@
             'name'  => 'admin::app.acl.delete',
             'route' => 'admin.settings.locales.delete',
             'sort'  => 3,
    +    ], [
    +        'key'   => 'settings.locales.mass_update',
    +        'name'  => 'admin::app.acl.mass-update',
    +        'route' => 'admin.settings.locales.mass_update',
    +        'sort'  => 4,
    +    ], [
    +        'key'   => 'settings.locales.mass_delete',
    +        'name'  => 'admin::app.acl.mass-delete',
    +        'route' => 'admin.settings.locales.mass_delete',
    +        'sort'  => 5,
         ], [
             'key'   => 'settings.currencies',
             'name'  => 'admin::app.acl.currencies',
    @@ -295,7 +335,17 @@
             'name'  => 'admin::app.acl.delete',
             'route' => 'admin.settings.currencies.delete',
             'sort'  => 3,
    -    ],  [
    +    ], [
    +        'key'   => 'settings.currencies.mass_update',
    +        'name'  => 'admin::app.acl.mass-update',
    +        'route' => 'admin.settings.currencies.mass_update',
    +        'sort'  => 4,
    +    ], [
    +        'key'   => 'settings.currencies.mass_delete',
    +        'name'  => 'admin::app.acl.mass-delete',
    +        'route' => 'admin.settings.currencies.mass_delete',
    +        'sort'  => 5,
    +    ], [
             'key'   => 'settings.channels',
             'name'  => 'admin::app.acl.channels',
             'route' => 'admin.settings.channels.index',
    
  • packages/Webkul/Admin/src/DataGrids/Catalog/AttributeDataGrid.php+1 1 modified
    @@ -169,7 +169,7 @@ public function prepareActions()
          */
         public function prepareMassActions()
         {
    -        if (bouncer()->hasPermission('catalog.attributes.delete')) {
    +        if (bouncer()->hasPermission('catalog.attributes.mass_delete')) {
                 $this->addMassAction([
                     'icon'    => 'icon-delete',
                     'title'   => trans('admin::app.catalog.attributes.index.datagrid.delete'),
    
  • packages/Webkul/Admin/src/DataGrids/Catalog/CategoryDataGrid.php+1 1 modified
    @@ -145,7 +145,7 @@ public function prepareActions()
          */
         public function prepareMassActions()
         {
    -        if (bouncer()->hasPermission('catalog.categories.delete')) {
    +        if (bouncer()->hasPermission('catalog.categories.mass_delete')) {
                 $this->addMassAction([
                     'title'   => trans('admin::app.catalog.categories.index.datagrid.delete'),
                     'method'  => 'POST',
    
  • packages/Webkul/Admin/src/DataGrids/Catalog/CategoryFieldDataGrid.php+2 2 modified
    @@ -170,7 +170,7 @@ public function prepareActions()
          */
         public function prepareMassActions()
         {
    -        if (bouncer()->hasPermission('catalog.category_fields.delete')) {
    +        if (bouncer()->hasPermission('catalog.category_fields.mass_delete')) {
                 $this->addMassAction([
                     'icon'    => 'icon-delete',
                     'title'   => trans('admin::app.catalog.category_fields.index.datagrid.delete'),
    @@ -180,7 +180,7 @@ public function prepareMassActions()
                 ]);
             }
     
    -        if (bouncer()->hasPermission('catalog.category_fields.edit')) {
    +        if (bouncer()->hasPermission('catalog.category_fields.mass_update')) {
                 $this->addMassAction([
                     'icon'    => 'icon-edit',
                     'title'   => trans('admin::app.catalog.category_fields.index.datagrid.update-status'),
    
  • packages/Webkul/Admin/src/DataGrids/Catalog/ProductDataGrid.php+2 2 modified
    @@ -325,7 +325,7 @@ public function prepareActions()
          */
         public function prepareMassActions()
         {
    -        if (bouncer()->hasPermission('catalog.products.delete')) {
    +        if (bouncer()->hasPermission('catalog.products.mass_delete')) {
                 $this->addMassAction([
                     'title'   => trans('admin::app.catalog.products.index.datagrid.delete'),
                     'url'     => route('admin.catalog.products.mass_delete'),
    @@ -334,7 +334,7 @@ public function prepareMassActions()
                 ]);
             }
     
    -        if (bouncer()->hasPermission('catalog.products.edit')) {
    +        if (bouncer()->hasPermission('catalog.products.mass_update')) {
                 $this->addMassAction([
                     'title'   => trans('admin::app.catalog.products.index.datagrid.update-status'),
                     'url'     => route('admin.catalog.products.mass_update'),
    
  • packages/Webkul/Admin/src/DataGrids/Settings/CurrencyDataGrid.php+2 2 modified
    @@ -139,7 +139,7 @@ public function prepareActions()
          */
         public function prepareMassActions()
         {
    -        if (bouncer()->hasPermission('settings.currencies.edit')) {
    +        if (bouncer()->hasPermission('settings.currencies.mass_update')) {
                 $this->addMassAction([
                     'title'   => trans('admin::app.settings.currencies.index.datagrid.mass-update'),
                     'url'     => route('admin.settings.currencies.mass_update'),
    @@ -156,7 +156,7 @@ public function prepareMassActions()
                 ]);
             }
     
    -        if (bouncer()->hasPermission('settings.currencies.delete')) {
    +        if (bouncer()->hasPermission('settings.currencies.mass_delete')) {
                 $this->addMassAction([
                     'title'   => trans('admin::app.settings.currencies.index.datagrid.delete'),
                     'url'     => route('admin.settings.currencies.mass_delete'),
    
  • packages/Webkul/Admin/src/DataGrids/Settings/LocalesDataGrid.php+2 2 modified
    @@ -134,7 +134,7 @@ public function prepareActions()
          */
         public function prepareMassActions()
         {
    -        if (bouncer()->hasPermission('settings.locales.edit')) {
    +        if (bouncer()->hasPermission('settings.locales.mass_update')) {
                 $this->addMassAction([
                     'title'   => trans('admin::app.settings.locales.index.datagrid.mass-update'),
                     'url'     => route('admin.settings.locales.mass_update'),
    @@ -151,7 +151,7 @@ public function prepareMassActions()
                 ]);
             }
     
    -        if (bouncer()->hasPermission('settings.locales.delete')) {
    +        if (bouncer()->hasPermission('settings.locales.mass_delete')) {
                 $this->addMassAction([
                     'title'   => trans('admin::app.settings.locales.index.datagrid.delete'),
                     'url'     => route('admin.settings.locales.mass_delete'),
    
  • packages/Webkul/Admin/src/Resources/lang/ar_AE/app.php+2 0 modified
    @@ -2442,6 +2442,8 @@
             'restore'                  => 'يعيد',
             'integrations'             => 'التكامل',
             'api'                      => 'واجهة برمجة التطبيقات',
    +        'mass-update'              => 'تحديث جماعي',
    +        'mass-delete'              => 'حذف جماعي',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/ca_ES/app.php+2 0 modified
    @@ -1987,6 +1987,8 @@
             'tracker'                  => 'Rastrejador de treball',
             'imports'                  => 'Imports',
             'exports'                  => 'Exports',
    +        'mass-update'              => 'Actualització en massa',
    +        'mass-delete'              => 'Eliminació en massa',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/da_DK/app.php+2 0 modified
    @@ -1597,6 +1597,8 @@
             'tracker'                  => 'Job Tracker',
             'imports'                  => 'Importer',
             'exports'                  => 'Eksporter',
    +        'mass-update'              => 'Masseopdatering',
    +        'mass-delete'              => 'Masse sletning',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/de_DE/app.php+2 0 modified
    @@ -1992,6 +1992,8 @@
             'tracker'                  => 'Job-Tracker',
             'imports'                  => 'Importe',
             'exports'                  => 'Exporte',
    +        'mass-update'              => 'Massenaktualisierung',
    +        'mass-delete'              => 'Massenlöschung',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/en_AU/app.php+2 0 modified
    @@ -1593,6 +1593,8 @@
             'tracker'                  => 'Job Tracker',
             'imports'                  => 'Imports',
             'exports'                  => 'Exports',
    +        'mass-update'              => 'Mass Update',
    +        'mass-delete'              => 'Mass Delete',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/en_GB/app.php+2 0 modified
    @@ -1599,6 +1599,8 @@
             'tracker'                  => 'Job Tracker',
             'imports'                  => 'Imports',
             'exports'                  => 'Exports',
    +        'mass-update'              => 'Mass Update',
    +        'mass-delete'              => 'Mass Delete',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/en_NZ/app.php+2 0 modified
    @@ -1597,6 +1597,8 @@
             'tracker'                  => 'Job Tracker',
             'imports'                  => 'Imports',
             'exports'                  => 'Exports',
    +        'mass-update'              => 'Mass Update',
    +        'mass-delete'              => 'Mass Delete',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/en_US/app.php+2 0 modified
    @@ -1996,6 +1996,8 @@
             'tracker'                  => 'Job Tracker',
             'imports'                  => 'Imports',
             'exports'                  => 'Exports',
    +        'mass-update'              => 'Mass Update',
    +        'mass-delete'              => 'Mass Delete',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/es_ES/app.php+2 0 modified
    @@ -1997,6 +1997,8 @@
             'restore'                  => 'Restaurar',
             'integrations'             => 'Integraciones',
             'api'                      => 'API',
    +        'mass-update'              => 'Actualización masiva',
    +        'mass-delete'              => 'Eliminación en masa',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/es_VE/app.php+2 0 modified
    @@ -1596,6 +1596,8 @@
             'tracker'                  => 'Rastreador de trabajos',
             'imports'                  => 'Importaciones',
             'exports'                  => 'Exportaciones',
    +        'mass-update'              => 'Actualización masiva',
    +        'mass-delete'              => 'Eliminación en masa',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/fi_FI/app.php+2 0 modified
    @@ -1595,6 +1595,8 @@
             'tracker'                  => 'Työseuranta',
             'imports'                  => 'Tuonti',
             'exports'                  => 'Vienti',
    +        'mass-update'              => 'Määräpäivitys',
    +        'mass-delete'              => 'Määräpoisto',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/fr_FR/app.php+2 0 modified
    @@ -1963,6 +1963,8 @@
             'api'                => 'API',
             'tracker'            => 'Suivi des tâches',
             'exports'            => 'Exports',
    +        'mass-update'        => 'Mise à jour en masse',
    +        'mass-delete'        => 'Suppression en masse',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/hi_IN/app.php+2 0 modified
    @@ -2441,6 +2441,8 @@
             'restore'                  => 'पुनर्स्थापित करना',
             'integrations'             => 'एकीकरण',
             'api'                      => 'एपीआई',
    +        'mass-update'              => 'सामूहिक अद्यतन',
    +        'mass-delete'              => 'सामूहिक हटाना',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/hr_HR/app.php+2 0 modified
    @@ -1596,6 +1596,8 @@
             'tracker'                  => 'Praćenje poslova',
             'imports'                  => 'Uvozi',
             'exports'                  => 'Izvozi',
    +        'mass-update'              => 'Masovno ažuriranje',
    +        'mass-delete'              => 'Masovno brisanje',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/id_ID/app.php+2 0 modified
    @@ -2016,6 +2016,8 @@
             'tracker'                  => 'Pelacak Pekerjaan',
             'imports'                  => 'Impor',
             'exports'                  => 'Ekspor',
    +        'mass-update'              => 'Pembaruan massal',
    +        'mass-delete'              => 'Penghapusan massal',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/it_IT/app.php+2 0 modified
    @@ -1595,6 +1595,8 @@
             'tracker'                  => 'Tracker di lavoro',
             'imports'                  => 'Importazioni',
             'exports'                  => 'Esportazioni',
    +        'mass-update'              => 'Aggiornamento di massa',
    +        'mass-delete'              => 'Eliminazione di massa',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/ja_JP/app.php+2 0 modified
    @@ -1992,6 +1992,8 @@
             'tracker'                  => 'ジョブ トラッカー',
             'imports'                  => 'インポート',
             'exports'                  => 'エクスポート',
    +        'mass-update'              => '一括更新',
    +        'mass-delete'              => '一括削除',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/ko_KR/app.php+2 0 modified
    @@ -1596,6 +1596,8 @@
             'tracker'                  => '추적기',
             'imports'                  => '임포트',
             'exports'                  => '임포트',
    +        'mass-update'              => '대량 업데이트',
    +        'mass-delete'              => '대량 삭제',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/mn_MN/app.php+2 0 modified
    @@ -2442,6 +2442,8 @@
             'restore'                  => 'Сэргээх',
             'integrations'             => 'Бүртгэл',
             'api'                      => 'Api',
    +        'mass-update'              => '[translation needed]',
    +        'mass-delete'              => '[translation needed]',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/nl_NL/app.php+2 0 modified
    @@ -2442,6 +2442,8 @@
             'restore'                  => 'Herstellen',
             'integrations'             => 'Integratie',
             'api'                      => 'API',
    +        'mass-update'              => 'Massabijwerking',
    +        'mass-delete'              => 'Massaverwijdering',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/no_NO/app.php+2 0 modified
    @@ -1596,6 +1596,8 @@
             'tracker'                  => 'Jobbspor',
             'imports'                  => 'Importer',
             'exports'                  => 'Eksporter',
    +        'mass-update'              => 'Masseoppdatering',
    +        'mass-delete'              => 'Masse sletting',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/pl_PL/app.php+2 0 modified
    @@ -1596,6 +1596,8 @@
             'tracker'                  => 'Śledzenie',
             'imports'                  => 'Importy',
             'exports'                  => 'Eksporty',
    +        'mass-update'              => 'Masowa aktualizacja',
    +        'mass-delete'              => 'Masowe usuwanie',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/pt_BR/app.php+2 0 modified
    @@ -1596,6 +1596,8 @@
             'tracker'                  => 'Rastreamento de Tarefas',
             'imports'                  => 'Importações',
             'exports'                  => 'Exportações',
    +        'mass-update'              => 'Atualização em massa',
    +        'mass-delete'              => 'Exclusão em massa',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/pt_PT/app.php+2 0 modified
    @@ -1596,6 +1596,8 @@
             'tracker'                  => 'Rastreamento de Tarefas',
             'imports'                  => 'Importações',
             'exports'                  => 'Exportações',
    +        'mass-update'              => 'Atualização em massa',
    +        'mass-delete'              => 'Eliminação em massa',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/ro_RO/app.php+2 0 modified
    @@ -1596,6 +1596,8 @@
             'tracker'                  => 'Urmărire sarcini',
             'imports'                  => 'Importuri',
             'exports'                  => 'Exporturi',
    +        'mass-update'              => 'Actualizare în masă',
    +        'mass-delete'              => 'Ștergere în masă',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/ru_RU/app.php+2 0 modified
    @@ -2441,6 +2441,8 @@
             'restore'                  => 'Восстановить',
             'integrations'             => 'Интеграции',
             'api'                      => 'API',
    +        'mass-update'              => 'Массовое обновление',
    +        'mass-delete'              => 'Массовое удаление',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/sv_SE/app.php+2 0 modified
    @@ -1596,6 +1596,8 @@
             'tracker'                  => 'Uppgiftsspårning',
             'imports'                  => 'Importer',
             'exports'                  => 'Exporter',
    +        'mass-update'              => 'Massuppdatering',
    +        'mass-delete'              => 'Massradering',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/tl_PH/app.php+2 0 modified
    @@ -1596,6 +1596,8 @@
             'tracker'                  => 'Tagasunod ng Trabaho',
             'imports'                  => 'Mga Pag-import',
             'exports'                  => 'Mga Pag-export',
    +        'mass-update'              => 'Maramihang pag-update',
    +        'mass-delete'              => 'Maramihang pagtanggal',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/tr_TR/app.php+2 0 modified
    @@ -1596,6 +1596,8 @@
             'tracker'                  => 'İş Takibi',
             'imports'                  => 'İçe Aktarımlar',
             'exports'                  => 'Dışa Aktarımlar',
    +        'mass-update'              => 'Toplu güncelleme',
    +        'mass-delete'              => 'Toplu silme',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/uk_UA/app.php+2 0 modified
    @@ -1596,6 +1596,8 @@
             'tracker'                  => 'Моніторинг завдань',
             'imports'                  => 'Імпорти',
             'exports'                  => 'Експорти',
    +        'mass-update'              => 'Масове оновлення',
    +        'mass-delete'              => 'Масове видалення',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/vi_VN/app.php+2 0 modified
    @@ -1596,6 +1596,8 @@
             'tracker'                  => 'Theo dõi công việc',
             'imports'                  => 'Nhập khẩu',
             'exports'                  => 'Xuất khẩu',
    +        'mass-update'              => 'Cập nhật hàng loạt',
    +        'mass-delete'              => 'Xóa hàng loạt',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/zh_CN/app.php+2 0 modified
    @@ -1992,6 +1992,8 @@
             'tracker'                  => '工作追踪',
             'imports'                  => '导入',
             'exports'                  => '出口',
    +        'mass-update'              => '批量更新',
    +        'mass-delete'              => '批量删除',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/lang/zh_TW/app.php+2 0 modified
    @@ -1596,6 +1596,8 @@
             'tracker'                  => '工作追踪器',
             'imports'                  => '導入',
             'exports'                  => '出口',
    +        'mass-update'              => '批次更新',
    +        'mass-delete'              => '批次刪除',
         ],
     
         'errors' => [
    
  • packages/Webkul/Admin/src/Resources/views/catalog/categories/index.blade.php+4 2 modified
    @@ -30,6 +30,8 @@
         >
             @php
                 $hasPermission = bouncer()->hasPermission('catalog.categories.edit') || bouncer()->hasPermission('catalog.categories.delete');
    +
    +            $hasMassActionPermission = bouncer()->hasPermission('catalog.categories.mass_delete');
             @endphp
             
             <template #header="{ columns, records, sortPage, selectAllRecords, applied, isLoading, actions}">
    @@ -42,7 +44,7 @@ class="row grid grid-rows-1 gap-2.5 items-center px-4 py-2.5 border-b bg-violet-
                             class="flex items-center select-none"
                             v-for="(columnGroup, index) in ['display_name', 'category_name', 'code']"
                         >
    -                        @if ($hasPermission)
    +                        @if ($hasMassActionPermission)
                                 <label
                                     class="flex mr-2 gap-1 items-center w-max cursor-pointer select-none"
                                     for="mass_action_select_all_records"
    @@ -125,7 +127,7 @@ class="row grid gap-2.5 items-center px-4 py-4 border-b dark:border-cherry-800 t
                         :style="'grid-template-columns: 2fr repeat(' + (actions.length ? columns.length : (columns.length -1 )) + ', 1fr)'"
                     >
                         <div class="flex items-center gap-2.5 overflow-hidden">
    -                        @if ($hasPermission)
    +                        @if ($hasMassActionPermission)
                                 <div class="mass-action-input">
                                     <input
                                         type="checkbox"
    
  • packages/Webkul/Admin/src/Resources/views/settings/currencies/index.blade.php+11 6 modified
    @@ -54,6 +54,14 @@ class="primary-button"
                     </div>
                 </div>
     
    +            @php
    +                $hasDeletePermission = bouncer()->hasPermission('settings.currencies.delete');
    +
    +                $hasEditPermission = bouncer()->hasPermission('settings.currencies.edit');
    +
    +                $hasMassActionPermission = bouncer()->hasPermission('settings.currencies.mass_update') || bouncer()->hasPermission('settings.currencies.mass_delete');
    +            @endphp
    +
                 <x-admin::datagrid
                     :src="route('admin.settings.currencies.index')"
                     ref="datagrid"
    @@ -66,10 +74,7 @@ class="row grid gap-2.5 items-center px-4 py-4 border-b dark:border-cherry-800 t
                             :style="`grid-template-columns: repeat(${gridsCount}, minmax(0, 1fr))`"
                         >
                             <!-- Mass actions -->
    -                        @if (
    -                            bouncer()->hasPermission('settings.currencies.edit')
    -                            || bouncer()->hasPermission('settings.currencies.delete')
    -                        )
    +                        @if ($hasMassActionPermission)
                                 <input
                                     type="checkbox"
                                     :name="`mass_action_select_record_${record.id}`"
    @@ -100,7 +105,7 @@ class="icon-checkbox-normal rounded-md text-2xl cursor-pointer peer-checked:icon
     
                             <!-- Actions -->
                             <div class="flex justify-end">
    -                            @if (bouncer()->hasPermission('settings.currencies.edit'))
    +                            @if ($hasEditPermission)
                                     <a @click="selectedCurrencies=1; editModal(record.actions.find(action => action.index === 'edit')?.url)">
                                         <span
                                             :class="record.actions.find(action => action.index === 'edit')?.icon"
    @@ -111,7 +116,7 @@ class="cursor-pointer rounded-md p-1.5 text-2xl transition-all hover:bg-violet-1
                                     </a>
                                 @endif
     
    -                            @if (bouncer()->hasPermission('settings.currencies.delete'))
    +                            @if ($hasDeletePermission)
                                     <a @click="performAction(record.actions.find(action => action.index === 'delete'))">
                                         <span
                                             :class="record.actions.find(action => action.index === 'delete')?.icon"
    
  • packages/Webkul/Admin/src/Resources/views/settings/locales/index.blade.php+10 6 modified
    @@ -53,6 +53,13 @@ class="primary-button"
                     </div>
                 </div>
     
    +            @php
    +                $hasDeletePermission = bouncer()->hasPermission('settings.locales.delete');
    +
    +                $hasEditPermission = bouncer()->hasPermission('settings.locales.edit');
    +
    +                $hasMassActionPermission = bouncer()->hasPermission('settings.locales.mass_update') || bouncer()->hasPermission('settings.locales.mass_delete');
    +            @endphp
                 <x-admin::datagrid :src="route('admin.settings.locales.index')" ref="datagrid">
                     <!-- DataGrid Body -->
                     <template #body="{ columns, records, performAction, applied, setCurrentSelectionMode }">
    @@ -62,10 +69,7 @@ class="row grid gap-2.5 items-center px-4 py-4 border-b dark:border-cherry-800 t
                             :style="`grid-template-columns: repeat(${gridsCount}, minmax(0, 1fr))`"
                         >
                             <!-- Mass actions -->
    -                        @if (
    -                            bouncer()->hasPermission('settings.locales.edit')
    -                            || bouncer()->hasPermission('settings.locales.delete')
    -                        )
    +                        @if ($hasMassActionPermission)
                                 <input
                                     type="checkbox"
                                     :name="`mass_action_select_record_${record.id}`"
    @@ -95,7 +99,7 @@ class="icon-checkbox-normal rounded-md text-2xl cursor-pointer peer-checked:icon
     
                             <!-- Actions -->
                             <div class="flex justify-end">
    -                            @if (bouncer()->hasPermission('settings.locales.edit'))
    +                            @if ($hasEditPermission)
                                     <a @click="selectedLocales=1; editModal(record.actions.find(action => action.index === 'edit')?.url)">
                                         <span
                                             :class="record.actions.find(action => action.index === 'edit')?.icon"
    @@ -106,7 +110,7 @@ class="cursor-pointer rounded-md p-1.5 text-2xl transition-all hover:bg-violet-1
                                     </a>
                                 @endif
     
    -                            @if (bouncer()->hasPermission('settings.locales.delete'))
    +                            @if ($hasDeletePermission)
                                     <a @click="performAction(record.actions.find(action => action.index === 'delete'))">
                                         <span
                                             :class="record.actions.find(action => action.index === 'delete')?.icon"
    
  • packages/Webkul/Admin/src/Routes/catalog-routes.php+0 4 modified
    @@ -50,8 +50,6 @@
                 Route::put('update-sort', 'updateSort')->name('admin.catalog.attributes.options.update_sort');
     
                 Route::delete('delete/{id}', 'destroy')->name('admin.catalog.attributes.options.delete');
    -
    -            Route::post('mass-delete', 'massDestroy')->name('admin.catalog.attributes.options.mass_delete');
             });
     
             /**
    @@ -69,8 +67,6 @@
                 Route::put('edit/{id}', 'update')->name('admin.catalog.attribute.groups.update');
     
                 Route::delete('edit/{id}', 'destroy')->name('admin.catalog.attribute.groups.delete');
    -
    -            Route::post('mass-delete', 'massDestroy')->name('admin.catalog.attribute.groups.mass_delete');
             });
     
             /**
    
  • packages/Webkul/Admin/tests/Feature/Acl/Catalog/AttributeAclTest.php+28 0 modified
    @@ -69,3 +69,31 @@
     
         $this->assertDatabaseMissing($this->getFullTableName(Attribute::class), ['id' => $attribute->id]);
     });
    +
    +it('should not be able to mass delete attributes if does not have permission', function () {
    +    $this->loginWithPermissions(permissions: ['catalog', 'catalog.attributes', 'catalog.attributes.delete']);
    +    $attributes = Attribute::factory()->count(3)->create();
    +
    +    $ids = $attributes->pluck('id')->toArray();
    +
    +    $this->post(route('admin.catalog.attributes.mass_delete'), ['indices' => $ids])
    +        ->assertSeeText('Unauthorized');
    +
    +    foreach ($ids as $id) {
    +        $this->assertDatabaseHas($this->getFullTableName(Attribute::class), ['id' => $id]);
    +    }
    +});
    +
    +it('should be able to mass delete attributes if has permission', function () {
    +    $this->loginWithPermissions(permissions: ['catalog', 'catalog.attributes', 'catalog.attributes.mass_delete']);
    +    $attributes = Attribute::factory()->count(1)->create();
    +
    +    $ids = $attributes->pluck('id')->toArray();
    +
    +    $this->post(route('admin.catalog.attributes.mass_delete'), ['indices' => $ids])
    +        ->assertStatus(200);
    +
    +    foreach ($ids as $id) {
    +        $this->assertDatabaseMissing($this->getFullTableName(Attribute::class), ['id' => $id]);
    +    }
    +});
    
  • packages/Webkul/Admin/tests/Feature/Acl/Catalog/CategoryAclTest.php+28 0 modified
    @@ -69,3 +69,31 @@
     
         $this->assertDatabaseMissing($this->getFullTableName(Category::class), ['id' => $category->id]);
     });
    +
    +it('should not be able to mass delete categories if does not have permission', function () {
    +    $this->loginWithPermissions(permissions: ['catalog', 'catalog.categories', 'catalog.categories.delete']);
    +    $categories = Category::factory()->count(1)->create();
    +
    +    $ids = $categories->pluck('id')->toArray();
    +
    +    $this->post(route('admin.catalog.categories.mass_delete'), ['indices' => $ids])
    +        ->assertSeeText('Unauthorized');
    +
    +    foreach ($ids as $id) {
    +        $this->assertDatabaseHas($this->getFullTableName(Category::class), ['id' => $id]);
    +    }
    +});
    +
    +it('should be able to mass delete categories if has permission', function () {
    +    $this->loginWithPermissions(permissions: ['catalog', 'catalog.categories', 'catalog.categories.mass_delete']);
    +    $categories = Category::factory()->count(1)->create();
    +
    +    $ids = $categories->pluck('id')->toArray();
    +
    +    $this->post(route('admin.catalog.categories.mass_delete'), ['indices' => $ids])
    +        ->assertStatus(200);
    +
    +    foreach ($ids as $id) {
    +        $this->assertDatabaseMissing($this->getFullTableName(Category::class), ['id' => $id]);
    +    }
    +});
    
  • packages/Webkul/Admin/tests/Feature/Acl/Catalog/CategoryFieldAclTest.php+52 0 modified
    @@ -69,3 +69,55 @@
     
         $this->assertDatabaseMissing($this->getFullTableName(CategoryField::class), ['id' => $categoryField->id]);
     });
    +
    +it('should not be able to mass delete category fields if does not have permission', function () {
    +    $this->loginWithPermissions(permissions: ['catalog', 'catalog.category_fields', 'catalog.category_fields.delete']);
    +
    +    $categoryFieldIds = CategoryField::factory()->count(3)->create()->pluck('id')->toArray();
    +
    +    $this->post(route('admin.catalog.category_fields.mass_delete'), ['indices' => $categoryFieldIds])
    +        ->assertSeeText('Unauthorized');
    +
    +    foreach ($categoryFieldIds as $id) {
    +        $this->assertDatabaseHas($this->getFullTableName(CategoryField::class), ['id' => $id]);
    +    }
    +});
    +
    +it('should be able to mass delete category fields if has permission', function () {
    +    $this->loginWithPermissions(permissions: ['catalog', 'catalog.category_fields', 'catalog.category_fields.mass_delete']);
    +
    +    $categoryFieldIds = CategoryField::factory()->count(3)->create()->pluck('id')->toArray();
    +
    +    $this->post(route('admin.catalog.category_fields.mass_delete'), ['indices' => $categoryFieldIds])
    +        ->assertOk();
    +
    +    foreach ($categoryFieldIds as $id) {
    +        $this->assertDatabaseMissing($this->getFullTableName(CategoryField::class), ['id' => $id]);
    +    }
    +});
    +
    +it('should not be able to mass update category fields if does not have permission', function () {
    +    $this->loginWithPermissions(permissions: ['catalog', 'catalog.category_fields']);
    +
    +    $categoryFieldIds = CategoryField::factory()->count(3)->create(['status' => 0])->pluck('id')->toArray();
    +
    +    $this->post(route('admin.catalog.category_fields.mass_update'), ['indices' => $categoryFieldIds, 'value' => 1])
    +        ->assertSeeText('Unauthorized');
    +
    +    foreach ($categoryFieldIds as $id) {
    +        $this->assertDatabaseHas($this->getFullTableName(CategoryField::class), ['id' => $id, 'status' => 0]);
    +    }
    +});
    +
    +it('should be able to mass update category fields if has permission', function () {
    +    $this->loginWithPermissions(permissions: ['catalog', 'catalog.category_fields', 'catalog.category_fields.mass_update']);
    +
    +    $categoryFieldIds = CategoryField::factory()->count(3)->create(['status' => 0])->pluck('id')->toArray();
    +
    +    $this->post(route('admin.catalog.category_fields.mass_update'), ['indices' => $categoryFieldIds, 'value' => 1])
    +        ->assertOk();
    +
    +    foreach ($categoryFieldIds as $id) {
    +        $this->assertDatabaseHas($this->getFullTableName(CategoryField::class), ['id' => $id, 'status' => 1]);
    +    }
    +});
    
  • packages/Webkul/Admin/tests/Feature/Acl/Catalog/ProductAclTest.php+51 0 modified
    @@ -97,3 +97,54 @@
     
         $this->assertDatabaseMissing($this->getFullTableName(Product::class), ['id' => $product->id]);
     });
    +
    +it('should not be able to mass update products if does not have permission', function () {
    +    $this->loginWithPermissions(permissions: ['catalog', 'catalog.products']);
    +
    +    $products = Product::factory()->simple()->createMany(2);
    +
    +    $this->post(route('admin.catalog.products.mass_update'), ['indices' => $products->pluck('id')->toArray(), 'value' => true])
    +        ->assertSeeText('Unauthorized');
    +});
    +
    +it('should be able to mass update products if has permission', function () {
    +    $this->loginWithPermissions(permissions: ['catalog', 'catalog.products', 'catalog.products.mass_update']);
    +
    +    $products = Product::factory()->simple()->createMany(2);
    +
    +    $this->post(route('admin.catalog.products.mass_update'), ['indices' => $products->pluck('id')->toArray(), 'value' => true])
    +        ->assertOk();
    +
    +    foreach ($products as $product) {
    +        $product->refresh();
    +
    +        $this->assertEquals(1, $product->status);
    +    }
    +});
    +
    +it('should not be able to mass delete products if does not have permission', function () {
    +    $this->loginWithPermissions(permissions: ['catalog', 'catalog.products', 'catalog.products.delete']);
    +
    +    $productIds = Product::factory()->simple()->createMany(2)->pluck('id')->toArray();
    +
    +    $this->post(route('admin.catalog.products.mass_delete'), ['indices' => $productIds])
    +        ->assertSeeText('Unauthorized');
    +
    +    foreach ($productIds as $id) {
    +        $this->assertDatabaseHas($this->getFullTableName(Product::class), ['id' => $id]);
    +    }
    +});
    +
    +it('should be able to mass delete products if has permission', function () {
    +    $this->loginWithPermissions(permissions: ['catalog', 'catalog.products', 'catalog.products.mass_delete']);
    +
    +    $productIds = Product::factory()->simple()->createMany(2)->pluck('id')->toArray();
    +
    +    $this->post(route('admin.catalog.products.mass_delete'), ['indices' => $productIds])
    +        ->assertOk()
    +        ->assertJsonFragment(['message' => trans('admin::app.catalog.products.index.datagrid.mass-delete-success')]);
    +
    +    foreach ($productIds as $id) {
    +        $this->assertDatabaseMissing($this->getFullTableName(Product::class), ['id' => $id]);
    +    }
    +});
    
  • packages/Webkul/Admin/tests/Feature/Acl/Settings/CurrencyAclTest.php+64 0 modified
    @@ -57,3 +57,67 @@
             'id' => $currency->id,
         ]);
     });
    +
    +it('should not be able to mass update currencies if does not have permission', function () {
    +    $this->loginWithPermissions(permissions: ['settings', 'settings.currencies']);
    +
    +    $currencyIds = Currency::where('status', 0)->limit(2)->pluck('id')->toArray();
    +
    +    $this->post(route('admin.settings.currencies.mass_update'), [
    +        'indices' => $currencyIds,
    +        'value'   => 1,
    +    ])
    +        ->assertSeeText('Unauthorized');
    +
    +    foreach ($currencyIds as $id) {
    +        $this->assertDatabaseHas($this->getFullTableName(Currency::class), ['id' => $id, 'status' => 0]);
    +    }
    +});
    +
    +it('should be able to mass update currencies if has permission', function () {
    +    $this->loginWithPermissions(permissions: ['settings', 'settings.currencies', 'settings.currencies.mass_update']);
    +
    +    $currencyIds = Currency::where('status', 0)->limit(2)->pluck('id')->toArray();
    +
    +    $this->post(route('admin.settings.currencies.mass_update'), [
    +        'indices' => $currencyIds,
    +        'value'   => 1,
    +    ])
    +        ->assertOk()
    +        ->assertJsonFragment(['message' => trans('admin::app.settings.currencies.index.update-success')]);
    +
    +    foreach ($currencyIds as $id) {
    +        $this->assertDatabaseHas($this->getFullTableName(Currency::class), ['id' => $id, 'status' => 1]);
    +    }
    +});
    +
    +it('should not be able to mass delete currencies if does not have permission', function () {
    +    $this->loginWithPermissions(permissions: ['settings', 'settings.currencies', 'settings.currencies.delete']);
    +
    +    $currencyIds = Currency::where('status', 0)->limit(2)->pluck('id')->toArray();
    +
    +    $this->post(route('admin.settings.currencies.mass_delete'), [
    +        'indices' => $currencyIds,
    +    ])
    +        ->assertSeeText('Unauthorized');
    +
    +    foreach ($currencyIds as $id) {
    +        $this->assertDatabaseHas($this->getFullTableName(Currency::class), ['id' => $id]);
    +    }
    +});
    +
    +it('should be able to mass delete currencies if has permission', function () {
    +    $this->loginWithPermissions(permissions: ['settings', 'settings.currencies', 'settings.currencies.mass_delete']);
    +
    +    $currencyIds = Currency::where('status', 0)->limit(2)->pluck('id')->toArray();
    +
    +    $this->post(route('admin.settings.currencies.mass_delete'), [
    +        'indices' => $currencyIds,
    +    ])
    +        ->assertOk()
    +        ->assertJsonFragment(['message' => trans('admin::app.settings.currencies.index.delete-success')]);
    +
    +    foreach ($currencyIds as $id) {
    +        $this->assertDatabaseMissing($this->getFullTableName(Currency::class), ['id' => $id]);
    +    }
    +});
    
  • packages/Webkul/Admin/tests/Feature/Acl/Settings/LocaleAclTest.php+64 0 modified
    @@ -87,3 +87,67 @@
             'status' => 0,
         ]);
     });
    +
    +it('should not be able to mass update locales if does not have permission', function () {
    +    $this->loginWithPermissions(permissions: ['settings', 'settings.locales', 'settings.locales.edit']);
    +
    +    $localeIds = Locale::where('status', 0)->limit(2)->pluck('id')->toArray();
    +
    +    $this->post(route('admin.settings.locales.mass_update'), [
    +        'indices' => $localeIds,
    +        'value'   => 1,
    +    ])
    +        ->assertSeeText('Unauthorized');
    +
    +    foreach ($localeIds as $id) {
    +        $this->assertDatabaseHas($this->getFullTableName(Locale::class), ['id' => $id, 'status' => 0]);
    +    }
    +});
    +
    +it('should be able to mass update locales if has permission', function () {
    +    $this->loginWithPermissions(permissions: ['settings', 'settings.locales', 'settings.locales.mass_update']);
    +
    +    $localeIds = Locale::where('status', 0)->limit(2)->pluck('id')->toArray();
    +
    +    $this->post(route('admin.settings.locales.mass_update'), [
    +        'indices' => $localeIds,
    +        'value'   => 1,
    +    ])
    +        ->assertOk()
    +        ->assertJsonFragment(['message' => trans('admin::app.settings.locales.index.update-success')]);
    +
    +    foreach ($localeIds as $id) {
    +        $this->assertDatabaseHas($this->getFullTableName(Locale::class), ['id' => $id, 'status' => 1]);
    +    }
    +});
    +
    +it('should not be able to mass delete locales if does not have permission', function () {
    +    $this->loginWithPermissions(permissions: ['settings', 'settings.locales', 'settings.locales.delete']);
    +
    +    $localeIds = Locale::where('status', 0)->limit(2)->pluck('id')->toArray();
    +
    +    $this->post(route('admin.settings.locales.mass_delete'), [
    +        'indices' => $localeIds,
    +    ])
    +        ->assertSeeText('Unauthorized');
    +
    +    foreach ($localeIds as $id) {
    +        $this->assertDatabaseHas($this->getFullTableName(Locale::class), ['id' => $id]);
    +    }
    +});
    +
    +it('should be able to mass delete locales if has permission', function () {
    +    $this->loginWithPermissions(permissions: ['settings', 'settings.locales', 'settings.locales.mass_delete']);
    +
    +    $localeIds = Locale::where('status', 0)->limit(2)->pluck('id')->toArray();
    +
    +    $this->post(route('admin.settings.locales.mass_delete'), [
    +        'indices' => $localeIds,
    +    ])
    +        ->assertOk()
    +        ->assertJsonFragment(['message' => trans('admin::app.settings.locales.index.delete-success')]);
    +
    +    foreach ($localeIds as $id) {
    +        $this->assertDatabaseMissing($this->getFullTableName(Locale::class), ['id' => $id]);
    +    }
    +});
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.