优化构架
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
export type RouteAccessDecision =
|
||||
| { type: 'allow' }
|
||||
| { type: 'login'; redirect: string }
|
||||
| { type: 'forbidden'; from: string }
|
||||
|
||||
export interface RouteAccessInput {
|
||||
requiresAuth?: boolean
|
||||
isAuthenticated: boolean
|
||||
fullPath: string
|
||||
permission?: string
|
||||
hasPermission: boolean
|
||||
}
|
||||
|
||||
export interface PreviewTargetInput {
|
||||
currentPath: string
|
||||
currentPermission?: string
|
||||
candidateCodes: ReadonlySet<string>
|
||||
firstPath: string | null
|
||||
}
|
||||
|
||||
export function sanitizeInternalPath(value: unknown): string {
|
||||
if (
|
||||
typeof value !== 'string'
|
||||
|| !value.startsWith('/')
|
||||
|| value[1] === '/'
|
||||
|| value[1] === '\\'
|
||||
|| /[\u0000-\u001F\u007F]/.test(value)
|
||||
) return '/'
|
||||
return value
|
||||
}
|
||||
|
||||
export function decideRouteAccess(input: RouteAccessInput): RouteAccessDecision {
|
||||
if (input.requiresAuth && !input.isAuthenticated) {
|
||||
return { type: 'login', redirect: sanitizeInternalPath(input.fullPath) }
|
||||
}
|
||||
if (input.permission && !input.hasPermission) {
|
||||
return { type: 'forbidden', from: sanitizeInternalPath(input.fullPath) }
|
||||
}
|
||||
return { type: 'allow' }
|
||||
}
|
||||
|
||||
export function resolvePreviewTarget(input: PreviewTargetInput): string | null {
|
||||
if (input.currentPath === '/403') return input.firstPath ?? '/403'
|
||||
if (input.currentPermission && !input.candidateCodes.has(input.currentPermission)) {
|
||||
return input.firstPath ?? '/403'
|
||||
}
|
||||
return null
|
||||
}
|
||||
Reference in New Issue
Block a user