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 if (to.meta.public) return true
const auth = useAuthStore() const auth = useAuthStore()
const ok = await auth.check() if (!auth.isAuthenticated) return { name: 'login' }
if (!ok) return { name: 'login' }
}) })
export default router export default router
+4 -5
View File
@@ -1,5 +1,6 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { ref, computed } from 'vue' import { ref, computed } from 'vue'
import { api } from '@/services/api'
import spriteData from '@/assets/sprite-data.json' import spriteData from '@/assets/sprite-data.json'
export interface PlayerProfile { export interface PlayerProfile {
@@ -59,21 +60,19 @@ export const useGameStore = defineStore('game', () => {
async function fetchSummary() { async function fetchSummary() {
loading.value = true loading.value = true
try { try {
const res = await fetch('/api/game/summary') summary.value = await api.get<GameSummary>('/game/summary')
if (!res.ok) throw new Error('failed')
summary.value = await res.json()
} finally { } finally {
loading.value = false loading.value = false
} }
} }
async function claimQuest(playerQuestId: number) { async function claimQuest(playerQuestId: number) {
await fetch(`/api/game/quests/${playerQuestId}/claim`, { method: 'POST' }) await api.post(`/game/quests/${playerQuestId}/claim`, {})
await fetchSummary() await fetchSummary()
} }
async function equipCosmetic(cosmeticId: number) { async function equipCosmetic(cosmeticId: number) {
await fetch(`/api/game/cosmetics/${cosmeticId}/equip`, { method: 'POST' }) await api.post(`/game/cosmetics/${cosmeticId}/equip`, {})
await fetchSummary() await fetchSummary()
} }
+7 -7
View File
@@ -131,6 +131,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, onMounted } from 'vue' import { ref, computed, onMounted } from 'vue'
import { useGameStore, type Achievement, type Cosmetic } from '@/stores/game' import { useGameStore, type Achievement, type Cosmetic } from '@/stores/game'
import { api } from '@/services/api'
import CharacterSprite from '@/components/CharacterSprite.vue' import CharacterSprite from '@/components/CharacterSprite.vue'
import XPBar from '@/components/XPBar.vue' import XPBar from '@/components/XPBar.vue'
import NeonPanel from '@/components/NeonPanel.vue' import NeonPanel from '@/components/NeonPanel.vue'
@@ -152,12 +153,12 @@ const spriteImages = Object.fromEntries(
onMounted(async () => { onMounted(async () => {
await store.fetchSummary() await store.fetchSummary()
const [achRes, cosRes] = await Promise.all([ const [ach, cos] = await Promise.all([
fetch('/api/game/achievements'), api.get<Achievement[]>('/game/achievements'),
fetch('/api/game/cosmetics'), api.get<Cosmetic[]>('/game/cosmetics'),
]) ])
if (achRes.ok) achievements.value = await achRes.json() achievements.value = ach
if (cosRes.ok) allCosmetics.value = await cosRes.json() allCosmetics.value = cos
}) })
const xpPct = computed(() => { const xpPct = computed(() => {
@@ -183,8 +184,7 @@ async function claim(q: { id: number }) {
async function equip(id: number) { async function equip(id: number) {
await store.equipCosmetic(id) await store.equipCosmetic(id)
const res = await fetch('/api/game/cosmetics') allCosmetics.value = await api.get<Cosmetic[]>('/game/cosmetics')
if (res.ok) allCosmetics.value = await res.json()
} }
function cosmeticImg(c: Cosmetic): string { function cosmeticImg(c: Cosmetic): string {