Add /me/sessions endpoint and show sessions table on account page

This commit is contained in:
advplyr 2026-07-25 17:18:38 -05:00
parent 4c71a076e7
commit 35a2c5e87c
5 changed files with 130 additions and 1 deletions

View file

@ -1,10 +1,12 @@
const { Request, Response } = require('express')
const { Op } = require('sequelize')
const Logger = require('../Logger')
const SocketAuthority = require('../SocketAuthority')
const Database = require('../Database')
const { sort } = require('../libs/fastSort')
const { toNumber, isNullOrNaN } = require('../utils/index')
const userStats = require('../utils/queries/userStats')
const parseUserAgent = require('../utils/parsers/parseUserAgent')
/**
* @typedef RequestUserObject
@ -26,6 +28,40 @@ class MeController {
res.json(req.user.toOldJSONForBrowser())
}
/**
* GET: /api/me/sessions
*
* @param {RequestWithUser} req
* @param {Response} res
*/
async getSessions(req, res) {
if (req.user.isGuest) {
return res.json({ sessions: [] })
}
const refreshToken = req.cookies.refresh_token || req.headers['x-refresh-token']
const sessions = await Database.sessionModel.findAll({
where: {
userId: req.user.id,
expiresAt: { [Op.gt]: new Date() }
},
order: [['updatedAt', 'DESC']]
})
res.json({
sessions: sessions.map((session) => ({
id: session.id,
ipAddress: session.ipAddress,
userAgent: session.userAgent,
// For display convenience
deviceInfo: parseUserAgent(session.userAgent),
createdAt: session.createdAt?.valueOf() ?? null,
updatedAt: session.updatedAt?.valueOf() ?? null,
current: !!refreshToken && (session.refreshToken === refreshToken || session.lastRefreshToken === refreshToken)
}))
})
}
/**
* GET: /api/me/progress
*

View file

@ -171,6 +171,7 @@ class ApiRouter {
// Current User Routes (Me)
//
this.router.get('/me', MeController.getCurrentUser.bind(this))
this.router.get('/me/sessions', MeController.getSessions.bind(this))
this.router.get('/me/progress', MeController.getAllMediaProgress.bind(this))
this.router.get('/me/bookmarks', MeController.getAllBookmarks.bind(this))
this.router.get('/me/bookmarks/:libraryItemId', MeController.getBookmarksForLibraryItem.bind(this))

View file

@ -0,0 +1,28 @@
const uaParserJs = require('../../libs/uaParser')
/**
* @param {string|null|undefined} userAgent
* @returns {{ browserName?:string, browserVersion?:string, osName?:string, osVersion?:string, deviceType?:string, model?:string, vendor?:string }|null}
*/
function parseUserAgent(userAgent) {
if (!userAgent) return null
const ua = uaParserJs(userAgent)
const deviceInfo = {
browserName: ua?.browser?.name || undefined,
browserVersion: ua?.browser?.version || undefined,
osName: ua?.os?.name || undefined,
osVersion: ua?.os?.version || undefined,
deviceType: ua?.device?.type || undefined,
model: ua?.device?.model || undefined,
vendor: ua?.device?.vendor || undefined
}
for (const key in deviceInfo) {
if (deviceInfo[key] === undefined) delete deviceInfo[key]
}
return Object.keys(deviceInfo).length ? deviceInfo : null
}
module.exports = parseUserAgent