mirror of
https://github.com/sct/overseerr.git
synced 2025-09-17 17:24:35 +02:00
feat(api): allow plex logins from users who have access to the server
This commit is contained in:
@@ -58,6 +58,7 @@
|
|||||||
"@types/react-transition-group": "^4.4.0",
|
"@types/react-transition-group": "^4.4.0",
|
||||||
"@types/swagger-ui-express": "^4.1.2",
|
"@types/swagger-ui-express": "^4.1.2",
|
||||||
"@types/uuid": "^8.3.0",
|
"@types/uuid": "^8.3.0",
|
||||||
|
"@types/xml2js": "^0.4.5",
|
||||||
"@types/yamljs": "^0.2.31",
|
"@types/yamljs": "^0.2.31",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.0.0",
|
"@typescript-eslint/eslint-plugin": "^4.0.0",
|
||||||
"@typescript-eslint/parser": "^3.10.1",
|
"@typescript-eslint/parser": "^3.10.1",
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
import axios, { AxiosInstance } from 'axios';
|
import axios, { AxiosInstance } from 'axios';
|
||||||
|
import xml2js from 'xml2js';
|
||||||
|
import { getSettings } from '../lib/settings';
|
||||||
|
|
||||||
interface PlexAccountResponse {
|
interface PlexAccountResponse {
|
||||||
user: PlexUser;
|
user: PlexUser;
|
||||||
@@ -26,6 +28,33 @@ interface PlexUser {
|
|||||||
entitlements: string[];
|
entitlements: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ServerResponse {
|
||||||
|
$: {
|
||||||
|
id: string;
|
||||||
|
serverId: string;
|
||||||
|
machineIdentifier: string;
|
||||||
|
name: string;
|
||||||
|
lastSeenAt: string;
|
||||||
|
numLibraries: string;
|
||||||
|
owned: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FriendResponse {
|
||||||
|
MediaContainer: {
|
||||||
|
User: {
|
||||||
|
$: {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
username: string;
|
||||||
|
email: string;
|
||||||
|
thumb: string;
|
||||||
|
};
|
||||||
|
Server: ServerResponse[];
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
class PlexTvAPI {
|
class PlexTvAPI {
|
||||||
private authToken: string;
|
private authToken: string;
|
||||||
private axios: AxiosInstance;
|
private axios: AxiosInstance;
|
||||||
@@ -57,6 +86,48 @@ class PlexTvAPI {
|
|||||||
throw new Error('Invalid auth token');
|
throw new Error('Invalid auth token');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getFriends(): Promise<FriendResponse> {
|
||||||
|
const response = await this.axios.get('/pms/friends/all', {
|
||||||
|
transformResponse: [],
|
||||||
|
responseType: 'text',
|
||||||
|
});
|
||||||
|
|
||||||
|
const parsedXml = (await xml2js.parseStringPromise(
|
||||||
|
response.data
|
||||||
|
)) as FriendResponse;
|
||||||
|
|
||||||
|
return parsedXml;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async checkUserAccess(authUser: PlexUser): Promise<boolean> {
|
||||||
|
const settings = getSettings();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!settings.plex.machineId) {
|
||||||
|
throw new Error('Plex is not configured!');
|
||||||
|
}
|
||||||
|
|
||||||
|
const friends = await this.getFriends();
|
||||||
|
|
||||||
|
const users = friends.MediaContainer.User;
|
||||||
|
|
||||||
|
const user = users.find((u) => Number(u.$.id) === authUser.id);
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
throw new Error(
|
||||||
|
'This user does not exist on the main plex accounts shared list'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !!user.Server.find(
|
||||||
|
(server) => server.$.machineIdentifier === settings.plex.machineId
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(`Error checking user access: ${e.message}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default PlexTvAPI;
|
export default PlexTvAPI;
|
||||||
|
@@ -10,7 +10,7 @@ interface Library {
|
|||||||
|
|
||||||
interface PlexSettings {
|
interface PlexSettings {
|
||||||
name: string;
|
name: string;
|
||||||
machineId: string;
|
machineId?: string;
|
||||||
ip: string;
|
ip: string;
|
||||||
port: number;
|
port: number;
|
||||||
libraries: Library[];
|
libraries: Library[];
|
||||||
@@ -67,10 +67,9 @@ class Settings {
|
|||||||
apiKey: 'temp',
|
apiKey: 'temp',
|
||||||
},
|
},
|
||||||
plex: {
|
plex: {
|
||||||
name: 'Main Server',
|
name: '',
|
||||||
ip: '127.0.0.1',
|
ip: '127.0.0.1',
|
||||||
port: 32400,
|
port: 32400,
|
||||||
machineId: '',
|
|
||||||
libraries: [],
|
libraries: [],
|
||||||
},
|
},
|
||||||
radarr: [],
|
radarr: [],
|
||||||
|
@@ -70,8 +70,22 @@ authRoutes.post('/login', async (req, res) => {
|
|||||||
|
|
||||||
// If we get to this point, the user does not already exist so we need to create the
|
// 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
|
||||||
// (We cant do this until we finish the settings sytem and actually
|
const mainUser = await userRepository.findOneOrFail({
|
||||||
// store the user token in ticket #55)
|
select: ['id', 'plexToken'],
|
||||||
|
order: { id: 'ASC' },
|
||||||
|
});
|
||||||
|
const mainPlexTv = new PlexTvAPI(mainUser.plexToken ?? '');
|
||||||
|
if (await mainPlexTv.checkUserAccess(account)) {
|
||||||
|
user = new User({
|
||||||
|
email: account.email,
|
||||||
|
username: account.username,
|
||||||
|
plexId: account.id,
|
||||||
|
plexToken: account.authToken,
|
||||||
|
permissions: Permission.REQUEST,
|
||||||
|
avatar: account.thumb,
|
||||||
|
});
|
||||||
|
await userRepository.save(user);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set logged in session
|
// Set logged in session
|
||||||
|
@@ -1845,6 +1845,13 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.0.tgz#215c231dff736d5ba92410e6d602050cce7e273f"
|
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.0.tgz#215c231dff736d5ba92410e6d602050cce7e273f"
|
||||||
integrity sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ==
|
integrity sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ==
|
||||||
|
|
||||||
|
"@types/xml2js@^0.4.5":
|
||||||
|
version "0.4.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/xml2js/-/xml2js-0.4.5.tgz#d21759b056f282d9c7066f15bbf5c19b908f22fa"
|
||||||
|
integrity sha512-yohU3zMn0fkhlape1nxXG2bLEGZRc1FeqF80RoHaYXJN7uibaauXfhzhOJr1Xh36sn+/tx21QAOf07b/xYVk1w==
|
||||||
|
dependencies:
|
||||||
|
"@types/node" "*"
|
||||||
|
|
||||||
"@types/yamljs@^0.2.31":
|
"@types/yamljs@^0.2.31":
|
||||||
version "0.2.31"
|
version "0.2.31"
|
||||||
resolved "https://registry.yarnpkg.com/@types/yamljs/-/yamljs-0.2.31.tgz#b1a620b115c96db7b3bfdf0cf54aee0c57139245"
|
resolved "https://registry.yarnpkg.com/@types/yamljs/-/yamljs-0.2.31.tgz#b1a620b115c96db7b3bfdf0cf54aee0c57139245"
|
||||||
|
Reference in New Issue
Block a user