mirror of
https://github.com/Bubka/2FAuth.git
synced 2025-08-09 05:54:34 +02:00
Add authentications log
This commit is contained in:
90
resources/js/components/AccessLogViewer.vue
Normal file
90
resources/js/components/AccessLogViewer.vue
Normal file
@ -0,0 +1,90 @@
|
||||
<script setup>
|
||||
import SearchBox from '@/components/SearchBox.vue'
|
||||
import { useNotifyStore } from '@/stores/notify'
|
||||
import userService from '@/services/userService'
|
||||
import { FontAwesomeLayers } from '@fortawesome/vue-fontawesome'
|
||||
|
||||
const notify = useNotifyStore()
|
||||
|
||||
const props = defineProps({
|
||||
userId: [Number, String],
|
||||
lastOnly: Boolean,
|
||||
showSearch: Boolean
|
||||
})
|
||||
|
||||
const authentications = ref([])
|
||||
const isFetching = ref(false)
|
||||
const searched = ref('')
|
||||
|
||||
const visibleAuthentications = computed(() => {
|
||||
return authentications.value.filter(authentication => {
|
||||
return JSON.stringify(authentication)
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.includes(searched.value);
|
||||
})
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
getAuthentications()
|
||||
})
|
||||
|
||||
/**
|
||||
* Gets user authentication logs
|
||||
*/
|
||||
function getAuthentications() {
|
||||
isFetching.value = true
|
||||
let limit = props.lastOnly ? 3 : false
|
||||
|
||||
userService.getauthentications(props.userId, limit, {returnError: true})
|
||||
.then(response => {
|
||||
authentications.value = response.data
|
||||
})
|
||||
.catch(error => {
|
||||
notify.error(error)
|
||||
})
|
||||
.finally(() => {
|
||||
isFetching.value = false
|
||||
})
|
||||
}
|
||||
|
||||
const deviceIcon = (device) => {
|
||||
switch (device) {
|
||||
case "phone":
|
||||
return 'mobile-screen'
|
||||
case "tablet":
|
||||
return 'tablet-screen-button'
|
||||
default:
|
||||
return 'display'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<SearchBox v-if="props.showSearch" v-model:keyword="searched" :hasNoBackground="true" />
|
||||
<div v-if="visibleAuthentications.length > 0">
|
||||
<div v-for="authentication in visibleAuthentications" :key="authentication.id" class="list-item is-size-6 is-size-7-mobile has-text-grey is-flex is-justify-content-space-between">
|
||||
<div>
|
||||
<div >
|
||||
<span v-if="authentication.login_successful" v-html="$t('admin.successful_login_on', { login_at: authentication.login_at })" />
|
||||
<span v-else v-html="$t('admin.failed_login_on', { login_at: authentication.login_at })" />
|
||||
</div>
|
||||
<div>
|
||||
{{ $t('commons.IP') }}: <span class="has-text-grey-light">{{ authentication.ip_address }}</span> - {{ $t('commons.browser') }}: <span class="has-text-grey-light">{{ authentication.browser }}</span> - {{ $t('commons.operating_system_short') }}: <span class="has-text-grey-light">{{ authentication.platform }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="is-align-self-center has-text-grey-darker">
|
||||
<font-awesome-layers class="fa-2x">
|
||||
<FontAwesomeIcon :icon="['fas', deviceIcon(authentication.device)]" transform="grow-6" fixed-width />
|
||||
<FontAwesomeIcon :icon="['fas', authentication.login_successful ? 'check' : 'times']" :transform="'shrink-7' + (authentication.device == 'desktop' ? ' up-2' : '')" fixed-width :class="authentication.login_successful ? 'has-text-success-dark' : 'has-text-danger-dark'" />
|
||||
</font-awesome-layers>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="authentications.length == 0" class="mt-4">
|
||||
{{ $t('commons.no_entry_yet') }}
|
||||
</div>
|
||||
<div v-else class="mt-5 pl-3">
|
||||
{{ $t('commons.no_result') }}
|
||||
</div>
|
||||
</template>
|
Reference in New Issue
Block a user