180 lines
4.2 KiB
TypeScript
180 lines
4.2 KiB
TypeScript
/**
|
|
* 인증 상태 관리 composable
|
|
*/
|
|
|
|
interface User {
|
|
employeeId: number
|
|
employeeName: string
|
|
employeeEmail: string
|
|
employeePosition: string | null
|
|
roles?: string[] // 권한 코드 배열 추가
|
|
}
|
|
|
|
interface MenuItem {
|
|
menuId: number
|
|
menuCode: string
|
|
menuName: string
|
|
menuPath: string | null
|
|
menuIcon: string | null
|
|
parentMenuId: number | null
|
|
sortOrder: number
|
|
children: MenuItem[]
|
|
}
|
|
|
|
// 전역 상태
|
|
const currentUser = ref<User | null>(null)
|
|
const userMenus = ref<MenuItem[]>([])
|
|
const isLoading = ref(false)
|
|
|
|
export function useAuth() {
|
|
/**
|
|
* 현재 로그인 사용자 조회
|
|
*/
|
|
async function fetchCurrentUser(): Promise<User | null> {
|
|
try {
|
|
isLoading.value = true
|
|
const response = await $fetch<{ user: User | null }>('/api/auth/current-user')
|
|
currentUser.value = response.user
|
|
|
|
// 로그인된 경우 메뉴 정보도 가져오기
|
|
if (response.user) {
|
|
await fetchUserMenus()
|
|
} else {
|
|
userMenus.value = []
|
|
}
|
|
|
|
return response.user
|
|
} catch (error) {
|
|
currentUser.value = null
|
|
userMenus.value = []
|
|
return null
|
|
} finally {
|
|
isLoading.value = false
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 사용자 메뉴 조회
|
|
*/
|
|
async function fetchUserMenus(): Promise<void> {
|
|
try {
|
|
const response = await $fetch<{ menus: MenuItem[] }>('/api/auth/menu')
|
|
userMenus.value = response.menus
|
|
} catch (error) {
|
|
console.error('메뉴 조회 실패:', error)
|
|
userMenus.value = []
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 이메일+이름으로 로그인
|
|
*/
|
|
async function login(email: string, name: string): Promise<User> {
|
|
const response = await $fetch<{ user: User }>('/api/auth/login', {
|
|
method: 'POST',
|
|
body: { email, name }
|
|
})
|
|
currentUser.value = response.user
|
|
await fetchUserMenus()
|
|
return response.user
|
|
}
|
|
|
|
/**
|
|
* 기존 사용자 선택 로그인
|
|
*/
|
|
async function selectUser(employeeId: number): Promise<User> {
|
|
const response = await $fetch<{ user: User }>('/api/auth/select-user', {
|
|
method: 'POST',
|
|
body: { employeeId }
|
|
})
|
|
currentUser.value = response.user
|
|
await fetchUserMenus()
|
|
return response.user
|
|
}
|
|
|
|
/**
|
|
* 최근 로그인 사용자 목록
|
|
*/
|
|
async function getRecentUsers(): Promise<User[]> {
|
|
const response = await $fetch<{ users: User[] }>('/api/auth/recent-users')
|
|
return response.users
|
|
}
|
|
|
|
/**
|
|
* 로그아웃
|
|
*/
|
|
async function logout(): Promise<void> {
|
|
await $fetch('/api/auth/logout', { method: 'POST' })
|
|
currentUser.value = null
|
|
userMenus.value = []
|
|
}
|
|
|
|
/**
|
|
* 로그인 여부 확인
|
|
*/
|
|
const isLoggedIn = computed(() => currentUser.value !== null)
|
|
|
|
/**
|
|
* 특정 권한 보유 여부 확인
|
|
*/
|
|
function hasRole(roleCode: string): boolean {
|
|
return currentUser.value?.roles?.includes(roleCode) ?? false
|
|
}
|
|
|
|
/**
|
|
* 특정 메뉴 접근 가능 여부 확인
|
|
*/
|
|
function hasMenuAccess(menuCode: string): boolean {
|
|
const findMenu = (menus: MenuItem[]): boolean => {
|
|
for (const menu of menus) {
|
|
if (menu.menuCode === menuCode) return true
|
|
if (menu.children && findMenu(menu.children)) return true
|
|
}
|
|
return false
|
|
}
|
|
return findMenu(userMenus.value)
|
|
}
|
|
|
|
/**
|
|
* 특정 경로 접근 가능 여부 확인
|
|
*/
|
|
function hasPathAccess(path: string): boolean {
|
|
const findPath = (menus: MenuItem[]): boolean => {
|
|
for (const menu of menus) {
|
|
if (menu.menuPath && path.startsWith(menu.menuPath)) return true
|
|
if (menu.children && findPath(menu.children)) return true
|
|
}
|
|
return false
|
|
}
|
|
return findPath(userMenus.value)
|
|
}
|
|
|
|
/**
|
|
* 관리자 여부 (ROLE_ADMIN)
|
|
*/
|
|
const isAdmin = computed(() => hasRole('ROLE_ADMIN'))
|
|
|
|
/**
|
|
* 매니저 이상 여부 (ROLE_MANAGER 또는 ROLE_ADMIN)
|
|
*/
|
|
const isManager = computed(() => hasRole('ROLE_MANAGER') || hasRole('ROLE_ADMIN'))
|
|
|
|
return {
|
|
currentUser: readonly(currentUser),
|
|
userMenus: readonly(userMenus),
|
|
isLoading: readonly(isLoading),
|
|
isLoggedIn,
|
|
isAdmin,
|
|
isManager,
|
|
fetchCurrentUser,
|
|
fetchUserMenus,
|
|
login,
|
|
selectUser,
|
|
getRecentUsers,
|
|
logout,
|
|
hasRole,
|
|
hasMenuAccess,
|
|
hasPathAccess
|
|
}
|
|
}
|