diff --git a/front-end/app/composables/useAuth.ts b/front-end/app/composables/useAuth.ts index 574d08b..87eacfc 100644 --- a/front-end/app/composables/useAuth.ts +++ b/front-end/app/composables/useAuth.ts @@ -1,6 +1,3 @@ -const MOCK_EMAIL = 'admin@licitatche.gov.br' -const MOCK_PASSWORD = 'admin123' - interface AuthUser { nome: string email: string @@ -8,26 +5,54 @@ interface AuthUser { } export function useAuth() { + const { public: { apiBase } } = useRuntimeConfig() + const user = useState('auth_user', () => null) - const token = useCookie('auth_token', { maxAge: 60 * 60 * 8 }) + const token = useCookie('auth_token', { maxAge: 60 * 60 * 8 }) + const refreshToken = useCookie('refresh_token', { maxAge: 60 * 60 * 24 * 7 }) const isAuthenticated = computed(() => !!token.value) + // Restaura usuário do token ao recarregar if (token.value && !user.value) { - user.value = { nome: 'Admin', email: MOCK_EMAIL, papel: 'Administrador' } + try { + const payload = JSON.parse(atob(token.value.split('.')[1])) + user.value = { nome: payload.email.split('@')[0], email: payload.email, papel: payload.role } + } catch { + token.value = null + } } - async function login(email: string, password: string): Promise<{ success: boolean; error?: string }> { - if (email === MOCK_EMAIL && password === MOCK_PASSWORD) { - token.value = 'mock_token_' + Date.now() - user.value = { nome: 'Admin', email, papel: 'Administrador' } + async function login(email: string, password: string, slug: string): Promise<{ success: boolean; error?: string }> { + try { + const res = await $fetch<{ access_token: string; refresh_token: string }>(`${apiBase}/auth/login`, { + method: 'POST', + body: { email, password, slug }, + }) + + token.value = res.access_token + refreshToken.value = res.refresh_token + + const payload = JSON.parse(atob(res.access_token.split('.')[1])) + user.value = { nome: payload.email.split('@')[0], email: payload.email, papel: payload.role } + return { success: true } + } catch (err: any) { + const msg = err?.data?.error || 'E-mail, senha ou organização incorretos.' + return { success: false, error: msg } } - return { success: false, error: 'E-mail ou senha incorretos.' } } function logout() { + // Fire-and-forget logout no back (invalida refresh token) + if (refreshToken.value) { + $fetch(`${apiBase}/auth/logout`, { + method: 'POST', + body: { refresh_token: refreshToken.value }, + }).catch(() => {}) + } token.value = null + refreshToken.value = null user.value = null navigateTo('/login') } diff --git a/front-end/app/pages/login.vue b/front-end/app/pages/login.vue index 9a50932..0680764 100644 --- a/front-end/app/pages/login.vue +++ b/front-end/app/pages/login.vue @@ -5,13 +5,14 @@ definePageMeta({ layout: 'auth' }) const { login } = useAuth() const email = ref('') const password = ref('') +const slug = ref('') const error = ref('') const loading = ref(false) async function handleSubmit() { error.value = '' loading.value = true - const result = await login(email.value, password.value) + const result = await login(email.value, password.value, slug.value) loading.value = false if (result.success) { navigateTo('/') @@ -49,6 +50,16 @@ async function handleSubmit() { /> + + + + diff --git a/front-end/nuxt.config.ts b/front-end/nuxt.config.ts index 3985560..a28aaf3 100644 --- a/front-end/nuxt.config.ts +++ b/front-end/nuxt.config.ts @@ -15,6 +15,12 @@ export default defineNuxtConfig({ '/': { prerender: true } }, + runtimeConfig: { + public: { + apiBase: process.env.NUXT_PUBLIC_API_BASE || 'http://localhost:8080/api/v1', + }, + }, + compatibilityDate: '2025-01-15', eslint: {