ADD:use token for check permission
This commit is contained in:
		
							parent
							
								
									07eea0f484
								
							
						
					
					
						commit
						11be4d032c
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -33,3 +33,4 @@ coverage | ||||
| /playwright/.cache/ | ||||
| # Webkit with playwright creates a salt file | ||||
| salt | ||||
| package-lock.json | ||||
|  | ||||
							
								
								
									
										1
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -118,6 +118,7 @@ declare module '@vue/runtime-core' { | ||||
|     KeycodeInfo: typeof import('./src/tools/keycode-info/keycode-info.vue')['default'] | ||||
|     ListConverter: typeof import('./src/tools/list-converter/list-converter.vue')['default'] | ||||
|     LocaleSelector: typeof import('./src/modules/i18n/components/locale-selector.vue')['default'] | ||||
|     Login: typeof import('./src/pages/Login.vue')['default'] | ||||
|     LoremIpsumGenerator: typeof import('./src/tools/lorem-ipsum-generator/lorem-ipsum-generator.vue')['default'] | ||||
|     MacAddressGenerator: typeof import('./src/tools/mac-address-generator/mac-address-generator.vue')['default'] | ||||
|     MacAddressLookup: typeof import('./src/tools/mac-address-lookup/mac-address-lookup.vue')['default'] | ||||
|  | ||||
| @ -27,6 +27,12 @@ export const config = figue({ | ||||
|       default: 'development', | ||||
|       env: 'VITE_VERCEL_ENV', | ||||
|     }, | ||||
|     token: { | ||||
|       doc: 'Application token', | ||||
|       format: 'string', | ||||
|       default: '', | ||||
|       env: 'VITE_TOKEN', | ||||
|     }, | ||||
|   }, | ||||
|   plausible: { | ||||
|     isTrackerEnabled: { | ||||
|  | ||||
							
								
								
									
										120
									
								
								src/pages/Login.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								src/pages/Login.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,120 @@ | ||||
| <script setup lang="ts"> | ||||
| import { ref } from 'vue'; | ||||
| import { config } from '@/config'; | ||||
| 
 | ||||
| const token = ref(''); | ||||
| 
 | ||||
| async function handleLogin() { | ||||
|   if (config.app.token === token.value) { | ||||
|     localStorage.setItem('isLoggedIn', 'true'); | ||||
|     window.location.href = `${window.location.protocol}//${window.location.host}/`; | ||||
|   } else { | ||||
|     alert('Invalid Token'); | ||||
|   } | ||||
| } | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|   <div class="login-container"> | ||||
|     <div class="login-card"> | ||||
|       <h1 class="login-title">Login</h1> | ||||
|       <form @submit.prevent="handleLogin" class="login-form"> | ||||
|         <div class="form-group"> | ||||
|           <label for="token" class="form-label">Token:</label> | ||||
|           <input | ||||
|             id="token" | ||||
|             v-model="token" | ||||
|             type="text" | ||||
|             required | ||||
|             class="form-input" | ||||
|             placeholder="Enter your access token" | ||||
|           /> | ||||
|         </div> | ||||
|         <button type="submit" class="login-button">Login</button> | ||||
|       </form> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| .login-container { | ||||
|   display: flex; | ||||
|   justify-content: center; | ||||
|   align-items: center; | ||||
|   min-height: 100vh; | ||||
|   background-color: #f5f5f5; /* 浅灰色背景,与截图一致 */ | ||||
|   padding: 20px; | ||||
| } | ||||
| 
 | ||||
| .login-card { | ||||
|   background: white; | ||||
|   border-radius: 8px; | ||||
|   box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); | ||||
|   padding: 40px; | ||||
|   width: 100%; | ||||
|   max-width: 400px; | ||||
| } | ||||
| 
 | ||||
| .login-title { | ||||
|   color: #2c3e50; | ||||
|   text-align: center; | ||||
|   margin-bottom: 30px; | ||||
|   font-size: 24px; | ||||
|   font-weight: 600; | ||||
| } | ||||
| 
 | ||||
| .login-form { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   gap: 20px; | ||||
| } | ||||
| 
 | ||||
| .form-group { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   gap: 8px; | ||||
| } | ||||
| 
 | ||||
| .form-label { | ||||
|   color: #2c3e50; | ||||
|   font-size: 14px; | ||||
|   font-weight: 500; | ||||
| } | ||||
| 
 | ||||
| .form-input { | ||||
|   padding: 12px 16px; | ||||
|   border: 1px solid #e0e0e0; | ||||
|   border-radius: 6px; | ||||
|   font-size: 14px; | ||||
|   transition: border-color 0.3s; | ||||
| } | ||||
| 
 | ||||
| .form-input:focus { | ||||
|   outline: none; | ||||
|   border-color: #4CAF50; /* 深绿色,与导航栏渐变一致 */ | ||||
|   box-shadow: 0 0 0 2px rgba(76, 175, 80, 0.2); | ||||
| } | ||||
| 
 | ||||
| .login-button { | ||||
|   background: linear-gradient(135deg, #4CAF50, #81C784); /* 与导航栏相似的渐变 */ | ||||
|   color: white; | ||||
|   border: none; | ||||
|   border-radius: 6px; | ||||
|   padding: 12px; | ||||
|   font-size: 16px; | ||||
|   font-weight: 500; | ||||
|   cursor: pointer; | ||||
|   transition: all 0.3s; | ||||
|   margin-top: 10px; | ||||
| } | ||||
| 
 | ||||
| .login-button:hover { | ||||
|   background: linear-gradient(135deg, #3e8e41, #66BB6A); | ||||
|   transform: translateY(-2px); | ||||
|   box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); | ||||
| } | ||||
| 
 | ||||
| .login-button:active { | ||||
|   transform: translateY(0); | ||||
| } | ||||
| </style> | ||||
| @ -26,6 +26,11 @@ const router = createRouter({ | ||||
|       name: 'home', | ||||
|       component: HomePage, | ||||
|     }, | ||||
|     { | ||||
|       path: '/login', | ||||
|       name: 'login', | ||||
|       component: () => import('./pages/Login.vue'), | ||||
|     }, | ||||
|     { | ||||
|       path: '/about', | ||||
|       name: 'about', | ||||
| @ -38,4 +43,15 @@ const router = createRouter({ | ||||
|   ], | ||||
| }); | ||||
| 
 | ||||
| if (config.app.token){ | ||||
|   router.beforeEach((to, from, next) => { | ||||
|     const isLoggedIn = localStorage.getItem('isLoggedIn') === 'true'; | ||||
|     if (to.path !== '/login' && !isLoggedIn) { | ||||
|       next('/login'); | ||||
|     } else { | ||||
|       next(); | ||||
|     } | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| export default router; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user