v2.1.0 — Security & Bug Fix Release
This release focuses on security hardening, bug fixes, and code quality improvements. No breaking changes — fully backward-compatible with v2.0.
🔒 Security Fixes
XSS Protection for Custom Button Links
customBtnLink values are now validated before being rendered into href attributes. Previously, a malicious value like javascript:... could execute arbitrary code when the button was clicked.
A sanitizeUrl() guard was added to both the standard and Livewire JS builds. Any URL that does not start with http://, https://, /, or # is automatically replaced with #.
Affected files:
assets/js/laravel-toaster-magic.jsassets/js/livewire-v3/laravel-toaster-magic.js
Removed Unsafe javascript: Default in Livewire Events
The Livewire event listener was using 'javascript:' as the default fallback for customBtnLink when none was provided. This has been replaced with an empty string, which correctly suppresses the button from rendering entirely.
🐛 Bug Fixes
Fatal Error During php artisan migrate with Database Cache Driver
Fixes: #19
The service provider called Cache::rememberForever() during boot(). When CACHE_STORE=database, this immediately fired a SQL query against the cache table — but on a fresh installation the table doesn't exist yet, causing a fatal error that prevented php artisan migrate from running at all.
The fix wraps the cache call in a try-catch. If the cache driver throws for any reason (missing table, connection error, misconfigured driver), the value is computed directly without caching. Once migrations complete, normal caching resumes automatically.
// Before — crashes if cache table doesn't exist yet
$systemProcessingDirectory = Cache::rememberForever($cacheKey, $compute);
// After — falls back gracefully
try {
$systemProcessingDirectory = Cache::rememberForever($cacheKey, $compute);
} catch (\Throwable) {
$systemProcessingDirectory = $compute();
}rtrim() Was Silently Corrupting Toast Messages
When building toast messages from a Laravel MessageBag, the code used rtrim($string, "<br>") to strip the trailing <br> separator. PHP's rtrim() treats its second argument as a character mask, not a string — meaning it was stripping any of the individual characters <, b, r, > from the right end of the message. Words like "error", "number", or "better" at the end of a validation message would be silently truncated.
Fixed with preg_replace('/(<br>)+$/', '', $string) across all four methods: info, success, warning, error.
Livewire Close Button Not Responding to closeButton Option
The Livewire event listener only read showCloseBtn from event options, while the rest of the package used closeButton. Users passing closeButton: true in a Livewire dispatch would silently get no close button.
Both keys are now supported with a fallback chain — fully backward-compatible:
const showCloseBtn = detail?.options?.showCloseBtn ?? detail?.options?.closeButton ?? false;🧹 Code Quality
- Removed dead
str_replace('\n', ...)— single-quoted'\n'in PHP is a literal backslash-n, never a newline. The line was unreachable and has been removed. - Removed unused
use Exception;import fromToastMagic.php. - Fixed wrong inline comment in Livewire JS — comment said "Wait 500ms" but the actual timeout was 1000ms.
- Config values corrected to integers —
showDurationandtimeOutinconfig/laravel-toaster-magic.phpwere stored as strings ("300","5000"). They are now proper integers (300,5000).
✅ Compatibility
- No public API changes
- No config changes required
- Fully compatible with Laravel 10, 11, and 12
- Fully compatible with Livewire v3 and v4
- All existing
closeButtonandshowCloseBtnintegrations continue to work
Upgrade
composer update devrabiul/laravel-toaster-magicThen re-publish assets:
php artisan vendor:publish --tag=laravel-toaster-magic-assets --forceAssets are also auto-published on the next page load via the built-in version-diffing mechanism.