Files
My-KOPKB/fe/src/modules/user/composables/useImpersonate.ts
T

173 lines
4.6 KiB
TypeScript

import { computed, ref } from 'vue'
import { useRouter } from 'vue-router'
import Swal from 'sweetalert2'
import { useAuthStore } from '@/stores/auth'
import { getApiErrorMessage } from '@/core/utils/getApiErrorMessage'
import { resolvePostLoginRoute } from '@/modules/auth'
import { leaveImpersonation, takeImpersonation } from '../services/impersonate.service'
import type { UserListItem } from '../types/user.types'
const IMPERSONATE_PERMISSION = 'menyamar pengguna'
const DEVELOPER_ROLE = 'DEVELOPER'
function userCanImpersonate(): boolean {
const authStore = useAuthStore()
const roles = authStore.user?.roles ?? []
if (roles.some((role) => role.name === DEVELOPER_ROLE)) {
return true
}
const activeRole = authStore.activeRole
const roleWithPermissions = roles.find((role) => role.id === activeRole?.id)
return (
roleWithPermissions?.permissions?.some(
(permission) => permission.name === IMPERSONATE_PERMISSION,
) ?? false
)
}
function isImpersonateTargetVisible(target: UserListItem, currentUserId?: string): boolean {
if (!currentUserId || target.id === currentUserId) {
return false
}
return !target.roles?.some((role) => role.name === DEVELOPER_ROLE)
}
function targetCanBeImpersonated(target: UserListItem, currentUserId?: string): boolean {
if (!isImpersonateTargetVisible(target, currentUserId)) {
return false
}
return target.status === 'active'
}
export function useImpersonate() {
const authStore = useAuthStore()
const router = useRouter()
const loading = ref(false)
const impersonating = computed(() => authStore.isImpersonating)
const canImpersonate = computed(() => userCanImpersonate())
function showImpersonateButton(target: UserListItem): boolean {
return canImpersonate.value && isImpersonateTargetVisible(target, authStore.user?.id)
}
function canImpersonateUser(target: UserListItem): boolean {
return canImpersonate.value && targetCanBeImpersonated(target, authStore.user?.id)
}
function impersonateButtonTitle(target: UserListItem): string {
if (impersonating.value) {
return 'Anda sedang menyamar pengguna'
}
if (target.status !== 'active') {
return 'Hanya pengguna aktif boleh disamar'
}
return 'Menyamar sebagai pengguna'
}
async function refreshImpersonationStatus() {
await authStore.refreshImpersonationStatus()
}
async function impersonateUser(target: UserListItem) {
if (!canImpersonateUser(target) || loading.value || impersonating.value) {
return
}
const result = await Swal.fire({
title: 'Menyamar pengguna?',
text: `Anda akan log masuk sebagai "${target.name}".`,
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Ya, menyamar',
cancelButtonText: 'Batal',
reverseButtons: true,
})
if (!result.isConfirmed) {
return
}
loading.value = true
try {
const response = await takeImpersonation(target.id)
authStore.applySession(response)
authStore.isImpersonating = true
await Swal.fire({
toast: true,
position: 'top-end',
icon: 'success',
title: response.message,
showConfirmButton: false,
showCloseButton: true,
timer: 500,
})
await router.push(resolvePostLoginRoute(response.redirect_path))
} catch (error) {
await Swal.fire({
icon: 'error',
title: 'Gagal menyamar',
text: getApiErrorMessage(error, 'Tidak dapat menyamar sebagai pengguna ini.'),
})
} finally {
loading.value = false
}
}
async function stopImpersonation() {
if (!impersonating.value || loading.value) {
return
}
loading.value = true
try {
const response = await leaveImpersonation()
authStore.applySession(response)
authStore.isImpersonating = false
await Swal.fire({
toast: true,
position: 'top-end',
icon: 'success',
title: response.message,
showConfirmButton: false,
showCloseButton: true,
timer: 500,
})
await router.push(resolvePostLoginRoute(response.redirect_path))
} catch (error) {
await Swal.fire({
icon: 'error',
title: 'Gagal tamatkan penyamaran',
text: getApiErrorMessage(error, 'Tidak dapat kembali ke akaun asal.'),
})
} finally {
loading.value = false
}
}
return {
canImpersonate,
showImpersonateButton,
canImpersonateUser,
impersonateButtonTitle,
impersonating,
loading,
refreshImpersonationStatus,
impersonateUser,
stopImpersonation,
}
}