mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 23:41:08 +02:00
fix(auth): use getValidToken() instead of getAccessToken() for API calls
getAccessToken() reads the stored JWT without checking expiry, causing 401s when the token ages out — especially for services not covered by the fetch interceptor (credits, events, api, etc.). getValidToken() checks validity first and refreshes automatically when needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4616798d34
commit
16fef572bf
18 changed files with 18 additions and 18 deletions
|
|
@ -104,7 +104,7 @@ export async function fetchWithRetry<T>(
|
|||
for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
|
||||
try {
|
||||
// Get fresh token for each attempt
|
||||
const token = await authStore.getAccessToken();
|
||||
const token = await authStore.getValidToken();
|
||||
|
||||
const response = await fetch(url, {
|
||||
...options,
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ export interface CreditPurchase {
|
|||
|
||||
// Helper function for authenticated requests
|
||||
async function fetchWithAuth<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
|
||||
const token = await authStore.getAccessToken();
|
||||
const token = await authStore.getValidToken();
|
||||
|
||||
const response = await fetch(`${getManaCreditsUrl()}${endpoint}`, {
|
||||
...options,
|
||||
|
|
|
|||
|
|
@ -9,5 +9,5 @@ import { getManaAuthUrl } from './config';
|
|||
export const feedbackService = createFeedbackService({
|
||||
apiUrl: getManaAuthUrl(),
|
||||
appId: 'mana',
|
||||
getAuthToken: async () => authStore.getAccessToken(),
|
||||
getAuthToken: async () => authStore.getValidToken(),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ async function fetchPublic<T>(endpoint: string): Promise<T> {
|
|||
|
||||
// Helper function for authenticated requests
|
||||
async function fetchWithAuth<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
|
||||
const token = await authStore.getAccessToken();
|
||||
const token = await authStore.getValidToken();
|
||||
|
||||
const response = await fetch(`${getManaAuthUrl()}${endpoint}`, {
|
||||
...options,
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ export interface AvatarUploadUrlResponse {
|
|||
|
||||
// Helper function for authenticated requests
|
||||
async function fetchWithAuth<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
|
||||
const token = await authStore.getAccessToken();
|
||||
const token = await authStore.getValidToken();
|
||||
|
||||
const response = await fetch(`${getManaAuthUrl()}${endpoint}`, {
|
||||
...options,
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ export class ResearchApiError extends Error {
|
|||
// ─── Internal helpers ───────────────────────────────────────
|
||||
|
||||
async function authHeaders(extra: HeadersInit = {}): Promise<HeadersInit> {
|
||||
const token = await authStore.getAccessToken();
|
||||
const token = await authStore.getValidToken();
|
||||
return {
|
||||
'Content-Type': 'application/json',
|
||||
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ export const myDataService = {
|
|||
*/
|
||||
async downloadMyData(): Promise<void> {
|
||||
const baseUrl = getAuthApiUrl();
|
||||
const token = await authStore.getAccessToken();
|
||||
const token = await authStore.getValidToken();
|
||||
|
||||
// Use fetch with blob response for file download
|
||||
const response = await fetch(`${baseUrl}/me/data/export`, {
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ export interface CurrentSubscription {
|
|||
|
||||
// Helper function for authenticated requests
|
||||
async function fetchWithAuth<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
|
||||
const token = await authStore.getAccessToken();
|
||||
const token = await authStore.getValidToken();
|
||||
|
||||
const response = await fetch(`${getManaAuthUrl()}${endpoint}`, {
|
||||
...options,
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ export interface SyncActivateResponse {
|
|||
|
||||
// Helper
|
||||
async function fetchWithAuth<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
|
||||
const token = await authStore.getAccessToken();
|
||||
const token = await authStore.getValidToken();
|
||||
|
||||
const response = await fetch(`${getManaCreditsUrl()}${endpoint}`, {
|
||||
...options,
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ export function getVaultClient(): VaultClient {
|
|||
if (!_instance) {
|
||||
_instance = createVaultClient({
|
||||
authUrl: getManaAuthUrl(),
|
||||
getToken: () => authStore.getAccessToken(),
|
||||
getToken: () => authStore.getValidToken(),
|
||||
});
|
||||
}
|
||||
return _instance;
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ async function resolveSystemPrompt(templateId: string | undefined): Promise<stri
|
|||
* Returns an empty object when no token is available (guest mode).
|
||||
*/
|
||||
async function authHeader(): Promise<Record<string, string>> {
|
||||
const token = await authStore.getAccessToken();
|
||||
const token = await authStore.getValidToken();
|
||||
return token ? { Authorization: `Bearer ${token}` } : {};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ export interface PublicRsvpRecord {
|
|||
}
|
||||
|
||||
async function fetchWithAuth<T>(path: string, init: RequestInit = {}): Promise<T> {
|
||||
const token = await authStore.getAccessToken();
|
||||
const token = await authStore.getValidToken();
|
||||
const res = await fetch(`${getManaEventsUrl()}${path}`, {
|
||||
...init,
|
||||
headers: {
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@
|
|||
if (uploading) return;
|
||||
uploading = true;
|
||||
|
||||
const token = await authStore.getAccessToken();
|
||||
const token = await authStore.getValidToken();
|
||||
|
||||
for (let i = 0; i < uploadFiles.length; i++) {
|
||||
if (uploadFiles[i]!.status !== 'pending') continue;
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ export interface UploadMealPhotoResult {
|
|||
}
|
||||
|
||||
async function authHeader(): Promise<Record<string, string>> {
|
||||
const token = await authStore.getAccessToken();
|
||||
const token = await authStore.getValidToken();
|
||||
return token ? { Authorization: `Bearer ${token}` } : {};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ export interface UploadPhotoResult {
|
|||
}
|
||||
|
||||
async function authHeader(): Promise<Record<string, string>> {
|
||||
const token = await authStore.getAccessToken();
|
||||
const token = await authStore.getValidToken();
|
||||
return token ? { Authorization: `Bearer ${token}` } : {};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
onMount(async () => {
|
||||
try {
|
||||
const token = await authStore.getAccessToken();
|
||||
const token = await authStore.getValidToken();
|
||||
if (!token) {
|
||||
loadingDecks = false;
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ const API_BASE = '/api/v1/who';
|
|||
* Same pattern as base-client.ts uses for every other API call.
|
||||
*/
|
||||
async function postJson<T>(path: string, body: unknown): Promise<T> {
|
||||
const token = await authStore.getAccessToken();
|
||||
const token = await authStore.getValidToken();
|
||||
if (!token) {
|
||||
guestPrompt.requireAccount(
|
||||
'who',
|
||||
|
|
|
|||
|
|
@ -24,5 +24,5 @@ function getAuthUrl(): string {
|
|||
export const userSettings = createUserSettingsStore({
|
||||
appId: 'mana',
|
||||
authUrl: getAuthUrl,
|
||||
getAccessToken: () => authStore.getAccessToken(),
|
||||
getAccessToken: () => authStore.getValidToken(),
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue