From 09b5019e95c5d8392a286d74bf7bec23be5d766b Mon Sep 17 00:00:00 2001 From: TheCatLady <52870424+TheCatLady@users.noreply.github.com> Date: Tue, 23 Feb 2021 07:26:21 -0500 Subject: [PATCH] refactor(api): rename Plex auth endpoint (#949) --- docs/extending-overseerr/fail2ban.md | 4 +- overseerr-api.yml | 6 +-- server/routes/auth.ts | 55 ++++++++++++++------------ src/components/Login/index.tsx | 4 +- src/components/Setup/LoginWithPlex.tsx | 2 +- 5 files changed, 38 insertions(+), 33 deletions(-) diff --git a/docs/extending-overseerr/fail2ban.md b/docs/extending-overseerr/fail2ban.md index 4f6b7e16b..fbfe6fa82 100644 --- a/docs/extending-overseerr/fail2ban.md +++ b/docs/extending-overseerr/fail2ban.md @@ -8,7 +8,7 @@ To use Fail2ban with Overseerr, create a new file named `overseerr.local` in you ``` [Definition] -failregex = .*\[info\]\[Auth\]\: Failed login attempt.*"ip":"" +failregex = .*\[info\]\[Auth\]\: Failed sign-in attempt.*"ip":"" ``` -You can then add a jail using this filter in `jail.local`. Please see the [Fail2ban documetation](https://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Jails) for details on how to configure the jail. +You can then add a jail using this filter in `jail.local`. Please see the [Fail2ban documetation](https://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Jails) for details on how to configure the jail. diff --git a/overseerr-api.yml b/overseerr-api.yml index 90b90d11d..b4047e52f 100644 --- a/overseerr-api.yml +++ b/overseerr-api.yml @@ -7,8 +7,8 @@ info: Two primary authentication methods are supported: - - **Cookie Authentication**: A valid login to the `/auth/login` or `/auth/local` will generate a valid authentication cookie. - - **API Key Authentication**: Login is also possible by passing an `X-Api-Key` header along with a valid API Key generated by Overseerr. + - **Cookie Authentication**: A valid sign-in to the `/auth/plex` or `/auth/local` will generate a valid authentication cookie. + - **API Key Authentication**: Sign-in is also possible by passing an `X-Api-Key` header along with a valid API Key generated by Overseerr. tags: - name: public description: Public API endpoints requiring no authentication. @@ -2613,7 +2613,7 @@ paths: application/json: schema: $ref: '#/components/schemas/User' - /auth/login: + /auth/plex: post: summary: Sign in using a Plex token description: Takes an `authToken` (Plex token) to log the user in. Generates a session cookie for use in further requests. If the user does not exist, and there are no other users, then a user will be created with full admin privileges. If a user logs in with access to the main Plex server, they will also have an account created, but without any permissions. diff --git a/server/routes/auth.ts b/server/routes/auth.ts index 3437f76ad..d5bf42bce 100644 --- a/server/routes/auth.ts +++ b/server/routes/auth.ts @@ -26,7 +26,7 @@ authRoutes.get('/me', isAuthenticated(), async (req, res) => { return res.status(200).json(user); }); -authRoutes.post('/login', async (req, res, next) => { +authRoutes.post('/plex', async (req, res, next) => { const settings = getSettings(); const userRepository = getRepository(User); const body = req.body as { authToken?: string }; @@ -35,7 +35,7 @@ authRoutes.post('/login', async (req, res, next) => { return res.status(500).json({ error: 'You must provide an auth token' }); } try { - // First we need to use this auth token to get the users email from plex tv + // First we need to use this auth token to get the users email from plex.tv const plextv = new PlexTvAPI(body.authToken); const account = await plextv.getUser(); @@ -45,12 +45,12 @@ authRoutes.post('/login', async (req, res, next) => { }); if (user) { - // Let's check if their plex token is up to date + // Let's check if their Plex token is up-to-date if (user.plexToken !== body.authToken) { user.plexToken = body.authToken; } - // Update the users avatar with their plex thumbnail (incase it changed) + // Update the user's avatar with their Plex thumbnail, in case it changed user.avatar = account.thumb; user.email = account.email; user.plexUsername = account.username; @@ -80,7 +80,7 @@ authRoutes.post('/login', async (req, res, next) => { // Double check that we didn't create the first admin user before running this if (!user) { // If we get to this point, the user does not already exist so we need to create the - // user _assuming_ they have access to the plex server + // user _assuming_ they have access to the Plex server const mainUser = await userRepository.findOneOrFail({ select: ['id', 'plexToken'], order: { id: 'ASC' }, @@ -100,7 +100,7 @@ authRoutes.post('/login', async (req, res, next) => { await userRepository.save(user); } else { logger.info( - 'Failed login attempt from user without access to plex server', + 'Failed sign-in attempt from user without access to the Plex server.', { label: 'Auth', account: { @@ -112,7 +112,7 @@ authRoutes.post('/login', async (req, res, next) => { ); return next({ status: 403, - message: 'You do not have access to this Plex server', + message: 'You do not have access to this Plex server.', }); } } @@ -139,11 +139,11 @@ authRoutes.post('/local', async (req, res, next) => { const body = req.body as { email?: string; password?: string }; if (!settings.main.localLogin) { - return res.status(500).json({ error: 'Local user login is disabled' }); + return res.status(500).json({ error: 'Local user sign-in is disabled.' }); } else if (!body.email || !body.password) { - return res - .status(500) - .json({ error: 'You must provide an email and a password' }); + return res.status(500).json({ + error: 'You must provide both an email address and a password.', + }); } try { const user = await userRepository.findOne({ @@ -155,17 +155,20 @@ authRoutes.post('/local', async (req, res, next) => { // User doesn't exist or credentials are incorrect if (!isCorrectCredentials) { - logger.info('Failed login attempt from user with incorrect credentials', { - label: 'Auth', - account: { - ip: req.ip, - email: body.email, - password: '__REDACTED__', - }, - }); + logger.info( + 'Failed sign-in attempt from user with incorrect credentials.', + { + label: 'Auth', + account: { + ip: req.ip, + email: body.email, + password: '__REDACTED__', + }, + } + ); return next({ status: 403, - message: 'You do not have access to this Plex server', + message: 'Your sign-in credentials are incorrect.', }); } @@ -176,7 +179,7 @@ authRoutes.post('/local', async (req, res, next) => { return res.status(200).json(user?.filter() ?? {}); } catch (e) { - logger.error('Something went wrong when trying to authenticate', { + logger.error('Something went wrong while attempting to authenticate.', { label: 'Auth', error: e.message, }); @@ -205,7 +208,9 @@ authRoutes.post('/reset-password', async (req, res) => { const body = req.body as { email?: string }; if (!body.email) { - return res.status(500).json({ error: 'You must provide an email' }); + return res + .status(500) + .json({ error: 'You must provide an email address.' }); } const user = await userRepository.findOne({ @@ -215,12 +220,12 @@ authRoutes.post('/reset-password', async (req, res) => { if (user) { await user.resetPassword(); userRepository.save(user); - logger.info('Successful request made for recovery link', { + logger.info('Successful request made for recovery link.', { label: 'User Management', context: { ip: req.ip, email: body.email }, }); } else { - logger.info('Failed request made to reset a password', { + logger.info('Failed request made to reset a password.', { label: 'User Management', context: { ip: req.ip, email: body.email }, }); @@ -235,7 +240,7 @@ authRoutes.post('/reset-password/:guid', async (req, res, next) => { try { if (!req.body.password || req.body.password?.length < 8) { const message = - 'Failed to reset password. Password must be atleast 8 characters long.'; + 'Failed to reset password. Password must be at least 8 characters long.'; logger.info(message, { label: 'User Management', context: { ip: req.ip, guid: req.params.guid }, diff --git a/src/components/Login/index.tsx b/src/components/Login/index.tsx index d812b7f73..ebd95e371 100644 --- a/src/components/Login/index.tsx +++ b/src/components/Login/index.tsx @@ -29,13 +29,13 @@ const Login: React.FC = () => { const settings = useSettings(); // Effect that is triggered when the `authToken` comes back from the Plex OAuth - // We take the token and attempt to login. If we get a success message, we will + // We take the token and attempt to sign in. If we get a success message, we will // ask swr to revalidate the user which _should_ come back with a valid user. useEffect(() => { const login = async () => { setProcessing(true); try { - const response = await axios.post('/api/v1/auth/login', { authToken }); + const response = await axios.post('/api/v1/auth/plex', { authToken }); if (response.data?.id) { revalidate(); diff --git a/src/components/Setup/LoginWithPlex.tsx b/src/components/Setup/LoginWithPlex.tsx index 7ef61136a..3dc0404e2 100644 --- a/src/components/Setup/LoginWithPlex.tsx +++ b/src/components/Setup/LoginWithPlex.tsx @@ -23,7 +23,7 @@ const LoginWithPlex: React.FC = ({ onComplete }) => { useEffect(() => { const login = async () => { - const response = await axios.post('/api/v1/auth/login', { authToken }); + const response = await axios.post('/api/v1/auth/plex', { authToken }); if (response.data?.email) { revalidate();