diff --git a/Controllers/LoginController.cs b/Controllers/LoginController.cs index 31bc72f..80b41c3 100644 --- a/Controllers/LoginController.cs +++ b/Controllers/LoginController.cs @@ -75,12 +75,19 @@ public class LoginController( if (result.Errors.Any(e => e.PropertyName == "Password")) return Redirect("/register?error=Invalid password."); + + return Redirect("/register?error=An unexpected error has occurred."); } var user = await userService.CreateUser( dto.Username, dto.Password); + if (user is null) + { + return Redirect("/register?error=There was an issue registering the user."); + } + await loginService.LoginAsUser(user); return Redirect("/"); @@ -114,7 +121,7 @@ public class LoginController( [Route("change_password")] [HttpPost] [Authorize] - public async Task> ChangePassword( + public async Task> ChangePassword( [FromBody] PasswordChangeDto dto) { try @@ -122,7 +129,7 @@ public class LoginController( var user = await loginService.GetActiveUser(); if (!await userService.CheckPasswordForUser(user.Username, dto.OldPassword)) { - return TypedResults.Forbid(); + return TypedResults.Conflict(); } var validation = await passwordChangeValidator.ValidateAsync(dto); @@ -136,7 +143,7 @@ public class LoginController( } catch { - return TypedResults.Forbid(); + return TypedResults.Unauthorized(); } } diff --git a/Migrations/20250116072643_Adjust timestamp.Designer.cs b/Migrations/20250116072643_Adjust timestamp.Designer.cs new file mode 100644 index 0000000..57558c1 --- /dev/null +++ b/Migrations/20250116072643_Adjust timestamp.Designer.cs @@ -0,0 +1,88 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Mizuki.Database; + +#nullable disable + +namespace Mizuki.Migrations +{ + [DbContext(typeof(MizukiDbContext))] + [Migration("20250116072643_Adjust timestamp")] + partial class Adjusttimestamp + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "9.0.0"); + + modelBuilder.Entity("Mizuki.Database.Models.Upload", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("AuthorId") + .HasColumnType("TEXT"); + + b.Property("Filename") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OriginalFilename") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SizeInBytes") + .HasColumnType("INTEGER"); + + b.Property("TimeOfUpload") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.HasIndex("Filename") + .IsUnique(); + + b.ToTable("Uploads"); + }); + + modelBuilder.Entity("Mizuki.Database.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Mizuki.Database.Models.Upload", b => + { + b.HasOne("Mizuki.Database.Models.User", "Author") + .WithMany() + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Migrations/20250116072643_Adjust timestamp.cs b/Migrations/20250116072643_Adjust timestamp.cs new file mode 100644 index 0000000..d886182 --- /dev/null +++ b/Migrations/20250116072643_Adjust timestamp.cs @@ -0,0 +1,35 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Mizuki.Migrations +{ + /// + public partial class Adjusttimestamp : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "TimeOfUpload", + table: "Uploads", + type: "INTEGER", + nullable: false, + oldClrType: typeof(DateTimeOffset), + oldType: "TEXT"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "TimeOfUpload", + table: "Uploads", + type: "TEXT", + nullable: false, + oldClrType: typeof(long), + oldType: "INTEGER"); + } + } +} diff --git a/Migrations/MizukiDbContextModelSnapshot.cs b/Migrations/MizukiDbContextModelSnapshot.cs index 30ac0b9..99c3512 100644 --- a/Migrations/MizukiDbContextModelSnapshot.cs +++ b/Migrations/MizukiDbContextModelSnapshot.cs @@ -37,8 +37,8 @@ namespace Mizuki.Migrations b.Property("SizeInBytes") .HasColumnType("INTEGER"); - b.Property("TimeOfUpload") - .HasColumnType("TEXT"); + b.Property("TimeOfUpload") + .HasColumnType("INTEGER"); b.HasKey("Id"); diff --git a/Program.cs b/Program.cs index ecd4bae..a2f5db0 100644 --- a/Program.cs +++ b/Program.cs @@ -30,10 +30,11 @@ var app = builder.Build(); app.MapControllers(); app.MapFallbackToFile("index.html"); +app.UseStaticFiles(); app.UseAuthentication(); app.UseAuthorization(); app.MapRazorPages(); app.MapControllers(); -app.Run(); \ No newline at end of file +app.Run(); diff --git a/mizuki-frontend/src/components/PasswordChanger.vue b/mizuki-frontend/src/components/PasswordChanger.vue index bfe0639..419adcb 100644 --- a/mizuki-frontend/src/components/PasswordChanger.vue +++ b/mizuki-frontend/src/components/PasswordChanger.vue @@ -10,7 +10,7 @@ import {useToast} from "primevue/usetoast"; const toast = useToast(); const formResolver = (ev: FormResolverOptions): Record => { - const resp = { + const resp: Record = { errors: { CurrentPassword: [], Password: [], @@ -61,7 +61,7 @@ const onFormSubmit = async (event: FormSubmitEvent) => { severity: "error", detail: "Password didn't pass security validation." }); - } else if (resp.status == 403) { + } else if (resp.status == 419) { toast.add({ severity: "error", detail: "The old password was incorrect." diff --git a/mizuki-frontend/src/components/Uploader.vue b/mizuki-frontend/src/components/Uploader.vue index 3efdbdb..ad932d4 100644 --- a/mizuki-frontend/src/components/Uploader.vue +++ b/mizuki-frontend/src/components/Uploader.vue @@ -59,6 +59,14 @@ return `${formattedSize} ${sizes[i]}`; }; + + const copyToClipboard = async () => { + await navigator.clipboard.writeText(`http://localhost:5118/f/${filename.value}`); + toast.add({ + severity: "success", + detail: `Copied to clipboard!`, + }) + }; diff --git a/mizuki-frontend/src/views/RegisterView.vue b/mizuki-frontend/src/views/RegisterView.vue index 7e8498d..c2194fe 100644 --- a/mizuki-frontend/src/views/RegisterView.vue +++ b/mizuki-frontend/src/views/RegisterView.vue @@ -48,7 +48,7 @@ const onFormSubmit = (ev: FormSubmitEvent) => { }; const formResolver = (ev: FormResolverOptions): Record => { - const resp = { + const resp: Record = { errors: { Username: [], Password: [],