finished the project.
This commit is contained in:
parent
d7e136a7c3
commit
c26f948d2c
8 changed files with 150 additions and 11 deletions
|
|
@ -75,12 +75,19 @@ public class LoginController(
|
||||||
|
|
||||||
if (result.Errors.Any(e => e.PropertyName == "Password"))
|
if (result.Errors.Any(e => e.PropertyName == "Password"))
|
||||||
return Redirect("/register?error=Invalid password.");
|
return Redirect("/register?error=Invalid password.");
|
||||||
|
|
||||||
|
return Redirect("/register?error=An unexpected error has occurred.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var user = await userService.CreateUser(
|
var user = await userService.CreateUser(
|
||||||
dto.Username,
|
dto.Username,
|
||||||
dto.Password);
|
dto.Password);
|
||||||
|
|
||||||
|
if (user is null)
|
||||||
|
{
|
||||||
|
return Redirect("/register?error=There was an issue registering the user.");
|
||||||
|
}
|
||||||
|
|
||||||
await loginService.LoginAsUser(user);
|
await loginService.LoginAsUser(user);
|
||||||
|
|
||||||
return Redirect("/");
|
return Redirect("/");
|
||||||
|
|
@ -114,7 +121,7 @@ public class LoginController(
|
||||||
[Route("change_password")]
|
[Route("change_password")]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public async Task<Results<Ok, BadRequest, ForbidHttpResult>> ChangePassword(
|
public async Task<Results<Ok, BadRequest, Conflict, UnauthorizedHttpResult>> ChangePassword(
|
||||||
[FromBody] PasswordChangeDto dto)
|
[FromBody] PasswordChangeDto dto)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
@ -122,7 +129,7 @@ public class LoginController(
|
||||||
var user = await loginService.GetActiveUser();
|
var user = await loginService.GetActiveUser();
|
||||||
if (!await userService.CheckPasswordForUser(user.Username, dto.OldPassword))
|
if (!await userService.CheckPasswordForUser(user.Username, dto.OldPassword))
|
||||||
{
|
{
|
||||||
return TypedResults.Forbid();
|
return TypedResults.Conflict();
|
||||||
}
|
}
|
||||||
|
|
||||||
var validation = await passwordChangeValidator.ValidateAsync(dto);
|
var validation = await passwordChangeValidator.ValidateAsync(dto);
|
||||||
|
|
@ -136,7 +143,7 @@ public class LoginController(
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
return TypedResults.Forbid();
|
return TypedResults.Unauthorized();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
88
Migrations/20250116072643_Adjust timestamp.Designer.cs
generated
Normal file
88
Migrations/20250116072643_Adjust timestamp.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
// <auto-generated />
|
||||||
|
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
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
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<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<Guid>("AuthorId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Filename")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("OriginalFilename")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<long>("SizeInBytes")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<long>("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<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PasswordHash")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
35
Migrations/20250116072643_Adjust timestamp.cs
Normal file
35
Migrations/20250116072643_Adjust timestamp.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Mizuki.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Adjusttimestamp : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AlterColumn<long>(
|
||||||
|
name: "TimeOfUpload",
|
||||||
|
table: "Uploads",
|
||||||
|
type: "INTEGER",
|
||||||
|
nullable: false,
|
||||||
|
oldClrType: typeof(DateTimeOffset),
|
||||||
|
oldType: "TEXT");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AlterColumn<DateTimeOffset>(
|
||||||
|
name: "TimeOfUpload",
|
||||||
|
table: "Uploads",
|
||||||
|
type: "TEXT",
|
||||||
|
nullable: false,
|
||||||
|
oldClrType: typeof(long),
|
||||||
|
oldType: "INTEGER");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -37,8 +37,8 @@ namespace Mizuki.Migrations
|
||||||
b.Property<long>("SizeInBytes")
|
b.Property<long>("SizeInBytes")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("TimeOfUpload")
|
b.Property<long>("TimeOfUpload")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,10 +30,11 @@ var app = builder.Build();
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
app.MapFallbackToFile("index.html");
|
app.MapFallbackToFile("index.html");
|
||||||
|
|
||||||
|
app.UseStaticFiles();
|
||||||
app.UseAuthentication();
|
app.UseAuthentication();
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
|
|
||||||
app.MapRazorPages();
|
app.MapRazorPages();
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import {useToast} from "primevue/usetoast";
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
const formResolver = (ev: FormResolverOptions): Record<string, any> => {
|
const formResolver = (ev: FormResolverOptions): Record<string, any> => {
|
||||||
const resp = {
|
const resp: Record<string, any> = {
|
||||||
errors: {
|
errors: {
|
||||||
CurrentPassword: [],
|
CurrentPassword: [],
|
||||||
Password: [],
|
Password: [],
|
||||||
|
|
@ -61,7 +61,7 @@ const onFormSubmit = async (event: FormSubmitEvent) => {
|
||||||
severity: "error",
|
severity: "error",
|
||||||
detail: "Password didn't pass security validation."
|
detail: "Password didn't pass security validation."
|
||||||
});
|
});
|
||||||
} else if (resp.status == 403) {
|
} else if (resp.status == 419) {
|
||||||
toast.add({
|
toast.add({
|
||||||
severity: "error",
|
severity: "error",
|
||||||
detail: "The old password was incorrect."
|
detail: "The old password was incorrect."
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,14 @@
|
||||||
|
|
||||||
return `${formattedSize} ${sizes[i]}`;
|
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!`,
|
||||||
|
})
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -117,9 +125,9 @@
|
||||||
<div class="space-y-3">
|
<div class="space-y-3">
|
||||||
<p>Your file has been uploaded and is now accessible at:</p>
|
<p>Your file has been uploaded and is now accessible at:</p>
|
||||||
<div class="p-5 bg-neutral-950 text-gray-50 rounded-2xl font-bold ">
|
<div class="p-5 bg-neutral-950 text-gray-50 rounded-2xl font-bold ">
|
||||||
https://localhost:5118/f/{{ filename }}
|
http://localhost:5118/f/{{ filename }}
|
||||||
</div>
|
</div>
|
||||||
<Button label="Click to copy" class="float-right"/>
|
<Button label="Click to copy" class="float-right" v-on:click.prevent="copyToClipboard"/>
|
||||||
</div>
|
</div>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ const onFormSubmit = (ev: FormSubmitEvent) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const formResolver = (ev: FormResolverOptions): Record<string, any> => {
|
const formResolver = (ev: FormResolverOptions): Record<string, any> => {
|
||||||
const resp = {
|
const resp: Record<string, any> = {
|
||||||
errors: {
|
errors: {
|
||||||
Username: [],
|
Username: [],
|
||||||
Password: [],
|
Password: [],
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue