ADD:use token for check permission

This commit is contained in:
pqdong 2025-04-30 16:21:02 +08:00
parent 07eea0f484
commit 11be4d032c
5 changed files with 145 additions and 1 deletions

3
.gitignore vendored
View file

@ -32,4 +32,5 @@ coverage
/playwright-report/
/playwright/.cache/
# Webkit with playwright creates a salt file
salt
salt
package-lock.json

1
components.d.ts vendored
View file

@ -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']

View file

@ -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
View 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>

View file

@ -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;