🛡️ Sentinel: [HIGH] Fix missing rate limiting on /api/exif/[id]

Co-authored-by: ralksta <16941050+ralksta@users.noreply.github.com>
This commit is contained in:
google-labs-jules[bot]
2026-03-12 11:30:45 +00:00
parent a0364ac9f0
commit 63e6a2f784
30 changed files with 1046 additions and 874 deletions

View File

@@ -1,34 +1,34 @@
import { useState, useCallback } from 'react';
export interface ExifData {
make?: string | null;
model?: string | null;
lensModel?: string | null;
focalLength?: number | null;
fNumber?: number | null;
exposureTime?: string | null;
iso?: number | null;
city?: string | null;
country?: string | null;
make?: string | null;
model?: string | null;
lensModel?: string | null;
focalLength?: number | null;
fNumber?: number | null;
exposureTime?: string | null;
iso?: number | null;
city?: string | null;
country?: string | null;
}
export function useExif() {
const [exifData, setExifData] = useState<ExifData | null>(null);
const [exifLoading, setExifLoading] = useState(false);
const [exifData, setExifData] = useState<ExifData | null>(null);
const [exifLoading, setExifLoading] = useState(false);
const fetchExif = useCallback((url: string) => {
setExifLoading(true);
setExifData(null);
fetch(url)
.then((res) => (res.ok ? res.json() : null))
.then((data) => setExifData(data))
.catch(() => setExifData(null))
.finally(() => setExifLoading(false));
}, []);
const fetchExif = useCallback((url: string) => {
setExifLoading(true);
setExifData(null);
fetch(url)
.then((res) => (res.ok ? res.json() : null))
.then((data) => setExifData(data))
.catch(() => setExifData(null))
.finally(() => setExifLoading(false));
}, []);
const clearExif = useCallback(() => {
setExifData(null);
}, []);
const clearExif = useCallback(() => {
setExifData(null);
}, []);
return { exifData, exifLoading, fetchExif, clearExif };
return { exifData, exifLoading, fetchExif, clearExif };
}

View File

@@ -1,32 +1,32 @@
import { useRef, useCallback } from 'react';
interface UseSwipeProps {
onSwipeLeft: () => void;
onSwipeRight: () => void;
threshold?: number;
onSwipeLeft: () => void;
onSwipeRight: () => void;
threshold?: number;
}
export function useSwipe({ onSwipeLeft, onSwipeRight, threshold = 60 }: UseSwipeProps) {
const touchStartX = useRef<number>(0);
const touchStartY = useRef<number>(0);
const touchStartX = useRef<number>(0);
const touchStartY = useRef<number>(0);
const handleTouchStart = useCallback((e: React.TouchEvent | TouchEvent) => {
touchStartX.current = e.touches[0].clientX;
touchStartY.current = e.touches[0].clientY;
}, []);
const handleTouchStart = useCallback((e: React.TouchEvent | TouchEvent) => {
touchStartX.current = e.touches[0].clientX;
touchStartY.current = e.touches[0].clientY;
}, []);
const handleTouchEnd = useCallback(
(e: React.TouchEvent | TouchEvent) => {
const dx = e.changedTouches[0].clientX - touchStartX.current;
const dy = e.changedTouches[0].clientY - touchStartY.current;
const handleTouchEnd = useCallback(
(e: React.TouchEvent | TouchEvent) => {
const dx = e.changedTouches[0].clientX - touchStartX.current;
const dy = e.changedTouches[0].clientY - touchStartY.current;
if (Math.abs(dx) > threshold && Math.abs(dx) > Math.abs(dy)) {
if (dx > 0) onSwipeRight();
else onSwipeLeft();
}
},
[onSwipeLeft, onSwipeRight, threshold],
);
if (Math.abs(dx) > threshold && Math.abs(dx) > Math.abs(dy)) {
if (dx > 0) onSwipeRight();
else onSwipeLeft();
}
},
[onSwipeLeft, onSwipeRight, threshold],
);
return { handleTouchStart, handleTouchEnd };
return { handleTouchStart, handleTouchEnd };
}