* fix(locale): validate language_code against known locales to block path traversal
postSaveLocale() stored language_code from user input with no allow-list validation, and it later flows into Language::setLocale()/load() where the locale segment is require()'d. An authenticated config-grant account could store a relative path (e.g. ../../public/uploads) and, combined with a planted file in public/uploads/, achieve unauthenticated RCE on the next request.
Validate the submitted language against array_keys(get_languages()) before storing, and harden languageExists() to reject path separators and dot-dot sequences. Adds regression tests.
* test(locale): give locale fixture valid reference-code min/max defaults
* fix(locale): reject null bytes in languageExists guard
A stored language_code containing a NUL byte passes the existing path-separator and parent-dir checks, then reaches file_exists(). On PHP 8.5+ file_exists() throws a ValueError for NUL-byte paths, which breaks configuration loading. Reject NUL bytes in the guard and add regression tests.
- Show 'Database Migration Required' heading instead of welcome message when migrations pending
- Add warning alert explaining credentials needed to authorize migration
- Change button text from 'Go' to 'Migrate' during migration flow
- Add language strings for clear migration messaging
This makes it clear to the user that they are performing a migration
authorization step (not a regular login), and will need to re-authenticate
after migrations complete.
- Prevents circular dependency where login requires session, but session requires database table created by migrations
- Fresh installs: use file session until migrations run, then switch to database session
- Upgrades: use file session during migration, then switch to database session
- Simplified: removed DDL from Load_config, migrations remain source of truth
Fixes: Sessions table missing on fresh install prevents login
Addresses CodeRabbit feedback:
- Remove duplicate session table DDL (migrations are source of truth)
- Remove MySQL-specific information_schema query
- Use proper session config cloning to avoid modifying shared config
* 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
- Format percentage per locale rules
- Moved constants to Constants.php
- Added PHPdoc comments
- Refactor code for clarity and simplicity.
- Added decimal formatting per locale for display.
- autoload locale helper
- Remove unneeded calls to helpers
- Removed unneeded comments
- fixed errors causing checks in parse_decimals to return false due to locales which use a comma.
- Added types to config.
- Added formatting to DB_log messages
- Corrected bug referencing non-existent OSPOS config property timezone
- set the date_default_timezone to the php-specified default when timezone is not set in the app rather than 'America/New York'
- Added TODO indicating problem.
- missing return type in Events->load_config(), added void
- Dynamic property creation is deprecated starting in php 8.2. The solution is to declare the property in the class before using it.
- Added ::class to model instantiations to remove "potentially polymorphic call" warnings
- Corrected phpdoc