feat: added an login page but the auth issue is still persisting, found a way to interprete the token the line is commneted in case it breaks code or needs a change
This commit is contained in:
		
							
								
								
									
										171
									
								
								front/MyINPulse-front/src/components/LoginComponent.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								front/MyINPulse-front/src/components/LoginComponent.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,171 @@ | ||||
| <script lang="ts" setup> | ||||
| import { onMounted } from "vue"; | ||||
| import { useRouter } from "vue-router"; | ||||
| import {jwtDecode} from "jwt-decode"; | ||||
| import { store } from "../main.ts"; | ||||
| import { callApi } from "@/services/api.ts"; | ||||
|  | ||||
| const router = useRouter(); | ||||
|  | ||||
| type TokenPayload = { | ||||
|   realm_access?: { | ||||
|     roles?: string[]; | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| onMounted(() => { | ||||
|   if (store.authenticated && store.user.token) { | ||||
|     try { | ||||
|       const decoded = jwtDecode<TokenPayload>(store.user.token); | ||||
|       const roles = decoded.realm_access?.roles || []; | ||||
|  | ||||
|       if (roles.includes("MyINPulse-admin")) { | ||||
|         router.push("/"); | ||||
|       } else if (roles.includes("entrepreneur")) { | ||||
|         router.push("/entrepreneur"); | ||||
|       } | ||||
|     } catch (err) { | ||||
|       console.error("Failed to decode token", err); | ||||
|     } | ||||
|   } | ||||
| }); | ||||
| </script> | ||||
|  | ||||
|  | ||||
| <template> | ||||
|     <error-wrapper></error-wrapper> | ||||
|     <div class="auth-container"> | ||||
|       <div class="auth-card"> | ||||
|         <h1>Bienvenue</h1> | ||||
|  | ||||
|         <div class="status" :class="store.authenticated ? 'success' : 'error'"> | ||||
|           <p> | ||||
|             {{ store.authenticated ? '✅ Authenticated' : '❌ Not Authenticated' }} | ||||
|           </p> | ||||
|         </div> | ||||
|  | ||||
|         <div class="actions"> | ||||
|           <button @click="store.login">Login</button> | ||||
|           <button @click="store.logout">Logout</button> | ||||
|           <button @click="store.signup">Signup-admin</button> | ||||
|           <button @click="store.signup">Signup-Entrepreneur</button> | ||||
|           <button @click="store.refreshUserToken">Refresh Token</button> | ||||
|         </div> | ||||
|  | ||||
|         <div class="token-section" v-if="store.authenticated"> | ||||
|           <p><strong>Access Token:</strong></p> | ||||
|           <pre>{{ store.user.token }}</pre> | ||||
|  | ||||
|           <p><strong>Refresh Token:</strong></p> | ||||
|           <pre>{{ store.user.refreshToken }}</pre> | ||||
|         </div> | ||||
|  | ||||
|         <div class="api-calls"> | ||||
|           <h2>Test API Calls</h2> | ||||
|           <button @click="callApi('random')">Call Entrepreneur API</button> | ||||
|           <button @click="callApi('random2')">Call Admin API</button> | ||||
|           <button @click="callApi('unauth/dev')">Call Unauth API</button> | ||||
|  | ||||
|           <div class="custom-call"> | ||||
|             <input v-model="customRequest" placeholder="Custom endpoint" /> | ||||
|             <button @click="callApi(customRequest)">Call</button> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
| </template> | ||||
|  | ||||
| <style scoped> | ||||
| .auth-container { | ||||
|   display: flex; | ||||
|   justify-content: center; | ||||
|   align-items: center; | ||||
|   padding: 3rem 1rem; | ||||
|   min-height: 100vh; | ||||
|   background-color: #eef1f5; | ||||
|   font-family: Arial, sans-serif; | ||||
| } | ||||
|  | ||||
| .auth-card { | ||||
|   background: white; | ||||
|   padding: 2rem; | ||||
|   border-radius: 12px; | ||||
|   box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); | ||||
|   width: 100%; | ||||
|   max-width: 600px; | ||||
| } | ||||
|  | ||||
| h1 { | ||||
|   text-align: center; | ||||
|   margin-bottom: 1rem; | ||||
|   color: #333; | ||||
| } | ||||
|  | ||||
| .status { | ||||
|   text-align: center; | ||||
|   margin-bottom: 1.5rem; | ||||
|   font-weight: bold; | ||||
| } | ||||
| .success { | ||||
|   color: green; | ||||
| } | ||||
| .error { | ||||
|   color: red; | ||||
| } | ||||
|  | ||||
| .actions { | ||||
|   display: flex; | ||||
|   flex-wrap: wrap; | ||||
|   gap: 1rem; | ||||
|   justify-content: center; | ||||
|   margin-bottom: 1.5rem; | ||||
| } | ||||
|  | ||||
| .actions button { | ||||
|   padding: 0.6rem 1rem; | ||||
|   background-color: #4a90e2; | ||||
|   border: none; | ||||
|   color: white; | ||||
|   border-radius: 8px; | ||||
|   cursor: pointer; | ||||
|   transition: background-color 0.2s; | ||||
| } | ||||
| .actions button:hover { | ||||
|   background-color: #357abd; | ||||
| } | ||||
|  | ||||
| .token-section pre { | ||||
|   background: #f6f8fa; | ||||
|   padding: 0.5rem; | ||||
|   overflow-x: auto; | ||||
|   border: 1px solid #ddd; | ||||
|   border-radius: 6px; | ||||
|   margin-bottom: 1rem; | ||||
|   font-size: 0.85rem; | ||||
| } | ||||
|  | ||||
| .api-calls { | ||||
|   margin-top: 2rem; | ||||
| } | ||||
| .api-calls h2 { | ||||
|   margin-bottom: 1rem; | ||||
|   color: #444; | ||||
|   font-size: 1.1rem; | ||||
| } | ||||
| .api-calls button { | ||||
|   margin-right: 0.5rem; | ||||
|   margin-bottom: 0.5rem; | ||||
| } | ||||
|  | ||||
| .custom-call { | ||||
|   margin-top: 1rem; | ||||
|   display: flex; | ||||
|   gap: 0.5rem; | ||||
| } | ||||
| .custom-call input { | ||||
|   flex: 1; | ||||
|   padding: 0.5rem; | ||||
|   border: 1px solid #ccc; | ||||
|   border-radius: 6px; | ||||
| } | ||||
| </style> | ||||
| @@ -3,7 +3,7 @@ | ||||
|         <div class="project-header"> | ||||
|             <div class="project-title"> | ||||
|                 <h2>{{ projectName }}</h2> | ||||
|                 <p>projet mis le: {{ creationDate }}</p> | ||||
|                 <p>Projet mis le: {{ creationDate }}</p> | ||||
|             </div> | ||||
|         <div class="project-button"> | ||||
|             <button id="accept" @click="acceptProject">Accepter</button> | ||||
|   | ||||
| @@ -11,7 +11,11 @@ const router = createRouter({ | ||||
|       // which is lazy-loaded when the route is visited. | ||||
|       component: () => import('../views/testComponent.vue'), | ||||
|     }, | ||||
|  | ||||
|     { | ||||
|       path: '/login', | ||||
|       name: 'login', | ||||
|       component: () => import('../components/LoginComponent.vue'), | ||||
|     }, | ||||
|     { | ||||
|       path: '/', | ||||
|       name: 'Admin-main', | ||||
|   | ||||
| @@ -54,7 +54,7 @@ const useAuthStore = defineStore("storeAuth", { | ||||
|         async logout() { | ||||
|             try { | ||||
|                 await keycloakService.CallLogout( | ||||
|                     import.meta.env.VITE_APP_URL + "/test" | ||||
|                     import.meta.env.VITE_APP_URL + "/login" //redirect to login page instead of test... | ||||
|                 ); | ||||
|                 await this.clearUserData(); | ||||
|             } catch (error) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user