Files
WhatToWatch/server/services/plex/auth.js
2019-09-08 20:34:34 -05:00

110 lines
2.8 KiB
JavaScript

import parser from 'xml2json';
import uuid from 'uuid';
import btoa from 'btoa';
import request from 'request-promise';
import models from '../../db/models';
import logger from '../../../config/winston';
const getPlexPin = async user => {
try {
logger.info(`getPlexPin(User) ${user}`);
const params = {
url: 'https://plex.tv/pins.xml',
headers: {
'X-Plex-Client-Identifier': user.email,
},
};
const res = await request.post(params);
const formattedResponse = JSON.parse(parser.toJson(res));
return formattedResponse;
} catch (error) {
logger.error(error);
return error.message;
}
};
const fetchToken = async (username, password) => {
try {
const res = await request.post(
tokenUrlParams(username, password),
);
const token = res.match(rxAuthToken)[1];
return token;
} catch (error) {
return error.message;
}
};
const tokenUrlParams = (username, password) => ({
url: 'https://plex.tv/users/sign_in.xml',
headers: {
'X-Plex-Client-Identifier': uuid(),
Authorization: `Basic ${encryptUserCreds(username, password)}`,
},
});
const plexUrlParams = (plexToken, user) => ({
url: 'https://plex.tv/pms/servers.xml',
headers: {
'X-Plex-Client-Identifier': user.user.email,
'X-Plex-Token': plexToken,
},
});
const checkPlexPin = async (pinId, user) => {
try {
const params = {
url: `https://plex.tv/pins/${pinId}.xml`,
headers: {
'X-Plex-Client-Identifier': user.googleId,
},
};
const res = await request.get(params);
const formattedResponse = JSON.parse(parser.toJson(res));
return formattedResponse.pin.auth_token;
} catch (error) {
console.log(error);
return error.message;
}
};
const getPlexUrl = async (plexToken, user) => {
try {
const res = await request.get(plexUrlParams(plexToken, user));
let formattedResponse = JSON.parse(parser.toJson(res))
.MediaContainer.Server;
if (!Array.isArray(formattedResponse)) {
formattedResponse = [formattedResponse];
}
formattedResponse.reduce((acc, other) =>
acc.createdAt > other.createdAt ? acc : other,
);
const server = formattedResponse.slice(-1)[0];
await models.User.update(
{
plexToken: plexToken.trim(),
plexUrl: `http://${server.address}:${server.port}`.trim(),
},
{ where: { googleId: user.googleId } },
);
console.log('server--', server);
return `http://${server.address}:${server.port}`;
} catch (error) {
console.log(error.message);
return error.message;
}
};
const rxAuthToken = /authenticationToken="([^"]+)"/;
const encryptUserCreds = (username, password) => {
const creds = `${username}:${password}`;
return btoa(creds);
};
export default { fetchToken, getPlexPin, checkPlexPin, getPlexUrl };