* fix(xss): remove redundant escaping that double-encoded item attribute values
- Remove esc()/html_entity_decode() calls now that output is escaped
at render time by the framework, preventing double-encoding of
special characters in attribute names, units, and definition values
- Fix employee_name form_input value fields to stop pre-escaping
before form_input applies its own escaping
- Reorder Items.php use statements and add missing BaseConnection import
- Change items/manage.php start_date from let to plain assignment for
proper reassignment scope
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* test(sales): add regression tests for permission checks on sales endpoints
- Ensure role-based permissions correctly restrict access to sensitive actions like price edits, receipt/invoice views, and report generation.
- Add tests for both granted and restricted user scenarios to validate the behavior.
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* fix(attributes): validate `attribute_value` before processing
- Add checks to ensure `attribute_value` is a non-empty string in `postSaveAttributeValue` and `postDeleteDropdownAttributeValue` methods.
- Return error response if validation fails to prevent invalid data handling.
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* fix(attributes): improve error handling and optimize affected items processing
- Use `array_column` for extracting item IDs to streamline logic.
- Add JSON validation with `JSON_THROW_ON_ERROR` and return proper error response for invalid `definition_values`.
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* test(sales): enable database refresh for consistent test state
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* test(sales): assert unauthorized message is displayed on restricted access
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
* refactor(attributes): use camelCase for `attributeValue` in controller methods
- Standardize variable naming in `postSaveAttributeValue` and `postDeleteDropdownAttributeValue` methods by switching to camelCase.
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
---------
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: Travis Garrison <travis@chiraqbookstore.com>
* refactor: Replace var with let/const in JavaScript files
- Replace var with let for variables that are reassigned
- Replace var with const for variables that are never reassigned
- Modernize manage_tables.js and nominatim.autocomplete.js
- Skip third-party libraries (imgpreview.full.jquery.js, clipboard.min.js)
Closes#4491
* refactor: Replace var with let/const in inline JavaScript
- Fixed CodeRabbit review: changed enable_actions and load_success
from const to let in manage_tables.js (they are reassigned in init)
- Replaced all var declarations in inline JavaScript in Views with
let (for reassigned) or const (for never reassigned)
- Modernized 48 additional files with inline JavaScript
* refactor: Replace var with let/const in remaining JS files
- Modernized gulpfile.js: 3 var declarations replaced
- Modernized app/Views/errors/html/debug.js: all var declarations replaced
- Used const for never-reassigned, let for reassigned variables
* fix: Replace remaining var declarations in Views
- Changed var to const in sales/register.php
- Changed var to const in configs/receipt_config.php
These were missed in the initial pass.
* fix: Replace remaining var declarations in gulpfile.js
- Converted 12 remaining var declarations to const
- All variables are function-scoped and never reassigned
- Complete coverage for this file now
* fix: Address CodeRabbit review comments
- items/manage.php: Remove duplicate let declaration for start_date
(partial/daterangepicker already declares it)
- header_js.php: Escape CSRF hash in JavaScript context
- tax_jurisdictions.php: Fix mismatched selector (remove_tax_jurisdictions
-> remove_tax_jurisdiction)
* style(views): Replace var with let/const and fix comment casing
- Convert var to let in items/manage.php for JS modernization
- Capitalize \"Submit\" in validation comments across tax view files
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
---------
Signed-off-by: Travis Garrison <travis@chiraqbookstore.com>
Co-authored-by: Ollama <ollama@steganos.dev>
Co-authored-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
Co-authored-by: Travis Garrison <travis@chiraqbookstore.com>
* Fix stored XSS vulnerability in Attribute Definitions
GHSA-rvfg-ww4r-rwqf: Stored XSS via Attribute Definition Name
Security Impact:
- Authenticated users with attribute management permission can inject XSS payloads
- Payloads execute when viewing/editing attributes in admin panel
- Can steal session cookies, perform CSRF attacks, or compromise admin operations
Root Cause:
1. Input: Attributes.php postSaveDefinition() accepts definition_name without sanitization
2. Output: Views echo definition_name without proper escaping
Fix Applied:
- Input sanitization: Added FILTER_SANITIZE_FULL_SPECIAL_CHARS to definition_name and definition_unit
- Output escaping: Added esc() wrapper when displaying definition_name in views
- Defense-in-depth: htmlspecialchars on attribute values saved to database
Files Changed:
- app/Controllers/Attributes.php - Sanitize inputs on save
- app/Views/attributes/form.php - Escape output on display
- app/Views/attributes/item.php - Escape output on display
* Remove input sanitization, keep output escaping only
Use escaping on output (esc() in views) as the sole XSS prevention
measure instead of sanitizing on input. This preserves the original
data in the database while still protecting against XSS attacks.
* Add validation for definition_fk foreign key in attribute definitions
Validate definition_group input before saving:
- Must be a positive integer (> 0)
- Must exist in attribute_definitions table
- Must be of type GROUP to ensure data integrity
Also add translation for definition_invalid_group error message
in all 45 language files (English placeholder for translations).
* Refactor definition_fk validation into single conditional statement
* Add esc() to attribute value outputs for XSS protection
- Add esc() to TEXT input value in item.php
- Add esc() to definition_unit in form.php
These fields display user-provided content and need output escaping
to prevent stored XSS attacks.
* Refactor definition_group validation into separate method
Extract validation logic for definition_fk into validateDefinitionGroup()
private method to improve code readability and reduce method complexity.
Returns:
- null if input is empty (no group selected)
- false if validation fails (invalid group)
- integer ID if valid
* Add translations for definition_invalid_group in all languages
- Added proper translations for 28 languages (de, es, fr, it, nl, pl, pt-BR, ru, tr, uk, th, zh-Hans, zh-Hant, ro, sv, vi, id, el, he, fa, hu, da, sw-KE, sw-TZ, ar-LB, ar-EG)
- Set empty string for 14 languages to fallback to English (cs, hr-HR, bg, bs, ckb, hy, km, lo, ml, nb, ta, tl, ur, az)
---------
Co-authored-by: Ollama <ollama@steganos.dev>
Modified definition_values() function in app/Views/attributes/item.php to properly handle checkbox attributes.
The issue was that checkbox attributes have two input elements (hidden and checkbox) with the same name pattern. When collecting attribute values during the refresh operation, both inputs were being processed, with the hidden input potentially overwriting the checkbox state.
Changes:
- Skip hidden inputs that have a corresponding checkbox input
- For checkbox inputs, explicitly capture the checked state using prop('checked')
- Convert checked state to '1' or '0' for consistency
This ensures that when adding another attribute to an item, existing checkbox states are preserved correctly.
* Improve code style and PSR-12 compliance
- refactored code formatting to adhere to PSR-12 guidelines
- standardized coding conventions across the codebase
- added missing framework files and reverted markup changes
- reformatted arrays for enhanced readability
- updated language files for consistent styling and clarity
- minor miscellaneous improvements
- Updated formatting to reflect standard
- Wrapped Decimal type in to_decimals() function for localization
Signed-off-by: objecttothis <objecttothis@gmail.com>
- Made view CI form helper function call format uniform.
- replaced calls to array() with []
- Placed { on its own line
- Removed empty lines where there shouldn't be any.
- Replaced text/javascript with application/javascript as the former is deprecated
- Replaced TRUE/FALSE constants with true/false keywords
- Replaced NULL constant with null keyword
- Replaced `<?php echo` in views with shortened `<?=`
- Added missing variable declaration
- Added missing function return type in declaration
- replaced `== true`, `== false`, `=== true` and `=== false` in if statements with simplified forms
- Added `@noinspection PhpUnused` tags to PHPdocs for functions which are called via AJAX.
- removed conversion to array in getResult in favor of returning an array to begin with.
- Refactored variable for clarity.
- declared variable in view coming from controller
- Added PHPdocs
- Refactored nested if/else statements into ternary notation.
- Corrected tab type
- added missing model declaration in view
- Modified query builder to extrapolate out the set() command for clarity