Add admin login
- admins and login_attempts tables - cli/create_admin.php: create an admin or reset a password over SSH (no email involved) - includes/auth.php: hardened admin sessions, login throttling (5 failures per IP per 15 minutes) and CSRF helpers - admin/: login, logout and a dashboard showing broadcast status - includes/admin_layout.php: shared admin page layout Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
74dfb3c146
commit
babb71660c
8 files changed
+389
No files matched your search
@@ -26,6 +26,8 @@ This repo covers the **frontend only** — the public-facing website. Icecast co
|
||||
- [includes/broadcasts.php](includes/broadcasts.php) — Broadcast lifecycle and track history logic.
|
||||
- [cli/poll_icecast.php](cli/poll_icecast.php) — Cron-run poller that records broadcasts and tracks.
|
||||
- [cli/set_show.php](cli/set_show.php) — Sets which show is airing next (or now).
|
||||
- [cli/create_admin.php](cli/create_admin.php) — Creates an admin account or resets its password.
|
||||
- [admin/](admin/) — Admin backend. Every page calls `requireAdmin()` from [includes/auth.php](includes/auth.php) and uses `adminHeader()`/`adminFooter()` from [includes/admin_layout.php](includes/admin_layout.php).
|
||||
|
||||
## Architecture
|
||||
|
||||
@@ -43,6 +45,10 @@ MariaDB on localhost. Credentials live in `config/db_credentials.php`, which is
|
||||
|
||||
`cli/poll_icecast.php` runs from cron every minute and polls Icecast four times, 15 seconds apart. A broadcast starts when the stream comes online and ends after five minutes unseen (so brief drop-outs don't split a show). Before going live, run `php cli/set_show.php <slug>` to choose the show.
|
||||
|
||||
## Admin Authentication
|
||||
|
||||
Username and password only; the site sends no email. Accounts are created and passwords reset over SSH with `php cli/create_admin.php <username>`. Passwords are hashed with `password_hash()` (PASSWORD_DEFAULT). Sessions use a `rfe_admin` cookie scoped to the admin directory (HttpOnly, SameSite=Strict, Secure over HTTPS) and expire after four hours idle. Five failed logins from one IP within 15 minutes locks that IP out for the rest of the window. Every POST form must include `csrfField()` and its handler must call `verifyCsrf()` first.
|
||||
|
||||
## Icecast Integration
|
||||
|
||||
- **Stream URL:** `https://radio.cyberpunklibrarian.nohost.me/rfe`
|
||||
|
||||
Reference in new issue
Block a user