Skip to content

Implement session-scoped media source access and deduplicate Plex playback metadata#30

Merged
KyleTryon merged 3 commits intomainfrom
fix/dual-sessions
Apr 18, 2026
Merged

Implement session-scoped media source access and deduplicate Plex playback metadata#30
KyleTryon merged 3 commits intomainfrom
fix/dual-sessions

Conversation

@KyleTryon
Copy link
Copy Markdown
Contributor

This pull request introduces several improvements to how media sources are managed and how currently playing Plex sessions are deduplicated and identified. The main changes are focused on ensuring that media source operations are account-scoped for better security and correctness, and on improving the reliability of playback session tracking by deduplicating Plex session data.

Account-scoped media source operations:

  • All routes and repository functions that interact with media sources now require a providerAccountId, ensuring that only sources belonging to the current account can be accessed or modified. This includes updates to the requireMediaSource function, all route handlers in sources.ts, and the media sources listing in both media.ts and sources.ts. [1] [2] [3] [4] [5] [6] [7] [8] [9]

Plex playback session deduplication and identification:

  • New utility functions (playbackFallbackIdentity, playbackDeduplicationKey, dedupeCurrentlyPlayingMetadata) are added to deduplicate currently playing Plex session metadata, addressing issues with duplicate session rows from certain clients. The normalization of current playback now uses deduplicated metadata. [1] [2]
  • The logic for generating a unique playback session identity is improved to prioritize sessionKey, then Session.id, then a fallback identity, ensuring more robust and consistent session tracking.

These changes improve both the security of media source management and the accuracy of Plex playback session handling.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR tightens server-side media source access to be provider-account scoped (using the current session’s providerAccountId) and improves Plex “currently playing” tracking by deduplicating duplicate session rows and using a more robust playback identity.

Changes:

  • Scope media source list/get/update/delete/check routes to providerAccountId.
  • Export and use getMediaSourceForAccount to enforce account-scoped lookups in routes.
  • Deduplicate Plex /status/sessions metadata and improve session identity selection (sessionKeySession.id → fallback).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
apps/server/src/routes/sources.ts Enforces account-scoped media source operations throughout the sources routes.
apps/server/src/routes/media.ts Filters enabled media sources by the current session’s providerAccountId for currently-playing aggregation.
apps/server/src/providers/plex/playback.ts Adds dedupe utilities for Plex sessions and improves playback session identity stability.
apps/server/src/db/mediaSourcesRepository.ts Exports getMediaSourceForAccount to support account-scoped access patterns from routes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +132 to 136
requireMediaSource(req.params.id as string, session.providerAccountId);
const source = updateMediaSourceForAccount(
req.params.id as string,
existingSource.providerAccountId,
session.providerAccountId,
parseSourceUpdate(req.body)
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this PATCH handler, requireMediaSource(...) performs an extra DB read but the result is unused. Since updateMediaSourceForAccount(...) is already account-scoped and you already handle the !source case, you can drop the pre-check and rely on the update call to return undefined for non-existent/unauthorized sources (avoids an extra query).

Copilot uses AI. Check for mistakes.
Comment thread apps/server/src/routes/sources.ts Outdated
Comment on lines +150 to +152
const source = requireMediaSource(req.params.id as string, session.providerAccountId);

const deleted = deleteMediaSourceForAccount(source.id, source.providerAccountId);
const deleted = deleteMediaSourceForAccount(source.id, session.providerAccountId);
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DELETE handler loads the full source via requireMediaSource(...) but only needs to delete by id for the current account. Consider calling deleteMediaSourceForAccount(req.params.id, session.providerAccountId) directly and returning 404 when deleted is false, to avoid an extra DB read and simplify the flow.

Copilot uses AI. Check for mistakes.
@KyleTryon KyleTryon merged commit e2900bb into main Apr 18, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants