Files
Momento/memento-note/app/api/cron/reminders/route.ts
sepehr fa72672aac
Some checks failed
Deploy to Production / Build and Deploy (push) Failing after 39s
security: fix critical auth gaps, SSRF, IDOR, and embedding error handling
CRITICAL:
- Add auth + admin check to 10 unprotected API routes (test-*, debug/*,
  config, models, fix-labels)
- Add CRON_SECRET bearer auth to /api/cron/reminders (was fully open)
- Add SSRF protection to getOllamaModels (blocks private/internal IPs)

HIGH:
- Fix getAllLabels() missing userId filter (leaked all users' labels)
- Fix /api/labels OR clause leaking other users' labels
- Fix IDOR in toggleAgent/getAgentActions (add ownership check)
- Fix getEmbeddings() returning [] on error in all 5 providers (corrupted
  semantic search with NaN cosine similarity) — now throws instead

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 21:02:13 +02:00

74 lines
2.0 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import prisma from '@/lib/prisma';
export const dynamic = 'force-dynamic'; // No caching
export async function POST(request: NextRequest) {
// Optional auth: set CRON_SECRET env var, callers must pass
// Authorization: Bearer <CRON_SECRET>
const cronSecret = process.env.CRON_SECRET
if (cronSecret) {
const authHeader = request.headers.get('authorization')
if (authHeader !== `Bearer ${cronSecret}`) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
}
try {
const now = new Date();
// 1. Find all due reminders that haven't been processed
const dueNotes = await prisma.note.findMany({
where: {
reminder: {
lte: now, // Less than or equal to now
},
isReminderDone: false,
isArchived: false, // Optional: exclude archived notes
trashedAt: null, // Exclude trashed notes
},
select: {
id: true,
title: true,
content: true,
reminder: true,
// Add other fields useful for notification
},
});
if (dueNotes.length === 0) {
return NextResponse.json({
success: true,
count: 0,
message: 'No due reminders found'
});
}
// 2. Mark them as done (Atomic operation logic would be better but simple batch update is fine here)
const noteIds = dueNotes.map((n: any) => n.id);
await prisma.note.updateMany({
where: {
id: { in: noteIds }
},
data: {
isReminderDone: true
}
});
// 3. Return the notes to N8N so it can send emails/messages
return NextResponse.json({
success: true,
count: dueNotes.length,
reminders: dueNotes
});
} catch (error) {
console.error('Error processing cron reminders:', error);
return NextResponse.json(
{ success: false, error: 'Internal Server Error' },
{ status: 500 }
);
}
}