feat(system): implement 404 page with activity logging and change profile route format
Backend Changes:
- Added public API endpoint /api/public/log-404 (no auth required)
- Created backend/src/routes/public.js for public endpoints
- Added ACTIONS.SYSTEM_404 and CATEGORIES.system to activity log service
- Registered public routes in app.js
Frontend Changes:
- Created NotFoundPage.jsx with standalone layout (no auth required)
- Added publicAPI.log404() to log 404 access attempts
- Logs both authenticated and anonymous users
- Changed profile route from /@:username to /u/:username
- Made profile route public (removed ProtectedRoute wrapper)
- Updated all profile links from /@${username} to /u/${username} in:
- ChatMessage.jsx
- DashboardMatchCard.jsx
- MatchRequestCards.jsx
- MatchCard.jsx
- UserListItem.jsx
- MatchChatPage.jsx
- PublicProfilePage.jsx
Fixes:
- React Router doesn't support @ in path segments
- 404 page now accessible to non-authenticated users without redirect
- Profile route no longer catches all unmatched routes
This commit is contained in:
@@ -131,6 +131,9 @@ app.get('/api/debug/ip', (req, res) => {
|
||||
// Apply rate limiting to all API routes
|
||||
app.use('/api/', apiLimiter);
|
||||
|
||||
// Public routes (no authentication required)
|
||||
app.use('/api/public', require('./routes/public'));
|
||||
|
||||
// API routes
|
||||
app.use('/api/auth', require('./routes/auth'));
|
||||
app.use('/api/users', require('./routes/users'));
|
||||
|
||||
49
backend/src/routes/public.js
Normal file
49
backend/src/routes/public.js
Normal file
@@ -0,0 +1,49 @@
|
||||
const express = require('express');
|
||||
const { ACTIONS, log: activityLog } = require('../services/activityLog');
|
||||
const { getClientIP } = require('../utils/request');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
/**
|
||||
* POST /api/public/log-404
|
||||
* Log 404 page access (no authentication required)
|
||||
* Logs both authenticated and unauthenticated users
|
||||
*/
|
||||
router.post('/log-404', async (req, res) => {
|
||||
try {
|
||||
const { path, search } = req.body;
|
||||
|
||||
// Get user info if authenticated (optional)
|
||||
const userId = req.user?.id || null;
|
||||
const username = req.user?.username || 'anonymous';
|
||||
|
||||
// Construct full path
|
||||
const fullPath = search ? `${path}${search}` : path;
|
||||
|
||||
// Log to activity logs
|
||||
activityLog({
|
||||
userId,
|
||||
username,
|
||||
ipAddress: getClientIP(req),
|
||||
action: ACTIONS.SYSTEM_404,
|
||||
resource: fullPath,
|
||||
method: 'GET',
|
||||
path: fullPath,
|
||||
metadata: {
|
||||
requestedPath: path,
|
||||
queryString: search || null,
|
||||
userAgent: req.headers['user-agent'] || null,
|
||||
referer: req.headers.referer || null,
|
||||
},
|
||||
success: true,
|
||||
});
|
||||
|
||||
res.json({ success: true, logged: true });
|
||||
} catch (error) {
|
||||
console.error('Error logging 404:', error);
|
||||
// Don't fail the request if logging fails
|
||||
res.json({ success: true, logged: false });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
@@ -34,6 +34,9 @@ const ACTIONS = {
|
||||
CHAT_MESSAGE: 'chat.message',
|
||||
CHAT_JOIN_ROOM: 'chat.join_room',
|
||||
CHAT_LEAVE_ROOM: 'chat.leave_room',
|
||||
|
||||
// System actions
|
||||
SYSTEM_404: 'system.404',
|
||||
};
|
||||
|
||||
// Category mapping from action
|
||||
@@ -43,6 +46,7 @@ const CATEGORIES = {
|
||||
'match': 'match',
|
||||
'admin': 'admin',
|
||||
'chat': 'chat',
|
||||
'system': 'system',
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user