fix: corrigir auth em game store e evitar logout no refresh

- Router usa isAuthenticated (localStorage) em vez de auth.check()
  que fazia round-trip ao servidor e deslogava se houvesse falha
- game.ts e CharacterView substituem fetch raw por api() que injeta
  Bearer token automaticamente, corrigindo erro 401/failed no personagem

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
2026-05-27 21:31:01 -03:00
co-authored by Claude Sonnet 4.6
parent 3db4c66d01
commit 433c4f42a5
3 changed files with 13 additions and 15 deletions
+2 -3
View File
@@ -54,11 +54,10 @@ const router = createRouter({
],
})
router.beforeEach(async (to) => {
router.beforeEach((to) => {
if (to.meta.public) return true
const auth = useAuthStore()
const ok = await auth.check()
if (!ok) return { name: 'login' }
if (!auth.isAuthenticated) return { name: 'login' }
})
export default router
+4 -5
View File
@@ -1,5 +1,6 @@
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { api } from '@/services/api'
import spriteData from '@/assets/sprite-data.json'
export interface PlayerProfile {
@@ -59,21 +60,19 @@ export const useGameStore = defineStore('game', () => {
async function fetchSummary() {
loading.value = true
try {
const res = await fetch('/api/game/summary')
if (!res.ok) throw new Error('failed')
summary.value = await res.json()
summary.value = await api.get<GameSummary>('/game/summary')
} finally {
loading.value = false
}
}
async function claimQuest(playerQuestId: number) {
await fetch(`/api/game/quests/${playerQuestId}/claim`, { method: 'POST' })
await api.post(`/game/quests/${playerQuestId}/claim`, {})
await fetchSummary()
}
async function equipCosmetic(cosmeticId: number) {
await fetch(`/api/game/cosmetics/${cosmeticId}/equip`, { method: 'POST' })
await api.post(`/game/cosmetics/${cosmeticId}/equip`, {})
await fetchSummary()
}
+7 -7
View File
@@ -131,6 +131,7 @@
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { useGameStore, type Achievement, type Cosmetic } from '@/stores/game'
import { api } from '@/services/api'
import CharacterSprite from '@/components/CharacterSprite.vue'
import XPBar from '@/components/XPBar.vue'
import NeonPanel from '@/components/NeonPanel.vue'
@@ -152,12 +153,12 @@ const spriteImages = Object.fromEntries(
onMounted(async () => {
await store.fetchSummary()
const [achRes, cosRes] = await Promise.all([
fetch('/api/game/achievements'),
fetch('/api/game/cosmetics'),
const [ach, cos] = await Promise.all([
api.get<Achievement[]>('/game/achievements'),
api.get<Cosmetic[]>('/game/cosmetics'),
])
if (achRes.ok) achievements.value = await achRes.json()
if (cosRes.ok) allCosmetics.value = await cosRes.json()
achievements.value = ach
allCosmetics.value = cos
})
const xpPct = computed(() => {
@@ -183,8 +184,7 @@ async function claim(q: { id: number }) {
async function equip(id: number) {
await store.equipCosmetic(id)
const res = await fetch('/api/game/cosmetics')
if (res.ok) allCosmetics.value = await res.json()
allCosmetics.value = await api.get<Cosmetic[]>('/game/cosmetics')
}
function cosmeticImg(c: Cosmetic): string {