chore: redirect back to login page for deactivated users

This commit is contained in:
Feng Yue
2025-08-13 20:13:32 +08:00
parent aa86e062f1
commit bb60df8b41
4 changed files with 57 additions and 5 deletions

View File

@@ -447,10 +447,19 @@ class LdapService {
// 6. 创建或更新本地用户 // 6. 创建或更新本地用户
const user = await userService.createOrUpdateUser(userInfo) const user = await userService.createOrUpdateUser(userInfo)
// 7. 记录登录 // 7. 检查用户是否被禁用
if (!user.isActive) {
logger.security(`🔒 Disabled user LDAP login attempt: ${username} from LDAP authentication`)
return {
success: false,
message: 'Your account has been disabled. Please contact administrator.'
}
}
// 8. 记录登录
await userService.recordUserLogin(user.id) await userService.recordUserLogin(user.id)
// 8. 创建用户会话 // 9. 创建用户会话
const sessionToken = await userService.createUserSession(user.id) const sessionToken = await userService.createUserSession(user.id)
logger.info(`✅ LDAP authentication successful for user: ${username}`) logger.info(`✅ LDAP authentication successful for user: ${username}`)

View File

@@ -5,6 +5,7 @@ import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import 'element-plus/dist/index.css' import 'element-plus/dist/index.css'
import App from './App.vue' import App from './App.vue'
import router from './router' import router from './router'
import { useUserStore } from './stores/user'
import './assets/styles/main.css' import './assets/styles/main.css'
import './assets/styles/global.css' import './assets/styles/global.css'
@@ -23,5 +24,9 @@ app.use(ElementPlus, {
locale: zhCn locale: zhCn
}) })
// 设置axios拦截器
const userStore = useUserStore()
userStore.setupAxiosInterceptors()
// 挂载应用 // 挂载应用
app.mount('#app') app.mount('#app')

View File

@@ -169,10 +169,20 @@ router.beforeEach(async (to, from, next) => {
if (to.meta.requiresUserAuth) { if (to.meta.requiresUserAuth) {
if (!userStore.isAuthenticated) { if (!userStore.isAuthenticated) {
// 尝试检查本地存储的认证信息 // 尝试检查本地存储的认证信息
try {
const isUserLoggedIn = await userStore.checkAuth() const isUserLoggedIn = await userStore.checkAuth()
if (!isUserLoggedIn) { if (!isUserLoggedIn) {
return next('/user-login') return next('/user-login')
} }
} catch (error) {
// If the error is about disabled account, redirect to login with error
if (error.message && error.message.includes('disabled')) {
// Import showToast to display the error
const { showToast } = await import('@/utils/toast')
showToast(error.message, 'error')
}
return next('/user-login')
}
} }
return next() return next()
} }

View File

@@ -1,5 +1,6 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import axios from 'axios' import axios from 'axios'
import { showToast } from '@/utils/toast'
const API_BASE = '/users' const API_BASE = '/users'
@@ -104,8 +105,13 @@ export const useUserStore = defineStore('user', {
return response.data.user return response.data.user
} }
} catch (error) { } catch (error) {
if (error.response?.status === 401) { if (error.response?.status === 401 || error.response?.status === 403) {
// 401: Invalid/expired session, 403: Account disabled
this.clearAuth() this.clearAuth()
// If it's a disabled account error, throw a specific error
if (error.response?.status === 403) {
throw new Error(error.response.data?.message || 'Your account has been disabled')
}
} }
throw error throw error
} }
@@ -184,6 +190,28 @@ export const useUserStore = defineStore('user', {
if (this.sessionToken) { if (this.sessionToken) {
axios.defaults.headers.common['x-user-token'] = this.sessionToken axios.defaults.headers.common['x-user-token'] = this.sessionToken
} }
},
// 🔧 设置axios拦截器
setupAxiosInterceptors() {
// Response interceptor to handle disabled user responses globally
axios.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 403) {
const message = error.response.data?.message
if (message && (message.includes('disabled') || message.includes('Account disabled'))) {
this.clearAuth()
showToast(message, 'error')
// Redirect to login page
if (window.location.pathname !== '/user-login') {
window.location.href = '/user-login'
}
}
}
return Promise.reject(error)
}
)
} }
} }
}) })