Hlaboi site upgrade notes
========================

Included:
- Login rate limiting: five failed attempts per email/IP combination; 15-minute lock.
- Registration welcome email via PHP mail() (username/email included; password deliberately omitted for security).
- User dashboard Download App placeholder at /app-download.php; replace link/content when the app is ready.
- Admin User Management: create user, block/activate, delete non-admin users.
- Admin Notification Management: publish/delete in-app notifications, shown through users/notifications.php.
- Song add form accepts a validated cover image (JPG/PNG/WebP, max 5 MB) and stores it under assets/song-images/.
- Quick links added to admin dashboard.

Database:
- Import database.sql only for a fresh database. It contains original schema plus upgrade statements.
- For an EXISTING database, run only these statements once in phpMyAdmin:
  ALTER TABLE songs ADD COLUMN image_file VARCHAR(255) NULL;
  CREATE TABLE IF NOT EXISTS login_attempts (id INT AUTO_INCREMENT PRIMARY KEY, identifier_hash CHAR(64) NOT NULL, ip_hash CHAR(64) NOT NULL, attempts INT NOT NULL DEFAULT 0, last_attempt_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, locked_until DATETIME NULL, UNIQUE KEY unique_login_attempt (identifier_hash, ip_hash));
  CREATE TABLE IF NOT EXISTS notifications (id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(200) NOT NULL, message TEXT NOT NULL, status ENUM('draft','published') NOT NULL DEFAULT 'published', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
  CREATE TABLE IF NOT EXISTS user_notifications_read (id INT AUTO_INCREMENT PRIMARY KEY, user_id INT NOT NULL, notification_id INT NOT NULL, read_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uniq_user_notification(user_id,notification_id));
- If image_file already exists, skip the ALTER TABLE statement.

Email:
- Registration email uses PHP mail(). Delivery depends on the host's mail configuration. For reliable delivery, configure authenticated SMTP (for example PHPMailer with your hosting mail account). Do not send plaintext passwords by email; the welcome email intentionally omits it.

Device notification bar:
- Admin messages currently appear in the site's in-app Notifications page. Native phone notification-bar delivery is NOT enabled by this ZIP alone. It requires HTTPS, a service worker, user permission, push subscription storage, and a server-side Web Push/VAPID sender. A user cannot be notified after closing the browser without that push infrastructure.

Security/deployment:
- Test on a backup/staging copy first and check your hosting PHP error log.
- This ZIP was syntax-checked with PHP CLI for the modified core files; live database, SMTP and hosting behavior cannot be verified from this environment.
- Rotate database credentials before deployment if the uploaded archive's credentials are active. Keep config/database.php private and never publish it.
