1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00
jellyfin-web/src/components/ServerConnections.js
gnattu c0b86a39c7 Only connect to manuall addresses specified by user
This should never be enabled on the web because users are not expected to connect to an address they don't specify. For specific use cases like auto endpoint switching between networks, this should be managed by DNS or the router itself, not by the application. 

Having an address that is not always connectable causes our Android users to be unable to reliably connect to the server. It also breaks many reverse-proxy setups, as this address exposed by the server usually bypasses the proxy unless explicitly configured by the user. This has far more negative impact than the benifit it brings.
2024-05-20 22:37:19 +08:00

147 lines
4.3 KiB
JavaScript

import { MINIMUM_VERSION } from '@jellyfin/sdk/lib/versions';
import { ConnectionManager, Credentials, ApiClient } from 'jellyfin-apiclient';
import { appHost } from './apphost';
import Dashboard from '../utils/dashboard';
import Events from '../utils/events.ts';
import { setUserInfo } from '../scripts/settings/userSettings';
import appSettings from '../scripts/settings/appSettings';
const normalizeImageOptions = options => {
if (!options.quality && (options.maxWidth || options.width || options.maxHeight || options.height || options.fillWidth || options.fillHeight)) {
options.quality = 90;
}
};
const getMaxBandwidth = () => {
/* eslint-disable compat/compat */
if (navigator.connection) {
let max = navigator.connection.downlinkMax;
if (max && max > 0 && max < Number.POSITIVE_INFINITY) {
max /= 8;
max *= 1000000;
max *= 0.7;
return parseInt(max, 10);
}
}
/* eslint-enable compat/compat */
return null;
};
class ServerConnections extends ConnectionManager {
constructor() {
super(...arguments);
this.localApiClient = null;
// Set the apiclient minimum version to match the SDK
this._minServerVersion = MINIMUM_VERSION;
Events.on(this, 'localusersignedout', (_e, logoutInfo) => {
setUserInfo(null, null);
// Ensure the updated credentials are persisted to storage
credentialProvider.credentials(credentialProvider.credentials());
if (window.NativeShell && typeof window.NativeShell.onLocalUserSignedOut === 'function') {
window.NativeShell.onLocalUserSignedOut(logoutInfo);
}
});
Events.on(this, 'apiclientcreated', (_e, apiClient) => {
apiClient.getMaxBandwidth = getMaxBandwidth;
apiClient.normalizeImageOptions = normalizeImageOptions;
});
}
initApiClient(server) {
console.debug('creating ApiClient singleton');
const apiClient = new ApiClient(
server,
appHost.appName(),
appHost.appVersion(),
appHost.deviceName(),
appHost.deviceId()
);
apiClient.enableAutomaticNetworking = false;
apiClient.manualAddressOnly = true;
this.addApiClient(apiClient);
this.setLocalApiClient(apiClient);
console.debug('loaded ApiClient singleton');
}
connect(options) {
return super.connect({
enableAutoLogin: appSettings.enableAutoLogin(),
...options
});
}
setLocalApiClient(apiClient) {
if (apiClient) {
this.localApiClient = apiClient;
window.ApiClient = apiClient;
}
}
getLocalApiClient() {
return this.localApiClient;
}
/**
* Gets the ApiClient that is currently connected.
* @returns {ApiClient|undefined} apiClient
*/
currentApiClient() {
let apiClient = this.getLocalApiClient();
if (!apiClient) {
const server = this.getLastUsedServer();
if (server) {
apiClient = this.getApiClient(server.Id);
}
}
return apiClient;
}
/**
* Gets the ApiClient that is currently connected or throws if not defined.
* @async
* @returns {Promise<ApiClient>} The current ApiClient instance.
*/
async getCurrentApiClientAsync() {
const apiClient = this.currentApiClient();
if (!apiClient) throw new Error('[ServerConnection] No current ApiClient instance');
return apiClient;
}
onLocalUserSignedIn(user) {
const apiClient = this.getApiClient(user.ServerId);
this.setLocalApiClient(apiClient);
return setUserInfo(user.Id, apiClient).then(() => {
if (window.NativeShell && typeof window.NativeShell.onLocalUserSignedIn === 'function') {
return window.NativeShell.onLocalUserSignedIn(user, apiClient.accessToken());
}
return Promise.resolve();
});
}
}
const credentialProvider = new Credentials();
const capabilities = Dashboard.capabilities(appHost);
export default new ServerConnections(
credentialProvider,
appHost.appName(),
appHost.appVersion(),
appHost.deviceName(),
appHost.deviceId(),
capabilities);