UNPKG

2.67 kBJavaScriptView Raw
1'use strict'
2
3const { default: fetch, Headers } = require('node-fetch')
4
5const { AUTH_ENDPOINT, REQUIRED } = require('./config')
6const { APIError, ArgumentError, ERRORS } = require('./errors')
7
8function extractToken (res) {
9 const token = res.payload.user && res.payload.user.authToken
10 if (token) { return Promise.resolve(token) }
11 throw new APIError(res.status, res.statusText, 'Payload is missing token.')
12}
13
14async function parseAPIResponse (res) {
15 const data = {
16 payload: await res.json(),
17 status: res.status,
18 statusText: res.statusText
19 }
20 if (res.ok) { return data }
21 throw new APIError(res.status, res.statusText, data.payload.error)
22}
23
24function validateOptions (options) {
25 let missing = []
26
27 if (!(options && options.constructor === Object)) {
28 throw new ArgumentError(ERRORS.missingOptionsArg)
29 }
30 missing = (
31 opts => REQUIRED.options.filter(k => !opts.includes(k))
32 )(Object.keys(options))
33 if (missing.length > 0) {
34 throw new ArgumentError({ ...ERRORS.missingOptions, missing })
35 }
36 const { headers: hdrs, password: pw, username: un } = options
37
38 if (!(
39 hdrs &&
40 (
41 hdrs.constructor === Object ||
42 hdrs.constructor === Headers
43 ))) {
44 throw new ArgumentError(ERRORS.missingHeadersOpt)
45 }
46 missing = REQUIRED.headers.filter(
47 h => hdrs.get ? !hdrs.get(h) : !(typeof hdrs[h] === 'string' && hdrs[h])
48 )
49 if (missing.length > 0) {
50 throw new ArgumentError({ ...ERRORS.missingHeaders, missing })
51 }
52
53 if (!(typeof pw === 'string' && !!pw)) {
54 throw new ArgumentError(ERRORS.missingPassword)
55 }
56 if (!(typeof un === 'string' && !!un)) {
57 throw new ArgumentError(ERRORS.missingUsername)
58 }
59
60 return true
61}
62
63class PlexAppAuthenticator {
64 constructor ({ headers = {}, username = '', password = '' } = {}) {
65 validateOptions(arguments[0])
66
67 this.headers = new Headers(headers)
68 this.options = { username, password }
69 this.token = ''
70
71 return this
72 }
73
74 authorize () {
75 const params = new URLSearchParams()
76
77 this.headers.set('Accept', 'application/json')
78 this.headers.set('Content-Type', 'application/x-www-form-urlencoded')
79 params.set('user[login]', this.options.username)
80 params.set('user[password]', this.options.password)
81
82 return fetch(AUTH_ENDPOINT, {
83 method: 'POST',
84 body: params,
85 headers: this.headers
86 })
87 .then(parseAPIResponse)
88 .then(extractToken)
89 .then(token => {
90 this.token = token
91 return token
92 })
93 }
94}
95
96module.exports = exports = PlexAppAuthenticator
97module.exports.default = exports
98module.exports.APIError = APIError
99module.exports.ArgumentError = ArgumentError