diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 51fb446eeb..d03d44a1ca 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -22,16 +22,16 @@ jobs:
- name: Checkout repository
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
- name: Setup .NET
- uses: actions/setup-dotnet@aa983c550dfda0d1722b6ac6aed55724ffacc6d3 # v3.1.0
+ uses: actions/setup-dotnet@3447fd6a9f9e57506b15f895c5b76d3b197dc7c2 # v3.2.0
with:
dotnet-version: '7.0.x'
- name: Initialize CodeQL
- uses: github/codeql-action/init@f0e3dfb30302f8a0881bb509b044e0de4f6ef589 # v2.3.4
+ uses: github/codeql-action/init@83f0fe6c4988d98a455712a27f0255212bba9bd4 # v2.3.6
with:
languages: ${{ matrix.language }}
queries: +security-extended
- name: Autobuild
- uses: github/codeql-action/autobuild@f0e3dfb30302f8a0881bb509b044e0de4f6ef589 # v2.3.4
+ uses: github/codeql-action/autobuild@83f0fe6c4988d98a455712a27f0255212bba9bd4 # v2.3.6
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@f0e3dfb30302f8a0881bb509b044e0de4f6ef589 # v2.3.4
+ uses: github/codeql-action/analyze@83f0fe6c4988d98a455712a27f0255212bba9bd4 # v2.3.6
diff --git a/.github/workflows/openapi.yml b/.github/workflows/openapi.yml
index c2387f2ef6..539da7aefe 100644
--- a/.github/workflows/openapi.yml
+++ b/.github/workflows/openapi.yml
@@ -19,7 +19,7 @@ jobs:
ref: ${{ github.event.pull_request.head.sha }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
- name: Setup .NET
- uses: actions/setup-dotnet@aa983c550dfda0d1722b6ac6aed55724ffacc6d3 # v3.1.0
+ uses: actions/setup-dotnet@3447fd6a9f9e57506b15f895c5b76d3b197dc7c2 # v3.2.0
with:
dotnet-version: '7.0.x'
- name: Generate openapi.json
@@ -51,7 +51,7 @@ jobs:
ANCESTOR_REF=$(git merge-base upstream/${{ github.base_ref }} origin/${{ github.head_ref }})
git checkout --progress --force $ANCESTOR_REF
- name: Setup .NET
- uses: actions/setup-dotnet@aa983c550dfda0d1722b6ac6aed55724ffacc6d3 # v3.1.0
+ uses: actions/setup-dotnet@3447fd6a9f9e57506b15f895c5b76d3b197dc7c2 # v3.2.0
with:
dotnet-version: '7.0.x'
- name: Generate openapi.json
diff --git a/Directory.Packages.props b/Directory.Packages.props
index b9a9a1b687..f0389038f4 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -17,7 +17,7 @@
-
+
@@ -46,14 +46,14 @@
-
+
-
+
diff --git a/Emby.Server.Implementations/ConfigurationOptions.cs b/Emby.Server.Implementations/ConfigurationOptions.cs
index 630265dac9..f0c2676279 100644
--- a/Emby.Server.Implementations/ConfigurationOptions.cs
+++ b/Emby.Server.Implementations/ConfigurationOptions.cs
@@ -11,14 +11,15 @@ namespace Emby.Server.Implementations
///
/// Gets a new copy of the default configuration options.
///
- public static Dictionary DefaultConfiguration => new Dictionary
+ public static Dictionary DefaultConfiguration => new()
{
{ HostWebClientKey, bool.TrueString },
{ DefaultRedirectKey, "web/" },
{ FfmpegProbeSizeKey, "1G" },
{ FfmpegAnalyzeDurationKey, "200M" },
{ PlaylistsAllowDuplicatesKey, bool.FalseString },
- { BindToUnixSocketKey, bool.FalseString }
+ { BindToUnixSocketKey, bool.FalseString },
+ { SqliteCacheSizeKey, "20000" }
};
}
}
diff --git a/Emby.Server.Implementations/Data/BaseSqliteRepository.cs b/Emby.Server.Implementations/Data/BaseSqliteRepository.cs
index 4b9ab53ae4..d05534ee75 100644
--- a/Emby.Server.Implementations/Data/BaseSqliteRepository.cs
+++ b/Emby.Server.Implementations/Data/BaseSqliteRepository.cs
@@ -82,9 +82,10 @@ namespace Emby.Server.Implementations.Data
///
/// Gets the journal size limit. .
+ /// The default (-1) is overriden to prevent unconstrained WAL size, as reported by users.
///
/// The journal size limit.
- protected virtual int? JournalSizeLimit => 0;
+ protected virtual int? JournalSizeLimit => 134_217_728; // 128MiB
///
/// Gets the page size.
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index c32e7c75ad..ca8f605a02 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -25,6 +25,7 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Extensions;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Persistence;
@@ -34,6 +35,7 @@ using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Querying;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using SQLitePCL.pretty;
@@ -319,13 +321,15 @@ namespace Emby.Server.Implementations.Data
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
+ /// Instance of the interface.
/// config is null.
public SqliteItemRepository(
IServerConfigurationManager config,
IServerApplicationHost appHost,
ILogger logger,
ILocalizationManager localization,
- IImageProcessor imageProcessor)
+ IImageProcessor imageProcessor,
+ IConfiguration configuration)
: base(logger)
{
_config = config;
@@ -337,11 +341,13 @@ namespace Emby.Server.Implementations.Data
_jsonOptions = JsonDefaults.Options;
DbFilePath = Path.Combine(_config.ApplicationPaths.DataPath, "library.db");
+
+ CacheSize = configuration.GetSqliteCacheSize();
ReadConnectionsCount = Environment.ProcessorCount * 2;
}
///
- protected override int? CacheSize => 20000;
+ protected override int? CacheSize { get; }
///
protected override TempStoreMode TempStore => TempStoreMode.Memory;
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index 75a1a5a4d8..ea45bf0ba0 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -1264,7 +1264,14 @@ namespace Emby.Server.Implementations.Library
AddUserToQuery(query, query.User, allowExternalContent);
}
- return _itemRepository.GetItemList(query);
+ var itemList = _itemRepository.GetItemList(query);
+ var user = query.User;
+ if (user is not null)
+ {
+ return itemList.Where(i => i.IsVisible(user)).ToList();
+ }
+
+ return itemList;
}
public List GetItemList(InternalItemsQuery query)
diff --git a/Emby.Server.Implementations/Localization/Core/hi.json b/Emby.Server.Implementations/Localization/Core/hi.json
index 4bbb1dd352..47d3eeac5d 100644
--- a/Emby.Server.Implementations/Localization/Core/hi.json
+++ b/Emby.Server.Implementations/Localization/Core/hi.json
@@ -104,5 +104,24 @@
"TaskCleanActivityLog": "क्रियाकलाप लॉग साफ करें",
"TasksChannelsCategory": "इंटरनेट प्रणाली",
"TasksApplicationCategory": "अनुप्रयोग",
- "TaskRefreshPeople": "लोगोकी जानकारी ताज़ी करें"
+ "TaskRefreshPeople": "लोगोकी जानकारी ताज़ी करें",
+ "TaskKeyframeExtractor": "कीफ़्रेम एक्सट्रैक्टर",
+ "TaskCleanActivityLogDescription": "कॉन्फ़िगर की गई आयु से पुरानी गतिविधि लॉग प्रविष्टियां हटाता है।",
+ "TaskRefreshChapterImagesDescription": "अध्याय वाले वीडियो के लिए थंबनेल बनाता है।",
+ "TaskRefreshLibraryDescription": "नई फ़ाइलों के लिए आपकी मीडिया लाइब्रेरी को स्कैन करता है और मेटाडेटा को ताज़ा करता है।",
+ "TaskCleanLogs": "स्वच्छ लॉग निर्देशिका",
+ "TaskUpdatePluginsDescription": "प्लगइन्स के लिए अपडेट डाउनलोड और इंस्टॉल करें जो स्वचालित रूप से अपडेट करने के लिए कॉन्फ़िगर किए गए हैं।",
+ "TaskCleanTranscode": "स्वच्छ ट्रांसकोड निर्देशिका",
+ "TaskCleanTranscodeDescription": "एक दिन से अधिक पुरानी ट्रांसकोड फ़ाइलें हटाता है.",
+ "TaskRefreshChannelsDescription": "इंटरनेट चैनल की जानकारी को ताज़ा करता है।",
+ "TaskOptimizeDatabaseDescription": "डेटाबेस को कॉम्पैक्ट करता है और मुक्त स्थान को छोटा करता है। लाइब्रेरी को स्कैन करने के बाद इस कार्य को चलाने या अन्य परिवर्तन करने से जो डेटाबेस संशोधनों को लागू करते हैं, प्रदर्शन में सुधार कर सकते हैं।",
+ "TaskRefreshChannels": "इंटरनेट चैनल की जानकारी को ताज़ा करता है",
+ "TaskRefreshChapterImages": "अध्याय छवियाँ निकालें",
+ "TaskCleanLogsDescription": "{0} दिन से अधिक पुरानी लॉग फ़ाइलें हटाता है।",
+ "TaskCleanCacheDescription": "उन कैश फ़ाइलों को हटाता है जिनकी अब सिस्टम को आवश्यकता नहीं है।",
+ "TaskUpdatePlugins": "अद्यतन प्लगइन्स",
+ "TaskRefreshPeopleDescription": "आपकी मीडिया लाइब्रेरी में अभिनेताओं और निर्देशकों के लिए मेटाडेटा अपडेट करता है।",
+ "TaskCleanCache": "स्वच्छ कैश निर्देशिका",
+ "TaskDownloadMissingSubtitlesDescription": "मेटाडेटा कॉन्फ़िगरेशन के आधार पर लापता उपशीर्षक के लिए इंटरनेट खोजता है।",
+ "TaskKeyframeExtractorDescription": "अधिक सटीक एचएलएस प्लेलिस्ट बनाने के लिए वीडियो फ़ाइलों से मुख्य-फ़्रेम निकालता है। यह कार्य लंबे समय तक चल सकता है।"
}
diff --git a/Emby.Server.Implementations/Localization/Core/lt-LT.json b/Emby.Server.Implementations/Localization/Core/lt-LT.json
index e1c937b6cd..ce8d8fc322 100644
--- a/Emby.Server.Implementations/Localization/Core/lt-LT.json
+++ b/Emby.Server.Implementations/Localization/Core/lt-LT.json
@@ -20,9 +20,9 @@
"HeaderFavoriteAlbums": "Mėgstami Albumai",
"HeaderFavoriteArtists": "Mėgstami Atlikėjai",
"HeaderFavoriteEpisodes": "Mėgstamiausios serijos",
- "HeaderFavoriteShows": "Mėgstamiausi serialai",
- "HeaderFavoriteSongs": "Mėgstamos dainos",
- "HeaderLiveTV": "TV gyvai",
+ "HeaderFavoriteShows": "Mėgstamiausios TV Laidos",
+ "HeaderFavoriteSongs": "Mėgstamos Dainos",
+ "HeaderLiveTV": "Tiesioginė TV",
"HeaderNextUp": "Toliau eilėje",
"HeaderRecordingGroups": "Įrašų grupės",
"HomeVideos": "Namų vaizdo įrašai",
diff --git a/Emby.Server.Implementations/Playlists/PlaylistsFolder.cs b/Emby.Server.Implementations/Playlists/PlaylistsFolder.cs
index 5492097152..d67caa52dc 100644
--- a/Emby.Server.Implementations/Playlists/PlaylistsFolder.cs
+++ b/Emby.Server.Implementations/Playlists/PlaylistsFolder.cs
@@ -42,7 +42,7 @@ namespace Emby.Server.Implementations.Playlists
query.Recursive = true;
query.IncludeItemTypes = new[] { BaseItemKind.Playlist };
- return LibraryManager.GetItemsResult(query);
+ return QueryWithPostFiltering2(query);
}
public override string GetClientTypeName()
diff --git a/Jellyfin.Api/Controllers/ItemsController.cs b/Jellyfin.Api/Controllers/ItemsController.cs
index d4116116bd..7650b861f4 100644
--- a/Jellyfin.Api/Controllers/ItemsController.cs
+++ b/Jellyfin.Api/Controllers/ItemsController.cs
@@ -512,12 +512,10 @@ public class ItemsController : BaseJellyfinApiController
result = new QueryResult(itemsArray);
}
- // result might include items not accessible by the user, DtoService will remove them
- var accessibleItems = _dtoService.GetBaseItemDtos(result.Items, dtoOptions, user);
return new QueryResult(
startIndex,
- accessibleItems.Count,
- accessibleItems);
+ result.TotalRecordCount,
+ _dtoService.GetBaseItemDtos(result.Items, dtoOptions, user));
}
///
diff --git a/Jellyfin.Api/Controllers/StartupController.cs b/Jellyfin.Api/Controllers/StartupController.cs
index aab390d1f9..1098733b2c 100644
--- a/Jellyfin.Api/Controllers/StartupController.cs
+++ b/Jellyfin.Api/Controllers/StartupController.cs
@@ -131,6 +131,10 @@ public class StartupController : BaseJellyfinApiController
public async Task UpdateStartupUser([FromBody] StartupUserDto startupUserDto)
{
var user = _userManager.Users.First();
+ if (string.IsNullOrWhiteSpace(startupUserDto.Password))
+ {
+ return BadRequest("Password must not be empty");
+ }
if (startupUserDto.Name is not null)
{
diff --git a/Jellyfin.Api/Controllers/UserController.cs b/Jellyfin.Api/Controllers/UserController.cs
index 6296bfa87e..4f61af35e0 100644
--- a/Jellyfin.Api/Controllers/UserController.cs
+++ b/Jellyfin.Api/Controllers/UserController.cs
@@ -323,36 +323,16 @@ public class UserController : BaseJellyfinApiController
/// User not found.
/// A indicating success or a or a on failure.
[HttpPost("{userId}/EasyPassword")]
+ [Obsolete("Use Quick Connect instead")]
[Authorize]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
- public async Task UpdateUserEasyPassword(
+ public ActionResult UpdateUserEasyPassword(
[FromRoute, Required] Guid userId,
[FromBody, Required] UpdateUserEasyPassword request)
{
- if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true))
- {
- return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update the easy password.");
- }
-
- var user = _userManager.GetUserById(userId);
-
- if (user is null)
- {
- return NotFound("User not found");
- }
-
- if (request.ResetPassword)
- {
- await _userManager.ResetEasyPassword(user).ConfigureAwait(false);
- }
- else
- {
- await _userManager.ChangeEasyPassword(user, request.NewPw ?? string.Empty, request.NewPassword ?? string.Empty).ConfigureAwait(false);
- }
-
- return NoContent();
+ return Forbid();
}
///
diff --git a/Jellyfin.Data/Entities/User.cs b/Jellyfin.Data/Entities/User.cs
index 606e1b5427..58ddaaf83a 100644
--- a/Jellyfin.Data/Entities/User.cs
+++ b/Jellyfin.Data/Entities/User.cs
@@ -91,16 +91,6 @@ namespace Jellyfin.Data.Entities
[StringLength(65535)]
public string? Password { get; set; }
- ///
- /// Gets or sets the user's easy password, or null if none is set.
- ///
- ///
- /// Max length = 65535.
- ///
- [MaxLength(65535)]
- [StringLength(65535)]
- public string? EasyPassword { get; set; }
-
///
/// Gets or sets a value indicating whether the user must update their password.
///
diff --git a/Jellyfin.Server.Implementations/Migrations/20230526173516_RemoveEasyPassword.Designer.cs b/Jellyfin.Server.Implementations/Migrations/20230526173516_RemoveEasyPassword.Designer.cs
new file mode 100644
index 0000000000..00ccd9f0ff
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Migrations/20230526173516_RemoveEasyPassword.Designer.cs
@@ -0,0 +1,650 @@
+//
+using System;
+using Jellyfin.Server.Implementations;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace Jellyfin.Server.Implementations.Migrations
+{
+ [DbContext(typeof(JellyfinDbContext))]
+ [Migration("20230526173516_RemoveEasyPassword")]
+ partial class RemoveEasyPassword
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder.HasAnnotation("ProductVersion", "7.0.5");
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.AccessSchedule", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("DayOfWeek")
+ .HasColumnType("INTEGER");
+
+ b.Property("EndHour")
+ .HasColumnType("REAL");
+
+ b.Property("StartHour")
+ .HasColumnType("REAL");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AccessSchedules");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ActivityLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("DateCreated")
+ .HasColumnType("TEXT");
+
+ b.Property("ItemId")
+ .HasMaxLength(256)
+ .HasColumnType("TEXT");
+
+ b.Property("LogSeverity")
+ .HasColumnType("INTEGER");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(512)
+ .HasColumnType("TEXT");
+
+ b.Property("Overview")
+ .HasMaxLength(512)
+ .HasColumnType("TEXT");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property("ShortOverview")
+ .HasMaxLength(512)
+ .HasColumnType("TEXT");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("TEXT");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DateCreated");
+
+ b.ToTable("ActivityLogs");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.CustomItemDisplayPreferences", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Client")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("TEXT");
+
+ b.Property("ItemId")
+ .HasColumnType("TEXT");
+
+ b.Property("Key")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.Property("Value")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId", "ItemId", "Client", "Key")
+ .IsUnique();
+
+ b.ToTable("CustomItemDisplayPreferences");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.DisplayPreferences", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("ChromecastVersion")
+ .HasColumnType("INTEGER");
+
+ b.Property("Client")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("TEXT");
+
+ b.Property("DashboardTheme")
+ .HasMaxLength(32)
+ .HasColumnType("TEXT");
+
+ b.Property("EnableNextVideoInfoOverlay")
+ .HasColumnType("INTEGER");
+
+ b.Property("IndexBy")
+ .HasColumnType("INTEGER");
+
+ b.Property("ItemId")
+ .HasColumnType("TEXT");
+
+ b.Property("ScrollDirection")
+ .HasColumnType("INTEGER");
+
+ b.Property("ShowBackdrop")
+ .HasColumnType("INTEGER");
+
+ b.Property("ShowSidebar")
+ .HasColumnType("INTEGER");
+
+ b.Property("SkipBackwardLength")
+ .HasColumnType("INTEGER");
+
+ b.Property("SkipForwardLength")
+ .HasColumnType("INTEGER");
+
+ b.Property("TvHome")
+ .HasMaxLength(32)
+ .HasColumnType("TEXT");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId", "ItemId", "Client")
+ .IsUnique();
+
+ b.ToTable("DisplayPreferences");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.HomeSection", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("DisplayPreferencesId")
+ .HasColumnType("INTEGER");
+
+ b.Property("Order")
+ .HasColumnType("INTEGER");
+
+ b.Property("Type")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DisplayPreferencesId");
+
+ b.ToTable("HomeSection");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ImageInfo", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("LastModified")
+ .HasColumnType("TEXT");
+
+ b.Property("Path")
+ .IsRequired()
+ .HasMaxLength(512)
+ .HasColumnType("TEXT");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId")
+ .IsUnique();
+
+ b.ToTable("ImageInfos");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ItemDisplayPreferences", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Client")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("TEXT");
+
+ b.Property("IndexBy")
+ .HasColumnType("INTEGER");
+
+ b.Property("ItemId")
+ .HasColumnType("TEXT");
+
+ b.Property("RememberIndexing")
+ .HasColumnType("INTEGER");
+
+ b.Property("RememberSorting")
+ .HasColumnType("INTEGER");
+
+ b.Property("SortBy")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("TEXT");
+
+ b.Property("SortOrder")
+ .HasColumnType("INTEGER");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.Property("ViewType")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("ItemDisplayPreferences");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Permission", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Kind")
+ .HasColumnType("INTEGER");
+
+ b.Property("Permission_Permissions_Guid")
+ .HasColumnType("TEXT");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.Property("Value")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId", "Kind")
+ .IsUnique()
+ .HasFilter("[UserId] IS NOT NULL");
+
+ b.ToTable("Permissions");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Preference", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Kind")
+ .HasColumnType("INTEGER");
+
+ b.Property("Preference_Preferences_Guid")
+ .HasColumnType("TEXT");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.Property("Value")
+ .IsRequired()
+ .HasMaxLength(65535)
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId", "Kind")
+ .IsUnique()
+ .HasFilter("[UserId] IS NOT NULL");
+
+ b.ToTable("Preferences");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Security.ApiKey", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("AccessToken")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("DateCreated")
+ .HasColumnType("TEXT");
+
+ b.Property("DateLastActivity")
+ .HasColumnType("TEXT");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AccessToken")
+ .IsUnique();
+
+ b.ToTable("ApiKeys");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Security.Device", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("AccessToken")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("AppName")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("TEXT");
+
+ b.Property("AppVersion")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("TEXT");
+
+ b.Property("DateCreated")
+ .HasColumnType("TEXT");
+
+ b.Property("DateLastActivity")
+ .HasColumnType("TEXT");
+
+ b.Property("DateModified")
+ .HasColumnType("TEXT");
+
+ b.Property("DeviceId")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("TEXT");
+
+ b.Property("DeviceName")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("TEXT");
+
+ b.Property("IsActive")
+ .HasColumnType("INTEGER");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DeviceId");
+
+ b.HasIndex("AccessToken", "DateLastActivity");
+
+ b.HasIndex("DeviceId", "DateLastActivity");
+
+ b.HasIndex("UserId", "DeviceId");
+
+ b.ToTable("Devices");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Security.DeviceOptions", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("CustomName")
+ .HasColumnType("TEXT");
+
+ b.Property("DeviceId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DeviceId")
+ .IsUnique();
+
+ b.ToTable("DeviceOptions");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.User", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT");
+
+ b.Property("AudioLanguagePreference")
+ .HasMaxLength(255)
+ .HasColumnType("TEXT");
+
+ b.Property("AuthenticationProviderId")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("TEXT");
+
+ b.Property("DisplayCollectionsView")
+ .HasColumnType("INTEGER");
+
+ b.Property("DisplayMissingEpisodes")
+ .HasColumnType("INTEGER");
+
+ b.Property("EnableAutoLogin")
+ .HasColumnType("INTEGER");
+
+ b.Property("EnableLocalPassword")
+ .HasColumnType("INTEGER");
+
+ b.Property("EnableNextEpisodeAutoPlay")
+ .HasColumnType("INTEGER");
+
+ b.Property("EnableUserPreferenceAccess")
+ .HasColumnType("INTEGER");
+
+ b.Property("HidePlayedInLatest")
+ .HasColumnType("INTEGER");
+
+ b.Property("InternalId")
+ .HasColumnType("INTEGER");
+
+ b.Property("InvalidLoginAttemptCount")
+ .HasColumnType("INTEGER");
+
+ b.Property("LastActivityDate")
+ .HasColumnType("TEXT");
+
+ b.Property("LastLoginDate")
+ .HasColumnType("TEXT");
+
+ b.Property("LoginAttemptsBeforeLockout")
+ .HasColumnType("INTEGER");
+
+ b.Property("MaxActiveSessions")
+ .HasColumnType("INTEGER");
+
+ b.Property("MaxParentalAgeRating")
+ .HasColumnType("INTEGER");
+
+ b.Property("MustUpdatePassword")
+ .HasColumnType("INTEGER");
+
+ b.Property("Password")
+ .HasMaxLength(65535)
+ .HasColumnType("TEXT");
+
+ b.Property("PasswordResetProviderId")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("TEXT");
+
+ b.Property("PlayDefaultAudioTrack")
+ .HasColumnType("INTEGER");
+
+ b.Property("RememberAudioSelections")
+ .HasColumnType("INTEGER");
+
+ b.Property("RememberSubtitleSelections")
+ .HasColumnType("INTEGER");
+
+ b.Property("RemoteClientBitrateLimit")
+ .HasColumnType("INTEGER");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property("SubtitleLanguagePreference")
+ .HasMaxLength(255)
+ .HasColumnType("TEXT");
+
+ b.Property("SubtitleMode")
+ .HasColumnType("INTEGER");
+
+ b.Property("SyncPlayAccess")
+ .HasColumnType("INTEGER");
+
+ b.Property("Username")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("TEXT")
+ .UseCollation("NOCASE");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Username")
+ .IsUnique();
+
+ b.ToTable("Users");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.AccessSchedule", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("AccessSchedules")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.DisplayPreferences", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("DisplayPreferences")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.HomeSection", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.DisplayPreferences", null)
+ .WithMany("HomeSections")
+ .HasForeignKey("DisplayPreferencesId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ImageInfo", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithOne("ProfileImage")
+ .HasForeignKey("Jellyfin.Data.Entities.ImageInfo", "UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ItemDisplayPreferences", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("ItemDisplayPreferences")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Permission", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("Permissions")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Preference", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.User", null)
+ .WithMany("Preferences")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Security.Device", b =>
+ {
+ b.HasOne("Jellyfin.Data.Entities.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.DisplayPreferences", b =>
+ {
+ b.Navigation("HomeSections");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.User", b =>
+ {
+ b.Navigation("AccessSchedules");
+
+ b.Navigation("DisplayPreferences");
+
+ b.Navigation("ItemDisplayPreferences");
+
+ b.Navigation("Permissions");
+
+ b.Navigation("Preferences");
+
+ b.Navigation("ProfileImage");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Jellyfin.Server.Implementations/Migrations/20230526173516_RemoveEasyPassword.cs b/Jellyfin.Server.Implementations/Migrations/20230526173516_RemoveEasyPassword.cs
new file mode 100644
index 0000000000..9496ff3c0d
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Migrations/20230526173516_RemoveEasyPassword.cs
@@ -0,0 +1,164 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace Jellyfin.Server.Implementations.Migrations
+{
+ ///
+ public partial class RemoveEasyPassword : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "EasyPassword",
+ schema: "jellyfin",
+ table: "Users");
+
+ migrationBuilder.RenameTable(
+ name: "Users",
+ schema: "jellyfin",
+ newName: "Users");
+
+ migrationBuilder.RenameTable(
+ name: "Preferences",
+ schema: "jellyfin",
+ newName: "Preferences");
+
+ migrationBuilder.RenameTable(
+ name: "Permissions",
+ schema: "jellyfin",
+ newName: "Permissions");
+
+ migrationBuilder.RenameTable(
+ name: "ItemDisplayPreferences",
+ schema: "jellyfin",
+ newName: "ItemDisplayPreferences");
+
+ migrationBuilder.RenameTable(
+ name: "ImageInfos",
+ schema: "jellyfin",
+ newName: "ImageInfos");
+
+ migrationBuilder.RenameTable(
+ name: "HomeSection",
+ schema: "jellyfin",
+ newName: "HomeSection");
+
+ migrationBuilder.RenameTable(
+ name: "DisplayPreferences",
+ schema: "jellyfin",
+ newName: "DisplayPreferences");
+
+ migrationBuilder.RenameTable(
+ name: "Devices",
+ schema: "jellyfin",
+ newName: "Devices");
+
+ migrationBuilder.RenameTable(
+ name: "DeviceOptions",
+ schema: "jellyfin",
+ newName: "DeviceOptions");
+
+ migrationBuilder.RenameTable(
+ name: "CustomItemDisplayPreferences",
+ schema: "jellyfin",
+ newName: "CustomItemDisplayPreferences");
+
+ migrationBuilder.RenameTable(
+ name: "ApiKeys",
+ schema: "jellyfin",
+ newName: "ApiKeys");
+
+ migrationBuilder.RenameTable(
+ name: "ActivityLogs",
+ schema: "jellyfin",
+ newName: "ActivityLogs");
+
+ migrationBuilder.RenameTable(
+ name: "AccessSchedules",
+ schema: "jellyfin",
+ newName: "AccessSchedules");
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.EnsureSchema(
+ name: "jellyfin");
+
+ migrationBuilder.RenameTable(
+ name: "Users",
+ newName: "Users",
+ newSchema: "jellyfin");
+
+ migrationBuilder.RenameTable(
+ name: "Preferences",
+ newName: "Preferences",
+ newSchema: "jellyfin");
+
+ migrationBuilder.RenameTable(
+ name: "Permissions",
+ newName: "Permissions",
+ newSchema: "jellyfin");
+
+ migrationBuilder.RenameTable(
+ name: "ItemDisplayPreferences",
+ newName: "ItemDisplayPreferences",
+ newSchema: "jellyfin");
+
+ migrationBuilder.RenameTable(
+ name: "ImageInfos",
+ newName: "ImageInfos",
+ newSchema: "jellyfin");
+
+ migrationBuilder.RenameTable(
+ name: "HomeSection",
+ newName: "HomeSection",
+ newSchema: "jellyfin");
+
+ migrationBuilder.RenameTable(
+ name: "DisplayPreferences",
+ newName: "DisplayPreferences",
+ newSchema: "jellyfin");
+
+ migrationBuilder.RenameTable(
+ name: "Devices",
+ newName: "Devices",
+ newSchema: "jellyfin");
+
+ migrationBuilder.RenameTable(
+ name: "DeviceOptions",
+ newName: "DeviceOptions",
+ newSchema: "jellyfin");
+
+ migrationBuilder.RenameTable(
+ name: "CustomItemDisplayPreferences",
+ newName: "CustomItemDisplayPreferences",
+ newSchema: "jellyfin");
+
+ migrationBuilder.RenameTable(
+ name: "ApiKeys",
+ newName: "ApiKeys",
+ newSchema: "jellyfin");
+
+ migrationBuilder.RenameTable(
+ name: "ActivityLogs",
+ newName: "ActivityLogs",
+ newSchema: "jellyfin");
+
+ migrationBuilder.RenameTable(
+ name: "AccessSchedules",
+ newName: "AccessSchedules",
+ newSchema: "jellyfin");
+
+ migrationBuilder.AddColumn(
+ name: "EasyPassword",
+ schema: "jellyfin",
+ table: "Users",
+ type: "TEXT",
+ maxLength: 65535,
+ nullable: true);
+ }
+ }
+}
diff --git a/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs b/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs
index dd5f7f0121..d23508096f 100644
--- a/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs
+++ b/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs
@@ -15,9 +15,7 @@ namespace Jellyfin.Server.Implementations.Migrations
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
- modelBuilder
- .HasDefaultSchema("jellyfin")
- .HasAnnotation("ProductVersion", "6.0.9");
+ modelBuilder.HasAnnotation("ProductVersion", "7.0.5");
modelBuilder.Entity("Jellyfin.Data.Entities.AccessSchedule", b =>
{
@@ -41,7 +39,7 @@ namespace Jellyfin.Server.Implementations.Migrations
b.HasIndex("UserId");
- b.ToTable("AccessSchedules", "jellyfin");
+ b.ToTable("AccessSchedules");
});
modelBuilder.Entity("Jellyfin.Data.Entities.ActivityLog", b =>
@@ -89,7 +87,7 @@ namespace Jellyfin.Server.Implementations.Migrations
b.HasIndex("DateCreated");
- b.ToTable("ActivityLogs", "jellyfin");
+ b.ToTable("ActivityLogs");
});
modelBuilder.Entity("Jellyfin.Data.Entities.CustomItemDisplayPreferences", b =>
@@ -121,7 +119,7 @@ namespace Jellyfin.Server.Implementations.Migrations
b.HasIndex("UserId", "ItemId", "Client", "Key")
.IsUnique();
- b.ToTable("CustomItemDisplayPreferences", "jellyfin");
+ b.ToTable("CustomItemDisplayPreferences");
});
modelBuilder.Entity("Jellyfin.Data.Entities.DisplayPreferences", b =>
@@ -178,7 +176,7 @@ namespace Jellyfin.Server.Implementations.Migrations
b.HasIndex("UserId", "ItemId", "Client")
.IsUnique();
- b.ToTable("DisplayPreferences", "jellyfin");
+ b.ToTable("DisplayPreferences");
});
modelBuilder.Entity("Jellyfin.Data.Entities.HomeSection", b =>
@@ -200,7 +198,7 @@ namespace Jellyfin.Server.Implementations.Migrations
b.HasIndex("DisplayPreferencesId");
- b.ToTable("HomeSection", "jellyfin");
+ b.ToTable("HomeSection");
});
modelBuilder.Entity("Jellyfin.Data.Entities.ImageInfo", b =>
@@ -225,7 +223,7 @@ namespace Jellyfin.Server.Implementations.Migrations
b.HasIndex("UserId")
.IsUnique();
- b.ToTable("ImageInfos", "jellyfin");
+ b.ToTable("ImageInfos");
});
modelBuilder.Entity("Jellyfin.Data.Entities.ItemDisplayPreferences", b =>
@@ -269,7 +267,7 @@ namespace Jellyfin.Server.Implementations.Migrations
b.HasIndex("UserId");
- b.ToTable("ItemDisplayPreferences", "jellyfin");
+ b.ToTable("ItemDisplayPreferences");
});
modelBuilder.Entity("Jellyfin.Data.Entities.Permission", b =>
@@ -300,7 +298,7 @@ namespace Jellyfin.Server.Implementations.Migrations
.IsUnique()
.HasFilter("[UserId] IS NOT NULL");
- b.ToTable("Permissions", "jellyfin");
+ b.ToTable("Permissions");
});
modelBuilder.Entity("Jellyfin.Data.Entities.Preference", b =>
@@ -333,7 +331,7 @@ namespace Jellyfin.Server.Implementations.Migrations
.IsUnique()
.HasFilter("[UserId] IS NOT NULL");
- b.ToTable("Preferences", "jellyfin");
+ b.ToTable("Preferences");
});
modelBuilder.Entity("Jellyfin.Data.Entities.Security.ApiKey", b =>
@@ -362,7 +360,7 @@ namespace Jellyfin.Server.Implementations.Migrations
b.HasIndex("AccessToken")
.IsUnique();
- b.ToTable("ApiKeys", "jellyfin");
+ b.ToTable("ApiKeys");
});
modelBuilder.Entity("Jellyfin.Data.Entities.Security.Device", b =>
@@ -420,7 +418,7 @@ namespace Jellyfin.Server.Implementations.Migrations
b.HasIndex("UserId", "DeviceId");
- b.ToTable("Devices", "jellyfin");
+ b.ToTable("Devices");
});
modelBuilder.Entity("Jellyfin.Data.Entities.Security.DeviceOptions", b =>
@@ -441,7 +439,7 @@ namespace Jellyfin.Server.Implementations.Migrations
b.HasIndex("DeviceId")
.IsUnique();
- b.ToTable("DeviceOptions", "jellyfin");
+ b.ToTable("DeviceOptions");
});
modelBuilder.Entity("Jellyfin.Data.Entities.User", b =>
@@ -465,10 +463,6 @@ namespace Jellyfin.Server.Implementations.Migrations
b.Property("DisplayMissingEpisodes")
.HasColumnType("INTEGER");
- b.Property("EasyPassword")
- .HasMaxLength(65535)
- .HasColumnType("TEXT");
-
b.Property("EnableAutoLogin")
.HasColumnType("INTEGER");
@@ -554,7 +548,7 @@ namespace Jellyfin.Server.Implementations.Migrations
b.HasIndex("Username")
.IsUnique();
- b.ToTable("Users", "jellyfin");
+ b.ToTable("Users");
});
modelBuilder.Entity("Jellyfin.Data.Entities.AccessSchedule", b =>
diff --git a/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs b/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs
index 9601954671..cefbd0624d 100644
--- a/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs
+++ b/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs
@@ -114,8 +114,6 @@ namespace Jellyfin.Server.Implementations.Users
await JsonSerializer.SerializeAsync(fileStream, spr).ConfigureAwait(false);
}
- user.EasyPassword = pin;
-
return new ForgotPasswordResult
{
Action = ForgotPasswordAction.PinCode,
diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs
index c4756433e0..1d03baa4c6 100644
--- a/Jellyfin.Server.Implementations/Users/UserManager.cs
+++ b/Jellyfin.Server.Implementations/Users/UserManager.cs
@@ -268,37 +268,16 @@ namespace Jellyfin.Server.Implementations.Users
return ChangePassword(user, string.Empty);
}
- ///
- public Task ResetEasyPassword(User user)
- {
- return ChangeEasyPassword(user, string.Empty, null);
- }
-
///
public async Task ChangePassword(User user, string newPassword)
{
ArgumentNullException.ThrowIfNull(user);
-
- await GetAuthenticationProvider(user).ChangePassword(user, newPassword).ConfigureAwait(false);
- await UpdateUserAsync(user).ConfigureAwait(false);
-
- await _eventManager.PublishAsync(new UserPasswordChangedEventArgs(user)).ConfigureAwait(false);
- }
-
- ///
- public async Task ChangeEasyPassword(User user, string newPassword, string? newPasswordSha1)
- {
- if (newPassword is not null)
- {
- newPasswordSha1 = _cryptoProvider.CreatePasswordHash(newPassword).ToString();
- }
-
- if (string.IsNullOrWhiteSpace(newPasswordSha1))
+ if (user.HasPermission(PermissionKind.IsAdministrator) && string.IsNullOrWhiteSpace(newPassword))
{
- throw new ArgumentNullException(nameof(newPasswordSha1));
+ throw new ArgumentException("Admin user passwords must not be empty", nameof(newPassword));
}
- user.EasyPassword = newPasswordSha1;
+ await GetAuthenticationProvider(user).ChangePassword(user, newPassword).ConfigureAwait(false);
await UpdateUserAsync(user).ConfigureAwait(false);
await _eventManager.PublishAsync(new UserPasswordChangedEventArgs(user)).ConfigureAwait(false);
@@ -315,7 +294,6 @@ namespace Jellyfin.Server.Implementations.Users
ServerId = _appHost.SystemId,
HasPassword = hasPassword,
HasConfiguredPassword = hasPassword,
- HasConfiguredEasyPassword = !string.IsNullOrEmpty(user.EasyPassword),
EnableAutoLogin = user.EnableAutoLogin,
LastLoginDate = user.LastLoginDate,
LastActivityDate = user.LastActivityDate,
@@ -832,16 +810,6 @@ namespace Jellyfin.Server.Implementations.Users
}
}
- if (!success
- && _networkManager.IsInLocalNetwork(remoteEndPoint)
- && user?.EnableLocalPassword == true
- && !string.IsNullOrEmpty(user.EasyPassword))
- {
- // Check easy password
- var passwordHash = PasswordHash.Parse(user.EasyPassword);
- success = _cryptoProvider.Verify(passwordHash, password);
- }
-
return (authenticationProvider, username, success);
}
diff --git a/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs
index 9bf1e6b808..0186500a12 100644
--- a/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs
+++ b/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs
@@ -127,7 +127,6 @@ namespace Jellyfin.Server.Migrations.Routines
RememberSubtitleSelections = config.RememberSubtitleSelections,
SubtitleLanguagePreference = config.SubtitleLanguagePreference,
Password = mockup.Password,
- EasyPassword = mockup.EasyPassword,
LastLoginDate = mockup.LastLoginDate,
LastActivityDate = mockup.LastActivityDate
};
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index bccb4107ff..84952295c4 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -730,7 +730,7 @@ namespace MediaBrowser.Controller.Entities
return LibraryManager.GetItemsResult(query);
}
- private QueryResult QueryWithPostFiltering2(InternalItemsQuery query)
+ protected QueryResult QueryWithPostFiltering2(InternalItemsQuery query)
{
var startIndex = query.StartIndex;
var limit = query.Limit;
@@ -1272,7 +1272,7 @@ namespace MediaBrowser.Controller.Entities
{
ArgumentNullException.ThrowIfNull(user);
- return GetChildren(user, includeLinkedChildren, null);
+ return GetChildren(user, includeLinkedChildren, new InternalItemsQuery(user));
}
public virtual List GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query)
diff --git a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs
index 3b5e8ece71..6c58064ce9 100644
--- a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs
+++ b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs
@@ -59,6 +59,11 @@ namespace MediaBrowser.Controller.Extensions
///
public const string UnixSocketPermissionsKey = "kestrel:socketPermissions";
+ ///
+ /// The cache size of the SQL database, see cache_size.
+ ///
+ public const string SqliteCacheSizeKey = "sqlite:cacheSize";
+
///
/// Gets a value indicating whether the application should host static web content from the .
///
@@ -115,5 +120,13 @@ namespace MediaBrowser.Controller.Extensions
/// The unix socket permissions.
public static string? GetUnixSocketPermissions(this IConfiguration configuration)
=> configuration[UnixSocketPermissionsKey];
+
+ ///
+ /// Gets the cache_size from the .
+ ///
+ /// The configuration to read the setting from.
+ /// The sqlite cache size.
+ public static int? GetSqliteCacheSize(this IConfiguration configuration)
+ => configuration.GetValue(SqliteCacheSizeKey);
}
}
diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs
index 37b4afcf32..6d6a532dba 100644
--- a/MediaBrowser.Controller/Library/IUserManager.cs
+++ b/MediaBrowser.Controller/Library/IUserManager.cs
@@ -96,13 +96,6 @@ namespace MediaBrowser.Controller.Library
/// Task.
Task ResetPassword(User user);
- ///
- /// Resets the easy password.
- ///
- /// The user.
- /// Task.
- Task ResetEasyPassword(User user);
-
///
/// Changes the password.
///
@@ -111,15 +104,6 @@ namespace MediaBrowser.Controller.Library
/// Awaitable task.
Task ChangePassword(User user, string newPassword);
- ///
- /// Changes the easy password.
- ///
- /// The user.
- /// New password to use.
- /// Hash of new password.
- /// Task.
- Task ChangeEasyPassword(User user, string newPassword, string newPasswordSha1);
-
///
/// Gets the user dto.
///
diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs
index 27154c2978..8fab1ca6d6 100644
--- a/MediaBrowser.Model/Dto/BaseItemDto.cs
+++ b/MediaBrowser.Model/Dto/BaseItemDto.cs
@@ -783,7 +783,7 @@ namespace MediaBrowser.Model.Dto
/// Gets or sets the LUFS value.
///
/// The LUFS Value.
- public float LUFS { get; set; }
+ public float? LUFS { get; set; }
///
/// Gets or sets the current program.
diff --git a/MediaBrowser.Model/Dto/UserDto.cs b/MediaBrowser.Model/Dto/UserDto.cs
index 256d7b10f1..05019741e0 100644
--- a/MediaBrowser.Model/Dto/UserDto.cs
+++ b/MediaBrowser.Model/Dto/UserDto.cs
@@ -66,6 +66,7 @@ namespace MediaBrowser.Model.Dto
/// Gets or sets a value indicating whether this instance has configured easy password.
///
/// true if this instance has configured easy password; otherwise, false.
+ [Obsolete("Easy Password has been replaced with Quick Connect")]
public bool HasConfiguredEasyPassword { get; set; }
///
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Data/SqliteItemRepositoryTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Data/SqliteItemRepositoryTests.cs
index 7d92e7b261..0d2b488bc7 100644
--- a/tests/Jellyfin.Server.Implementations.Tests/Data/SqliteItemRepositoryTests.cs
+++ b/tests/Jellyfin.Server.Implementations.Tests/Data/SqliteItemRepositoryTests.cs
@@ -6,6 +6,7 @@ using Emby.Server.Implementations.Data;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Entities;
+using Microsoft.Extensions.Configuration;
using Moq;
using Xunit;
@@ -27,8 +28,18 @@ namespace Jellyfin.Server.Implementations.Tests.Data
appHost.Setup(x => x.ReverseVirtualPath(It.IsAny()))
.Returns((string x) => x.Replace(MetaDataPath, VirtualMetaDataPath, StringComparison.Ordinal));
+ var configSection = new Mock();
+ configSection
+ .SetupGet(x => x[It.Is(s => s == MediaBrowser.Controller.Extensions.ConfigurationExtensions.SqliteCacheSizeKey)])
+ .Returns("0");
+ var config = new Mock();
+ config
+ .Setup(x => x.GetSection(It.Is(s => s == MediaBrowser.Controller.Extensions.ConfigurationExtensions.SqliteCacheSizeKey)))
+ .Returns(configSection.Object);
+
_fixture = new Fixture().Customize(new AutoMoqCustomization { ConfigureMembers = true });
_fixture.Inject(appHost);
+ _fixture.Inject(config);
_sqliteItemRepository = _fixture.Create();
}