first init
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
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 targetCanBeImpersonated(target: UserListItem, currentUserId?: string): boolean {
|
||||
if (!currentUserId || target.id === currentUserId) {
|
||||
return false
|
||||
}
|
||||
|
||||
return !target.roles?.some((role) => role.name === DEVELOPER_ROLE)
|
||||
}
|
||||
|
||||
export function useImpersonate() {
|
||||
const authStore = useAuthStore()
|
||||
const router = useRouter()
|
||||
const loading = ref(false)
|
||||
|
||||
const impersonating = computed(() => authStore.isImpersonating)
|
||||
const canImpersonate = computed(() => userCanImpersonate())
|
||||
|
||||
function canImpersonateUser(target: UserListItem): boolean {
|
||||
return canImpersonate.value && targetCanBeImpersonated(target, authStore.user?.id)
|
||||
}
|
||||
|
||||
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: 2000,
|
||||
})
|
||||
|
||||
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: 2000,
|
||||
})
|
||||
|
||||
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,
|
||||
canImpersonateUser,
|
||||
impersonating,
|
||||
loading,
|
||||
refreshImpersonationStatus,
|
||||
impersonateUser,
|
||||
stopImpersonation,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user