mirror of
https://github.com/Crazyco-xyz/48hr.email.git
synced 2026-01-09 11:19:36 +01:00
97 lines
3.1 KiB
JavaScript
97 lines
3.1 KiB
JavaScript
/**
|
|
* API Authentication Middleware
|
|
* Supports both session-based auth and Bearer token auth
|
|
*/
|
|
|
|
function createAuthenticator(apiTokenRepository) {
|
|
/**
|
|
* Require authentication - returns 401 if not authenticated
|
|
*/
|
|
function requireAuth(req, res, next) {
|
|
// Check session first (existing web auth)
|
|
if (req.session && req.session.isAuthenticated && req.session.userId) {
|
|
req.user = {
|
|
id: req.session.userId,
|
|
username: req.session.username
|
|
}
|
|
req.authMethod = 'session'
|
|
return next()
|
|
}
|
|
|
|
// Check Bearer token
|
|
const authHeader = req.headers.authorization
|
|
if (authHeader && authHeader.startsWith('Bearer ')) {
|
|
const token = authHeader.substring(7) // Remove 'Bearer ' prefix
|
|
|
|
const tokenData = apiTokenRepository.getByToken(token)
|
|
if (tokenData) {
|
|
req.user = {
|
|
id: tokenData.user_id,
|
|
username: tokenData.username
|
|
}
|
|
req.authMethod = 'token'
|
|
|
|
// Update last_used timestamp asynchronously
|
|
setImmediate(() => {
|
|
try {
|
|
apiTokenRepository.updateLastUsed(token)
|
|
} catch (err) {
|
|
// Log but don't fail the request
|
|
console.error('Failed to update token last_used:', err)
|
|
}
|
|
})
|
|
|
|
return next()
|
|
}
|
|
}
|
|
|
|
// No valid authentication found
|
|
return res.apiError('Authentication required', 'UNAUTHORIZED', 401)
|
|
}
|
|
|
|
/**
|
|
* Optional authentication - sets req.user if authenticated, but doesn't require it
|
|
*/
|
|
function optionalAuth(req, res, next) {
|
|
// Check session first
|
|
if (req.session && req.session.isAuthenticated && req.session.userId) {
|
|
req.user = {
|
|
id: req.session.userId,
|
|
username: req.session.username
|
|
}
|
|
req.authMethod = 'session'
|
|
return next()
|
|
}
|
|
|
|
// Check Bearer token
|
|
const authHeader = req.headers.authorization
|
|
if (authHeader && authHeader.startsWith('Bearer ')) {
|
|
const token = authHeader.substring(7)
|
|
|
|
const tokenData = apiTokenRepository.getByToken(token)
|
|
if (tokenData) {
|
|
req.user = {
|
|
id: tokenData.user_id,
|
|
username: tokenData.username
|
|
}
|
|
req.authMethod = 'token'
|
|
|
|
// Update last_used timestamp asynchronously
|
|
setImmediate(() => {
|
|
try {
|
|
apiTokenRepository.updateLastUsed(token)
|
|
} catch (err) {
|
|
console.error('Failed to update token last_used:', err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// Continue regardless of auth status
|
|
next()
|
|
}
|
|
|
|
return { requireAuth, optionalAuth }
|
|
}
|
|
|
|
module.exports = createAuthenticator
|