fix(auth): 完善权限控制与强制改密流程
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
|
||||
import ClinicalLayout from '@/layouts/ClinicalLayout.vue'
|
||||
import ChangePasswordView from '@/views/auth/ChangePasswordView.vue'
|
||||
import ForbiddenView from '@/views/auth/ForbiddenView.vue'
|
||||
import LoginView from '@/views/auth/LoginView.vue'
|
||||
import DocumentPermissionsView from '@/views/management/document-permissions/index.vue'
|
||||
import DocumentsView from '@/views/management/documents/index.vue'
|
||||
@@ -11,6 +13,23 @@ import ConsentTasksView from '@/views/workbench/signing/index.vue'
|
||||
import DashboardView from '@/views/workbench/home/index.vue'
|
||||
import { useLoginStore } from '@/stores/login'
|
||||
import { readStoredAuthSession } from '@/utils/auth-storage'
|
||||
import { mockFlags } from '@/utils/mock-flags'
|
||||
|
||||
const authorizedLandingRoutes = [
|
||||
{ name: 'workbench-home', permission: 'sign:task:query' },
|
||||
{ name: 'workbench-signing', permission: 'sign:task:query' },
|
||||
{ name: 'management-documents', permission: 'sign:template:query' },
|
||||
{ name: 'management-reports', permission: 'report:signing:query' },
|
||||
{ name: 'management-users', permission: 'system:user:query' },
|
||||
{ name: 'management-document-permissions', permission: 'sign:template:permission:query' },
|
||||
] as const
|
||||
|
||||
function firstAuthorizedRoute(loginStore: ReturnType<typeof useLoginStore>) {
|
||||
return (
|
||||
authorizedLandingRoutes.find((route) => loginStore.hasPermission(route.permission))?.name ??
|
||||
'forbidden'
|
||||
)
|
||||
}
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
@@ -21,6 +40,18 @@ const router = createRouter({
|
||||
component: LoginView,
|
||||
meta: { title: '登录' },
|
||||
},
|
||||
{
|
||||
path: '/change-password',
|
||||
name: 'change-password',
|
||||
component: ChangePasswordView,
|
||||
meta: { title: '修改密码', requiresAuth: true },
|
||||
},
|
||||
{
|
||||
path: '/forbidden',
|
||||
name: 'forbidden',
|
||||
component: ForbiddenView,
|
||||
meta: { title: '无访问权限', requiresAuth: true },
|
||||
},
|
||||
{
|
||||
path: '/',
|
||||
name: 'clinical',
|
||||
@@ -36,13 +67,13 @@ const router = createRouter({
|
||||
path: 'home',
|
||||
name: 'workbench-home',
|
||||
component: DashboardView,
|
||||
meta: { title: '首页', group: '工作台' },
|
||||
meta: { title: '首页', group: '工作台', permission: 'sign:task:query' },
|
||||
},
|
||||
{
|
||||
path: 'signing',
|
||||
name: 'workbench-signing',
|
||||
component: ConsentTasksView,
|
||||
meta: { title: '签署工作台', group: '工作台' },
|
||||
meta: { title: '签署工作台', group: '工作台', permission: 'sign:task:query' },
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -54,13 +85,13 @@ const router = createRouter({
|
||||
path: 'documents',
|
||||
name: 'management-documents',
|
||||
component: DocumentsView,
|
||||
meta: { title: '文档库管理', group: '管理' },
|
||||
meta: { title: '文档库管理', group: '管理', permission: 'sign:template:query' },
|
||||
},
|
||||
{
|
||||
path: 'reports',
|
||||
name: 'management-reports',
|
||||
component: ReportsView,
|
||||
meta: { title: '报表分析', group: '管理' },
|
||||
meta: { title: '报表分析', group: '管理', permission: 'report:signing:query' },
|
||||
},
|
||||
{
|
||||
path: 'users',
|
||||
@@ -101,7 +132,7 @@ const router = createRouter({
|
||||
],
|
||||
})
|
||||
|
||||
router.beforeEach((to) => {
|
||||
router.beforeEach(async (to) => {
|
||||
const loginStore = useLoginStore()
|
||||
|
||||
if (to.name === 'login' && loginStore.isLoggedIn) {
|
||||
@@ -110,7 +141,11 @@ router.beforeEach((to) => {
|
||||
return true
|
||||
}
|
||||
|
||||
return { name: 'workbench-home' }
|
||||
return {
|
||||
name: loginStore.user?.passwordChangeRequired
|
||||
? 'change-password'
|
||||
: firstAuthorizedRoute(loginStore),
|
||||
}
|
||||
}
|
||||
|
||||
if (to.meta.requiresAuth && !loginStore.isLoggedIn) {
|
||||
@@ -121,21 +156,34 @@ router.beforeEach((to) => {
|
||||
}
|
||||
|
||||
if (to.meta.requiresAuth) {
|
||||
return loginStore
|
||||
.ensureCurrentUser()
|
||||
.then(() => {
|
||||
const requiredPermission = to.meta.permission as string | string[] | undefined
|
||||
try {
|
||||
const user = await loginStore.ensureCurrentUser()
|
||||
|
||||
if (requiredPermission && !loginStore.hasPermission(requiredPermission)) {
|
||||
return { name: 'workbench-home' }
|
||||
}
|
||||
if (user?.passwordChangeRequired && to.name !== 'change-password') {
|
||||
return { name: 'change-password' }
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
.catch(() => ({
|
||||
if (!user?.passwordChangeRequired && to.name === 'change-password') {
|
||||
return { name: firstAuthorizedRoute(loginStore) }
|
||||
}
|
||||
|
||||
if (to.name === 'management-settings' && !mockFlags.settings) {
|
||||
return { name: 'forbidden' }
|
||||
}
|
||||
|
||||
const requiredPermission = to.meta.permission as string | string[] | undefined
|
||||
if (requiredPermission && !loginStore.hasPermission(requiredPermission)) {
|
||||
return { name: firstAuthorizedRoute(loginStore) }
|
||||
}
|
||||
|
||||
return true
|
||||
} catch {
|
||||
loginStore.clearSession()
|
||||
return {
|
||||
name: 'login',
|
||||
query: { redirect: to.fullPath },
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
Reference in New Issue
Block a user