Skip to content

Commit

Permalink
Merge pull request #660 from sel10ut/bugfix/jellyfin-multiple-sessions
Browse files Browse the repository at this point in the history
(Jellyfin) Allow multiple sessions from the same user with different instances
  • Loading branch information
jeffvli authored Jul 3, 2024
2 parents 3c44db3 + ba64f4c commit 42bcc41
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 38 deletions.
16 changes: 11 additions & 5 deletions src/renderer/api/jellyfin/jellyfin-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import qs from 'qs';
import { ServerListItem } from '/@/renderer/api/types';
import omitBy from 'lodash/omitBy';
import { z } from 'zod';
import { authenticationFailure } from '/@/renderer/api/utils';
import { authenticationFailure, getClientType } from '/@/renderer/api/utils';
import i18n from '/@/i18n/i18n';
import packageJson from '../../../../package.json';

const c = initContract();

Expand All @@ -24,9 +25,6 @@ export const contract = c.router({
},
authenticate: {
body: jfType._parameters.authenticate,
headers: z.object({
'X-Emby-Authorization': z.string(),
}),
method: 'POST',
path: 'users/authenticatebyname',
responses: {
Expand Down Expand Up @@ -333,6 +331,12 @@ const parsePath = (fullPath: string) => {
};
};

export const createAuthHeader = (): string => {
return `MediaBrowser Client="Feishin", Device="${getClientType()}", DeviceId="${
useAuthStore.getState().deviceId
}", Version="${packageJson.version}"`;
};

export const jfApiClient = (args: {
server: ServerListItem | null;
signal?: AbortSignal;
Expand All @@ -359,7 +363,9 @@ export const jfApiClient = (args: {
data: body,
headers: {
...headers,
...(token && { 'X-MediaBrowser-Token': token }),
...(token
? { Authorization: createAuthHeader().concat(`, Token="${token}"`) }
: { Authorization: createAuthHeader() }),
},
method: method as Method,
params,
Expand Down
32 changes: 0 additions & 32 deletions src/renderer/api/jellyfin/jellyfin-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,8 @@ import {
import { jfApiClient } from '/@/renderer/api/jellyfin/jellyfin-api';
import { jfNormalize } from './jellyfin-normalize';
import { jfType } from '/@/renderer/api/jellyfin/jellyfin-types';
import packageJson from '../../../../package.json';
import { z } from 'zod';
import { JFSongListSort, JFSortOrder } from '/@/renderer/api/jellyfin.types';
import isElectron from 'is-electron';
import { ServerFeature } from '/@/renderer/api/features-types';
import { VersionInfo, getFeatures } from '/@/renderer/api/utils';
import chunk from 'lodash/chunk';
Expand All @@ -69,31 +67,6 @@ const formatCommaDelimitedString = (value: string[]) => {
return value.join(',');
};

function getHostname(): string {
if (isElectron()) {
return 'Desktop Client';
}
const agent = navigator.userAgent;
switch (true) {
case agent.toLowerCase().indexOf('edge') > -1:
return 'Microsoft Edge';
case agent.toLowerCase().indexOf('edg/') > -1:
return 'Edge Chromium'; // Match also / to avoid matching for the older Edge
case agent.toLowerCase().indexOf('opr') > -1:
return 'Opera';
case agent.toLowerCase().indexOf('chrome') > -1:
return 'Chrome';
case agent.toLowerCase().indexOf('trident') > -1:
return 'Internet Explorer';
case agent.toLowerCase().indexOf('firefox') > -1:
return 'Firefox';
case agent.toLowerCase().indexOf('safari') > -1:
return 'Safari';
default:
return 'PC';
}
}

const authenticate = async (
url: string,
body: {
Expand All @@ -108,11 +81,6 @@ const authenticate = async (
Pw: body.password,
Username: body.username,
},
headers: {
'x-emby-authorization': `MediaBrowser Client="Feishin", Device="${getHostname()}", DeviceId="Feishin-${getHostname()}-${encodeURIComponent(
body.username,
)}", Version="${packageJson.version}"`,
},
});

if (res.status !== 200) {
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/api/jellyfin/jellyfin-normalize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const getStreamUrl = (args: {
`?userId=${server?.userId}` +
`&deviceId=${deviceId}` +
'&audioCodec=aac' +
`&api_key=${server?.credential}` +
`&apiKey=${server?.credential}` +
`&playSessionId=${deviceId}` +
'&container=opus,mp3,aac,m4a,m4b,flac,wav,ogg' +
'&transcodingContainer=ts' +
Expand Down
26 changes: 26 additions & 0 deletions src/renderer/api/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AxiosHeaders } from 'axios';
import isElectron from 'is-electron';
import semverCoerce from 'semver/functions/coerce';
import semverGte from 'semver/functions/gte';
import { z } from 'zod';
Expand Down Expand Up @@ -99,4 +100,29 @@ export const getFeatures = (
return features;
};

export const getClientType = (): string => {
if (isElectron()) {
return 'Desktop Client';
}
const agent = navigator.userAgent;
switch (true) {
case agent.toLowerCase().indexOf('edge') > -1:
return 'Microsoft Edge';
case agent.toLowerCase().indexOf('edg/') > -1:
return 'Edge Chromium'; // Match also / to avoid matching for the older Edge
case agent.toLowerCase().indexOf('opr') > -1:
return 'Opera';
case agent.toLowerCase().indexOf('chrome') > -1:
return 'Chrome';
case agent.toLowerCase().indexOf('trident') > -1:
return 'Internet Explorer';
case agent.toLowerCase().indexOf('firefox') > -1:
return 'Firefox';
case agent.toLowerCase().indexOf('safari') > -1:
return 'Safari';
default:
return 'PC';
}
};

export const SEPARATOR_STRING = ' · ';

0 comments on commit 42bcc41

Please sign in to comment.