mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-07-08 02:11:35 +00:00
50 lines
1.5 KiB
JavaScript
50 lines
1.5 KiB
JavaScript
// server/middleware/sessionOrJwt.js
|
|
/**
|
|
* Accept either an existing session user (passport session)
|
|
* or a JWT bearer token (API). Returns 401 only if neither is present.
|
|
*
|
|
* 👉 Enhancement:
|
|
* When a user is authenticated, we emit the "userLoggedIn" achievement
|
|
* event in a fire-and-forget way so "First Login" (and streaks) unlock
|
|
* immediately for brand-new accounts too.
|
|
*/
|
|
const AchievementManager = require('../managers/AchievementManager')
|
|
|
|
function fireLoginEvent(req) {
|
|
try {
|
|
if (req._absLoginEventSent) return
|
|
const user = req.user
|
|
const uid = user && (user.id || user.userId)
|
|
if (!uid) return
|
|
|
|
req._absLoginEventSent = true
|
|
// Do not block the request if achievements write fails
|
|
AchievementManager.applyEvent(String(uid), 'userLoggedIn').catch(() => {})
|
|
} catch (_) {
|
|
// swallow — achievements must never break auth
|
|
}
|
|
}
|
|
|
|
module.exports = (auth) => {
|
|
if (!auth || typeof auth.isAuthenticated !== 'function') {
|
|
throw new Error('[sessionOrJwt] auth.isAuthenticated missing')
|
|
}
|
|
|
|
return (req, res, next) => {
|
|
// Session user already present?
|
|
if (req.user && (req.user.id || req.user.userId)) {
|
|
fireLoginEvent(req)
|
|
return next()
|
|
}
|
|
|
|
// Try JWT auth (no session). Use custom callback so we can continue.
|
|
auth.isAuthenticated(req, res, (err) => {
|
|
if (err) return next(err)
|
|
if (req.user && (req.user.id || req.user.userId)) {
|
|
fireLoginEvent(req)
|
|
return next()
|
|
}
|
|
return res.status(401).json({ error: 'Unauthorized' })
|
|
})
|
|
}
|
|
}
|