diff --git a/asteroid.lisp b/asteroid.lisp index 29c8c07..8d2f6d4 100644 --- a/asteroid.lisp +++ b/asteroid.lisp @@ -642,6 +642,78 @@ :top-artist-5-plays ""))) |# +;; Auth status API endpoint +(define-page api-auth-status #@"/api/auth-status" () + "Check if user is logged in and their role" + (setf (radiance:header "Content-Type") "application/json") + (handler-case + (let* ((user-id (session:field "user-id")) + (user (when user-id (find-user-by-id user-id)))) + (cl-json:encode-json-to-string + `(("loggedIn" . ,(if user t nil)) + ("isAdmin" . ,(if (and user (user-has-role-p user :admin)) t nil)) + ("username" . ,(if user + (let ((username (gethash "username" user))) + (if (listp username) (first username) username)) + nil))))) + (error (e) + (cl-json:encode-json-to-string + `(("loggedIn" . nil) + ("isAdmin" . nil) + ("error" . ,(format nil "~a" e))))))) + +;; Register page (GET) +(define-page register #@"/register" () + "User registration page" + (let ((username (radiance:post-var "username")) + (email (radiance:post-var "email")) + (password (radiance:post-var "password")) + (confirm-password (radiance:post-var "confirm-password"))) + (if (and username password) + ;; Handle registration form submission + (cond + ;; Validate passwords match + ((not (string= password confirm-password)) + (render-template-with-plist "register" + :title "Asteroid Radio - Register" + :display-error "display: block;" + :display-success "display: none;" + :error-message "Passwords do not match" + :success-message "")) + + ;; Check if username already exists + ((find-user-by-username username) + (render-template-with-plist "register" + :title "Asteroid Radio - Register" + :display-error "display: block;" + :display-success "display: none;" + :error-message "Username already exists" + :success-message "")) + + ;; Create the user + (t + (if (create-user username email password :role :listener :active t) + (progn + ;; Auto-login after successful registration + (let ((user (find-user-by-username username))) + (when user + (let ((user-id (gethash "_id" user))) + (setf (session:field "user-id") (if (listp user-id) (first user-id) user-id))))) + (radiance:redirect "/asteroid/")) + (render-template-with-plist "register" + :title "Asteroid Radio - Register" + :display-error "display: block;" + :display-success "display: none;" + :error-message "Registration failed. Please try again." + :success-message "")))) + ;; Show registration form (no POST data) + (render-template-with-plist "register" + :title "Asteroid Radio - Register" + :display-error "display: none;" + :display-success "display: none;" + :error-message "" + :success-message "")))) + (define-page player #@"/player" () (let ((template-path (merge-pathnames "template/player.chtml" (asdf:system-source-directory :asteroid)))) diff --git a/static/asteroid.css b/static/asteroid.css index 566e0db..8a0f257 100644 --- a/static/asteroid.css +++ b/static/asteroid.css @@ -64,6 +64,30 @@ body .nav a:hover{ background: #2a3441; } +body .nav .btn-logout{ + background: #2a3441; + border-color: #3a4551; + color: #ff9999; +} + +body .nav .btn-logout:hover{ + background: #3a4551; + border-color: #4a5561; + color: #ffaaaa; +} + +body [data-show-if-logged-in]{ + display: none; +} + +body [data-show-if-logged-out]{ + display: none; +} + +body [data-show-if-admin]{ + display: none; +} + body .controls{ margin: 20px 0; } diff --git a/static/asteroid.lass b/static/asteroid.lass index ec77ece..d49bee8 100644 --- a/static/asteroid.lass +++ b/static/asteroid.lass @@ -55,7 +55,28 @@ :margin-left "0") ((:and a :hover) - :background "#2a3441")) + :background "#2a3441") + + ;; Logout button styling - subtle, not alarming + (.btn-logout + :background "#2a3441" + :border-color "#3a4551" + :color "#ff9999") + + ((:and .btn-logout :hover) + :background "#3a4551" + :border-color "#4a5561" + :color "#ffaaaa")) + + ;; Hide conditional auth elements by default (JavaScript will show them) + (|[data-show-if-logged-in]| + :display none) + + (|[data-show-if-logged-out]| + :display none) + + (|[data-show-if-admin]| + :display none) (.controls :margin "20px 0" diff --git a/static/js/auth-ui.js b/static/js/auth-ui.js new file mode 100644 index 0000000..a3143cf --- /dev/null +++ b/static/js/auth-ui.js @@ -0,0 +1,38 @@ +// auth-ui.js - Handle authentication UI state across all pages + +// Check if user is logged in by calling the API +async function checkAuthStatus() { + try { + const response = await fetch('/asteroid/api/auth-status'); + const data = await response.json(); + return data; + } catch (error) { + console.error('Error checking auth status:', error); + return { loggedIn: false, isAdmin: false }; + } +} + +// Update UI based on authentication status +function updateAuthUI(authStatus) { + // Show/hide elements based on login status + document.querySelectorAll('[data-show-if-logged-in]').forEach(el => { + el.style.display = authStatus.loggedIn ? 'inline-block' : 'none'; + }); + + document.querySelectorAll('[data-show-if-logged-out]').forEach(el => { + el.style.display = authStatus.loggedIn ? 'none' : 'inline-block'; + }); + + document.querySelectorAll('[data-show-if-admin]').forEach(el => { + el.style.display = authStatus.isAdmin ? 'inline-block' : 'none'; + }); +} + +// Initialize auth UI on page load +document.addEventListener('DOMContentLoaded', async function() { + console.log('Auth UI initializing...'); + const authStatus = await checkAuthStatus(); + console.log('Auth status:', authStatus); + updateAuthUI(authStatus); + console.log('Auth UI updated'); +}); diff --git a/template/admin.chtml b/template/admin.chtml index 807379d..0b72c9b 100644 --- a/template/admin.chtml +++ b/template/admin.chtml @@ -5,6 +5,7 @@ + @@ -13,7 +14,9 @@ diff --git a/template/front-page.chtml b/template/front-page.chtml index 2b0791a..df13e02 100644 --- a/template/front-page.chtml +++ b/template/front-page.chtml @@ -5,7 +5,8 @@ - + +
@@ -14,11 +15,12 @@ diff --git a/template/player.chtml b/template/player.chtml index 2470f57..17db19c 100644 --- a/template/player.chtml +++ b/template/player.chtml @@ -5,6 +5,7 @@ + @@ -12,7 +13,9 @@

🎵 WEB PLAYER

diff --git a/template/profile.chtml b/template/profile.chtml index 2f12567..15412d7 100644 --- a/template/profile.chtml +++ b/template/profile.chtml @@ -5,6 +5,7 @@ + @@ -14,6 +15,7 @@ ← Back to Main Web Player Admin + Logout
diff --git a/template/register.chtml b/template/register.chtml new file mode 100644 index 0000000..a125286 --- /dev/null +++ b/template/register.chtml @@ -0,0 +1,56 @@ + + + + Asteroid Radio - Register + + + + + +
+

🎵 ASTEROID RADIO - REGISTER

+ + +
+
+

Create Account

+
+ Registration failed +
+
+ Registration successful! +
+
+
+ + + Minimum 3 characters +
+
+ + +
+
+ + + Minimum 6 characters +
+
+ + +
+
+ +
+
+ +
+
+
+ +