aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCody Robibero <cody@robibe.ro>2023-05-29 18:37:26 -0600
committerGitHub <noreply@github.com>2023-05-29 18:37:26 -0600
commitcfca6fc56ea56e42833ea7d46e7fb90bb7e4dce0 (patch)
treee89fc97f76434c730879cdcd3b37681b6b907dc1
parentc14a6f53668743a870a37a69f345c24d72e86219 (diff)
parent3bdef7207c39d077c8548006ae4a545e2fa27dae (diff)
Merge pull request #9820 from cvium/deprecate_easypassword
-rw-r--r--Jellyfin.Api/Controllers/UserController.cs26
-rw-r--r--Jellyfin.Data/Entities/User.cs10
-rw-r--r--Jellyfin.Server.Implementations/Migrations/20230526173516_RemoveEasyPassword.Designer.cs650
-rw-r--r--Jellyfin.Server.Implementations/Migrations/20230526173516_RemoveEasyPassword.cs164
-rw-r--r--Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs34
-rw-r--r--Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs2
-rw-r--r--Jellyfin.Server.Implementations/Users/UserManager.cs36
-rw-r--r--Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs1
-rw-r--r--MediaBrowser.Controller/Library/IUserManager.cs16
-rw-r--r--MediaBrowser.Model/Dto/UserDto.cs1
10 files changed, 832 insertions, 108 deletions
diff --git a/Jellyfin.Api/Controllers/UserController.cs b/Jellyfin.Api/Controllers/UserController.cs
index e49528867..530bd9603 100644
--- a/Jellyfin.Api/Controllers/UserController.cs
+++ b/Jellyfin.Api/Controllers/UserController.cs
@@ -323,36 +323,16 @@ public class UserController : BaseJellyfinApiController
/// <response code="404">User not found.</response>
/// <returns>A <see cref="NoContentResult"/> indicating success or a <see cref="ForbidResult"/> or a <see cref="NotFoundResult"/> on failure.</returns>
[HttpPost("{userId}/EasyPassword")]
+ [Obsolete("Use Quick Connect instead")]
[Authorize]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
- public async Task<ActionResult> 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();
}
/// <summary>
diff --git a/Jellyfin.Data/Entities/User.cs b/Jellyfin.Data/Entities/User.cs
index 606e1b542..58ddaaf83 100644
--- a/Jellyfin.Data/Entities/User.cs
+++ b/Jellyfin.Data/Entities/User.cs
@@ -92,16 +92,6 @@ namespace Jellyfin.Data.Entities
public string? Password { get; set; }
/// <summary>
- /// Gets or sets the user's easy password, or <c>null</c> if none is set.
- /// </summary>
- /// <remarks>
- /// Max length = 65535.
- /// </remarks>
- [MaxLength(65535)]
- [StringLength(65535)]
- public string? EasyPassword { get; set; }
-
- /// <summary>
/// Gets or sets a value indicating whether the user must update their password.
/// </summary>
/// <remarks>
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 000000000..00ccd9f0f
--- /dev/null
+++ b/Jellyfin.Server.Implementations/Migrations/20230526173516_RemoveEasyPassword.Designer.cs
@@ -0,0 +1,650 @@
+// <auto-generated />
+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
+ {
+ /// <inheritdoc />
+ 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<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("DayOfWeek")
+ .HasColumnType("INTEGER");
+
+ b.Property<double>("EndHour")
+ .HasColumnType("REAL");
+
+ b.Property<double>("StartHour")
+ .HasColumnType("REAL");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AccessSchedules");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ActivityLog", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<DateTime>("DateCreated")
+ .HasColumnType("TEXT");
+
+ b.Property<string>("ItemId")
+ .HasMaxLength(256)
+ .HasColumnType("TEXT");
+
+ b.Property<int>("LogSeverity")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasMaxLength(512)
+ .HasColumnType("TEXT");
+
+ b.Property<string>("Overview")
+ .HasMaxLength(512)
+ .HasColumnType("TEXT");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("ShortOverview")
+ .HasMaxLength(512)
+ .HasColumnType("TEXT");
+
+ b.Property<string>("Type")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("TEXT");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DateCreated");
+
+ b.ToTable("ActivityLogs");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.CustomItemDisplayPreferences", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Client")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("TEXT");
+
+ b.Property<Guid>("ItemId")
+ .HasColumnType("TEXT");
+
+ b.Property<string>("Key")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("TEXT");
+
+ b.Property<string>("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<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("ChromecastVersion")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Client")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("TEXT");
+
+ b.Property<string>("DashboardTheme")
+ .HasMaxLength(32)
+ .HasColumnType("TEXT");
+
+ b.Property<bool>("EnableNextVideoInfoOverlay")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("IndexBy")
+ .HasColumnType("INTEGER");
+
+ b.Property<Guid>("ItemId")
+ .HasColumnType("TEXT");
+
+ b.Property<int>("ScrollDirection")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("ShowBackdrop")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("ShowSidebar")
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("SkipBackwardLength")
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("SkipForwardLength")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("TvHome")
+ .HasMaxLength(32)
+ .HasColumnType("TEXT");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId", "ItemId", "Client")
+ .IsUnique();
+
+ b.ToTable("DisplayPreferences");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.HomeSection", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("DisplayPreferencesId")
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("Order")
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("Type")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DisplayPreferencesId");
+
+ b.ToTable("HomeSection");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ImageInfo", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<DateTime>("LastModified")
+ .HasColumnType("TEXT");
+
+ b.Property<string>("Path")
+ .IsRequired()
+ .HasMaxLength(512)
+ .HasColumnType("TEXT");
+
+ b.Property<Guid?>("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId")
+ .IsUnique();
+
+ b.ToTable("ImageInfos");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.ItemDisplayPreferences", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Client")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("TEXT");
+
+ b.Property<int?>("IndexBy")
+ .HasColumnType("INTEGER");
+
+ b.Property<Guid>("ItemId")
+ .HasColumnType("TEXT");
+
+ b.Property<bool>("RememberIndexing")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("RememberSorting")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("SortBy")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("TEXT");
+
+ b.Property<int>("SortOrder")
+ .HasColumnType("INTEGER");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("TEXT");
+
+ b.Property<int>("ViewType")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("ItemDisplayPreferences");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.Permission", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("Kind")
+ .HasColumnType("INTEGER");
+
+ b.Property<Guid?>("Permission_Permissions_Guid")
+ .HasColumnType("TEXT");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<Guid?>("UserId")
+ .HasColumnType("TEXT");
+
+ b.Property<bool>("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<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("Kind")
+ .HasColumnType("INTEGER");
+
+ b.Property<Guid?>("Preference_Preferences_Guid")
+ .HasColumnType("TEXT");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<Guid?>("UserId")
+ .HasColumnType("TEXT");
+
+ b.Property<string>("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<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("AccessToken")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property<DateTime>("DateCreated")
+ .HasColumnType("TEXT");
+
+ b.Property<DateTime>("DateLastActivity")
+ .HasColumnType("TEXT");
+
+ b.Property<string>("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<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("AccessToken")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property<string>("AppName")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("TEXT");
+
+ b.Property<string>("AppVersion")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("TEXT");
+
+ b.Property<DateTime>("DateCreated")
+ .HasColumnType("TEXT");
+
+ b.Property<DateTime>("DateLastActivity")
+ .HasColumnType("TEXT");
+
+ b.Property<DateTime>("DateModified")
+ .HasColumnType("TEXT");
+
+ b.Property<string>("DeviceId")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("TEXT");
+
+ b.Property<string>("DeviceName")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("TEXT");
+
+ b.Property<bool>("IsActive")
+ .HasColumnType("INTEGER");
+
+ b.Property<Guid>("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<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("CustomName")
+ .HasColumnType("TEXT");
+
+ b.Property<string>("DeviceId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DeviceId")
+ .IsUnique();
+
+ b.ToTable("DeviceOptions");
+ });
+
+ modelBuilder.Entity("Jellyfin.Data.Entities.User", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT");
+
+ b.Property<string>("AudioLanguagePreference")
+ .HasMaxLength(255)
+ .HasColumnType("TEXT");
+
+ b.Property<string>("AuthenticationProviderId")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("TEXT");
+
+ b.Property<bool>("DisplayCollectionsView")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("DisplayMissingEpisodes")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("EnableAutoLogin")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("EnableLocalPassword")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("EnableNextEpisodeAutoPlay")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("EnableUserPreferenceAccess")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("HidePlayedInLatest")
+ .HasColumnType("INTEGER");
+
+ b.Property<long>("InternalId")
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("InvalidLoginAttemptCount")
+ .HasColumnType("INTEGER");
+
+ b.Property<DateTime?>("LastActivityDate")
+ .HasColumnType("TEXT");
+
+ b.Property<DateTime?>("LastLoginDate")
+ .HasColumnType("TEXT");
+
+ b.Property<int?>("LoginAttemptsBeforeLockout")
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("MaxActiveSessions")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("MaxParentalAgeRating")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("MustUpdatePassword")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("Password")
+ .HasMaxLength(65535)
+ .HasColumnType("TEXT");
+
+ b.Property<string>("PasswordResetProviderId")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("TEXT");
+
+ b.Property<bool>("PlayDefaultAudioTrack")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("RememberAudioSelections")
+ .HasColumnType("INTEGER");
+
+ b.Property<bool>("RememberSubtitleSelections")
+ .HasColumnType("INTEGER");
+
+ b.Property<int?>("RemoteClientBitrateLimit")
+ .HasColumnType("INTEGER");
+
+ b.Property<uint>("RowVersion")
+ .IsConcurrencyToken()
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("SubtitleLanguagePreference")
+ .HasMaxLength(255)
+ .HasColumnType("TEXT");
+
+ b.Property<int>("SubtitleMode")
+ .HasColumnType("INTEGER");
+
+ b.Property<int>("SyncPlayAccess")
+ .HasColumnType("INTEGER");
+
+ b.Property<string>("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 000000000..9496ff3c0
--- /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
+{
+ /// <inheritdoc />
+ public partial class RemoveEasyPassword : Migration
+ {
+ /// <inheritdoc />
+ 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");
+ }
+
+ /// <inheritdoc />
+ 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<string>(
+ 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 dd5f7f012..d23508096 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<bool>("DisplayMissingEpisodes")
.HasColumnType("INTEGER");
- b.Property<string>("EasyPassword")
- .HasMaxLength(65535)
- .HasColumnType("TEXT");
-
b.Property<bool>("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 960195467..cefbd0624 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 c4756433e..fa23fe148 100644
--- a/Jellyfin.Server.Implementations/Users/UserManager.cs
+++ b/Jellyfin.Server.Implementations/Users/UserManager.cs
@@ -269,12 +269,6 @@ namespace Jellyfin.Server.Implementations.Users
}
/// <inheritdoc/>
- public Task ResetEasyPassword(User user)
- {
- return ChangeEasyPassword(user, string.Empty, null);
- }
-
- /// <inheritdoc/>
public async Task ChangePassword(User user, string newPassword)
{
ArgumentNullException.ThrowIfNull(user);
@@ -286,25 +280,6 @@ namespace Jellyfin.Server.Implementations.Users
}
/// <inheritdoc/>
- public async Task ChangeEasyPassword(User user, string newPassword, string? newPasswordSha1)
- {
- if (newPassword is not null)
- {
- newPasswordSha1 = _cryptoProvider.CreatePasswordHash(newPassword).ToString();
- }
-
- if (string.IsNullOrWhiteSpace(newPasswordSha1))
- {
- throw new ArgumentNullException(nameof(newPasswordSha1));
- }
-
- user.EasyPassword = newPasswordSha1;
- await UpdateUserAsync(user).ConfigureAwait(false);
-
- await _eventManager.PublishAsync(new UserPasswordChangedEventArgs(user)).ConfigureAwait(false);
- }
-
- /// <inheritdoc/>
public UserDto GetUserDto(User user, string? remoteEndPoint = null)
{
var hasPassword = GetAuthenticationProvider(user).HasPassword(user);
@@ -315,7 +290,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 +806,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 9bf1e6b80..0186500a1 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/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs
index 37b4afcf3..6d6a532db 100644
--- a/MediaBrowser.Controller/Library/IUserManager.cs
+++ b/MediaBrowser.Controller/Library/IUserManager.cs
@@ -97,13 +97,6 @@ namespace MediaBrowser.Controller.Library
Task ResetPassword(User user);
/// <summary>
- /// Resets the easy password.
- /// </summary>
- /// <param name="user">The user.</param>
- /// <returns>Task.</returns>
- Task ResetEasyPassword(User user);
-
- /// <summary>
/// Changes the password.
/// </summary>
/// <param name="user">The user.</param>
@@ -112,15 +105,6 @@ namespace MediaBrowser.Controller.Library
Task ChangePassword(User user, string newPassword);
/// <summary>
- /// Changes the easy password.
- /// </summary>
- /// <param name="user">The user.</param>
- /// <param name="newPassword">New password to use.</param>
- /// <param name="newPasswordSha1">Hash of new password.</param>
- /// <returns>Task.</returns>
- Task ChangeEasyPassword(User user, string newPassword, string newPasswordSha1);
-
- /// <summary>
/// Gets the user dto.
/// </summary>
/// <param name="user">The user.</param>
diff --git a/MediaBrowser.Model/Dto/UserDto.cs b/MediaBrowser.Model/Dto/UserDto.cs
index 256d7b10f..05019741e 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.
/// </summary>
/// <value><c>true</c> if this instance has configured easy password; otherwise, <c>false</c>.</value>
+ [Obsolete("Easy Password has been replaced with Quick Connect")]
public bool HasConfiguredEasyPassword { get; set; }
/// <summary>