diff --git a/server/routes/auth.ts b/server/routes/auth.ts index 7adcc73ab..c3d9d0f61 100644 --- a/server/routes/auth.ts +++ b/server/routes/auth.ts @@ -11,6 +11,7 @@ import logger from '@server/logger'; import { isAuthenticated } from '@server/middleware/auth'; import * as EmailValidator from 'email-validator'; import { Router } from 'express'; +import gravatarUrl from 'gravatar-url'; const authRoutes = Router(); @@ -274,24 +275,82 @@ authRoutes.post('/jellyfin', async (req, res, next) => { where: { jellyfinUserId: account.User.Id }, }); - if (user) { + if (!user && !(await userRepository.count())) { + logger.info( + 'Sign-in attempt from Jellyfin user with access to the media server; creating initial admin user for Overseerr', + { + label: 'API', + ip: req.ip, + jellyfinUsername: account.User.Name, + } + ); + + // User doesn't exist, and there are no users in the database, we'll create the user + // with admin permission + settings.main.mediaServerType = MediaServerType.JELLYFIN; + user = new User({ + email: body.email, + jellyfinUsername: account.User.Name, + jellyfinUserId: account.User.Id, + jellyfinDeviceId: deviceId, + jellyfinAuthToken: account.AccessToken, + permissions: Permission.ADMIN, + avatar: account.User.PrimaryImageTag + ? `${jellyfinHost}/Users/${account.User.Id}/Images/Primary/?tag=${account.User.PrimaryImageTag}&quality=90` + : gravatarUrl(body.email ?? '', { default: 'mm', size: 200 }), + userType: UserType.JELLYFIN, + }); + + settings.jellyfin.hostname = body.hostname ?? ''; + settings.jellyfin.serverId = account.User.ServerId; + settings.save(); + startJobs(); + + await userRepository.save(user); + } + // User already exists, let's update their information + else if (body.username === user?.jellyfinUsername) { + logger.info( + `Found matching ${ + settings.main.mediaServerType === MediaServerType.JELLYFIN + ? 'Jellyfin' + : 'Emby' + } user; updating user with ${ + settings.main.mediaServerType === MediaServerType.JELLYFIN + ? 'Jellyfin' + : 'Emby' + }`, + { + label: 'API', + ip: req.ip, + jellyfinUsername: account.User.Name, + } + ); // Let's check if their authtoken is up to date if (user.jellyfinAuthToken !== account.AccessToken) { user.jellyfinAuthToken = account.AccessToken; } - // Update the users avatar with their jellyfin profile pic (incase it changed) if (account.User.PrimaryImageTag) { user.avatar = `${jellyfinHost}/Users/${account.User.Id}/Images/Primary/?tag=${account.User.PrimaryImageTag}&quality=90`; } else { - user.avatar = '/os_logo_square.png'; + user.avatar = gravatarUrl(user.email, { + default: 'mm', + size: 200, + }); } - user.jellyfinUsername = account.User.Name; if (user.username === account.User.Name) { user.username = ''; } + + // If JELLYFIN_TYPE is set to 'emby' then set mediaServerType to EMBY + if (process.env.JELLYFIN_TYPE === 'emby') { + settings.main.mediaServerType = MediaServerType.EMBY; + settings.save(); + } + await userRepository.save(user); } else if (!settings.main.newPlexLogin) { logger.warn( @@ -307,69 +366,38 @@ authRoutes.post('/jellyfin', async (req, res, next) => { status: 403, message: 'Access denied.', }); - } else { - // Here we check if it's the first user. If it is, we create the user with no check - // and give them admin permissions - const totalUsers = await userRepository.count(); - if (totalUsers === 0) { - logger.info( - 'Sign-in attempt from Jellyfin user with access to the media server; creating initial admin user for Overseerr', - { - label: 'API', - ip: req.ip, - jellyfinUsername: account.User.Name, - } - ); - user = new User({ - email: body.email, + } else if (!user) { + logger.info( + 'Sign-in attempt from Jellyfin user with access to the media server; creating new Overseerr user', + { + label: 'API', + ip: req.ip, jellyfinUsername: account.User.Name, - jellyfinUserId: account.User.Id, - jellyfinDeviceId: deviceId, - jellyfinAuthToken: account.AccessToken, - permissions: Permission.ADMIN, - avatar: account.User.PrimaryImageTag - ? `${jellyfinHost}/Users/${account.User.Id}/Images/Primary/?tag=${account.User.PrimaryImageTag}&quality=90` - : '/os_logo_square.png', - userType: UserType.JELLYFIN, - }); - await userRepository.save(user); - - //Update hostname in settings if it doesn't exist (initial configuration) - //Also set mediaservertype to JELLYFIN - if (settings.jellyfin.hostname === '') { - settings.main.mediaServerType = MediaServerType.JELLYFIN; - settings.jellyfin.hostname = body.hostname ?? ''; - settings.jellyfin.serverId = account.User.ServerId; - settings.save(); - startJobs(); } - } + ); - if (!user) { - if (!body.email) { - throw new Error('add_email'); - } + if (!body.email) { + throw new Error('add_email'); + } - user = new User({ - email: body.email, - jellyfinUsername: account.User.Name, - jellyfinUserId: account.User.Id, - jellyfinDeviceId: deviceId, - jellyfinAuthToken: account.AccessToken, - permissions: settings.main.defaultPermissions, - avatar: account.User.PrimaryImageTag - ? `${jellyfinHost}/Users/${account.User.Id}/Images/Primary/?tag=${account.User.PrimaryImageTag}&quality=90` - : '/os_logo_square.png', - userType: UserType.JELLYFIN, - }); - //initialize Jellyfin/Emby users with local login - const passedExplicitPassword = - body.password && body.password.length > 0; - if (passedExplicitPassword) { - await user.setPassword(body.password ?? ''); - } - await userRepository.save(user); + user = new User({ + email: body.email, + jellyfinUsername: account.User.Name, + jellyfinUserId: account.User.Id, + jellyfinDeviceId: deviceId, + jellyfinAuthToken: account.AccessToken, + permissions: settings.main.defaultPermissions, + avatar: account.User.PrimaryImageTag + ? `${jellyfinHost}/Users/${account.User.Id}/Images/Primary/?tag=${account.User.PrimaryImageTag}&quality=90` + : gravatarUrl(body.email, { default: 'mm', size: 200 }), + userType: UserType.JELLYFIN, + }); + //initialize Jellyfin/Emby users with local login + const passedExplicitPassword = body.password && body.password.length > 0; + if (passedExplicitPassword) { + await user.setPassword(body.password ?? ''); } + await userRepository.save(user); } // Set logged in session @@ -400,6 +428,11 @@ authRoutes.post('/jellyfin', async (req, res, next) => { status: 406, message: 'CREDENTIAL_ERROR_ADD_EMAIL', }); + } else if (e.message === 'select_server_type') { + return next({ + status: 406, + message: 'CREDENTIAL_ERROR_NO_SERVER_TYPE', + }); } else { logger.error(e.message, { label: 'Auth' }); return next({ diff --git a/server/routes/settings/index.ts b/server/routes/settings/index.ts index 5703cccc0..de86ed71b 100644 --- a/server/routes/settings/index.ts +++ b/server/routes/settings/index.ts @@ -29,6 +29,7 @@ import { getAppVersion } from '@server/utils/appVersion'; import { Router } from 'express'; import rateLimit from 'express-rate-limit'; import fs from 'fs'; +import gravatarUrl from 'gravatar-url'; import { escapeRegExp, merge, omit, set, sortBy } from 'lodash'; import { rescheduleJob } from 'node-schedule'; import path from 'path'; @@ -337,7 +338,7 @@ settingsRoutes.get('/jellyfin/users', async (req, res) => { id: user.Id, thumb: user.PrimaryImageTag ? `${jellyfinHost}/Users/${user.Id}/Images/Primary/?tag=${user.PrimaryImageTag}&quality=90` - : '/os_logo_square.png', + : gravatarUrl(user.Name, { default: 'mm', size: 200 }), email: user.Name, })); diff --git a/server/routes/user/index.ts b/server/routes/user/index.ts index 9d9370cf2..789c90765 100644 --- a/server/routes/user/index.ts +++ b/server/routes/user/index.ts @@ -537,7 +537,10 @@ router.post( permissions: settings.main.defaultPermissions, avatar: jellyfinUser?.PrimaryImageTag ? `${jellyfinHost}/Users/${jellyfinUser.Id}/Images/Primary/?tag=${jellyfinUser.PrimaryImageTag}&quality=90` - : '/os_logo_square.png', + : gravatarUrl(jellyfinUser?.Name ?? '', { + default: 'mm', + size: 200, + }), userType: UserType.JELLYFIN, });