diff --git a/api/src/Models/User.cs b/api/src/Models/User.cs index 17d0363..2a44e84 100644 --- a/api/src/Models/User.cs +++ b/api/src/Models/User.cs @@ -7,5 +7,7 @@ public class User { public string Name { get; set; } = ""; public string Email { get; set; } = ""; public string PasswordHash { get; set; } = ""; + public string Role { get; set; } + public DateTime CreatedAt { get; set; } }; diff --git a/client/src/api/UsersApi.ts b/client/src/api/UsersApi.ts index 150a63a..608b879 100644 --- a/client/src/api/UsersApi.ts +++ b/client/src/api/UsersApi.ts @@ -1,19 +1,12 @@ // services are kinda whatever, but in general its a good idea for all api calls to be within a service (at least thats how angular handles it) // this user service will handle all to <-> from the server when handling user objects -// should be injected with the http client (I think its axios ?) -import axios from "axios"; -import type {AxiosResponse } from "axios"; +import api from "./axios.ts" import type { User } from "../models/User.ts"; const API_URL: string = "/users"; -const baseUrl: string = import.meta.env.DEV ? import.meta.env.VITE_DEV_API_URL : "https://app.vxbard.net/api" // TODO: overarching api service -const api = axios.create({ - baseURL: baseUrl -}); - export const getUsers = () => api.get(`${API_URL}`); export const getUser = (id: number) => api.get(`${API_URL}/${id}`); diff --git a/client/src/models/User.ts b/client/src/models/User.ts index 03387ef..a5e3504 100644 --- a/client/src/models/User.ts +++ b/client/src/models/User.ts @@ -4,5 +4,6 @@ export interface User { id: number; name: string; - email: string + email: string; + password: string; } diff --git a/client/src/pages/UserForm.vue b/client/src/pages/UserForm.vue index 96510d3..75079bf 100644 --- a/client/src/pages/UserForm.vue +++ b/client/src/pages/UserForm.vue @@ -13,9 +13,10 @@ const route = useRoute(); const router = useRouter(); const user = ref({ - name: "", id: 0, + name: "", email: "", + password: "" }); const id: string | undefined = route.params.id as string | undefined diff --git a/client/src/pages/UsersList.vue b/client/src/pages/UsersList.vue index 0fb4214..342b4b9 100644 --- a/client/src/pages/UsersList.vue +++ b/client/src/pages/UsersList.vue @@ -2,14 +2,22 @@ \ No newline at end of file diff --git a/client/src/router/index.ts b/client/src/router/index.ts index e96dc27..dd201b8 100644 --- a/client/src/router/index.ts +++ b/client/src/router/index.ts @@ -2,21 +2,48 @@ // the router creates front-end endpoints and serves pages to them import { createRouter, createWebHistory } from "vue-router"; +import LoginForm from "../pages/LoginForm.vue"; +import RegisterForm from "../pages/RegisterForm.vue"; import UsersList from "../pages/UsersList.vue"; import UserForm from "../pages/UserForm.vue"; import index from "../pages/index.vue"; // link path to the page component const routes = [ - { path: "/", component: index }, - { path: "/users", component: UsersList }, - { path: "/user/new", component: UserForm }, - { path: "/user/:id", component: UserForm } + { path: "/", component: index }, + { path: "/login", component: LoginForm }, + { path: "/register", component: RegisterForm }, + { path: "/users", component: UsersList }, + { path: "/user/new", component: UserForm, meta: { requiresAuth: true } }, + { path: "/user/:id", component: UserForm, meta: { requiresAuth: true } } ]; // I really like this const router = createRouter({ - history: createWebHistory(import.meta.env.BASE_URL), - routes: routes, + history: createWebHistory(import.meta.env.BASE_URL), + routes: routes, +}); + +// intercept before routing +router.beforeEach((to, from, next) => { + + const token = localStorage.getItem("token"); + if(to.meta.requiresAuth && !token) { // if the page requires use to be signed in, they must have at least a token set + next("/login"); + } else { + next(); + } + // TODO: if they have a token, but invalid, it will still send them to the page (the api will catch non-authorized though) + // maybe have a "validate token" from the api and refresh it if valid + /* + } else { + bool authorizedUser = authApi.refreshToken(token); + if(authorizedUser) { + next(); + } else { + next("/login"); + } + } + */ }); export default router; diff --git a/client/src/stores/UsersStore.ts b/client/src/stores/UsersStore.ts index a4d4b01..1d78fb0 100644 --- a/client/src/stores/UsersStore.ts +++ b/client/src/stores/UsersStore.ts @@ -6,7 +6,7 @@ import { defineStore } from "pinia"; import type { User } from "../models/User.ts"; -import * as api from "../api/UsersApi"; +import * as usersApi from "../api/UsersApi"; interface UserState { users: User[]; @@ -23,24 +23,24 @@ export const useUsersStore = defineStore("users", { actions: { async fetchUsers() { this.loading = true; - const response = await api.getUsers(); + const response = await usersApi.getUsers(); this.users = response.data; this.loading = false; }, async addUser(user: User) { - const response = await api.createUser(user); + const response = await usersApi.createUser(user); this.users.push(response.data); }, async updateUser(id: number, user: User) { - await api.updateUser(id, user); + await usersApi.updateUser(id, user); const index = this.users.findIndex(i => i.id === id); this.users[index] = user; }, async removeUser(id: number) { - await api.deleteUser(id); + await usersApi.deleteUser(id); this.users = this.users.filter(i => i.id !== id); } }