2018-10-22 02:12:47 +03:00
define ( [ "events" , "apiclient" , "appStorage" ] , function ( events , apiClientFactory , appStorage ) {
"use strict" ;
function getServerAddress ( server , mode ) {
switch ( mode ) {
case ConnectionMode . Local :
return server . LocalAddress ;
case ConnectionMode . Manual :
return server . ManualAddress ;
case ConnectionMode . Remote :
return server . RemoteAddress ;
default :
return server . ManualAddress || server . LocalAddress || server . RemoteAddress
}
}
function paramsToString ( params ) {
var values = [ ] ;
for ( var key in params ) {
var value = params [ key ] ;
null !== value && void 0 !== value && "" !== value && values . push ( encodeURIComponent ( key ) + "=" + encodeURIComponent ( value ) )
}
return values . join ( "&" )
}
function resolveFailure ( instance , resolve ) {
resolve ( {
State : "Unavailable" ,
ConnectUser : instance . connectUser ( )
} )
}
function mergeServers ( credentialProvider , list1 , list2 ) {
for ( var i = 0 , length = list2 . length ; i < length ; i ++ ) credentialProvider . addOrUpdateServer ( list1 , list2 [ i ] ) ;
return list1
}
function updateServerInfo ( server , systemInfo ) {
2019-09-19 15:52:00 -04:00
server . Name = systemInfo . ServerName , systemInfo . Id && ( server . Id = systemInfo . Id ) , systemInfo . LocalAddress && ( server . LocalAddress = systemInfo . LocalAddress )
2018-10-22 02:12:47 +03:00
}
function getEmbyServerUrl ( baseUrl , handler ) {
2019-07-30 23:26:12 -07:00
return baseUrl + "/" + handler
2018-10-22 02:12:47 +03:00
}
function getFetchPromise ( request ) {
var headers = request . headers || { } ;
"json" === request . dataType && ( headers . accept = "application/json" ) ;
var fetchRequest = {
headers : headers ,
method : request . type ,
credentials : "same-origin"
} ,
contentType = request . contentType ;
return request . data && ( "string" == typeof request . data ? fetchRequest . body = request . data : ( fetchRequest . body = paramsToString ( request . data ) , contentType = contentType || "application/x-www-form-urlencoded; charset=UTF-8" ) ) , contentType && ( headers [ "Content-Type" ] = contentType ) , request . timeout ? fetchWithTimeout ( request . url , fetchRequest , request . timeout ) : fetch ( request . url , fetchRequest )
}
function fetchWithTimeout ( url , options , timeoutMs ) {
return console . log ( "fetchWithTimeout: timeoutMs: " + timeoutMs + ", url: " + url ) , new Promise ( function ( resolve , reject ) {
var timeout = setTimeout ( reject , timeoutMs ) ;
options = options || { } , options . credentials = "same-origin" , fetch ( url , options ) . then ( function ( response ) {
clearTimeout ( timeout ) , console . log ( "fetchWithTimeout: succeeded connecting to url: " + url ) , resolve ( response )
} , function ( error ) {
clearTimeout ( timeout ) , console . log ( "fetchWithTimeout: timed out connecting to url: " + url ) , reject ( )
} )
} )
}
function ajax ( request ) {
if ( ! request ) throw new Error ( "Request cannot be null" ) ;
return request . headers = request . headers || { } , console . log ( "ConnectionManager requesting url: " + request . url ) , getFetchPromise ( request ) . then ( function ( response ) {
return console . log ( "ConnectionManager response status: " + response . status + ", url: " + request . url ) , response . status < 400 ? "json" === request . dataType || "application/json" === request . headers . accept ? response . json ( ) : response : Promise . reject ( response )
} , function ( err ) {
throw console . log ( "ConnectionManager request failed to url: " + request . url ) , err
} )
}
function getConnectUrl ( handler ) {
return "https://connect.emby.media/service/" + handler
}
function replaceAll ( originalString , strReplace , strWith ) {
var reg = new RegExp ( strReplace , "ig" ) ;
return originalString . replace ( reg , strWith )
}
function normalizeAddress ( address ) {
return address = address . trim ( ) , 0 !== address . toLowerCase ( ) . indexOf ( "http" ) && ( address = "http://" + address ) , address = replaceAll ( address , "Http:" , "http:" ) , address = replaceAll ( address , "Https:" , "https:" )
}
function stringEqualsIgnoreCase ( str1 , str2 ) {
return ( str1 || "" ) . toLowerCase ( ) === ( str2 || "" ) . toLowerCase ( )
}
function compareVersions ( a , b ) {
a = a . split ( "." ) , b = b . split ( "." ) ;
for ( var i = 0 , length = Math . max ( a . length , b . length ) ; i < length ; i ++ ) {
var aVal = parseInt ( a [ i ] || "0" ) ,
bVal = parseInt ( b [ i ] || "0" ) ;
if ( aVal < bVal ) return - 1 ;
if ( aVal > bVal ) return 1
}
return 0
}
var defaultTimeout = 2e4 ,
ConnectionMode = {
Local : 0 ,
Remote : 1 ,
Manual : 2
} ,
ConnectionManager = function ( credentialProvider , appName , appVersion , deviceName , deviceId , capabilities , devicePixelRatio ) {
function onConnectUserSignIn ( user ) {
connectUser = user , events . trigger ( self , "connectusersignedin" , [ user ] )
}
function onAuthenticated ( apiClient , result , options , saveCredentials ) {
var credentials = credentialProvider . credentials ( ) ,
servers = credentials . Servers . filter ( function ( s ) {
return s . Id === result . ServerId
} ) ,
server = servers . length ? servers [ 0 ] : apiClient . serverInfo ( ) ;
return ! 1 !== options . updateDateLastAccessed && ( server . DateLastAccessed = ( new Date ) . getTime ( ) ) , server . Id = result . ServerId , saveCredentials ? ( server . UserId = result . User . Id , server . AccessToken = result . AccessToken ) : ( server . UserId = null , server . AccessToken = null ) , credentialProvider . addOrUpdateServer ( credentials . Servers , server ) , credentialProvider . credentials ( credentials ) , apiClient . enableAutomaticBitrateDetection = options . enableAutomaticBitrateDetection , apiClient . serverInfo ( server ) , afterConnected ( apiClient , options ) , onLocalUserSignIn ( server , apiClient . serverAddress ( ) , result . User )
}
function afterConnected ( apiClient , options ) {
options = options || { } , ! 1 !== options . reportCapabilities && apiClient . reportCapabilities ( capabilities ) , apiClient . enableAutomaticBitrateDetection = options . enableAutomaticBitrateDetection , ! 1 !== options . enableWebSocket && ( console . log ( "calling apiClient.ensureWebSocket" ) , apiClient . ensureWebSocket ( ) )
}
function onLocalUserSignIn ( server , serverUrl , user ) {
return self . _getOrAddApiClient ( server , serverUrl ) , ( self . onLocalUserSignedIn ? self . onLocalUserSignedIn . call ( self , user ) : Promise . resolve ( ) ) . then ( function ( ) {
events . trigger ( self , "localusersignedin" , [ user ] )
} )
}
function ensureConnectUser ( credentials ) {
return connectUser && connectUser . Id === credentials . ConnectUserId ? Promise . resolve ( ) : credentials . ConnectUserId && credentials . ConnectAccessToken ? ( connectUser = null , getConnectUser ( credentials . ConnectUserId , credentials . ConnectAccessToken ) . then ( function ( user ) {
return onConnectUserSignIn ( user ) , Promise . resolve ( )
} , function ( ) {
return Promise . resolve ( )
} ) ) : Promise . resolve ( )
}
function getConnectUser ( userId , accessToken ) {
if ( ! userId ) throw new Error ( "null userId" ) ;
if ( ! accessToken ) throw new Error ( "null accessToken" ) ;
return ajax ( {
type : "GET" ,
url : "https://connect.emby.media/service/user?id=" + userId ,
dataType : "json" ,
headers : {
"X-Application" : appName + "/" + appVersion ,
"X-Connect-UserToken" : accessToken
}
} )
}
function addAuthenticationInfoFromConnect ( server , serverUrl , credentials ) {
if ( ! server . ExchangeToken ) throw new Error ( "server.ExchangeToken cannot be null" ) ;
if ( ! credentials . ConnectUserId ) throw new Error ( "credentials.ConnectUserId cannot be null" ) ;
var url = getEmbyServerUrl ( serverUrl , "Connect/Exchange?format=json&ConnectUserId=" + credentials . ConnectUserId ) ,
auth = 'MediaBrowser Client="' + appName + '", Device="' + deviceName + '", DeviceId="' + deviceId + '", Version="' + appVersion + '"' ;
return ajax ( {
type : "GET" ,
url : url ,
dataType : "json" ,
headers : {
"X-MediaBrowser-Token" : server . ExchangeToken ,
"X-Emby-Authorization" : auth
}
} ) . then ( function ( auth ) {
return server . UserId = auth . LocalUserId , server . AccessToken = auth . AccessToken , auth
} , function ( ) {
return server . UserId = null , server . AccessToken = null , Promise . reject ( )
} )
}
function validateAuthentication ( server , serverUrl ) {
return ajax ( {
type : "GET" ,
url : getEmbyServerUrl ( serverUrl , "System/Info" ) ,
dataType : "json" ,
headers : {
"X-MediaBrowser-Token" : server . AccessToken
}
} ) . then ( function ( systemInfo ) {
return updateServerInfo ( server , systemInfo ) , Promise . resolve ( )
} , function ( ) {
return server . UserId = null , server . AccessToken = null , Promise . resolve ( )
} )
}
function getImageUrl ( localUser ) {
if ( connectUser && connectUser . ImageUrl ) return {
url : connectUser . ImageUrl
} ;
if ( localUser && localUser . PrimaryImageTag ) {
return {
url : self . getApiClient ( localUser ) . getUserImageUrl ( localUser . Id , {
tag : localUser . PrimaryImageTag ,
type : "Primary"
} ) ,
supportsParams : ! 0
}
}
return {
url : null ,
supportsParams : ! 1
}
}
function logoutOfServer ( apiClient ) {
var serverInfo = apiClient . serverInfo ( ) || { } ,
logoutInfo = {
serverId : serverInfo . Id
} ;
return apiClient . logout ( ) . then ( function ( ) {
events . trigger ( self , "localusersignedout" , [ logoutInfo ] )
} , function ( ) {
events . trigger ( self , "localusersignedout" , [ logoutInfo ] )
} )
}
function getConnectServers ( credentials ) {
return console . log ( "Begin getConnectServers" ) , credentials . ConnectAccessToken && credentials . ConnectUserId ? ajax ( {
type : "GET" ,
url : "https://connect.emby.media/service/servers?userId=" + credentials . ConnectUserId ,
dataType : "json" ,
headers : {
"X-Application" : appName + "/" + appVersion ,
"X-Connect-UserToken" : credentials . ConnectAccessToken
}
} ) . then ( function ( servers ) {
return servers . map ( function ( i ) {
return {
ExchangeToken : i . AccessKey ,
ConnectServerId : i . Id ,
Id : i . SystemId ,
Name : i . Name ,
RemoteAddress : i . Url ,
LocalAddress : i . LocalAddress ,
UserLinkType : "guest" === ( i . UserType || "" ) . toLowerCase ( ) ? "Guest" : "LinkedUser"
}
} )
} , function ( ) {
return credentials . Servers . slice ( 0 ) . filter ( function ( s ) {
return s . ExchangeToken
} )
} ) : Promise . resolve ( [ ] )
}
function filterServers ( servers , connectServers ) {
return servers . filter ( function ( server ) {
return ! server . ExchangeToken || connectServers . filter ( function ( connectServer ) {
return server . Id === connectServer . Id
} ) . length > 0
} )
}
function findServers ( ) {
return new Promise ( function ( resolve , reject ) {
var onFinish = function ( foundServers ) {
var servers = foundServers . map ( function ( foundServer ) {
var info = {
Id : foundServer . Id ,
LocalAddress : convertEndpointAddressToManualAddress ( foundServer ) || foundServer . Address ,
Name : foundServer . Name
} ;
return info . LastConnectionMode = info . ManualAddress ? ConnectionMode . Manual : ConnectionMode . Local , info
} ) ;
resolve ( servers )
} ;
2019-03-16 17:15:37 +00:00
if ( window . NativeShell && typeof window . NativeShell . findServers === 'function' ) {
window . NativeShell . findServers ( 1e3 ) . then ( onFinish , function ( ) {
2018-10-22 02:12:47 +03:00
onFinish ( [ ] )
2019-03-16 17:15:37 +00:00
} ) ;
} else {
resolve ( [ ] ) ;
}
} ) ;
2018-10-22 02:12:47 +03:00
}
function convertEndpointAddressToManualAddress ( info ) {
if ( info . Address && info . EndpointAddress ) {
var address = info . EndpointAddress . split ( ":" ) [ 0 ] ,
parts = info . Address . split ( ":" ) ;
if ( parts . length > 1 ) {
var portString = parts [ parts . length - 1 ] ;
isNaN ( parseInt ( portString ) ) || ( address += ":" + portString )
}
return normalizeAddress ( address )
}
return null
}
function getTryConnectPromise ( url , connectionMode , state , resolve , reject ) {
console . log ( "getTryConnectPromise " + url ) , ajax ( {
url : getEmbyServerUrl ( url , "system/info/public" ) ,
timeout : defaultTimeout ,
type : "GET" ,
dataType : "json"
} ) . then ( function ( result ) {
state . resolved || ( state . resolved = ! 0 , console . log ( "Reconnect succeeded to " + url ) , resolve ( {
url : url ,
connectionMode : connectionMode ,
data : result
} ) )
} , function ( ) {
state . resolved || ( console . log ( "Reconnect failed to " + url ) , ++ state . rejects >= state . numAddresses && reject ( ) )
} )
}
function tryReconnect ( serverInfo ) {
var addresses = [ ] ,
addressesStrings = [ ] ;
return ! serverInfo . manualAddressOnly && serverInfo . LocalAddress && - 1 === addressesStrings . indexOf ( serverInfo . LocalAddress ) && ( addresses . push ( {
url : serverInfo . LocalAddress ,
mode : ConnectionMode . Local ,
timeout : 0
} ) , addressesStrings . push ( addresses [ addresses . length - 1 ] . url ) ) , serverInfo . ManualAddress && - 1 === addressesStrings . indexOf ( serverInfo . ManualAddress ) && ( addresses . push ( {
url : serverInfo . ManualAddress ,
mode : ConnectionMode . Manual ,
timeout : 100
} ) , addressesStrings . push ( addresses [ addresses . length - 1 ] . url ) ) , ! serverInfo . manualAddressOnly && serverInfo . RemoteAddress && - 1 === addressesStrings . indexOf ( serverInfo . RemoteAddress ) && ( addresses . push ( {
url : serverInfo . RemoteAddress ,
mode : ConnectionMode . Remote ,
timeout : 200
} ) , addressesStrings . push ( addresses [ addresses . length - 1 ] . url ) ) , console . log ( "tryReconnect: " + addressesStrings . join ( "|" ) ) , new Promise ( function ( resolve , reject ) {
var state = { } ;
state . numAddresses = addresses . length , state . rejects = 0 , addresses . map ( function ( url ) {
setTimeout ( function ( ) {
state . resolved || getTryConnectPromise ( url . url , url . mode , state , resolve , reject )
} , url . timeout )
} )
} )
}
function onSuccessfulConnection ( server , systemInfo , connectionMode , serverUrl , options , resolve ) {
var credentials = credentialProvider . credentials ( ) ;
options = options || { } , credentials . ConnectAccessToken && ! 1 !== options . enableAutoLogin ? ensureConnectUser ( credentials ) . then ( function ( ) {
server . ExchangeToken ? addAuthenticationInfoFromConnect ( server , serverUrl , credentials ) . then ( function ( ) {
afterConnectValidated ( server , credentials , systemInfo , connectionMode , serverUrl , ! 0 , options , resolve )
} , function ( ) {
afterConnectValidated ( server , credentials , systemInfo , connectionMode , serverUrl , ! 0 , options , resolve )
} ) : afterConnectValidated ( server , credentials , systemInfo , connectionMode , serverUrl , ! 0 , options , resolve )
} ) : afterConnectValidated ( server , credentials , systemInfo , connectionMode , serverUrl , ! 0 , options , resolve )
}
function afterConnectValidated ( server , credentials , systemInfo , connectionMode , serverUrl , verifyLocalAuthentication , options , resolve ) {
if ( options = options || { } , ! 1 === options . enableAutoLogin ) server . UserId = null , server . AccessToken = null ;
else if ( verifyLocalAuthentication && server . AccessToken && ! 1 !== options . enableAutoLogin ) return void validateAuthentication ( server , serverUrl ) . then ( function ( ) {
afterConnectValidated ( server , credentials , systemInfo , connectionMode , serverUrl , ! 1 , options , resolve )
} ) ;
updateServerInfo ( server , systemInfo ) , server . LastConnectionMode = connectionMode , ! 1 !== options . updateDateLastAccessed && ( server . DateLastAccessed = ( new Date ) . getTime ( ) ) , credentialProvider . addOrUpdateServer ( credentials . Servers , server ) , credentialProvider . credentials ( credentials ) ;
var result = {
Servers : [ ]
} ;
result . ApiClient = self . _getOrAddApiClient ( server , serverUrl ) , result . ApiClient . setSystemInfo ( systemInfo ) , result . State = server . AccessToken && ! 1 !== options . enableAutoLogin ? "SignedIn" : "ServerSignIn" , result . Servers . push ( server ) , result . ApiClient . enableAutomaticBitrateDetection = options . enableAutomaticBitrateDetection , result . ApiClient . updateServerInfo ( server , serverUrl ) ;
var resolveActions = function ( ) {
resolve ( result ) , events . trigger ( self , "connected" , [ result ] )
} ;
"SignedIn" === result . State ? ( afterConnected ( result . ApiClient , options ) , result . ApiClient . getCurrentUser ( ) . then ( function ( user ) {
onLocalUserSignIn ( server , serverUrl , user ) . then ( resolveActions , resolveActions )
} , resolveActions ) ) : resolveActions ( )
}
function getCacheKey ( feature , apiClient , options ) {
options = options || { } ;
var viewOnly = options . viewOnly ,
cacheKey = "regInfo-" + apiClient . serverId ( ) ;
return viewOnly && ( cacheKey += "-viewonly" ) , cacheKey
}
function addAppInfoToConnectRequest ( request ) {
request . headers = request . headers || { } , request . headers [ "X-Application" ] = appName + "/" + appVersion
}
function exchangePin ( pinInfo ) {
if ( ! pinInfo ) throw new Error ( "pinInfo cannot be null" ) ;
var request = {
type : "POST" ,
url : getConnectUrl ( "pin/authenticate" ) ,
data : {
deviceId : pinInfo . DeviceId ,
pin : pinInfo . Pin
} ,
dataType : "json"
} ;
return addAppInfoToConnectRequest ( request ) , ajax ( request )
}
console . log ( "Begin ConnectionManager constructor" ) ;
var self = this ;
this . _apiClients = [ ] ;
var connectUser ;
self . connectUser = function ( ) {
return connectUser
} , self . _minServerVersion = "3.2.33" , self . appVersion = function ( ) {
return appVersion
} , self . appName = function ( ) {
return appName
} , self . capabilities = function ( ) {
return capabilities
} , self . deviceId = function ( ) {
return deviceId
} , self . credentialProvider = function ( ) {
return credentialProvider
} , self . connectUserId = function ( ) {
return credentialProvider . credentials ( ) . ConnectUserId
} , self . connectToken = function ( ) {
return credentialProvider . credentials ( ) . ConnectAccessToken
} , self . getServerInfo = function ( id ) {
return credentialProvider . credentials ( ) . Servers . filter ( function ( s ) {
return s . Id === id
} ) [ 0 ]
} , self . getLastUsedServer = function ( ) {
var servers = credentialProvider . credentials ( ) . Servers ;
return servers . sort ( function ( a , b ) {
return ( b . DateLastAccessed || 0 ) - ( a . DateLastAccessed || 0 )
} ) , servers . length ? servers [ 0 ] : null
} , self . addApiClient = function ( apiClient ) {
self . _apiClients . push ( apiClient ) ;
var existingServers = credentialProvider . credentials ( ) . Servers . filter ( function ( s ) {
return stringEqualsIgnoreCase ( s . ManualAddress , apiClient . serverAddress ( ) ) || stringEqualsIgnoreCase ( s . LocalAddress , apiClient . serverAddress ( ) ) || stringEqualsIgnoreCase ( s . RemoteAddress , apiClient . serverAddress ( ) )
} ) ,
existingServer = existingServers . length ? existingServers [ 0 ] : apiClient . serverInfo ( ) ;
if ( existingServer . DateLastAccessed = ( new Date ) . getTime ( ) , existingServer . LastConnectionMode = ConnectionMode . Manual , existingServer . ManualAddress = apiClient . serverAddress ( ) , apiClient . manualAddressOnly && ( existingServer . manualAddressOnly = ! 0 ) , apiClient . serverInfo ( existingServer ) , apiClient . onAuthenticated = function ( instance , result ) {
return onAuthenticated ( instance , result , { } , ! 0 )
} , ! existingServers . length ) {
var credentials = credentialProvider . credentials ( ) ;
credentials . Servers = [ existingServer ] , credentialProvider . credentials ( credentials )
}
events . trigger ( self , "apiclientcreated" , [ apiClient ] )
} , self . clearData = function ( ) {
console . log ( "connection manager clearing data" ) , connectUser = null ;
var credentials = credentialProvider . credentials ( ) ;
credentials . ConnectAccessToken = null , credentials . ConnectUserId = null , credentials . Servers = [ ] , credentialProvider . credentials ( credentials )
} , self . _getOrAddApiClient = function ( server , serverUrl ) {
var apiClient = self . getApiClient ( server . Id ) ;
return apiClient || ( apiClient = new apiClientFactory ( serverUrl , appName , appVersion , deviceName , deviceId , devicePixelRatio ) , self . _apiClients . push ( apiClient ) , apiClient . serverInfo ( server ) , apiClient . onAuthenticated = function ( instance , result ) {
return onAuthenticated ( instance , result , { } , ! 0 )
} , events . trigger ( self , "apiclientcreated" , [ apiClient ] ) ) , console . log ( "returning instance from getOrAddApiClient" ) , apiClient
} , self . getOrCreateApiClient = function ( serverId ) {
var credentials = credentialProvider . credentials ( ) ,
servers = credentials . Servers . filter ( function ( s ) {
return stringEqualsIgnoreCase ( s . Id , serverId )
} ) ;
if ( ! servers . length ) throw new Error ( "Server not found: " + serverId ) ;
var server = servers [ 0 ] ;
return self . _getOrAddApiClient ( server , getServerAddress ( server , server . LastConnectionMode ) )
} , self . user = function ( apiClient ) {
return new Promise ( function ( resolve , reject ) {
function onLocalUserDone ( e ) {
var image = getImageUrl ( localUser ) ;
resolve ( {
localUser : localUser ,
name : connectUser ? connectUser . Name : localUser ? localUser . Name : null ,
imageUrl : image . url ,
supportsImageParams : image . supportsParams ,
connectUser : connectUser
} )
}
function onEnsureConnectUserDone ( ) {
apiClient && apiClient . getCurrentUserId ( ) ? apiClient . getCurrentUser ( ) . then ( function ( u ) {
localUser = u , onLocalUserDone ( )
} , onLocalUserDone ) : onLocalUserDone ( )
}
var localUser , credentials = credentialProvider . credentials ( ) ;
! credentials . ConnectUserId || ! credentials . ConnectAccessToken || apiClient && apiClient . getCurrentUserId ( ) ? onEnsureConnectUserDone ( ) : ensureConnectUser ( credentials ) . then ( onEnsureConnectUserDone , onEnsureConnectUserDone )
} )
} , self . logout = function ( ) {
console . log ( "begin connectionManager loguot" ) ;
for ( var promises = [ ] , i = 0 , length = self . _apiClients . length ; i < length ; i ++ ) {
var apiClient = self . _apiClients [ i ] ;
apiClient . accessToken ( ) && promises . push ( logoutOfServer ( apiClient ) )
}
return Promise . all ( promises ) . then ( function ( ) {
for ( var credentials = credentialProvider . credentials ( ) , servers = credentials . Servers . filter ( function ( u ) {
return "Guest" !== u . UserLinkType
} ) , j = 0 , numServers = servers . length ; j < numServers ; j ++ ) {
var server = servers [ j ] ;
server . UserId = null , server . AccessToken = null , server . ExchangeToken = null
}
credentials . Servers = servers , credentials . ConnectAccessToken = null , credentials . ConnectUserId = null , credentialProvider . credentials ( credentials ) , connectUser && ( connectUser = null , events . trigger ( self , "connectusersignedout" ) )
} )
} , self . getSavedServers = function ( ) {
var credentials = credentialProvider . credentials ( ) ,
servers = credentials . Servers . slice ( 0 ) ;
return servers . sort ( function ( a , b ) {
return ( b . DateLastAccessed || 0 ) - ( a . DateLastAccessed || 0 )
} ) , servers
} , self . getAvailableServers = function ( ) {
console . log ( "Begin getAvailableServers" ) ;
var credentials = credentialProvider . credentials ( ) ;
return Promise . all ( [ getConnectServers ( credentials ) , findServers ( ) ] ) . then ( function ( responses ) {
var connectServers = responses [ 0 ] ,
foundServers = responses [ 1 ] ,
servers = credentials . Servers . slice ( 0 ) ;
return mergeServers ( credentialProvider , servers , foundServers ) , mergeServers ( credentialProvider , servers , connectServers ) , servers = filterServers ( servers , connectServers ) , servers . sort ( function ( a , b ) {
return ( b . DateLastAccessed || 0 ) - ( a . DateLastAccessed || 0 )
} ) , credentials . Servers = servers , credentialProvider . credentials ( credentials ) , servers
} )
} , self . connectToServers = function ( servers , options ) {
console . log ( "Begin connectToServers, with " + servers . length + " servers" ) ;
var firstServer = servers . length ? servers [ 0 ] : null ;
return firstServer ? self . connectToServer ( firstServer , options ) . then ( function ( result ) {
return "Unavailable" === result . State && ( result . State = "ServerSelection" ) , console . log ( "resolving connectToServers with result.State: " + result . State ) , result
} ) : Promise . resolve ( {
Servers : servers ,
State : servers . length || self . connectUser ( ) ? "ServerSelection" : "ConnectSignIn" ,
ConnectUser : self . connectUser ( )
} )
} , self . connectToServer = function ( server , options ) {
return console . log ( "begin connectToServer" ) , new Promise ( function ( resolve , reject ) {
options = options || { } , tryReconnect ( server ) . then ( function ( result ) {
var serverUrl = result . url ,
connectionMode = result . connectionMode ;
result = result . data , 1 === compareVersions ( self . minServerVersion ( ) , result . Version ) ? ( console . log ( "minServerVersion requirement not met. Server version: " + result . Version ) , resolve ( {
State : "ServerUpdateNeeded" ,
Servers : [ server ]
} ) ) : server . Id && result . Id !== server . Id ? ( console . log ( "http request succeeded, but found a different server Id than what was expected" ) , resolveFailure ( self , resolve ) ) : onSuccessfulConnection ( server , result , connectionMode , serverUrl , options , resolve )
} , function ( ) {
resolveFailure ( self , resolve )
} )
} )
} , self . connectToAddress = function ( address , options ) {
function onFail ( ) {
return console . log ( "connectToAddress " + address + " failed" ) , Promise . resolve ( {
State : "Unavailable" ,
ConnectUser : instance . connectUser ( )
} )
}
if ( ! address ) return Promise . reject ( ) ;
address = normalizeAddress ( address ) ;
var instance = this ,
server = {
ManualAddress : address ,
LastConnectionMode : ConnectionMode . Manual
} ;
return self . connectToServer ( server , options ) . catch ( onFail )
} , self . loginToConnect = function ( username , password ) {
return username && password ? ajax ( {
type : "POST" ,
url : "https://connect.emby.media/service/user/authenticate" ,
data : {
nameOrEmail : username ,
rawpw : password
} ,
dataType : "json" ,
contentType : "application/x-www-form-urlencoded; charset=UTF-8" ,
headers : {
"X-Application" : appName + "/" + appVersion
}
} ) . then ( function ( result ) {
var credentials = credentialProvider . credentials ( ) ;
return credentials . ConnectAccessToken = result . AccessToken , credentials . ConnectUserId = result . User . Id , credentialProvider . credentials ( credentials ) , onConnectUserSignIn ( result . User ) , result
} ) : Promise . reject ( )
} , self . signupForConnect = function ( options ) {
var email = options . email ,
username = options . username ,
password = options . password ,
passwordConfirm = options . passwordConfirm ;
if ( ! email ) return Promise . reject ( {
errorCode : "invalidinput"
} ) ;
if ( ! username ) return Promise . reject ( {
errorCode : "invalidinput"
} ) ;
if ( ! password ) return Promise . reject ( {
errorCode : "invalidinput"
} ) ;
if ( ! passwordConfirm ) return Promise . reject ( {
errorCode : "passwordmatch"
} ) ;
if ( password !== passwordConfirm ) return Promise . reject ( {
errorCode : "passwordmatch"
} ) ;
var data = {
email : email ,
userName : username ,
rawpw : password
} ;
return options . grecaptcha && ( data . grecaptcha = options . grecaptcha ) , ajax ( {
type : "POST" ,
url : "https://connect.emby.media/service/register" ,
data : data ,
dataType : "json" ,
contentType : "application/x-www-form-urlencoded; charset=UTF-8" ,
headers : {
"X-Application" : appName + "/" + appVersion ,
"X-CONNECT-TOKEN" : "CONNECT-REGISTER"
}
} ) . catch ( function ( response ) {
try {
return response . json ( )
} catch ( err ) {
throw err
}
} ) . then ( function ( result ) {
if ( result && result . Status ) return "SUCCESS" === result . Status ? Promise . resolve ( result ) : Promise . reject ( {
errorCode : result . Status
} ) ;
Promise . reject ( )
} )
} , self . getUserInvitations = function ( ) {
var connectToken = self . connectToken ( ) ;
if ( ! connectToken ) throw new Error ( "null connectToken" ) ;
if ( ! self . connectUserId ( ) ) throw new Error ( "null connectUserId" ) ;
return ajax ( {
type : "GET" ,
url : "https://connect.emby.media/service/servers?userId=" + self . connectUserId ( ) + "&status=Waiting" ,
dataType : "json" ,
headers : {
"X-Connect-UserToken" : connectToken ,
"X-Application" : appName + "/" + appVersion
}
} )
} , self . deleteServer = function ( serverId ) {
if ( ! serverId ) throw new Error ( "null serverId" ) ;
var server = credentialProvider . credentials ( ) . Servers . filter ( function ( s ) {
return s . Id === serverId
} ) ;
return server = server . length ? server [ 0 ] : null , new Promise ( function ( resolve , reject ) {
function onDone ( ) {
var credentials = credentialProvider . credentials ( ) ;
credentials . Servers = credentials . Servers . filter ( function ( s ) {
return s . Id !== serverId
} ) , credentialProvider . credentials ( credentials ) , resolve ( )
}
if ( ! server . ConnectServerId ) return void onDone ( ) ;
var connectToken = self . connectToken ( ) ,
connectUserId = self . connectUserId ( ) ;
if ( ! connectToken || ! connectUserId ) return void onDone ( ) ;
ajax ( {
type : "DELETE" ,
url : "https://connect.emby.media/service/serverAuthorizations?serverId=" + server . ConnectServerId + "&userId=" + connectUserId ,
headers : {
"X-Connect-UserToken" : connectToken ,
"X-Application" : appName + "/" + appVersion
}
} ) . then ( onDone , onDone )
} )
} , self . rejectServer = function ( serverId ) {
var connectToken = self . connectToken ( ) ;
if ( ! serverId ) throw new Error ( "null serverId" ) ;
if ( ! connectToken ) throw new Error ( "null connectToken" ) ;
if ( ! self . connectUserId ( ) ) throw new Error ( "null connectUserId" ) ;
var url = "https://connect.emby.media/service/serverAuthorizations?serverId=" + serverId + "&userId=" + self . connectUserId ( ) ;
return fetch ( url , {
method : "DELETE" ,
headers : {
"X-Connect-UserToken" : connectToken ,
"X-Application" : appName + "/" + appVersion
}
} )
} , self . acceptServer = function ( serverId ) {
var connectToken = self . connectToken ( ) ;
if ( ! serverId ) throw new Error ( "null serverId" ) ;
if ( ! connectToken ) throw new Error ( "null connectToken" ) ;
if ( ! self . connectUserId ( ) ) throw new Error ( "null connectUserId" ) ;
return ajax ( {
type : "GET" ,
url : "https://connect.emby.media/service/ServerAuthorizations/accept?serverId=" + serverId + "&userId=" + self . connectUserId ( ) ,
headers : {
"X-Connect-UserToken" : connectToken ,
"X-Application" : appName + "/" + appVersion
}
} )
} , self . resetRegistrationInfo = function ( apiClient ) {
var cacheKey = getCacheKey ( "themes" , apiClient , {
viewOnly : ! 0
} ) ;
appStorage . removeItem ( cacheKey ) , cacheKey = getCacheKey ( "themes" , apiClient , {
viewOnly : ! 1
} ) , appStorage . removeItem ( cacheKey )
} , self . getRegistrationInfo = function ( feature , apiClient , options ) {
2018-10-22 02:23:33 +03:00
var cacheKey = getCacheKey ( feature , apiClient , options ) ;
appStorage . setItem ( cacheKey , JSON . stringify ( {
lastValidDate : new Date ( ) . getTime ( ) ,
deviceId : self . deviceId ( )
} ) ) ;
return Promise . resolve ( ) ;
2018-10-22 02:12:47 +03:00
} , self . createPin = function ( ) {
var request = {
type : "POST" ,
url : getConnectUrl ( "pin" ) ,
data : {
deviceId : deviceId
} ,
dataType : "json"
} ;
return addAppInfoToConnectRequest ( request ) , ajax ( request )
} , self . getPinStatus = function ( pinInfo ) {
if ( ! pinInfo ) throw new Error ( "pinInfo cannot be null" ) ;
var queryString = {
deviceId : pinInfo . DeviceId ,
pin : pinInfo . Pin
} ,
request = {
type : "GET" ,
url : getConnectUrl ( "pin" ) + "?" + paramsToString ( queryString ) ,
dataType : "json"
} ;
return addAppInfoToConnectRequest ( request ) , ajax ( request )
} , self . exchangePin = function ( pinInfo ) {
if ( ! pinInfo ) throw new Error ( "pinInfo cannot be null" ) ;
return exchangePin ( pinInfo ) . then ( function ( result ) {
var credentials = credentialProvider . credentials ( ) ;
return credentials . ConnectAccessToken = result . AccessToken , credentials . ConnectUserId = result . UserId , credentialProvider . credentials ( credentials ) , ensureConnectUser ( credentials )
} )
}
} ;
return ConnectionManager . prototype . connect = function ( options ) {
console . log ( "Begin connect" ) ;
var instance = this ;
return instance . getAvailableServers ( ) . then ( function ( servers ) {
return instance . connectToServers ( servers , options )
} )
} , ConnectionManager . prototype . isLoggedIntoConnect = function ( ) {
return ! ( ! this . connectToken ( ) || ! this . connectUserId ( ) )
} , ConnectionManager . prototype . getApiClients = function ( ) {
for ( var servers = this . getSavedServers ( ) , i = 0 , length = servers . length ; i < length ; i ++ ) {
var server = servers [ i ] ;
server . Id && this . _getOrAddApiClient ( server , getServerAddress ( server , server . LastConnectionMode ) )
}
return this . _apiClients
} , ConnectionManager . prototype . getApiClient = function ( item ) {
if ( ! item ) throw new Error ( "item or serverId cannot be null" ) ;
return item . ServerId && ( item = item . ServerId ) , this . _apiClients . filter ( function ( a ) {
var serverInfo = a . serverInfo ( ) ;
return ! serverInfo || serverInfo . Id === item
} ) [ 0 ]
} , ConnectionManager . prototype . minServerVersion = function ( val ) {
return val && ( this . _minServerVersion = val ) , this . _minServerVersion
} , ConnectionManager . prototype . handleMessageReceived = function ( msg ) {
var serverId = msg . ServerId ;
if ( serverId ) {
var apiClient = this . getApiClient ( serverId ) ;
if ( apiClient ) {
if ( "string" == typeof msg . Data ) try {
msg . Data = JSON . parse ( msg . Data )
} catch ( err ) { }
apiClient . handleMessageReceived ( msg )
}
}
} , ConnectionManager
2019-09-19 15:52:00 -04:00
} ) ;