Skip to content

Commit 74c8db4

Browse files
authored
feat: add jellyfin/emby quick connect authentication (#2212)
1 parent ebac489 commit 74c8db4

13 files changed

Lines changed: 1452 additions & 7 deletions

File tree

seerr-api.yml

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3998,6 +3998,85 @@ paths:
39983998
required:
39993999
- username
40004000
- password
4001+
/auth/jellyfin/quickconnect/initiate:
4002+
post:
4003+
summary: Initiate Jellyfin Quick Connect
4004+
description: Initiates a Quick Connect session and returns a code for the user to authorize on their Jellyfin server.
4005+
security: []
4006+
tags:
4007+
- auth
4008+
responses:
4009+
'200':
4010+
description: Quick Connect session initiated
4011+
content:
4012+
application/json:
4013+
schema:
4014+
type: object
4015+
properties:
4016+
code:
4017+
type: string
4018+
example: '123456'
4019+
secret:
4020+
type: string
4021+
example: 'abc123def456'
4022+
'500':
4023+
description: Failed to initiate Quick Connect
4024+
/auth/jellyfin/quickconnect/check:
4025+
get:
4026+
summary: Check Quick Connect authorization status
4027+
description: Checks if the Quick Connect code has been authorized by the user.
4028+
security: []
4029+
tags:
4030+
- auth
4031+
parameters:
4032+
- in: query
4033+
name: secret
4034+
required: true
4035+
schema:
4036+
type: string
4037+
description: The secret returned from the initiate endpoint
4038+
responses:
4039+
'200':
4040+
description: Authorization status returned
4041+
content:
4042+
application/json:
4043+
schema:
4044+
type: object
4045+
properties:
4046+
authenticated:
4047+
type: boolean
4048+
example: false
4049+
'404':
4050+
description: Quick Connect session not found or expired
4051+
/auth/jellyfin/quickconnect/authenticate:
4052+
post:
4053+
summary: Authenticate with Quick Connect
4054+
description: Completes the Quick Connect authentication flow and creates a user session.
4055+
security: []
4056+
tags:
4057+
- auth
4058+
requestBody:
4059+
required: true
4060+
content:
4061+
application/json:
4062+
schema:
4063+
type: object
4064+
properties:
4065+
secret:
4066+
type: string
4067+
required:
4068+
- secret
4069+
responses:
4070+
'200':
4071+
description: Successfully authenticated
4072+
content:
4073+
application/json:
4074+
schema:
4075+
$ref: '#/components/schemas/User'
4076+
'403':
4077+
description: Quick Connect not authorized or access denied
4078+
'500':
4079+
description: Authentication failed
40014080
/auth/local:
40024081
post:
40034082
summary: Sign in using a local account
@@ -5161,6 +5240,40 @@ paths:
51615240
description: Unlink request invalid
51625241
'404':
51635242
description: User does not exist
5243+
/user/{userId}/settings/linked-accounts/jellyfin/quickconnect:
5244+
post:
5245+
summary: Link Jellyfin/Emby account with Quick Connect
5246+
description: Links a Jellyfin/Emby account to the user's profile using Quick Connect authentication
5247+
tags:
5248+
- users
5249+
parameters:
5250+
- in: path
5251+
name: userId
5252+
required: true
5253+
schema:
5254+
type: number
5255+
requestBody:
5256+
required: true
5257+
content:
5258+
application/json:
5259+
schema:
5260+
type: object
5261+
properties:
5262+
secret:
5263+
type: string
5264+
required:
5265+
- secret
5266+
responses:
5267+
'400':
5268+
description: Invalid Quick Connect secret
5269+
'204':
5270+
description: Account successfully linked
5271+
'401':
5272+
description: Unauthorized
5273+
'422':
5274+
description: Account already linked
5275+
'500':
5276+
description: Server error
51645277
/user/{userId}/settings/notifications:
51655278
get:
51665279
summary: Get notification settings for a user

server/api/jellyfin.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,23 @@ export interface JellyfinLoginResponse {
4444
AccessToken: string;
4545
}
4646

47+
export interface QuickConnectInitiateResponse {
48+
Secret: string;
49+
Code: string;
50+
DateAdded: string;
51+
}
52+
53+
export interface QuickConnectStatusResponse {
54+
Authenticated: boolean;
55+
Secret: string;
56+
Code: string;
57+
DeviceId: string;
58+
DeviceName: string;
59+
AppName: string;
60+
AppVersion: string;
61+
DateAdded: string;
62+
}
63+
4764
export interface JellyfinUserListResponse {
4865
users: JellyfinUserResponse[];
4966
}
@@ -220,6 +237,62 @@ class JellyfinAPI extends ExternalAPI {
220237
}
221238
}
222239

240+
public async initiateQuickConnect(): Promise<QuickConnectInitiateResponse> {
241+
try {
242+
const response = await this.post<QuickConnectInitiateResponse>(
243+
'/QuickConnect/Initiate'
244+
);
245+
246+
return response;
247+
} catch (e) {
248+
logger.error(
249+
`Something went wrong while initiating Quick Connect: ${e.message}`,
250+
{ label: 'Jellyfin API', error: e.response?.status }
251+
);
252+
253+
throw new ApiError(e.response?.status, ApiErrorCode.Unknown);
254+
}
255+
}
256+
257+
public async checkQuickConnect(
258+
secret: string
259+
): Promise<QuickConnectStatusResponse> {
260+
try {
261+
const response = await this.get<QuickConnectStatusResponse>(
262+
'/QuickConnect/Connect',
263+
{ params: { secret } }
264+
);
265+
266+
return response;
267+
} catch (e) {
268+
logger.error(
269+
`Something went wrong while getting Quick Connect status: ${e.message}`,
270+
{ label: 'Jellyfin API', error: e.response?.status }
271+
);
272+
273+
throw new ApiError(e.response?.status, ApiErrorCode.Unknown);
274+
}
275+
}
276+
277+
public async authenticateQuickConnect(
278+
secret: string
279+
): Promise<JellyfinLoginResponse> {
280+
try {
281+
const response = await this.post<JellyfinLoginResponse>(
282+
'/Users/AuthenticateWithQuickConnect',
283+
{ Secret: secret }
284+
);
285+
return response;
286+
} catch (e) {
287+
logger.error(
288+
`Something went wrong while authenticating with Quick Connect: ${e.message}`,
289+
{ label: 'Jellyfin API', error: e.response?.status }
290+
);
291+
292+
throw new ApiError(e.response?.status, ApiErrorCode.Unknown);
293+
}
294+
}
295+
223296
public setUserId(userId: string): void {
224297
this.userId = userId;
225298
return;

0 commit comments

Comments
 (0)