Commit Graph
6808 Commits
Author SHA1 Message Date
objecttothis fab6fcf2a8 Merge branch 'master' into feature-optimize-items-view-queries 2026-09-02 01:31:53 +04:00
objecttothis f5f9052de1 fix(sales): harden payment validation and gift card handling
- Validate paymentType is a non-empty string before processing
- Reject negative or zero amounts for all payment types
- Enforce full payment coverage before completing a sale
- Bypass coverage check for invoice and quote mode sales
- Require a valid gift card number before decrementing value;
  rollback and return insufficient balance error on missing input
- Add "amount_due_not_covered" and "negative_amount_invalid"
  translations across 40+ locales
- Add test coverage for gift card validation, negative amounts,
  and quote/invoice zero-payment completion
- Rename snake_case locals to camelCase in postComplete (no behavior change)
2026-09-02 01:21:46 +04:00
objecttothis fdc1c38b43 feat(validation, tests): add valid_path_strict rule and integrate into mailpath validation (#4684)
- Introduce `valid_path_strict` rule in `OSPOSRules` to enforce stricter path validation, preventing security issues like injection attempts with newline or special characters.
- Update mail configuration validation in `Config` controller to use the new rule for the `mailpath` field.
- Add unit tests in `OSPOSRulesTest` to cover edge cases for `valid_path_strict`.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-09-01 19:41:41 +04:00
objecttothis 0849356aca Merge branch 'master' into feature-optimize-items-view-queries 2026-09-01 11:16:36 +04:00
objecttothis 6db3dde491 Bugfix tax names (#4677)
bugfix(items, validation): reject unsafe tax names and fix payments temp table collision

- Add unicode_alpha_numeric_punct rule (OSPOSRules) to allow accented/CJK
  chars in text fields while blocking HTML-unsafe chars (<, >) as
  defense-in-depth against injection
- Items controller: extract validateItemFields/validateBulkUpdateFields,
  validate tax_names on save and bulk update using new rule; add shared
  validateFields helper in Secure_Controller to DRY up validation +
  JSON error response
- Escape tax_group output in sales/quote.php and receipt_email.php views
  to harden output encoding at render time
- Rename sales_payments_temp -> sales_report_payments_temp (Summary_report)
  and -> sales_search_payments_temp (Sale model) to avoid name collision
  between concurrently-created temp tables
- AGENTS.md: document alignment rule for => columns when inserting new
  language keys

Tests:
- Add ItemsControllerTest covering postSave/bulkupdate tax_names validation
- Reject <, > in tax_names on /items/save and /items/bulkupdate
- Verify unicode and apostrophe-containing tax names are accepted
- Cover CSV import helpers: header generation (basic, multiple locations,
  attributes), stock-location/attribute header builders, get_csv_file
  parsing (plain, BOM-prefixed, multi-row)
- Validate required-header detection for import templates
- Remove outdated tax name test from SalesControllerTest
- Simplify Database class references in SalesControllerTest

i18n:
- Add tax_name_invalid translation to Items.php for 20+ locales, inserted
  alphabetically after tax_category in each file
- Normalize quote style in ar-EG/Items.php to single quotes
- Add ka/Items.php Georgian locale scaffold

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-09-01 10:59:29 +04:00
objecttothis a63863e7f3 Merge branch 'master' into feature-optimize-items-view-queries 2026-08-31 13:34:34 +04:00
objecttothis 905a447e55 fix(reports, home): resolve double-URL-decoding bypass for method grants (#4660) (#4666)
fix(reports, home): strengthen method grant validation and URI decoding (#4660)

- Reports, Home: fix URI decoding in hasGrant() method checks to use
  urldecode consistently, preventing malformed URI segments from
  bypassing access controls
- Reports: rename snake_case variables to camelCase for PSR-12 compliance
- Reports: adjust access checks to accurately handle null submodule IDs

Tests:
- Add grant check tests for encoded URI inputs across Reports and Home
- Add test case for employee access with base reports grant
- Add secondary grant check for reports_customers in relevant test cases
- Confirm logout bypass remains functional and properly controlled
- Refactor TestDatabaseBootstrapSeeder to expose static reset() for
  per-class DB re-initialization instead of only via seeder run()
- Standardize session handling, setup logic, and boolean declarations
- Use unique data in test helpers to avoid collisions
- Add docblocks to ReportsControllerTest and HomeTest for PSR-5 compliance
- Add exception handling for failed employee creation in test setup
- Wrap password validation test in try-finally to guarantee state cleanup

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-31 13:33:09 +04:00
objecttothis 99cd583acb Merge branch 'master' into feature-optimize-items-view-queries 2026-08-31 13:12:11 +04:00
objecttothis 8cfd1a4b1d fix(sales): enforce reports_sales grant on search endpoint (#4673)
- Sales::getSearch now enforces reports_sales grant before running
  search, returns 403 with lang message when missing
- Rename snake_case helpers/methods to camelCase across
  Sales controller, Sale model, and tabular_helper
  (get_sale_data_row -> getSaleDataRow, get_payments_summary ->
  getPaymentsSummary, sales_headers -> salesHeaders, etc.)
- Config/OSPOS: reset DB data cache before checking app_config
  table existence to avoid stale schema cache in tests
- TestDatabaseBootstrapSeeder: expose static reset() so tests can
  rebuild schema once per class instead of only via seeder run()
- SalesControllerTest: bootstrap DB once per class, seed once,
  refresh app settings each setUp, add tests for search endpoint
  authorization (cashier denied, supervisor allowed), move
  createTestItem into shared ItemFixtureTrait

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-31 13:08:33 +04:00
objecttothis 2870b85c44 Merge branch 'master' into feature-optimize-items-view-queries 2026-08-28 11:24:47 +04:00
objecttothis d63d31700d Ensure payload data is escaped to prevent XSS (#4664)
fix(barcode): escape payload fields to prevent XSS; PSR-12 refactor

- Apply `esc()` to name, ID, item number, category, and company name in `Barcode_lib` payloads
- Remove redundant `urldecode()` in `Item_kitsController` to prevent triple decoding
- Rename variables and methods to camelCase across barcode, item_kits, and tests
- Add type hint for `$layoutType` parameter in `manageDisplayLayout`
- Add/update unit tests covering escaping and HTTP response assertions

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-28 10:08:31 +04:00
objecttothis d872fa5b05 Merge branch 'master' into feature-optimize-items-view-queries 2026-08-27 14:05:08 +04:00
objecttothis 84bddcdd88 Feature admin account safeguards (#4657)
fix(employees): harden permissions UI and access control

- Prevent admins from removing their own minimum module grants (employees, home, office)
- Add session_status check before session regeneration
- Disable submit button and return no_access view for AJAX requests
- Replace fade class with active-only for Bootstrap compatibility
- Update permission toggle selectors to .module-toggle
- Add error_cannot_remove_own_minimum_grant translations for Armenian, Bulgarian, Georgian, Swedish, and Ukrainian

---------

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-27 11:29:32 +04:00
objecttothis 8579bc165d Merge branch 'master' into feature-optimize-items-view-queries 2026-08-25 18:33:48 +04:00
objecttothis 8b0f8533de fix(email): update method call to camelCase for PSR-12 compliance (#4659)
Corrected `check_encryption()` to `checkEncryption()` to align with coding standards.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-24 21:46:12 +04:00
objecttothis c701d21886 fix(sales): gate per-record endpoints behind reports_sales grant (#4627)
fix(sales): gate per-record endpoints behind reports_sales grant (REDACTED)

Cashiers holding only the base `sales` grant could reach per-sale endpoints
(getRow, getEdit, postSave, getReceipt, getInvoice, getSendPdf, getSendReceipt)
that require `reports_sales`. getManage() enforced this at the list level, but
individual endpoints did not re-check. Regression tests added.

Auth:
- Introduce `IsLoggedIn` filter to centralize login checks across controllers
- Replace custom `AccessDeniedRedirectException` with built-in `RedirectException`

Employees:
- Add `DISALLOW_PASSWORD_CHANGE` and `DISALLOW_GRANT_CHANGE` env vars to restrict
  credential and permission changes in locked-down environments
- Extract `hasGrantsChanged()` to streamline `postSave`

Refactor:
- Rename snake_case variables to camelCase in Sales, Items, and Employees
  controllers for PSR-12 compliance
- Use explicit `db_connect()` for transaction clarity in Items controller

Fixes:
- SMTP config entries fall back to defaults via null coalescing
- Migration uses `DROP FOREIGN KEY` instead of `DROP CONSTRAINT`
- Password hash upgrade only sets session on successful `hash_version` update
- Correct lang key for unknown error in Module model

Language:
- Translate `error_grant_change_disallowed` / `error_password_change_disallowed`
  across all 44 supported locales with => alignment matching en reference
- Fix "cannot be deleted" messages and misc typos across ~15 language files

Tests:
- Bootstrap seeder only once in ItemsCsvImportTest; close connection after
- Restore `DISALLOW_GRANT_CHANGE` in teardown to prevent side effects
- Use `uniqid()` for test user data to avoid collisions

Signed-off-by: 17935339+objecttothis@users.noreply.github.com
2026-08-23 17:40:06 +04:00
objecttothis 9ee530e454 Hotfix: Fix CI3 database migration caused by regression (#4649)
* refactor: standardize function and variable names to camelCase and improve naming consistency across files

* refactor(config): remove spaces around `=` in configuration files for improved consistency and formatting as is required by .env formatting rules.

* refactor(security): extract `.env` key management logic into reusable `writeEnvKey` helper, add throttle key provisioning logic, and streamline encryption key updates

* fix(migration): improve error handling in CI3 to CI4 encryption data migration
- Secure `up` and `convertCI3EncryptedData` methods with detailed exception handling for script execution and data saving.

* fix(migration): ensure empty string is correctly handled in CI3 to CI4 encryption data conversion

* refactor(security): enhance `.env` management with durable writes, better locking, and helper abstraction
- Update `writeEnvKey` to return a success flag and handle file locks robustly.
- Introduce `atomicWriteFile` for atomic writes to prevent partial file updates.
- Add `applyEnvKeyReplacement` to streamline `.env` key insertion and updates.
- Improve throttle key provisioning with validation and runtime persistence safeguards.

* refactor(security): implement dedicated `.env` file locking for robust and cross-platform safe write operations
- Add `lockEnvFile` and `unlockEnvFile` helpers to manage `.env` mutex files.
- Refactor `.env` write logic to use lock helpers, improving reliability and preventing race conditions.
- Enhance `atomicWriteFile` for better handling of file overwrites on Windows and POSIX systems.

* fix(migration): improve encryption error handling during CI3 to CI4 data conversion
- Add conditional checks for `checkEncryption` to prevent failed key persistence.
- Introduce `abortEncryptionConversion` for cleanup on failure.
- Update `writeEnvKey` to handle and return errors gracefully.

* refactor(security): improve `atomicWriteFile` for better file locking and cross-platform durability
- Replace `uniqid` with `bin2hex(random_bytes())` for more secure temp file naming.
- Add explicit file permissions and locking for safe concurrent writes.
- Enhance error handling to ensure atomicity on both Windows and POSIX systems.

* Add env temp files to gitignore so they don't get tracked.

---------

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-21 21:00:48 +04:00
objecttothis e336fc245a refactor(helpers): add optional parameter to itemSortColumns for dynamic attribute handling
- Introduced `$definitionIds` parameter in `itemSortColumns` to allow pre-resolved attribute handling.
- Updated `Items` controller to utilize the new parameter, improving code clarity and performance.
- Simplified dynamic column management and minimized unnecessary queries.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-21 17:19:16 +04:00
objecttothis 926982b116 refactor(controllers): simplify column key extraction in Secure_Controller
- Replaced nested loop with `array_key_first` for streamlined valid column generation.
- Improved code readability and performance by reducing iteration overhead.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-21 17:16:08 +04:00
objecttothis f299688540 fix(tests): ensure stock location creation in item quantity tests
- Add `ensureStockLocation` method to automatically create missing stock locations during test execution.
- Update `addItemQuantity` to call `ensureStockLocation` before adding item quantity.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-21 16:40:12 +04:00
objecttothis 13df4404f8 fix(localization): unify string quotations across language files
- Replaced double quotes with single quotes in all language attribute files for consistency.
- Updated language files in various locales: `uk`, `ar-LB`, `ml`, `es-MX`, `ro`, `tl`, `km`, and `en-GB`.
- Ensured no functional changes, preserving integrity of translation keys and values.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-21 16:38:51 +04:00
objecttothis 5fb0e947d1 fix(localization): unify string quotations across language files
- Replaced double quotes with single quotes in all language attribute files for consistency.
- Updated language files in various locales: `uk`, `ar-LB`, `ml`, `es-MX`, `ro`, `tl`, `km`, and `en-GB`.
- Ensured no functional changes, preserving integrity of translation keys and values.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-21 16:18:41 +04:00
objecttothis 91f8d89bc0 refactor(items): standardize function and variable names for consistency
- Updated function names to use camelCase (e.g., `item_sort_columns` to `itemSortColumns`).
- Adjusted variable naming to align with camelCase conventions.
- Updated related calls in controllers, helpers, and tests to reflect new naming.
- Improved code readability and adherence to naming standards.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-21 15:49:43 +04:00
objecttothis 1932251a73 fix(items): enhance named attribute search with improved type handling
- Add support for searching named attributes with decimal and date types.
- Extend parsing logic to handle locale-specific decimal separators.
- Update `applyNamedAttributeSearch` to return consumed names for better compatibility with free-text search.
- Refine regex matching for combined attribute search syntax.
- Expand test coverage for named attribute search across various scenarios.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-21 15:41:47 +04:00
objecttothis b359992350 fix(items): refine attribute query logic and improve column ordering
- Use `MAX` function in column sorting to ensure consistent results.
- Update attribute queries to use fully qualified table names for better clarity and maintainability.
- Adjust joins and group concatenation for improved query integrity.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-21 14:45:14 +04:00
objecttothis 80f5d4cd57 refactor(items): streamline column sorting and attribute search logic
- Replace static column list in `item_sort_columns` with dynamic headers.
- Simplify `sanitizeSortColumn` for accurate key validation.
- Revise attribute join logic to improve query efficiency and maintain integrity.
- Refactor tests to handle cache issues in configuration settings.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-21 14:27:21 +04:00
objecttothis 3c2d540cc6 Merge remote-tracking branch 'OpensourcePOS/master' into feature-optimize-items-view-queries 2026-08-21 14:14:24 +04:00
objecttothis 55fd835e70 fix(items): implement named attribute search and optimize attribute handling
- This commit harmonizes #4442 with this PR.
- Add `applyNamedAttributeSearch` method to enable searching by named attributes with specific values.
- Refactor `applyAttributeSort` to accept pre-resolved definition info, improving query integrity.
- Enhance free-text search to support combined attribute name:value syntax.
- Add tests for named attribute search and free-text parsing compatibility.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-21 14:07:25 +04:00
Ollama 953147a79a Implement Phase 3: Multi-attribute search AND logic and Phase 4: Sort by attribute columns
Phase 3 - Multi-attribute Search:
- Add parse_attribute_search() method to parse search syntax like
  'color: blue size: large' or 'color:blue AND size:large'
- Update search_by_attributes() to support AND/OR logic for multiple
  attribute queries
- Add search_by_attribute_value() private method for single value search

Phase 4 - Sort by Attribute Columns:
- Add get_attribute_sort_definition_id() method to detect attribute
  column sorting
- Update Item::search() to join attribute tables when sorting by
  attribute columns
- Update tabular_helper to make attribute columns sortable
- Add sanitizeSortColumnAttribute() method in Items controller to
  validate attribute definition IDs as sort columns

Fixes #2722 - sorting by attribute columns now works
2026-08-21 13:24:35 +04:00
Ollama b3a22c8c19 style: Apply PSR-12 formatting
- Fix PHPDoc comment format in item_sort_columns() helper
- Remove duplicate blank line after properties in Item model
- Remove unused variable assignment in Items controller
2026-08-21 13:21:39 +04:00
Ollama 6cd50baf01 Refactor: Use existing sanitizeSortColumn method with item_sort_columns helper
- Add item_sort_columns() helper function in tabular_helper.php
- Helper returns all sortable columns including dynamic attribute IDs
- Remove duplicate sanitizeSortColumnAttribute method from Items controller
- Remove unused ALLOWED_SORT_COLUMNS constant from Item model
- Reuses existing sanitizeSortColumn method from Secure_Controller
2026-08-21 13:21:07 +04:00
Ollama 37b359d146 Refactor: Add ALLOWED_SORT_COLUMNS constant and reuse in sanitization
- Add Item::ALLOWED_SORT_COLUMNS constant for allowed sort columns
- Use constant in sanitizeSortColumnAttribute() instead of inline array
- Enables reuse across the codebase for sort column validation
2026-08-21 13:20:34 +04:00
Ollama b829d796bc feat: Add show_in_search language strings to all languages
- Add 'show_in_search' and 'show_in_search_visibility' to all language files
- Translated: de-DE, es-ES, fr, it
- Placeholder English for remaining languages (awaiting translation)

This ensures the SHOW_IN_SEARCH attribute flag works in all locales.
2026-08-21 13:19:51 +04:00
Ollama 1654a4b65a Add SHOW_IN_SEARCH flag to separate attribute search from visibility
Phase 2 implementation:
- Add SHOW_IN_SEARCH constant (value 8) to Attribute model
- Update Items controller to include searchable attributes when
  search_custom filter is enabled
- Add language strings for the new visibility flag
- Update Attributes controller to include new flag in form

This allows attributes to be searchable even if they are not
displayed in the items table, addressing issue #2919.

Fixes #2919
2026-08-21 13:19:39 +04:00
objecttothis 50d07108a2 fix(tests): update quantity aggregation test for multi-location support
- Add test case for verifying quantity aggregation across multiple locations.
- Update assertion to reflect new total quantity calculation logic.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-21 12:57:15 +04:00
objecttothis 8f2f7ee528 fix(items): improve date range filtering logic in Item model
- Add validation to ensure both start and end dates are present before applying the date range filter.
- Adjust filtering logic to handle null date ranges gracefully without modifying queries.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-21 12:53:04 +04:00
objecttothis 9138127a67 fix(items): optimize quantity sum handling and add test to prevent over-counting
- Refactor quantity sum calculation by introducing a subquery to handle SUM without over-counting due to joins.
- Update search logic and related query clauses for consistent sorting by total quantities across locations.
- Add test to verify correct quantity aggregation without duplication.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-21 12:49:51 +04:00
objecttothis c25c372175 fix(items): rename deleted column alias to supplier_deleted in Item model query
- Adjusted query for clarity and to avoid potential alias conflicts.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-21 12:32:45 +04:00
objecttothis d01ea38b69 fix(items): add support for sorting by quantity across all locations
- Implement conditional logic to calculate and sort by the sum of quantities across all locations when `stock_location_id` is invalid.
- Adjust query joins and select clauses to handle the new sorting behavior.
- Maintain existing sorting logic for other cases to ensure backward compatibility.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-21 12:22:23 +04:00
objecttothis 09115461b1 fix(items): enhance filtering logic and sanitize definition IDs
- Ensure `definition_ids` are properly sanitized using `array_map` to prevent potential injection vulnerabilities.
- Add condition to `low_inventory` filter to require valid `stock_location_id`.
- Replace raw `reorder_level` handling with database-safe `RawSql`.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-21 12:03:39 +04:00
objecttothis d081346528 Codeigniter changes between 4.7.2 and 4.7.4 (#4650)
Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-21 11:28:19 +04:00
objecttothis 058ec2e9d4 refactor(items): optimize search method by splitting query into phases for better performance and readability
- Introduced two-phase query processing: Phase A resolves qualifying IDs, Phase B joins scoped display tables.
- Applied camelCase naming convention to method variables.
- Improved date range filtering and custom attribute handling.
- Streamlined logic for filtering item attributes and quantities.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-20 21:31:40 +04:00
objecttothis 410c6649e0 refactor(items): streamline tax computation and add tests for getItemDataRow
Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-20 21:28:56 +04:00
objecttothis cc93c31355 fix(items): add explicit sentinel value for clearing supplier in bulk edit (#4617)
* fix(items): add explicit sentinel value for clearing supplier in bulk edit

This fixes a regression introduced in the fix for [REDACTED]
Introduce `Item::CLEAR_SUPPLIER_OPTION = 'NONE'` to distinguish between
\"leave supplier_id unchanged\" (empty string) and \"clear supplier_id\"
(sentinel). Previously, empty string was ambiguous.

- Add `CLEAR_SUPPLIER_OPTION` constant with doc comment explaining intent
- Update supplier dropdown to include sentinel as first real option
- Shift empty string to mean \"do nothing\" across all bulk edit fields

* test(items): add regression tests for mass assignment in bulk edit

Cover [REDACTED]: Item::update_multiple() bypasses model
$allowedFields via Query Builder, allowing unintended field writes
during bulk edit operations.

* fix(items): add type validation to bulk-edit field filter

filterBulkEditFields now validates field values before accepting them:
- Non-scalar values are rejected (array injection guard)
- Price/quantity fields are locale-parsed to floats, invalid strings skipped
- Boolean fields must be 0 or 1, other values skipped
- supplier_id must be numeric; CLEAR_SUPPLIER_OPTION still nulls it

Update tests to assert parsed types (float for prices, int for
supplier_id) and replace the fill-all-fields fixture with a realistic
input that only covers fields a form would actually submit.

* test(items): add supplier cleanup and helper methods to bulk update tests

- Track created supplier person IDs for teardown cleanup
- Delete supplier records in tearDown to prevent test pollution
- Extract item/supplier creation into reusable helper methods

* style(tests): rename variables to camelCase in ItemBulkUpdateTest

* refactor(items): rename snake_case variables to camelCase

Convert Item model, Items controller, and bulk update tests to
PSR-compliant camelCase naming per project conventions.

- Rename update_multiple to updateMultiple in Item model
- Rename local variables (item_data, items_to_update, tax_names, etc.)
  to camelCase across Items controller and Item model
- Update ItemBulkUpdateTest to use new updateMultiple method name
- Reorder and update AGENTS.md naming conventions

* style(tests): convert snake_case variables to camelCase in ItemBulkUpdateTest

Rename local variables and property names to camelCase for PSR-12
consistency, matching convention used elsewhere in new test code.
2026-08-20 11:24:50 +04:00
objecttothis 61bb1a2c2a hotfix(auth): hash throttler keys to improve security (#4646)
* fix(auth): hash throttler keys to improve security

- Use MD5 hashing for IP and username-based throttler keys to obfuscate sensitive data while maintaining functionality.

* test(auth): add IPv6 throttling test and hash used throttler keys

- Add a test to ensure throttling works correctly with IPv6 addresses.
- Update throttler keys to use MD5 hashes for IPs and usernames for improved security and consistency.

* fix(auth): handle non-scalar usernames in throttler keys

- Ensure username input is validated as scalar before processing to prevent errors and maintain throttling logic integrity.

* fix(auth): enhance throttler key security with HMAC hashing

- Replace MD5 with HMAC-SHA256 for generating throttler keys.
- Include encryption key from app configuration for added security.

* test(filters): update ThrottleTest to use HMAC-SHA256 for throttler keys

- Replace MD5 with HMAC-SHA256 for generating throttler keys in tests.
- Introduce `check_encryption()` to ensure encryption configuration is available.

* fix(events): validate encryption key on app initialization

- Throw ConfigException if encryption key is missing or invalid during `pre_system` event.
- Remove redundant `check_encryption()` call from Throttle filter and tests.

* fix(events): improve encryption key validation in `pre_system`

- Add `check_encryption()` helper call for additional security verification.
- Update error message to highlight `.env` writability issues if the key is invalid.

* test(filters): handle non-scalar usernames in ThrottleTest

- Update `makeRequest` to validate usernames as scalar and cast them to strings before processing.
- Add a test to ensure array usernames are ignored, and throttling is applied only based on IP.
- Improve status code assertions for throttled requests.

---------

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-20 02:27:13 +04:00
objecttothis 29a9b1a7e7 Bugfix: Resolve Race Condition in Rewards and Gift Card Spending (#4640)
* Implement atomic updates for gift card and reward point decrements, enhance error handling for insufficient balances, and add regression tests for concurrency safety.

* Add translations for insufficient gift card balance and reward points error messages across all supported languages.

* Reorder `clear_suspended_sale_detail` call to ensure transactional consistency.

* Reorder `clear_all` call to align with success and error handling logic.

* Ensure soft-deleted gift cards are excluded in balance updates.

* Refactor change_quantity logic with atomic upserts, improve error handling for insufficient stock, and update related tests and constants.

* Added check for NEW_ENTRY

* Added unit tests to test changes.

* Fix class name casing in ItemQuantityTest for consistency.

* Fix Bulgarian translations for insufficient balance error messages in Sales module.

* Fix Greek translations for insufficient balance error messages in Sales module.

* Fix Armenian translations for insufficient balance error messages in Sales module.

* Fix Tamil translations for insufficient balance error messages in Sales module.

* Implement race condition testing for database methods with concurrent process support.

* Fix class name casing in ItemTest for consistency.

* Improve concurrent process handling in race condition tests; add readiness and synchronization barriers.

* Improve handling of process I/O streams and timeout management in race condition tests.

* Add test for decrementing gift card value when marked as deleted

* Add `finally` block to ensure proper cleanup in async database race condition tests

* Improve error handling and timeout management in async database race condition tests.

* Refactor test utilities to use shared `EmployeeFixtureTrait` and `ItemFixtureTrait`.

* Track process exit codes explicitly in race condition tests for improved error detection and debugging.

* Improve error handling in `ConcurrentDbRaceTrait` by adding exceptions for `mysqli_poll` and `mysqli_reap_async_query`.

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>

---------

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-20 02:24:23 +04:00
objecttothis a2b91493c7 Feature: CodeIgniter Throttler (#4619)
* fix(auth): throttle login attempts to prevent brute-force attacks

Add Throttle filter and wire into login route to mitigate
credential-stuffing/brute-force risk (redacted).

- Register App\\Filters\\Throttle in Filters config
- Add \"too_many_attempts\" language string for throttled responses
- Add tests for Throttle filter and Login controller throttling

* Correct bug causing error to not display.


* i18n(login): add too_many_attempts translation for login throttling

Add localized \"too many attempts\" message across all language files
to support login throttling feature. Message informs users to wait
before retrying after exceeding attempt limit.

* fix(auth): rate limit login attempts to prevent brute-force attacks

Add Throttle filter that rate limits login/migrate POST requests,
keyed by IP and submitted username, using CodeIgniter's cache-based
Throttler (redacted).

- Wire filter into login/migrate routes
- Show localized error message when rate limit exceeded
- Broaden writable/cache ignore pattern to cover throttler cache file

* Update app/Language/ar-EG/Login.php

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* style(i18n): use single quotes for translation array keys and values

Convert double-quoted array keys and string values to single quotes
across all Login.php language files for style consistency.

* test(auth): update LoginTest to use throttler service directly

Replace clearThrottleState's Services::resetSingle('throttler') call
with Services::throttler() to reset state via the service instance.
Add usedKeys property to track throttle keys used across test cases.

* test(auth): skip login test assertion when migration required

LoginTest now check migration-required response state before
asserting HTTP 200. Prevent false failures when app force
pending-migration redirect during test run.

* Added missing return statements
2026-08-19 00:25:22 +04:00
objecttothis 8bd2a51cb5 fix(items): validate item_number and skip receiving quantity default for temp items (#4621)
* fix(items): validate item_number and skip receiving quantity default for temp items

- Validate item_number against alpha_numeric_punct rule, return JSON error on failure
- Add item_number_invalid language string

* i18n: reorder Items language keys and add item_number_invalid string

Add item_number_invalid translation across all locale files and
resort surrounding keys alphabetically to match key ordering
convention.

* PSR-12 refactoring.

- Change local variable to camelCase.
- Use single quote in language files.

* i18n: translate item_number_invalid string in ta, th, tl, zh-Hans

Item_number_invalid key had English placeholder text in Tamil,
Thai, Tagalog, Chinese Simplified language files. Translate to
match each locale.

* fix(items): use FormatRules for item_number validation

* refactor(items): use camelCase for variable names

* refactor(items): use camelCase for variable names in Items controller
2026-08-18 02:51:42 +04:00
Sai Asish Yandobjecttothis 0e8fc0963a Reject item CSV imports whose header row is missing required columns (#4597)
* Reject item CSV imports whose header row is missing required columns

Signed-off-by: Sai Asish Y <say.apm35@gmail.com>

* Require all template columns when validating CSV import headers

Signed-off-by: Sai Asish Y <say.apm35@gmail.com>

* fix: derive required CSV import headers from the template generator

---------

Signed-off-by: Sai Asish Y <say.apm35@gmail.com>
Co-authored-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-08-14 14:05:43 +04:00
dependabot[bot] 65b99fea97 chore(deps): bump dompurify from 3.4.12 to 3.4.13 (#4639)
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.4.12 to 3.4.13.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.4.12...3.4.13)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-version: 3.4.13
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-10 21:42:43 +04:00