Update:Auth to use new user model

- Express requests include userNew to start migrating API controllers to new user model
This commit is contained in:
advplyr 2024-08-10 15:46:04 -05:00
parent 59370cae81
commit 202ceb02b5
14 changed files with 626 additions and 392 deletions

View file

@ -3,11 +3,20 @@ const Logger = require('./Logger')
const Database = require('./Database')
const Auth = require('./Auth')
/**
* @typedef SocketClient
* @property {string} id socket id
* @property {SocketIO.Socket} socket
* @property {number} connected_at
* @property {import('./models/User')} user
*/
class SocketAuthority {
constructor() {
this.Server = null
this.io = null
/** @type {Object.<string, SocketClient>} */
this.clients = {}
}
@ -18,27 +27,29 @@ class SocketAuthority {
*/
getUsersOnline() {
const onlineUsersMap = {}
Object.values(this.clients).filter(c => c.user).forEach(client => {
if (onlineUsersMap[client.user.id]) {
onlineUsersMap[client.user.id].connections++
} else {
onlineUsersMap[client.user.id] = {
...client.user.toJSONForPublic(this.Server.playbackSessionManager.sessions),
connections: 1
Object.values(this.clients)
.filter((c) => c.user)
.forEach((client) => {
if (onlineUsersMap[client.user.id]) {
onlineUsersMap[client.user.id].connections++
} else {
onlineUsersMap[client.user.id] = {
...client.user.toJSONForPublic(this.Server.playbackSessionManager.sessions),
connections: 1
}
}
}
})
})
return Object.values(onlineUsersMap)
}
getClientsForUser(userId) {
return Object.values(this.clients).filter(c => c.user && c.user.id === userId)
return Object.values(this.clients).filter((c) => c.user?.id === userId)
}
/**
* Emits event to all authorized clients
* @param {string} evt
* @param {any} data
* @param {string} evt
* @param {any} data
* @param {Function} [filter] optional filter function to only send event to specific users
*/
emitter(evt, data, filter = null) {
@ -67,7 +78,7 @@ class SocketAuthority {
// Emits event to all admin user clients
adminEmitter(evt, data) {
for (const socketId in this.clients) {
if (this.clients[socketId].user && this.clients[socketId].user.isAdminOrUp) {
if (this.clients[socketId].user?.isAdminOrUp) {
this.clients[socketId].socket.emit(evt, data)
}
}
@ -75,16 +86,14 @@ class SocketAuthority {
/**
* Closes the Socket.IO server and disconnect all clients
*
* @param {Function} callback
*
* @param {Function} callback
*/
close(callback) {
Logger.info('[SocketAuthority] Shutting down')
// This will close all open socket connections, and also close the underlying http server
if (this.io)
this.io.close(callback)
else
callback()
if (this.io) this.io.close(callback)
else callback()
}
initialize(Server) {
@ -93,7 +102,7 @@ class SocketAuthority {
this.io = new SocketIO.Server(this.Server.server, {
cors: {
origin: '*',
methods: ["GET", "POST"]
methods: ['GET', 'POST']
}
})
@ -144,7 +153,7 @@ class SocketAuthority {
// admin user can send a message to all authenticated users
// displays on the web app as a toast
const client = this.clients[socket.id] || {}
if (client.user && client.user.isAdminOrUp) {
if (client.user?.isAdminOrUp) {
this.emitter('admin_message', payload.message || '')
} else {
Logger.error(`[SocketAuthority] Non-admin user sent the message_all_users event`)
@ -162,8 +171,8 @@ class SocketAuthority {
/**
* When setting up a socket connection the user needs to be associated with a socket id
* for this the client will send a 'auth' event that includes the users API token
*
* @param {SocketIO.Socket} socket
*
* @param {SocketIO.Socket} socket
* @param {string} token JWT
*/
async authenticateSocket(socket, token) {
@ -176,6 +185,7 @@ class SocketAuthority {
Logger.error('Cannot validate socket - invalid token')
return socket.emit('invalid_token')
}
// get the user via the id from the decoded jwt.
const user = await Database.userModel.getUserByIdOrOldId(token_data.userId)
if (!user) {
@ -196,18 +206,13 @@ class SocketAuthority {
client.user = user
if (!client.user.toJSONForBrowser) {
Logger.error('Invalid user...', client.user)
return
}
Logger.debug(`[SocketAuthority] User Online ${client.user.username}`)
this.adminEmitter('user_online', client.user.toJSONForPublic(this.Server.playbackSessionManager.sessions))
// Update user lastSeen without firing sequelize bulk update hooks
user.lastSeen = Date.now()
await Database.userModel.updateFromOld(user, false)
await user.save({ hooks: false })
const initialPayload = {
userId: client.user.id,
@ -224,4 +229,4 @@ class SocketAuthority {
this.Server.cancelLibraryScan(id)
}
}
module.exports = new SocketAuthority()
module.exports = new SocketAuthority()