preliminary frontend for ther auth api
This commit is contained in:
@@ -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; }
|
||||
|
||||
};
|
||||
|
||||
@@ -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<User[]>(`${API_URL}`);
|
||||
|
||||
export const getUser = (id: number) => api.get<User>(`${API_URL}/${id}`);
|
||||
|
||||
@@ -4,5 +4,6 @@
|
||||
export interface User {
|
||||
id: number;
|
||||
name: string;
|
||||
email: string
|
||||
email: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
@@ -13,9 +13,10 @@ const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const user = ref<User>({
|
||||
name: "",
|
||||
id: 0,
|
||||
name: "",
|
||||
email: "",
|
||||
password: ""
|
||||
});
|
||||
|
||||
const id: string | undefined = route.params.id as string | undefined
|
||||
|
||||
@@ -2,14 +2,22 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import { onMounted } from "vue"
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { useUsersStore } from "../stores/UsersStore.ts"
|
||||
import * as authApi from "../api/AuthApi";
|
||||
|
||||
const store = useUsersStore()
|
||||
const router = useRouter();
|
||||
|
||||
onMounted(() => {
|
||||
store.fetchUsers()
|
||||
})
|
||||
|
||||
function logout() {
|
||||
authApi.logout();
|
||||
router.push("/login");
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -31,5 +39,6 @@ onMounted(() => {
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button @click="logout()">Logout</button>
|
||||
</div>
|
||||
</template>
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user