Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
8155180
feat: add managed Emby library publishing
Serph91P Aug 3, 2026
340cfbe
Merge remote-tracking branch 'upstream/dev' into feat/emby-library-pu…
Serph91P Aug 5, 2026
38dd0f9
fix: fail closed on unresolved managed Emby library mappings
Serph91P Aug 8, 2026
508ee3b
chore: merge origin/dev into feat/emby-library-publishing
Serph91P Aug 8, 2026
d23ef03
chore: merge upstream/dev into feat/emby-library-publishing
Serph91P Aug 8, 2026
61e4edf
fix: register Emby publisher writable paths
Serph91P Aug 9, 2026
78fcaf4
fix: Guest panel can see all playlist recordings
sparkison Aug 11, 2026
f6d1ed3
Merge branch 'dev' into pr/1362
sparkison Aug 11, 2026
cc5284c
fix(emby): authorize before validating input, and centralize writable…
sparkison Aug 11, 2026
f7cd62f
fix(emby): return a consistent createLibrary() result shape, and surf…
sparkison Aug 11, 2026
97c9b23
refactor(emby): DRY canonical-ID resolution across movies/series/epis…
sparkison Aug 11, 2026
68bb7fc
i18n: translate managed-library-publishing strings for de/es/fr/zh_CN
sparkison Aug 11, 2026
4345e8d
fix(emby): stop forcing a redundant re-selection on the "Mapped group…
sparkison Aug 11, 2026
1920482
fix(emby): scope "Mapped group" options to the selected library type
sparkison Aug 11, 2026
9ebdeef
fix(emby): stop pre-populating "Mapped group" with the custom playlis…
sparkison Aug 11, 2026
937e9b2
copy: drop "above" from the Mapped-group empty-state helper text
sparkison Aug 11, 2026
1bd083b
fix(emby): async-search the "Source" field and disambiguate cross-pla…
sparkison Aug 11, 2026
5cf905a
chore: Formatting
sparkison Aug 11, 2026
83e3bf5
chore: Update button actions to align with other table styles
sparkison Aug 11, 2026
ba5dbce
fix(emby): render the "Preview" catalog plan as scrollable, formatted…
sparkison Aug 11, 2026
e90dd01
fix(emby): cap Preview modal item count, drop clipboard copy, use x-f…
sparkison Aug 11, 2026
84e78a3
chore: Formatting
sparkison Aug 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,14 @@ public static function getEloquentQuery(): Builder

$currentAuth = static::getCurrentPlaylistAuth();

// A null $currentAuth is only safe to treat as "the playlist owner"
// when isOwnerAuth() confirms it — otherwise (a guest session that
// failed to resolve) ->where('playlist_auth_id', null) would become
// whereNull() and leak the owner's recordings to that guest.
if (! $currentAuth && ! static::isOwnerAuth()) {
return parent::getEloquentQuery()->whereRaw('1 = 0');
}

return parent::getEloquentQuery()
->with(['channel', 'playlistAuth', 'dvrSetting.playlist', 'dvrSetting.customPlaylist', 'dvrSetting.mergedPlaylist'])
->where('dvr_setting_id', $dvrSetting->id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,14 @@ public static function getEloquentQuery(): Builder

$currentAuth = static::getCurrentPlaylistAuth();

// A null $currentAuth is only safe to treat as "the playlist owner"
// when isOwnerAuth() confirms it — otherwise (a guest session that
// failed to resolve) ->where('playlist_auth_id', null) would become
// whereNull() and leak the owner's rules to that guest.
if (! $currentAuth && ! static::isOwnerAuth()) {
return parent::getEloquentQuery()->whereRaw('1 = 0');
}

return parent::getEloquentQuery()
->with(['channel', 'playlistAuth'])
->where('dvr_setting_id', $dvrSetting->id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ public function getSeriesRules(): Collection

$currentAuth = static::getCurrentPlaylistAuth();

// A null $currentAuth is only safe to treat as "the playlist owner"
// when isOwnerAuth() confirms it — otherwise (a guest session that
// failed to resolve) ->where('playlist_auth_id', null) would become
// whereNull() and leak the owner's series rules to that guest.
if (! $currentAuth && ! static::isOwnerAuth()) {
return new Collection;
}

return DvrRecordingRule::with(['channel'])
->where('dvr_setting_id', $dvrSetting->id)
->where('type', DvrRuleType::Series)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1695,6 +1695,7 @@ public static function getRelations(): array
RelationManagers\SeriesRelationManager::class,
RelationManagers\AioStreamsMoviesRelationManager::class,
RelationManagers\AioStreamsSeriesRelationManager::class,
RelationManagers\EmbyLibraryMappingsRelationManager::class,
];
}

Expand Down

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions app/Filament/Resources/PlaylistAuths/PlaylistAuthResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,20 @@ public static function getForm(): array
->collapsible()
->collapsed(fn ($record) => ! ($record?->aiostreams_enabled));

$libraryPublishingSection = Section::make(__('Library Publishing Access'))
->description(__('Allow this credential to read managed Emby publishing catalogs and report sync results.'))
->compact()
->hidden(fn () => ! (auth()->user()?->canUseIntegrations() ?? false))
->schema([
Toggle::make('library_publishing_enabled')
->label(__('Enable Library Publishing'))
->default(false)
->columnSpan(2),
])
->columns(2)
->collapsible()
->collapsed(fn ($record) => ! ($record?->library_publishing_enabled));

return [
Grid::make()
->schema([
Expand Down Expand Up @@ -475,6 +489,7 @@ public static function getForm(): array
$requestsSection,
$dvrSection,
$aiostreamsSection,
$libraryPublishingSection,
];
}
}
Loading
Loading