Files
seasonedShows/src/webserver/controllers/user/authenticatePlexAccount.js
Kevin 7168950dfe Feat: es modules (#139)
* All file imports change from commonjs to es-module

* Improved plex error responses back from api

* Converted viewHistory to es module

* Es-module requires file extension, updated all imports

* Fix esmodule not having __dirname defined in scope

* Replace dynamic-require with fs readFileSync

* Short message service module function is exported as default

* Resolved lint issues & ignore import/extension rule until typescript

* All tests file imports changed from commonjs to es-module

* Import json fixtures with new helper
2022-08-25 17:19:23 +02:00

113 lines
2.9 KiB
JavaScript

import FormData from "form-data";
import UserRepository from "../../../user/userRepository.js";
const userRepository = new UserRepository();
class PlexAuthenticationError extends Error {
constructor(errorResponse) {
const message =
"Unexptected error while authenticating to plex signin api. View error response.";
super(message);
this.errorResponse = errorResponse;
this.statusCode = 500;
this.success = false;
this.source = "plex";
}
}
class PlexUnauthorizedError extends Error {
constructor(errorResponse) {
const message = "Unauthorized. Please check plex credentials.";
super(message);
this.errorResponse = errorResponse;
this.statusCode = 401;
this.success = false;
this.source = "plex";
}
}
function handleResponse(response) {
if (!response.ok) {
if (response?.status === 401)
throw new PlexUnauthorizedError(response?.statusText);
throw new PlexAuthenticationError(response?.statusText);
}
return response.json();
}
function plexAuthenticate(username, password) {
const url = "https://plex.tv/api/v2/users/signin";
const form = new FormData();
form.append("login", username);
form.append("password", password);
form.append("rememberMe", "false");
const headers = {
Accept: "application/json, text/plain, */*",
"Content-Type": form.getHeaders()["content-type"],
"X-Plex-Client-Identifier": "seasonedRequest"
};
const options = {
method: "POST",
headers,
body: form
};
return fetch(url, options).then(resp => handleResponse(resp));
}
function link(req, res) {
const user = req.loggedInUser;
const { username, password } = req.body;
return plexAuthenticate(username, password)
.then(plexUser => userRepository.linkPlexUserId(user.username, plexUser.id))
.then(() =>
res.send({
success: true,
message:
"Successfully authenticated and linked plex account with seasoned request."
})
)
.catch(error =>
res.status(error?.statusCode || 500).send({
message:
error?.message ||
"Unexptected error occured while linking plex account",
success: error?.success || false,
source: error?.source,
errorResponse: error?.errorResponse
})
);
}
function unlink(req, res) {
const username = req.loggedInUser ? req.loggedInUser.username : null;
return userRepository
.unlinkPlexUserId(username)
.then(() =>
res.send({
success: true,
message: "Successfully unlinked plex account from seasoned request."
})
)
.catch(error =>
res.status(error?.statusCode || 500).send({
message:
error?.message ||
"Unexptected error occured while unlinking plex account",
success: error?.success || false,
source: error?.source,
errorResponse: error?.errorResponse
})
);
}
export default { link, unlink };