fix(profiles): make public profiles accessible without authentication and unify 404 behavior

Backend changes:
- Removed authentication requirement from GET /api/users/:username endpoint
- Removed authentication requirement from GET /api/users/:username/ratings endpoint
- These are public profile endpoints and should be accessible to all users

Frontend changes:
- PublicProfilePage now shows NotFoundPage component when user doesn't exist
- Unified 404 behavior: both invalid URLs and non-existent users show the same 404 page
- NotFoundPage "Requested URL" box now only shows in dev mode (import.meta.env.DEV)
- Removed unused AlertCircle icon import from PublicProfilePage
This commit is contained in:
Radosław Gierwiało
2025-12-05 16:54:38 +01:00
parent 948c694ed6
commit f90945aa47
3 changed files with 15 additions and 30 deletions

View File

@@ -82,7 +82,7 @@ router.patch('/me', authenticate, updateProfileValidation, updateProfile);
router.patch('/me/password', authenticate, changePasswordValidation, changePassword); router.patch('/me/password', authenticate, changePasswordValidation, changePassword);
// GET /api/users/:username - Get public user profile by username // GET /api/users/:username - Get public user profile by username
router.get('/:username', authenticate, async (req, res, next) => { router.get('/:username', async (req, res, next) => {
try { try {
const { username } = req.params; const { username } = req.params;
@@ -149,7 +149,7 @@ router.get('/:username', authenticate, async (req, res, next) => {
}); });
// GET /api/users/:username/ratings - Get ratings for a user // GET /api/users/:username/ratings - Get ratings for a user
router.get('/:username/ratings', authenticate, async (req, res, next) => { router.get('/:username/ratings', async (req, res, next) => {
try { try {
const { username } = req.params; const { username } = req.params;

View File

@@ -45,7 +45,8 @@ export default function NotFoundPage() {
</p> </p>
</div> </div>
{/* Current Path */} {/* Current Path - Only show in dev mode */}
{import.meta.env.DEV && (
<div className="mb-8 p-4 bg-gray-100 rounded-lg"> <div className="mb-8 p-4 bg-gray-100 rounded-lg">
<p className="text-sm text-gray-500 mb-1">Requested URL:</p> <p className="text-sm text-gray-500 mb-1">Requested URL:</p>
<code className="text-sm text-gray-800 break-all"> <code className="text-sm text-gray-800 break-all">
@@ -53,6 +54,7 @@ export default function NotFoundPage() {
{location.search} {location.search}
</code> </code>
</div> </div>
)}
{/* Action Buttons */} {/* Action Buttons */}
<div className="flex flex-col sm:flex-row gap-3 justify-center"> <div className="flex flex-col sm:flex-row gap-3 justify-center">

View File

@@ -2,8 +2,9 @@ import { useState, useEffect } from 'react';
import { useParams, Link } from 'react-router-dom'; import { useParams, Link } from 'react-router-dom';
import { authAPI, ratingsAPI } from '../services/api'; import { authAPI, ratingsAPI } from '../services/api';
import Layout from '../components/layout/Layout'; import Layout from '../components/layout/Layout';
import { User, MapPin, Globe, Hash, Youtube, Instagram, Facebook, Award, Users, Star, Calendar, Loader2, AlertCircle, ThumbsUp } from 'lucide-react'; import { User, MapPin, Globe, Hash, Youtube, Instagram, Facebook, Award, Users, Star, Calendar, Loader2, ThumbsUp } from 'lucide-react';
import Avatar from '../components/common/Avatar'; import Avatar from '../components/common/Avatar';
import NotFoundPage from './NotFoundPage';
const PublicProfilePage = () => { const PublicProfilePage = () => {
const { username: rawUsername } = useParams(); const { username: rawUsername } = useParams();
@@ -61,25 +62,7 @@ const PublicProfilePage = () => {
} }
if (error) { if (error) {
return ( return <NotFoundPage />;
<Layout>
<div className="min-h-screen bg-gray-50 flex items-center justify-center">
<div className="max-w-md w-full mx-4">
<div className="bg-white rounded-lg shadow-sm p-8 text-center">
<AlertCircle className="w-16 h-16 text-red-500 mx-auto mb-4" />
<h2 className="text-2xl font-bold text-gray-900 mb-2">User Not Found</h2>
<p className="text-gray-600 mb-6">{error}</p>
<Link
to="/events"
className="inline-block px-6 py-2 bg-primary-600 text-white rounded-md hover:bg-primary-700"
>
Back to Events
</Link>
</div>
</div>
</div>
</Layout>
);
} }
return ( return (