64 lines
1.5 KiB
Vue
64 lines
1.5 KiB
Vue
<script setup lang="ts">
|
|
import { authClient } from '@/lib/auth-client.ts'
|
|
import { ref, watchEffect } from 'vue'
|
|
|
|
interface Session {
|
|
id: string
|
|
createdAt: Date
|
|
updatedAt: Date
|
|
userId: string
|
|
expiresAt: Date
|
|
token: string
|
|
ipAddress?: string | null | undefined
|
|
userAgent?: string | null | undefined
|
|
}
|
|
|
|
const sessions = ref<Session[]>([])
|
|
|
|
const listSessions = async () => {
|
|
const result = await authClient.listSessions()
|
|
if (result.error) {
|
|
return
|
|
}
|
|
|
|
sessions.value = result.data
|
|
}
|
|
|
|
const revokeSession = async (token: string) => {
|
|
await authClient.revokeSession({
|
|
token: token,
|
|
})
|
|
}
|
|
|
|
const revokeOtherSessions = async () => {
|
|
await authClient.revokeOtherSessions()
|
|
}
|
|
|
|
const revokeAllSessions = async () => {
|
|
await authClient.revokeSessions()
|
|
}
|
|
|
|
watchEffect(async () => {
|
|
await listSessions()
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<div class="text-uppercase">Active sessions</div>
|
|
<div class="mb-2">
|
|
<v-btn prepend-icon="mdi-skull" @click="revokeOtherSessions()">revoke other sessions</v-btn>
|
|
</div>
|
|
<v-list border density="compact">
|
|
<v-list-item class="hover:bg-primary-300" v-for="session in sessions" :key="session.id">
|
|
<div class="text-truncate">{{ session.userAgent }}</div>
|
|
<template #append>
|
|
<v-icon-btn size="small" @click="revokeSession(session.token)" color="error" icon="mdi-trash-can" />
|
|
</template>
|
|
</v-list-item>
|
|
</v-list>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped lang="scss"></style>
|