Implement Permission Denied handling.
This commit is contained in:
parent
16de7b5f1f
commit
4a0fbd8199
@ -5,6 +5,7 @@
|
|||||||
<ProfileView v-if="store.currentView === 'profile'" />
|
<ProfileView v-if="store.currentView === 'profile'" />
|
||||||
<DeviceLinkView v-if="store.currentView === 'device-link'" />
|
<DeviceLinkView v-if="store.currentView === 'device-link'" />
|
||||||
<ResetView v-if="store.currentView === 'reset'" />
|
<ResetView v-if="store.currentView === 'reset'" />
|
||||||
|
<PermissionDeniedView v-if="store.currentView === 'permission-denied'" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -16,10 +17,15 @@ import LoginView from '@/components/LoginView.vue'
|
|||||||
import ProfileView from '@/components/ProfileView.vue'
|
import ProfileView from '@/components/ProfileView.vue'
|
||||||
import DeviceLinkView from '@/components/DeviceLinkView.vue'
|
import DeviceLinkView from '@/components/DeviceLinkView.vue'
|
||||||
import ResetView from '@/components/ResetView.vue'
|
import ResetView from '@/components/ResetView.vue'
|
||||||
|
import PermissionDeniedView from '@/components/PermissionDeniedView.vue'
|
||||||
|
|
||||||
const store = useAuthStore()
|
const store = useAuthStore()
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
// Detect restricted mode: any path not starting with /auth/
|
||||||
|
if (!location.pathname.startsWith('/auth/')) {
|
||||||
|
store.setRestrictedMode(true)
|
||||||
|
}
|
||||||
// Was an error message passed in the URL hash?
|
// Was an error message passed in the URL hash?
|
||||||
const message = location.hash.substring(1)
|
const message = location.hash.substring(1)
|
||||||
if (message) {
|
if (message) {
|
||||||
|
@ -26,7 +26,10 @@ const handleLogin = async () => {
|
|||||||
authStore.showMessage('Starting authentication...', 'info')
|
authStore.showMessage('Starting authentication...', 'info')
|
||||||
await authStore.authenticate()
|
await authStore.authenticate()
|
||||||
authStore.showMessage('Authentication successful!', 'success', 2000)
|
authStore.showMessage('Authentication successful!', 'success', 2000)
|
||||||
if (location.pathname.startsWith('/auth/')) {
|
if (authStore.restrictedMode) {
|
||||||
|
// In restricted mode after successful auth show permission denied (no profile outside /auth/)
|
||||||
|
authStore.currentView = 'permission-denied'
|
||||||
|
} else if (location.pathname.startsWith('/auth/')) {
|
||||||
authStore.currentView = 'profile'
|
authStore.currentView = 'profile'
|
||||||
} else {
|
} else {
|
||||||
location.reload()
|
location.reload()
|
||||||
|
44
frontend/src/components/PermissionDeniedView.vue
Normal file
44
frontend/src/components/PermissionDeniedView.vue
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="view active">
|
||||||
|
<h1>🚫 Forbidden</h1>
|
||||||
|
<div v-if="authStore.userInfo?.authenticated" class="user-header">
|
||||||
|
<span class="user-emoji" aria-hidden="true">{{ userEmoji }}</span>
|
||||||
|
<span class="user-name">{{ displayName }}</span>
|
||||||
|
</div>
|
||||||
|
<p>You lack the permissions required for this page.</p>
|
||||||
|
<div class="actions">
|
||||||
|
<button class="btn-secondary" @click="back">Back</button>
|
||||||
|
<button class="btn-primary" @click="goAuth">Account</button>
|
||||||
|
<button class="btn-danger" @click="logout">Logout</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { useAuthStore } from '@/stores/auth'
|
||||||
|
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
|
||||||
|
const userEmoji = '👤' // Placeholder / could be extended later if backend provides one
|
||||||
|
const displayName = authStore.userInfo?.user?.user_name || 'User'
|
||||||
|
|
||||||
|
function goAuth() {
|
||||||
|
location.href = '/auth/'
|
||||||
|
}
|
||||||
|
function back() {
|
||||||
|
if (history.length > 1) history.back()
|
||||||
|
else authStore.currentView = 'login'
|
||||||
|
}
|
||||||
|
async function logout() {
|
||||||
|
await authStore.logout()
|
||||||
|
authStore.currentView = 'login'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.user-header { display:flex; align-items:center; gap:.5rem; font-size:1.1rem; margin-bottom:.75rem; }
|
||||||
|
.user-emoji { font-size:1.5rem; line-height:1; }
|
||||||
|
.user-name { font-weight:600; }
|
||||||
|
.actions { margin-top:1.5rem; display:flex; gap:.5rem; flex-wrap:nowrap; }
|
||||||
|
.hint { font-size:.9rem; opacity:.85; }
|
||||||
|
</style>
|
Loading…
x
Reference in New Issue
Block a user