Consistently use apiJson for fetches, with timeout and proper error handling (less code duplication).
This commit is contained in:
@@ -101,7 +101,7 @@ import { useAuthStore } from '@/stores/auth'
|
||||
import { adminUiPath, makeUiHref } from '@/utils/settings'
|
||||
import passkey from '@/utils/passkey'
|
||||
import { goBack } from '@/utils/helpers'
|
||||
import { apiFetch } from '@/utils/api'
|
||||
import { apiJson } from '@/utils/api'
|
||||
|
||||
const authStore = useAuthStore()
|
||||
const updateInterval = ref(null)
|
||||
@@ -174,9 +174,7 @@ const saveName = async () => {
|
||||
if (!name) { authStore.showMessage('Name cannot be empty', 'error'); return }
|
||||
try {
|
||||
saving.value = true
|
||||
const res = await apiFetch('/auth/api/user/display-name', { method: 'PUT', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ display_name: name }) })
|
||||
const data = await res.json()
|
||||
if (!res.ok || data.detail) throw new Error(data.detail || 'Update failed')
|
||||
await apiJson('/auth/api/user/display-name', { method: 'PUT', body: { display_name: name } })
|
||||
showNameDialog.value = false
|
||||
await authStore.loadUserInfo()
|
||||
authStore.showMessage('Name updated successfully!', 'success', 3000)
|
||||
|
||||
@@ -59,7 +59,7 @@ import { ref, onMounted, watch, computed, nextTick } from 'vue'
|
||||
import QRCode from 'qrcode/lib/browser'
|
||||
import { formatDate } from '@/utils/helpers'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import { apiFetch } from '@/utils/api'
|
||||
import { apiJson, getUserFriendlyErrorMessage, shouldShowErrorToast } from '@/utils/api'
|
||||
|
||||
const authStore = useAuthStore()
|
||||
|
||||
@@ -87,9 +87,7 @@ const expirationMessage = computed(() => {
|
||||
|
||||
async function fetchLink() {
|
||||
try {
|
||||
const res = await apiFetch(props.endpoint, { method: 'POST' })
|
||||
const data = await res.json()
|
||||
if (data.detail) throw new Error(data.detail)
|
||||
const data = await apiJson(props.endpoint, { method: 'POST' })
|
||||
url.value = data.url
|
||||
expires.value = data.expires
|
||||
emit('generated', { url: data.url, expires: data.expires })
|
||||
@@ -98,6 +96,9 @@ async function fetchLink() {
|
||||
if (props.autoCopy) copy()
|
||||
} catch (e) {
|
||||
console.error('Failed to create link', e)
|
||||
if (shouldShowErrorToast(e)) {
|
||||
authStore.showMessage(getUserFriendlyErrorMessage(e), 'error', 4000)
|
||||
}
|
||||
// Close the dialog on any error (auth cancelled, network error, etc.)
|
||||
emit('close')
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
import { computed, onMounted, reactive, ref } from 'vue'
|
||||
import passkey from '@/utils/passkey'
|
||||
import { getSettings } from '@/utils/settings'
|
||||
import { apiJson, getUserFriendlyErrorMessage } from '@/utils/api'
|
||||
|
||||
const props = defineProps({
|
||||
mode: {
|
||||
@@ -120,13 +121,7 @@ async function fetchSettings() {
|
||||
|
||||
async function fetchUserInfo() {
|
||||
try {
|
||||
const res = await fetch('/auth/api/user-info', { method: 'POST' })
|
||||
if (!res.ok) {
|
||||
userInfo.value = null
|
||||
currentView.value = 'login'
|
||||
return
|
||||
}
|
||||
userInfo.value = await res.json()
|
||||
userInfo.value = await apiJson('/auth/api/user-info', { method: 'POST' })
|
||||
// Determine view based on authentication status
|
||||
if (isAuthenticated.value && props.mode !== 'reauth') {
|
||||
currentView.value = 'forbidden'
|
||||
@@ -136,6 +131,11 @@ async function fetchUserInfo() {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load user info', error)
|
||||
// For 401/403 just go to login, for other errors show message
|
||||
if (error.status !== 401 && error.status !== 403) {
|
||||
showMessage(getUserFriendlyErrorMessage(error), 'error', 4000)
|
||||
}
|
||||
userInfo.value = null
|
||||
currentView.value = 'login'
|
||||
}
|
||||
}
|
||||
@@ -168,12 +168,14 @@ async function logoutUser() {
|
||||
if (loading.value) return
|
||||
loading.value = true
|
||||
try {
|
||||
await fetch('/auth/api/logout', { method: 'POST' })
|
||||
await apiJson('/auth/api/logout', { method: 'POST' })
|
||||
userInfo.value = null
|
||||
// Switch to login view after logout
|
||||
currentView.value = 'login'
|
||||
showMessage('Logged out. You can sign in with a different account.', 'info', 3000)
|
||||
} catch (_) { /* ignore */ }
|
||||
} catch (error) {
|
||||
showMessage(getUserFriendlyErrorMessage(error), 'error', 4000)
|
||||
}
|
||||
finally { loading.value = false }
|
||||
emit('logout')
|
||||
}
|
||||
@@ -185,16 +187,11 @@ function openProfile() {
|
||||
}
|
||||
|
||||
async function setSessionCookie(sessionToken) {
|
||||
const response = await fetch('/auth/api/set-session', {
|
||||
return await apiJson('/auth/api/set-session', {
|
||||
method: 'POST', headers: { Authorization: `Bearer ${sessionToken}` }
|
||||
})
|
||||
const payload = await safeParseJson(response)
|
||||
if (!response.ok || payload?.detail) throw new Error(payload?.detail || 'Session could not be established.')
|
||||
return payload
|
||||
}
|
||||
|
||||
async function safeParseJson(response) { try { return await response.json() } catch (_) { return null } }
|
||||
|
||||
onMounted(async () => {
|
||||
await fetchSettings()
|
||||
await fetchUserInfo()
|
||||
|
||||
Reference in New Issue
Block a user