Feature/Auth: implement user authentication #3

Merged
homeburger merged 48 commits from feature/auth into main 2026-03-22 20:52:22 -05:00
7 changed files with 28 additions and 29 deletions
Showing only changes of commit 109d5f88ea - Show all commits

View File

@@ -22,9 +22,9 @@ public class AuthController : ControllerBase {
public async Task<ActionResult> Register(RegisterDto dto) { public async Task<ActionResult> Register(RegisterDto dto) {
var user = new User { var user = new User {
Name = dto.Username, Name = dto.Username,
Email = "dummy@goofy.xyz", Email = dto.Email,
PasswordHash = BCrypt.Net.BCrypt.HashPassword(dto.Password), // TODO: secondary hashing stage in client PasswordHash = BCrypt.Net.BCrypt.HashPassword(dto.Password), // TODO: secondary hashing stage in client
Role = "admin (FOR NOW !!)", Role = "user",
CreatedAt = DateTime.UtcNow // yeah why not utc CreatedAt = DateTime.UtcNow // yeah why not utc
}; };

View File

@@ -1,15 +0,0 @@
public class RegisterDto {
public string Username { get; set; } = "";
public string Email { get; set; } = "";
public string Password { get; set; } = "";
}
public class LoginDto {
public string Username { get; set; } = "";
public string Password { get; set; } = "";
}

View File

@@ -7,7 +7,7 @@ public class User {
public string Name { get; set; } = ""; public string Name { get; set; } = "";
public string Email { get; set; } = ""; public string Email { get; set; } = "";
public string PasswordHash { get; set; } = ""; public string PasswordHash { get; set; } = "";
public string Role { get; set; } public string Role { get; set; } = "";
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
}; };

View File

@@ -3,11 +3,11 @@
// handles user registration, user logins, tokens, password reset, etc. // handles user registration, user logins, tokens, password reset, etc.
import api from "./axios.ts" import api from "./axios.ts"
import type { User } from "../models/User.ts"; import type { User, RegisterDto, LoginDto } from "../models/User.ts";
const API_URL: string = "/auth"; const API_URL: string = "/auth";
export const register = async (user: { username: string; email: string; password: string }) => { export const register = async (user: RegisterDto) => {
try { try {
const response = await api.post(`${API_URL}/register`, user); const response = await api.post(`${API_URL}/register`, user);
@@ -24,7 +24,7 @@ export const register = async (user: { username: string; email: string; password
} }
export const login = async (user: { username: string; password: string }) => { export const login = async (user: LoginDto ) => {
try { try {
const response = await api.post(`${API_URL}/login`, user); const response = await api.post(`${API_URL}/login`, user);

View File

@@ -1,5 +1,6 @@
// models are the data objects stored in the database. models defined here must match models defined in api/models // models are the data objects stored in the database. models defined here must match models defined in api/models
// dtos here must match the the dtos in api/src/Modelts/Dto.cs in name (case insensitive) (types are intermediately serialized to strings)
export interface User { export interface User {
id: number; id: number;
@@ -7,3 +8,14 @@ export interface User {
email: string; email: string;
password: string; password: string;
} }
export interface RegisterDto {
name: string;
email: string;
password: string;
}
export interface LoginDto {
name: string;
password: string;
}

View File

@@ -4,13 +4,14 @@
import { onMounted, reactive } from "vue"; import { onMounted, reactive } from "vue";
import { useRoute, useRouter } from "vue-router"; import { useRoute, useRouter } from "vue-router";
import type { LoginDto } from "../models/User.ts";
import * as authApi from "../api/AuthApi"; import * as authApi from "../api/AuthApi";
const router = useRouter(); const router = useRouter();
const user = reactive({ const user = reactive<LoginDto>({ // the template ensures type consistency
username: "", name: "",
password: "" password: "",
}); });
onMounted(() => { onMounted(() => {
@@ -37,7 +38,7 @@ async function login(): Promise<void> {
<h2>Login</h2> <h2>Login</h2>
<form @submit.prevent="login"> <form @submit.prevent="login">
<input v-model="user.username" placeholder="username" /> <input v-model="user.name" placeholder="username" />
<input v-model="user.password" type="password" placeholder="password" /> <input v-model="user.password" type="password" placeholder="password" />
<button type="submit">Submit</button> <button type="submit">Submit</button>

View File

@@ -4,14 +4,15 @@
import { onMounted, reactive } from "vue"; import { onMounted, reactive } from "vue";
import { useRoute, useRouter } from "vue-router"; import { useRoute, useRouter } from "vue-router";
import type { RegisterDto } from "../models/User.ts";
import * as authApi from "../api/AuthApi"; import * as authApi from "../api/AuthApi";
const router = useRouter(); const router = useRouter();
const user = reactive({ const user = reactive<RegisterDto>({ // the template ensures type consistency
username: "", name: "",
email: "", email: "",
password: "" password: "",
}); });
onMounted(() => { onMounted(() => {
@@ -39,7 +40,7 @@ async function register(): Promise<void> {
<h2>Register</h2> <h2>Register</h2>
<form @submit.prevent="register"> <form @submit.prevent="register">
<input v-model="user.username" placeholder="username" /> <input v-model="user.name" placeholder="username" />
<input v-model="user.email" placeholder="email" /> <input v-model="user.email" placeholder="email" />
<input v-model="user.password" placeholder="password" /> <input v-model="user.password" placeholder="password" />