import { ref, type Ref } from 'vue'; import router from '../router'; const SESSION_TOKEN_KEY = 'nyx_session'; import { getApiBase } from '../utils/apiBase'; // Dev service token — auto-login for development const DEV_TOKEN = '7Oorb9S3OpwFyWgm4zi_Tq7GeamefbjjTgooPVPWAwPDOf6B4TvgvQlLbhmT4DjsqBS_D1g'; export function useAuth(connectFn: () => void) { // Auto-set dev token if no token exists if (!localStorage.getItem(SESSION_TOKEN_KEY) && !localStorage.getItem('titan_token')) { localStorage.setItem(SESSION_TOKEN_KEY, DEV_TOKEN); } const isLoggedIn: Ref = ref(!!localStorage.getItem(SESSION_TOKEN_KEY)); const loginToken: Ref = ref(''); const loginError: Ref = ref(''); const loggingIn: Ref = ref(false); async function doLogin(): Promise { const token = loginToken.value.trim(); if (!token) return; loggingIn.value = true; loginError.value = ''; try { const nonceRes = await fetch(`${getApiBase()}/api/auth/nonce`); if (!nonceRes.ok) { loginError.value = 'Auth unavailable'; loggingIn.value = false; return; } const { nonce } = await nonceRes.json(); const res = await fetch(`${getApiBase()}/api/auth`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ token, nonce }), }); if (!res.ok) { const err = await res.json().catch(() => ({ error: 'Login failed' })); loginError.value = err.error || 'Invalid token'; loggingIn.value = false; return; } const { sessionToken } = await res.json(); localStorage.removeItem('titan_token'); localStorage.removeItem('nyx_token'); localStorage.setItem(SESSION_TOKEN_KEY, sessionToken); sessionStorage.removeItem('agent'); isLoggedIn.value = true; connectFn(); router.push('/chat'); setTimeout(() => { loggingIn.value = false; }, 500); } catch { loginError.value = 'Network error'; loggingIn.value = false; } } async function doLogout(disconnectFn?: () => void): Promise { const sessionToken = localStorage.getItem(SESSION_TOKEN_KEY); if (sessionToken) { // Fire-and-forget revoke fetch(`${getApiBase()}/api/auth/logout`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ sessionToken }), }).catch(() => {}); } if (disconnectFn) disconnectFn(); localStorage.removeItem(SESSION_TOKEN_KEY); localStorage.removeItem('titan_token'); localStorage.removeItem('nyx_token'); sessionStorage.removeItem('agent'); sessionStorage.removeItem('viewer_auth'); // clear cached fstoken isLoggedIn.value = false; loginToken.value = ''; loggingIn.value = false; router.push('/'); } return { isLoggedIn, loginToken, loginError, loggingIn, doLogin, doLogout }; }