fix share

This commit is contained in:
itqop 2026-01-06 04:10:04 +03:00
parent ecfa339748
commit df1ff96e3c
3 changed files with 39 additions and 11 deletions

View File

@ -23,6 +23,8 @@ interface ViewerModalProps {
onClose: () => void; onClose: () => void;
onDelete?: (assetId: string) => void; onDelete?: (assetId: string) => void;
onShare?: (assetId: string) => void; onShare?: (assetId: string) => void;
shareToken?: string;
sharePassword?: string;
} }
export default function ViewerModal({ export default function ViewerModal({
@ -31,10 +33,13 @@ export default function ViewerModal({
onClose, onClose,
onDelete, onDelete,
onShare, onShare,
shareToken,
sharePassword,
}: ViewerModalProps) { }: ViewerModalProps) {
const [currentUrl, setCurrentUrl] = useState<string>(''); const [currentUrl, setCurrentUrl] = useState<string>('');
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [currentIndex, setCurrentIndex] = useState(-1); const [currentIndex, setCurrentIndex] = useState(-1);
const [isBlobUrl, setIsBlobUrl] = useState(false);
useEffect(() => { useEffect(() => {
if (asset) { if (asset) {
@ -45,7 +50,7 @@ export default function ViewerModal({
// Cleanup blob URL on unmount or asset change // Cleanup blob URL on unmount or asset change
return () => { return () => {
if (currentUrl) { if (currentUrl && isBlobUrl) {
URL.revokeObjectURL(currentUrl); URL.revokeObjectURL(currentUrl);
} }
}; };
@ -80,13 +85,26 @@ export default function ViewerModal({
try { try {
setLoading(true); setLoading(true);
// Revoke previous blob URL to prevent memory leaks // Revoke previous blob URL to prevent memory leaks
if (currentUrl) { if (currentUrl && isBlobUrl) {
URL.revokeObjectURL(currentUrl); URL.revokeObjectURL(currentUrl);
} }
// Load media through backend proxy with auth
const blob = await api.getMediaBlob(asset.id, 'original'); let url: string;
const url = URL.createObjectURL(blob); let isBlob: boolean;
// If viewing shared content, use share download URL (pre-signed S3 URL)
if (shareToken) {
url = await api.getShareDownloadUrl(shareToken, asset.id, 'original', sharePassword);
isBlob = false;
} else {
// Otherwise use authenticated media endpoint with blob
const blob = await api.getMediaBlob(asset.id, 'original');
url = URL.createObjectURL(blob);
isBlob = true;
}
setCurrentUrl(url); setCurrentUrl(url);
setIsBlobUrl(isBlob);
} catch (error) { } catch (error) {
console.error('Failed to load media:', error); console.error('Failed to load media:', error);
} finally { } finally {

View File

@ -171,6 +171,8 @@ export default function ShareViewPage() {
asset={viewerOpen ? asset : null} asset={viewerOpen ? asset : null}
assets={[asset]} assets={[asset]}
onClose={() => setViewerOpen(false)} onClose={() => setViewerOpen(false)}
shareToken={token}
sharePassword={password}
/> />
)} )}
</Container> </Container>

View File

@ -25,11 +25,17 @@ class ApiClient {
}, },
}); });
// Add auth token to requests // Add auth token to requests (except for public share endpoints)
this.client.interceptors.request.use((config) => { this.client.interceptors.request.use((config) => {
const token = localStorage.getItem('access_token'); // Skip auth for public share endpoints
if (token) { const isShareEndpoint = config.url?.startsWith('/shares/') &&
config.headers.Authorization = `Bearer ${token}`; !config.url?.includes('/revoke');
if (!isShareEndpoint) {
const token = localStorage.getItem('access_token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
} }
return config; return config;
}); });
@ -41,8 +47,10 @@ class ApiClient {
if (error.response?.status === 401) { if (error.response?.status === 401) {
localStorage.removeItem('access_token'); localStorage.removeItem('access_token');
localStorage.removeItem('refresh_token'); localStorage.removeItem('refresh_token');
// Redirect only if not already on login/register page // Redirect only if not on login/register/share pages
if (!['/login', '/register'].includes(window.location.pathname)) { const path = window.location.pathname;
const isPublicPage = ['/login', '/register'].includes(path) || path.startsWith('/share/');
if (!isPublicPage) {
window.location.href = '/login'; window.location.href = '/login';
} }
} }