Properly hash passwords
I can't believe this has gone unnoticed for so long. This will rehash all passwords upon startup using bcrypt.
This commit is contained in:
parent
00988bbc69
commit
ef2711c7f6
@ -12,6 +12,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
|
||||
<PackageReference Include="EntityFrameworkCore.Exceptions.Sqlite" Version="8.1.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.0-rc.2.23480.1" />
|
||||
|
572
GameDatabase/Migrations/20241024092832_ReHashPasswords.Designer.cs
generated
Normal file
572
GameDatabase/Migrations/20241024092832_ReHashPasswords.Designer.cs
generated
Normal file
@ -0,0 +1,572 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using GameDatabase.Context;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace GameDatabase.Migrations
|
||||
{
|
||||
[DbContext(typeof(TaikoDbContext))]
|
||||
[Migration("20241024092832_ReHashPasswords")]
|
||||
partial class ReHashPasswords
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.4");
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
|
||||
{
|
||||
b.Property<uint>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsWin")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "SongId", "Difficulty");
|
||||
|
||||
b.ToTable("AiScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiSectionScoreDatum", b =>
|
||||
{
|
||||
b.Property<uint>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("SectionIndex")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Crown")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DrumrollCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("GoodCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsWin")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("MissCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("OkCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Score")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "SongId", "Difficulty", "SectionIndex");
|
||||
|
||||
b.ToTable("AiSectionScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.Card", b =>
|
||||
{
|
||||
b.Property<string>("AccessCode")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("AccessCode");
|
||||
|
||||
b.HasIndex("Baid");
|
||||
|
||||
b.ToTable("Card", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.Credential", b =>
|
||||
{
|
||||
b.Property<uint>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Salt")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Baid");
|
||||
|
||||
b.ToTable("Credential", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
|
||||
{
|
||||
b.Property<uint>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DanId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("DanType")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(1);
|
||||
|
||||
b.Property<uint>("ArrivalSongCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ClearState")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(0u);
|
||||
|
||||
b.Property<uint>("ComboCountTotal")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SoulGaugeTotal")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "DanId", "DanType");
|
||||
|
||||
b.ToTable("DanScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanStageScoreDatum", b =>
|
||||
{
|
||||
b.Property<uint>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DanId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("DanType")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasDefaultValue(1);
|
||||
|
||||
b.Property<uint>("SongNumber")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BadCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ComboCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DrumrollCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("GoodCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("HighScore")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("OkCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("PlayScore")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("TotalHitCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "DanId", "DanType", "SongNumber");
|
||||
|
||||
b.ToTable("DanStageScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongBestDatum", b =>
|
||||
{
|
||||
b.Property<uint>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestCrown")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestRate")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestScore")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("BestScoreRank")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "SongId", "Difficulty");
|
||||
|
||||
b.ToTable("SongBestData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongPlayDatum", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ComboCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Crown")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("Difficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DrumrollCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("GoodCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("HitCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("MissCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("OkCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("PlayTime")
|
||||
.HasColumnType("datetime");
|
||||
|
||||
b.Property<uint>("Score")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ScoreRank")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ScoreRate")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("Skipped")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SongNumber")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Baid");
|
||||
|
||||
b.ToTable("SongPlayData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.Token", b =>
|
||||
{
|
||||
b.Property<uint>("Baid")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Id")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Baid", "Id");
|
||||
|
||||
b.ToTable("Tokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.UserDatum", b =>
|
||||
{
|
||||
b.Property<uint>("Baid")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("AchievementDisplayDifficulty")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("AiWinCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ColorBody")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ColorFace")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("ColorLimb")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("CostumeData")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CostumeFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("CurrentBody")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("CurrentFace")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("CurrentHead")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("CurrentKigurumi")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("CurrentPuchi")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("DifficultyPlayedArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("DifficultyPlayedCourse")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DifficultyPlayedSort")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DifficultyPlayedStar")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("DifficultySettingArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("DifficultySettingCourse")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DifficultySettingSort")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("DifficultySettingStar")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("DisplayAchievement")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("DisplayDan")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("FavoriteSongsArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("GenericInfoFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsAdmin")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsSkipOn")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsVoiceOn")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("LastPlayDatetime")
|
||||
.HasColumnType("datetime");
|
||||
|
||||
b.Property<uint>("LastPlayMode")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("MyDonName")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("MyDonNameLanguage")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("NotesPosition")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<short>("OptionSetting")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<uint>("SelectedToneId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TitleFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("TitlePlateId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ToneFlgArray")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UnlockedBody")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UnlockedFace")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UnlockedHead")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UnlockedKigurumi")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UnlockedPuchi")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UnlockedSongIdList")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Baid");
|
||||
|
||||
b.ToTable("UserData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiSectionScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.AiScoreDatum", "Parent")
|
||||
.WithMany("AiSectionScoreData")
|
||||
.HasForeignKey("Baid", "SongId", "Difficulty")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.Card", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.Credential", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanStageScoreDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.DanScoreDatum", "Parent")
|
||||
.WithMany("DanStageScoreData")
|
||||
.HasForeignKey("Baid", "DanId", "DanType")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongBestDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.SongPlayDatum", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.UserDatum", "Ba")
|
||||
.WithMany()
|
||||
.HasForeignKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Ba");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.Token", b =>
|
||||
{
|
||||
b.HasOne("GameDatabase.Entities.UserDatum", "Datum")
|
||||
.WithMany("Tokens")
|
||||
.HasForeignKey("Baid")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Datum");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
|
||||
{
|
||||
b.Navigation("AiSectionScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.DanScoreDatum", b =>
|
||||
{
|
||||
b.Navigation("DanStageScoreData");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.UserDatum", b =>
|
||||
{
|
||||
b.Navigation("Tokens");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
53
GameDatabase/Migrations/20241024092832_ReHashPasswords.cs
Normal file
53
GameDatabase/Migrations/20241024092832_ReHashPasswords.cs
Normal file
@ -0,0 +1,53 @@
|
||||
using BCrypt.Net;
|
||||
using GameDatabase.Context;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace GameDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ReHashPasswords : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
using var context = new TaikoDbContext();
|
||||
var credentials = context.Credentials.ToList();
|
||||
|
||||
foreach (var credential in credentials)
|
||||
{
|
||||
// Check if the password is empty or null
|
||||
if (!string.IsNullOrEmpty(credential.Password))
|
||||
{
|
||||
// Passwords are currenrly stored as a string containing Password + Salt encoded in base64 4 times.
|
||||
// This is unacceptable so we'll rehash everything with bcrypt.
|
||||
var decodedData = Encoding.UTF8.GetString(Convert.FromBase64String(credential.Password)); // First pass
|
||||
decodedData = Encoding.UTF8.GetString(Convert.FromBase64String(decodedData)); // Second pass
|
||||
decodedData = Encoding.UTF8.GetString(Convert.FromBase64String(decodedData)); // Third pass
|
||||
decodedData = Encoding.UTF8.GetString(Convert.FromBase64String(decodedData)); // Last pass, leaving us with plain text password + salt
|
||||
decodedData = decodedData.Substring(0, decodedData.Length - credential.Salt.Length); // Recovering plain text password
|
||||
|
||||
credential.Salt = BCrypt.Net.BCrypt.GenerateSalt(10);
|
||||
credential.Password = BCrypt.Net.BCrypt.HashPassword(decodedData, credential.Salt); // Hashing the pass properly this time
|
||||
Console.WriteLine("ReHashed password for baid " + credential.Baid + " (out of " + credentials.Count + " baids)");
|
||||
}
|
||||
}
|
||||
context.SaveChanges();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// On Down we reset all passes and salts for everyone.
|
||||
migrationBuilder.Sql(@"
|
||||
UPDATE Credential
|
||||
SET Password = '',
|
||||
Salt = ''
|
||||
");
|
||||
}
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ namespace TaikoLocalServer.Migrations
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.3");
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.4");
|
||||
|
||||
modelBuilder.Entity("GameDatabase.Entities.AiScoreDatum", b =>
|
||||
{
|
||||
|
@ -43,15 +43,7 @@ public class AuthController(IAuthService authService, IUserDatumService userDatu
|
||||
|
||||
private static string ComputeHash(string inputPassword, string salt)
|
||||
{
|
||||
var encDataByte = Encoding.UTF8.GetBytes(inputPassword + salt);
|
||||
var encodedData = Convert.ToBase64String(encDataByte);
|
||||
encDataByte = Encoding.UTF8.GetBytes(encodedData);
|
||||
encodedData = Convert.ToBase64String(encDataByte);
|
||||
encDataByte = Encoding.UTF8.GetBytes(encodedData);
|
||||
encodedData = Convert.ToBase64String(encDataByte);
|
||||
encDataByte = Encoding.UTF8.GetBytes(encodedData);
|
||||
encodedData = Convert.ToBase64String(encDataByte);
|
||||
return encodedData;
|
||||
return BCrypt.Net.BCrypt.HashPassword(inputPassword, salt);
|
||||
}
|
||||
|
||||
private static Totp MakeTotp(uint baid)
|
||||
@ -64,14 +56,7 @@ public class AuthController(IAuthService authService, IUserDatumService userDatu
|
||||
|
||||
private static string CreateSalt()
|
||||
{
|
||||
//Generate a cryptographic random number.
|
||||
var randomNumber = new byte[32];
|
||||
var rng = RandomNumberGenerator.Create();
|
||||
rng.GetBytes(randomNumber);
|
||||
var salt = Convert.ToBase64String(randomNumber);
|
||||
|
||||
// Return a Base64 string representation of the random number.
|
||||
return salt;
|
||||
return BCrypt.Net.BCrypt.GenerateSalt(10);
|
||||
}
|
||||
|
||||
private static bool VerifyOtp(string otp, uint baid)
|
||||
@ -150,6 +135,9 @@ public class AuthController(IAuthService authService, IUserDatumService userDatu
|
||||
if (credential.Password != "")
|
||||
return Unauthorized(new { message = "User Already Registered" });
|
||||
|
||||
if (password.Length <= 0)
|
||||
return Unauthorized(new { message = "Password Cannot Be Empty !" });
|
||||
|
||||
if (registerWithLastPlayTime)
|
||||
{
|
||||
var invited = false;
|
||||
@ -219,7 +207,10 @@ public class AuthController(IAuthService authService, IUserDatumService userDatu
|
||||
var hashedOldPassword = ComputeHash(oldPassword, credential.Salt);
|
||||
if (credential.Password != hashedOldPassword)
|
||||
return Unauthorized(new { message = "Wrong Old Password" });
|
||||
|
||||
|
||||
if (newPassword.Length <= 0)
|
||||
return Unauthorized(new { message = "Password Cannot Be Empty !" });
|
||||
|
||||
// Hash the new password with the salt
|
||||
var salt = CreateSalt();
|
||||
var hashedNewPassword = ComputeHash(newPassword, salt);
|
||||
|
@ -28,34 +28,35 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Templates\TemplateController.cs"/>
|
||||
<Compile Remove="Templates\TemplateController.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DotNetZip" Version="1.16.0"/>
|
||||
<PackageReference Include="MediatR" Version="12.2.0"/>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.4"/>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.4"/>
|
||||
<PackageReference Include="Microsoft.AspNetCore.ResponseCompression" Version="2.2.0"/>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.4"/>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.4"/>
|
||||
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
|
||||
<PackageReference Include="DotNetZip" Version="1.16.0" />
|
||||
<PackageReference Include="MediatR" Version="12.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.ResponseCompression" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.4">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Otp.NET" Version="1.4.0"/>
|
||||
<PackageReference Include="protobuf-net" Version="3.2.30"/>
|
||||
<PackageReference Include="protobuf-net.AspNetCore" Version="3.2.12"/>
|
||||
<PackageReference Include="Riok.Mapperly" Version="3.5.1"/>
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2-dev-00334"/>
|
||||
<PackageReference Include="Serilog.Expressions" Version="4.0.0"/>
|
||||
<PackageReference Include="Serilog.Sinks.File.Header" Version="1.0.2"/>
|
||||
<PackageReference Include="SharpZipLib" Version="1.4.2"/>
|
||||
<PackageReference Include="Swan.Core" Version="7.0.0-beta.2"/>
|
||||
<PackageReference Include="Swan.Logging" Version="6.0.2-beta.96"/>
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0"/>
|
||||
<PackageReference Include="Throw" Version="1.4.0"/>
|
||||
<PackageReference Include="Yoh.Text.Json.NamingPolicies" Version="1.1.2"/>
|
||||
<PackageReference Include="Otp.NET" Version="1.4.0" />
|
||||
<PackageReference Include="protobuf-net" Version="3.2.30" />
|
||||
<PackageReference Include="protobuf-net.AspNetCore" Version="3.2.12" />
|
||||
<PackageReference Include="Riok.Mapperly" Version="3.5.1" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2-dev-00334" />
|
||||
<PackageReference Include="Serilog.Expressions" Version="4.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File.Header" Version="1.0.2" />
|
||||
<PackageReference Include="SharpZipLib" Version="1.4.2" />
|
||||
<PackageReference Include="Swan.Core" Version="7.0.0-beta.2" />
|
||||
<PackageReference Include="Swan.Logging" Version="6.0.2-beta.96" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||
<PackageReference Include="Throw" Version="1.4.0" />
|
||||
<PackageReference Include="Yoh.Text.Json.NamingPolicies" Version="1.1.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@ -65,26 +66,26 @@
|
||||
<None Update="Certificates\root.pfx">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<Content Remove="Configurations\ServerSettings.json"/>
|
||||
<Content Remove="Configurations\ServerSettings.json" />
|
||||
<None Include="Configurations\AuthSettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Configurations\ServerSettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<Content Remove="Configurations\Database.json"/>
|
||||
<Content Remove="Configurations\Database.json" />
|
||||
<None Include="Configurations\Database.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<Content Remove="Configurations\DataSettings.json"/>
|
||||
<Content Remove="Configurations\DataSettings.json" />
|
||||
<None Include="Configurations\DataSettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<Content Remove="Configurations\Kestrel.json"/>
|
||||
<Content Remove="Configurations\Kestrel.json" />
|
||||
<None Include="Configurations\Kestrel.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<Content Remove="Configurations\Logging.json"/>
|
||||
<Content Remove="Configurations\Logging.json" />
|
||||
<None Include="Configurations\Logging.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
@ -199,8 +200,8 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\GameDatabase\GameDatabase.csproj"/>
|
||||
<ProjectReference Include="..\SharedProject\SharedProject.csproj"/>
|
||||
<ProjectReference Include="..\TaikoWebUI\TaikoWebUI.csproj"/>
|
||||
<ProjectReference Include="..\GameDatabase\GameDatabase.csproj" />
|
||||
<ProjectReference Include="..\SharedProject\SharedProject.csproj" />
|
||||
<ProjectReference Include="..\TaikoWebUI\TaikoWebUI.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
Loading…
Reference in New Issue
Block a user