From e7a14fe380596b38119ee398d6a5445d8bd3933a Mon Sep 17 00:00:00 2001 From: Dominic Villemure Date: Mon, 11 Mar 2024 12:16:13 -0400 Subject: [PATCH] Added client to call backend authentication logic --- .vscode/extensions.json | 7 ++- README.md | 2 +- src/components/HelloWorld.vue | 44 --------------- src/components/TheWelcome.vue | 88 ------------------------------ src/components/WelcomeItem.vue | 86 ----------------------------- src/layouts/DefaultLayout.vue | 26 ++++++--- src/main.js | 9 ++-- src/plugins/clientPlugin.js | 34 ++++++++++++ src/plugins/store/authStore.js | 55 +++++++++++++++++++ src/views/LoginView.vue | 99 ++++++++++++++++++++-------------- src/views/main/HomeView.vue | 57 ++++++++++++++++++-- 11 files changed, 233 insertions(+), 274 deletions(-) delete mode 100644 src/components/HelloWorld.vue delete mode 100644 src/components/TheWelcome.vue delete mode 100644 src/components/WelcomeItem.vue create mode 100644 src/plugins/clientPlugin.js create mode 100644 src/plugins/store/authStore.js diff --git a/.vscode/extensions.json b/.vscode/extensions.json index c0a6e5a..cf899f8 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,3 +1,6 @@ { - "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"] -} + "recommendations": [ + "Vue.volar", + "Vue.vscode-typescript-vue-plugin" + ] +} \ No newline at end of file diff --git a/README.md b/README.md index 7b23d92..4b1c5d4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Hutopia -This template should help get you started developing with Vue 3 in Vite. +Hutopia frontEnd. Using vue3 and vuetify3. ## Recommended IDE Setup diff --git a/src/components/HelloWorld.vue b/src/components/HelloWorld.vue deleted file mode 100644 index 5fb372c..0000000 --- a/src/components/HelloWorld.vue +++ /dev/null @@ -1,44 +0,0 @@ - - - - - diff --git a/src/components/TheWelcome.vue b/src/components/TheWelcome.vue deleted file mode 100644 index dab9536..0000000 --- a/src/components/TheWelcome.vue +++ /dev/null @@ -1,88 +0,0 @@ - - - diff --git a/src/components/WelcomeItem.vue b/src/components/WelcomeItem.vue deleted file mode 100644 index ac366d0..0000000 --- a/src/components/WelcomeItem.vue +++ /dev/null @@ -1,86 +0,0 @@ - - - diff --git a/src/layouts/DefaultLayout.vue b/src/layouts/DefaultLayout.vue index bfcff04..eb7e3d6 100644 --- a/src/layouts/DefaultLayout.vue +++ b/src/layouts/DefaultLayout.vue @@ -35,12 +35,16 @@ +
+ Hello, {{ user.email }} +
+ Logout @@ -50,10 +54,20 @@ - - \ No newline at end of file + @/plugins/store/authStore \ No newline at end of file diff --git a/src/main.js b/src/main.js index 98db279..e55acf4 100644 --- a/src/main.js +++ b/src/main.js @@ -3,24 +3,25 @@ import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' import router from './router' -import axios from 'axios' import '@mdi/font/css/materialdesignicons.css' import 'vuetify/styles' import { createVuetify } from 'vuetify' import * as components from 'vuetify/components' import * as directives from 'vuetify/directives' +import clientPlugin from './plugins/clientPlugin' const vuetify = createVuetify({ components, directives }); -axios.defaults.baseURL = 'http://127.0.0.1:8000'; - const app = createApp(App); +// Create an axios client preconfigured to the Hutopy API. +app.use(clientPlugin); + app.use(createPinia()); app.use(vuetify); -app.use(router, axios); +app.use(router); app.mount('#app') diff --git a/src/plugins/clientPlugin.js b/src/plugins/clientPlugin.js new file mode 100644 index 0000000..c3fac44 --- /dev/null +++ b/src/plugins/clientPlugin.js @@ -0,0 +1,34 @@ +import axios from "axios"; +import { inject } from 'vue'; + +const clientKey = Symbol('client'); + +export default { + install: (app) => { + const axiosInstance = axios.create({ + baseURL: 'https://localhost:5001/', + timeout: 5000, + }); + + axiosInstance.interceptors.request.use((config) => { + const token = localStorage.getItem('jwt'); + if (token) { + config.headers.Authorization = `Bearer ${token}`; + } + return config; + }, (error) => { + return Promise.reject(error); + }); + + app.provide(clientKey, axiosInstance); + console.log("client provided"); + } +}; + +export function useClient() { + const client = inject(clientKey); + if (!client) { + throw new Error('Axios instance is not provided'); + } + return client; +} \ No newline at end of file diff --git a/src/plugins/store/authStore.js b/src/plugins/store/authStore.js new file mode 100644 index 0000000..cf0fef0 --- /dev/null +++ b/src/plugins/store/authStore.js @@ -0,0 +1,55 @@ +import { defineStore } from 'pinia'; + +const baseUrl = '/api/Users'; + +export const useAuthStore = defineStore({ + id: 'auth', + state: () => ({ + user: null, + refreshTokenTimeout: null + }), + actions: { + async login(client, email, password) { + const requestBody = { + email: email, + password: password + }; + try { + const response = await client.post(`${baseUrl}/login`, requestBody) + this.user = { + accessToken: response.data.accessToken, + refreshToken: response.data.refreshToken, + email: email + } + localStorage.setItem('jwt', this.user.accessToken); + this.startRefreshTokenTimer(); + } catch (error) { + throw new Error('Login failed.') + } + + + + }, + logout() { + localStorage.setItem('jwt', ''); + this.stopRefreshTokenTimer(); + this.user = null; + + }, + async refreshToken(client) { + const response = await client.post(`${baseUrl}/refresh`, {}); + this.user.accessToken = response.accessToken; + localStorage.setItem('jwt', this.user.accessToken); + + + this.startRefreshTokenTimer(); + }, + startRefreshTokenTimer() { + const timeout = 50 * 1000; + this.refreshTokenTimeout = setTimeout(this.refreshToken, timeout); + }, + stopRefreshTokenTimer() { + clearTimeout(this.refreshTokenTimeout); + } + } +}); \ No newline at end of file diff --git a/src/views/LoginView.vue b/src/views/LoginView.vue index 698e5cb..1fb7010 100644 --- a/src/views/LoginView.vue +++ b/src/views/LoginView.vue @@ -1,47 +1,68 @@ -

Don't have an account ? Click - here to create one!

- - + \ No newline at end of file diff --git a/src/views/main/HomeView.vue b/src/views/main/HomeView.vue index 297dbcf..f2fb879 100644 --- a/src/views/main/HomeView.vue +++ b/src/views/main/HomeView.vue @@ -13,14 +13,63 @@ - - Button + + Get items + + Vous n'etes pas connecter ! + + + + + + + - +import { ref } from 'vue' +import { useClient } from '@/plugins/clientPlugin'; +import { useRouter } from 'vue-router' +const router = useRouter() +const client = useClient(); + +let itemList = ref([]); +let errorNoAccessSnackBar = ref(false); + +async function callBackend() { + try { + const response = await client.get('/api/TodoItems?ListId=1&PageNumber=1&PageSize=10'); + const responseItems = response.data.items; + const orderedResponseItems = responseItems.sort((a, b) => a.id - b.id); + console.log(orderedResponseItems); + itemList.value = orderedResponseItems + + } catch (error) { + errorNoAccessSnackBar.value = true; + console.log(error); + } +} + +const goToLoginPage = () => { + router.push('/login'); +} + + + \ No newline at end of file