mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-07-27 03:31:46 +00:00
Add /me/sessions endpoint and show sessions table on account page
This commit is contained in:
parent
4c71a076e7
commit
35a2c5e87c
5 changed files with 130 additions and 1 deletions
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
28
server/utils/parsers/parseUserAgent.js
Normal file
28
server/utils/parsers/parseUserAgent.js
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue