feat: implement centralized access token management for media downloads and user authentication

This commit is contained in:
2026-03-23 21:53:27 +11:00
parent f76fee23bf
commit 75a9b4ca1e
16 changed files with 183 additions and 54 deletions

View File

@@ -1,5 +1,6 @@
import { useCallback, useEffect, useState } from 'react';
import { useMatrixClient } from './useMatrixClient';
import { getCurrentAccessToken } from '../utils/auth';
/**
* Fetches media with authentication and returns a blob URL.
@@ -40,7 +41,8 @@ export const useAuthenticatedMediaUrl = (
const fetchMedia = async () => {
try {
const accessToken = mx.getAccessToken();
// Always use current session's token to avoid stale tokens during account switches
const accessToken = getCurrentAccessToken();
let response = await fetch(src, {
method: 'GET',
headers: accessToken
@@ -104,7 +106,8 @@ export const useAuthenticatedMediaFetch = () => {
}
try {
const accessToken = mx.getAccessToken();
// Always use current session's token to avoid stale tokens during account switches
const accessToken = getCurrentAccessToken();
let response = await fetch(src, {
method: 'GET',
headers: accessToken

View File

@@ -3,6 +3,7 @@ import { MatrixClient, UserEvent, UserEventHandlerMap } from 'matrix-js-sdk';
import { useMatrixClient } from './useMatrixClient';
import { useMediaAuthentication } from './useMediaAuthentication';
import { mxcUrlToHttp } from '../utils/matrix';
import { getCurrentAccessToken } from '../utils/auth';
import {
fetchAndExtractMetadata,
extractMetadataFromImage,
@@ -25,7 +26,8 @@ async function fetchAvatarData(
if (!url) return null;
try {
const accessToken = mx.getAccessToken();
// Always use current session's token to avoid stale tokens during account switches
const accessToken = getCurrentAccessToken();
let response = await fetch(url, {
method: 'GET',
headers: accessToken && useAuthentication ? { Authorization: `Bearer ${accessToken}` } : undefined,
@@ -85,7 +87,8 @@ export function useUserBanner(): [
return;
}
const accessToken = mx.getAccessToken();
// Always use current session's token to avoid stale tokens during account switches
const accessToken = getCurrentAccessToken();
const metadata = await fetchAndExtractMetadata(httpUrl, useAuthentication ? accessToken : null);
setBanner(metadata.banner);
} catch {
@@ -236,7 +239,8 @@ export function useOtherUserBanner(userId: string, avatarMxc: string | undefined
return;
}
const accessToken = mx.getAccessToken();
// Always use current session's token to avoid stale tokens during account switches
const accessToken = getCurrentAccessToken();
const metadata = await fetchAndExtractMetadata(httpUrl, useAuthentication ? accessToken : null);
bannerMxc = metadata.banner;
@@ -257,7 +261,8 @@ export function useOtherUserBanner(userId: string, avatarMxc: string | undefined
return;
}
const accessToken = mx.getAccessToken();
// Always use current session's token to avoid stale tokens during account switches
const accessToken = getCurrentAccessToken();
const headers: HeadersInit = {};
if (useAuthentication && accessToken) {
headers.Authorization = `Bearer ${accessToken}`;

View File

@@ -3,6 +3,7 @@ import { MatrixClient, UserEvent, UserEventHandlerMap } from 'matrix-js-sdk';
import { useMatrixClient } from './useMatrixClient';
import { useMediaAuthentication } from './useMediaAuthentication';
import { mxcUrlToHttp } from '../utils/matrix';
import { getCurrentAccessToken } from '../utils/auth';
import {
embedColorInImage,
extractColorFromImage,
@@ -25,7 +26,8 @@ async function fetchAvatarData(
if (!url) return null;
try {
const accessToken = mx.getAccessToken();
// Always use current session's token to avoid stale tokens during account switches
const accessToken = getCurrentAccessToken();
let response = await fetch(url, {
method: 'GET',
headers: accessToken && useAuthentication ? { Authorization: `Bearer ${accessToken}` } : undefined,
@@ -86,7 +88,8 @@ export function useUserColor(): [
return;
}
const accessToken = mx.getAccessToken();
// Always use current session's token to avoid stale tokens during account switches
const accessToken = getCurrentAccessToken();
const extractedColor = await fetchAndExtractColor(httpUrl, useAuthentication ? accessToken : null);
setColor(extractedColor);
} catch (e) {
@@ -237,7 +240,8 @@ export function useOtherUserColor(userId: string, avatarMxc: string | undefined)
return;
}
const accessToken = mx.getAccessToken();
// Always use current session's token to avoid stale tokens during account switches
const accessToken = getCurrentAccessToken();
const extractedColor = await fetchAndExtractColor(httpUrl, useAuthentication ? accessToken : null);
// Cache the result

View File

@@ -2,8 +2,7 @@ import { useCallback, useEffect, useState } from 'react';
import { UserEvent, UserEventHandlerMap } from 'matrix-js-sdk';
import { useMatrixClient } from './useMatrixClient';
import { useMediaAuthentication } from './useMediaAuthentication';
import { mxcUrlToHttp } from '../utils/matrix';
import {
import { mxcUrlToHttp } from '../utils/matrix';import { getCurrentAccessToken } from '../utils/auth';import {
fetchAndExtractMetadata,
extractMetadataFromImage,
embedMetadataInImage,
@@ -26,7 +25,8 @@ async function fetchAvatarData(
if (!url) return null;
try {
const accessToken = mx.getAccessToken();
// Always use current session's token to avoid stale tokens during account switches
const accessToken = getCurrentAccessToken();
let response = await fetch(url, {
method: 'GET',
headers: accessToken && useAuthentication ? { Authorization: `Bearer ${accessToken}` } : undefined,
@@ -91,7 +91,8 @@ export function useUserProfileStyle(): [
return;
}
const accessToken = mx.getAccessToken();
// Always use current session's token to avoid stale tokens during account switches
const accessToken = getCurrentAccessToken();
const metadata = await fetchAndExtractMetadata(httpUrl, useAuthentication ? accessToken : null);
setStyle({
avatarBorderColor: metadata.avatarBorderColor,
@@ -231,7 +232,8 @@ export function useOtherUserProfileStyle(userId: string, avatarMxc: string | und
return;
}
const accessToken = mx.getAccessToken();
// Always use current session's token to avoid stale tokens during account switches
const accessToken = getCurrentAccessToken();
const metadata = await fetchAndExtractMetadata(httpUrl, useAuthentication ? accessToken : null);
const styleData: ProfileStyleData = {