feat: add security headers to nginx configurations and improve environment variable handling

This commit is contained in:
2026-04-28 14:12:28 -04:00
parent 49d24b5fb5
commit 2eb887c486
15 changed files with 43 additions and 85 deletions
@@ -145,8 +145,6 @@ export default function LessonPlayerPage({ params }: { params: { id: string, les
}
return [...prev, res];
});
console.log(`Score for block ${blockId} submitted: ${score}`);
} catch (err) {
console.error(`Failed to submit score for block ${blockId}`, err);
}
}
@@ -89,7 +89,6 @@ export default function AudioResponsePlayer({
}
try {
console.log('[AudioResponse] Requesting microphone access...');
const stream = await navigator.mediaDevices.getUserMedia({
audio: {
echoCancellation: true,
@@ -97,7 +96,6 @@ export default function AudioResponsePlayer({
sampleRate: 44100
}
});
console.log('[AudioResponse] Microphone access granted');
const mediaRecorder = new MediaRecorder(stream, {
mimeType: MediaRecorder.isTypeSupported('audio/webm;codecs=opus') ? 'audio/webm;codecs=opus' : 'audio/webm'
@@ -108,15 +106,12 @@ export default function AudioResponsePlayer({
mediaRecorder.ondataavailable = (event) => {
if (event.data.size > 0) {
audioChunksRef.current.push(event.data);
console.log('[AudioResponse] Data available, chunk size:', event.data.size);
}
};
mediaRecorder.onstop = () => {
console.log('[AudioResponse] Recording stopped, creating blob...');
const audioBlob = new Blob(audioChunksRef.current, { type: 'audio/webm' });
setAudioBlob(audioBlob);
console.log('[AudioResponse] Blob created, size:', audioBlob.size, 'bytes');
stream.getTracks().forEach(track => track.stop());
};
@@ -128,14 +123,12 @@ export default function AudioResponsePlayer({
mediaRecorder.start();
setIsRecording(true);
setRecordingTime(0);
console.log('[AudioResponse] Recording started');
// Start speech recognition
if (!isGraded && recognitionRef.current) {
setTranscript("");
try {
recognitionRef.current.start();
console.log('[AudioResponse] Speech recognition started');
} catch (err) {
console.warn('[AudioResponse] Could not start speech recognition:', err);
}
@@ -146,7 +139,6 @@ export default function AudioResponsePlayer({
setRecordingTime(prev => {
const newTime = prev + 1;
if (timeLimit && newTime >= timeLimit) {
console.log('[AudioResponse] Time limit reached, stopping...');
stopRecording();
}
return newTime;
@@ -256,7 +256,6 @@ export default function MediaPlayer({ id, lessonId, title, url, media_type, conf
setFeedback({ isCorrect });
setA11yStatus(isCorrect ? "Respuesta correcta." : "Respuesta incorrecta.");
// Save answer to backend (mocked for now)
console.log(`Submitted answer for marker at ${activeMarker}: ${isCorrect ? 'Correct' : 'Wrong'}`);
setTimeout(() => {
setFeedback(null);
@@ -133,10 +133,7 @@ export default function GlobalAiControl() {
startDate.setDate(startDate.getDate() - 90);
}
console.log('Loading AI usage from', startDate.toISOString().split('T')[0], 'to', endDate.toISOString().split('T')[0]);
const token = localStorage.getItem('studio_token');
console.log('Token from localStorage:', token ? 'EXISTS' : 'NULL');
if (!token) {
console.error('No token found. Please login again.');
@@ -150,7 +147,6 @@ export default function GlobalAiControl() {
endDate.toISOString().split('T')[0]
);
console.log('Data loaded:', jsonData);
setData(jsonData);
setAuthError(false);
} catch (error) {
@@ -55,7 +55,6 @@ export default function AdminTokenTracking() {
const loadTokenUsage = async () => {
try {
const token = localStorage.getItem('studio_token');
console.log('[TokenUsage] Token from localStorage:', token ? 'Present (studio_token)' : 'Missing');
if (!token) {
console.error('[TokenUsage] No authentication token found!');
@@ -71,8 +70,6 @@ export default function AdminTokenTracking() {
},
});
console.log('[TokenUsage] API Response status:', response.status);
if (response.status === 401) {
console.error('[TokenUsage] Unauthorized - Token may be expired');
alert('Session expired. Please login again.');
@@ -28,26 +28,20 @@ export default function MemoryBlock({ id, title, pairs = [], editMode, onChange
left: "",
right: ""
};
console.log('[MemoryBlock] Adding new pair:', newPair);
onChange({ pairs: [...pairs, newPair] });
};
const updatePair = (index: number, updates: Partial<MatchingPair>) => {
const newPairs = [...pairs];
newPairs[index] = { ...newPairs[index], ...updates };
console.log('[MemoryBlock] Updating pair at index', index, ':', updates);
onChange({ pairs: newPairs });
};
const removePair = (index: number) => {
console.log('[MemoryBlock] Removing pair at index', index);
const newPairs = pairs.filter((_, i) => i !== index);
onChange({ pairs: newPairs });
};
// Debug: Log pairs on render
console.log('[MemoryBlock] Render with pairs:', pairs);
if (!editMode) {
return (
<div className="space-y-8" id={id}>