mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-22 19:06:41 +02:00
Users were getting signed out after ~15 minutes because API clients were reading tokens directly from localStorage without triggering the refresh logic. The tokenManager exists with proper refresh capability but was never being used. Changes: - Add getValidToken() method to auth stores in 9 web apps - Update API clients to use authStore.getValidToken() instead of localStorage - Token refresh now happens proactively before requests fail Apps updated: chat, calendar, picture, zitare, contacts, todo, clock, manacore, manadeck 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
128 lines
2.6 KiB
TypeScript
128 lines
2.6 KiB
TypeScript
import type { ManaUser } from '$lib/types/auth';
|
|
import { authService, tokenManager } from '$lib/auth';
|
|
import type { UserData } from '$lib/auth';
|
|
|
|
// Svelte 5 runes-based auth store
|
|
let user = $state<ManaUser | null>(null);
|
|
let loading = $state(true);
|
|
|
|
/**
|
|
* Convert UserData from shared-auth to ManaUser
|
|
*/
|
|
function toManaUser(userData: UserData | null): ManaUser | null {
|
|
if (!userData) return null;
|
|
return {
|
|
id: userData.id,
|
|
email: userData.email,
|
|
role: userData.role,
|
|
};
|
|
}
|
|
|
|
export const authStore = {
|
|
get user() {
|
|
return user;
|
|
},
|
|
get loading() {
|
|
return loading;
|
|
},
|
|
get isAuthenticated() {
|
|
return !!user;
|
|
},
|
|
|
|
/**
|
|
* Initialize auth state from stored tokens
|
|
*/
|
|
async initialize() {
|
|
loading = true;
|
|
try {
|
|
const isAuth = await authService.isAuthenticated();
|
|
if (isAuth) {
|
|
const userData = await authService.getUserFromToken();
|
|
user = toManaUser(userData);
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to initialize auth:', error);
|
|
user = null;
|
|
} finally {
|
|
loading = false;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Set user
|
|
*/
|
|
setUser(newUser: ManaUser | null) {
|
|
user = newUser;
|
|
},
|
|
|
|
/**
|
|
* Sign out
|
|
*/
|
|
async signOut() {
|
|
try {
|
|
await authService.signOut();
|
|
user = null;
|
|
} catch (error) {
|
|
console.error('Sign out failed:', error);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Check authentication status
|
|
*/
|
|
async checkAuth() {
|
|
const isAuth = await authService.isAuthenticated();
|
|
if (!isAuth) {
|
|
user = null;
|
|
return false;
|
|
}
|
|
return true;
|
|
},
|
|
|
|
/**
|
|
* Sign in with email and password
|
|
*/
|
|
async signIn(email: string, password: string) {
|
|
const result = await authService.signIn(email, password);
|
|
if (result.success) {
|
|
const userData = await authService.getUserFromToken();
|
|
user = toManaUser(userData);
|
|
}
|
|
return result;
|
|
},
|
|
|
|
/**
|
|
* Sign up with email and password
|
|
*/
|
|
async signUp(email: string, password: string) {
|
|
const result = await authService.signUp(email, password);
|
|
if (result.success && !result.needsVerification) {
|
|
const userData = await authService.getUserFromToken();
|
|
user = toManaUser(userData);
|
|
}
|
|
return result;
|
|
},
|
|
|
|
/**
|
|
* Send password reset email
|
|
*/
|
|
async forgotPassword(email: string) {
|
|
return authService.forgotPassword(email);
|
|
},
|
|
|
|
/**
|
|
* Get access token for API calls (raw token, no refresh)
|
|
* @deprecated Use getValidToken() instead for automatic refresh
|
|
*/
|
|
async getAccessToken(): Promise<string | null> {
|
|
return await authService.getAppToken();
|
|
},
|
|
|
|
/**
|
|
* Get a valid access token for API calls
|
|
* Automatically refreshes if the token is expired or about to expire
|
|
*/
|
|
async getValidToken(): Promise<string | null> {
|
|
return await tokenManager.getValidToken();
|
|
},
|
|
};
|