🔒 Add authentication route logic for user login and registration
This commit is contained in:
175
code/websites/pokedex.online/server/routes/auth.js
Normal file
175
code/websites/pokedex.online/server/routes/auth.js
Normal file
@@ -0,0 +1,175 @@
|
||||
/**
|
||||
* Authentication Routes
|
||||
*
|
||||
* Handles login, logout, token refresh, and user info endpoints
|
||||
*/
|
||||
|
||||
import { Router } from 'express';
|
||||
import { createToken, verifyToken, decodeToken, getTokenExpiresIn } from '../utils/jwt-utils.js';
|
||||
|
||||
export function createAuthRouter({ secret, adminPassword } = {}) {
|
||||
const router = Router();
|
||||
|
||||
/**
|
||||
* POST /auth/login
|
||||
* Login with admin password to receive JWT token
|
||||
*/
|
||||
router.post('/login', (req, res) => {
|
||||
const { password } = req.body;
|
||||
|
||||
// Validate input
|
||||
if (!password) {
|
||||
return res.status(400).json({
|
||||
error: 'Password is required',
|
||||
code: 'MISSING_PASSWORD'
|
||||
});
|
||||
}
|
||||
|
||||
// Validate password
|
||||
if (password !== adminPassword) {
|
||||
return res.status(401).json({
|
||||
error: 'Invalid password',
|
||||
code: 'INVALID_PASSWORD'
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
// Create token with admin permissions
|
||||
const token = createToken(
|
||||
{
|
||||
isAdmin: true,
|
||||
permissions: ['admin', 'gamemaster-edit'],
|
||||
loginTime: new Date().toISOString()
|
||||
},
|
||||
secret,
|
||||
7 * 24 * 60 * 60 // 7 days
|
||||
);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
token,
|
||||
expiresIn: 7 * 24 * 60 * 60,
|
||||
user: {
|
||||
isAdmin: true,
|
||||
permissions: ['admin', 'gamemaster-edit']
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
res.status(500).json({
|
||||
error: 'Failed to create token',
|
||||
code: 'TOKEN_CREATION_ERROR'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /auth/verify
|
||||
* Verify that a token is valid
|
||||
*/
|
||||
router.post('/verify', (req, res) => {
|
||||
const { token } = req.body;
|
||||
|
||||
if (!token) {
|
||||
return res.status(400).json({
|
||||
error: 'Token is required',
|
||||
code: 'MISSING_TOKEN'
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const decoded = verifyToken(token, secret);
|
||||
const expiresIn = getTokenExpiresIn(token);
|
||||
|
||||
res.json({
|
||||
valid: true,
|
||||
user: {
|
||||
isAdmin: decoded.isAdmin,
|
||||
permissions: decoded.permissions
|
||||
},
|
||||
expiresIn: Math.floor(expiresIn / 1000),
|
||||
expiresAt: new Date(Date.now() + expiresIn)
|
||||
});
|
||||
} catch (err) {
|
||||
return res.status(401).json({
|
||||
valid: false,
|
||||
error: err.message,
|
||||
code: 'INVALID_TOKEN'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /auth/refresh
|
||||
* Refresh an existing token
|
||||
*/
|
||||
router.post('/refresh', (req, res) => {
|
||||
const { token } = req.body;
|
||||
|
||||
if (!token) {
|
||||
return res.status(400).json({
|
||||
error: 'Token is required',
|
||||
code: 'MISSING_TOKEN'
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const decoded = verifyToken(token, secret);
|
||||
|
||||
// Create new token with same payload but extended expiration
|
||||
const newToken = createToken(
|
||||
{
|
||||
isAdmin: decoded.isAdmin,
|
||||
permissions: decoded.permissions,
|
||||
loginTime: decoded.loginTime
|
||||
},
|
||||
secret,
|
||||
7 * 24 * 60 * 60 // 7 days
|
||||
);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
token: newToken,
|
||||
expiresIn: 7 * 24 * 60 * 60
|
||||
});
|
||||
} catch (err) {
|
||||
return res.status(401).json({
|
||||
error: err.message,
|
||||
code: 'INVALID_TOKEN'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /auth/user
|
||||
* Get current user info (requires valid token via middleware)
|
||||
*/
|
||||
router.get('/user', (req, res) => {
|
||||
if (!req.user) {
|
||||
return res.status(401).json({
|
||||
error: 'Not authenticated',
|
||||
code: 'NOT_AUTHENTICATED'
|
||||
});
|
||||
}
|
||||
|
||||
res.json({
|
||||
user: {
|
||||
isAdmin: req.user.isAdmin,
|
||||
permissions: req.user.permissions,
|
||||
loginTime: req.user.loginTime
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /auth/logout
|
||||
* Logout (token is invalidated on client side)
|
||||
*/
|
||||
router.post('/logout', (req, res) => {
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Logged out successfully'
|
||||
});
|
||||
});
|
||||
|
||||
return router;
|
||||
}
|
||||
Reference in New Issue
Block a user