My-Weekly-ToDo-List/src/middleware.ts
mARTin f9c7893341 feat: add push notifications for calendar event reminders
- Service worker + Web Push API for browser/mobile notifications
- PWA manifest with icons for home screen install (iOS 16.4+)
- Push subscription management (subscribe/unsubscribe API routes)
- Notification toggle in Settings > General
- Push scheduler script (cron) checks cached events and sends
  notifications at reminder times, with dedup tracking
- Test notification endpoint at /api/push/test
- Persists reminders in calendar event cache for scheduler access
- New DB models: PushSubscription, SentNotification
- New user field: notificationsEnabled

Setup: generate VAPID keys with `npx tsx scripts/generate-vapid-keys.ts`
and add to .env, then run scheduler via cron every minute.

v1.37.0
2026-03-16 21:38:15 +01:00

45 lines
1.3 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import { getToken } from 'next-auth/jwt';
export async function middleware(request: NextRequest) {
// Skip middleware for public paths
if (
request.nextUrl.pathname.startsWith('/auth') ||
request.nextUrl.pathname.startsWith('/api/auth') || // CRITICAL: Allow NextAuth API routes
request.nextUrl.pathname.startsWith('/_next') ||
request.nextUrl.pathname === '/favicon.ico' ||
request.nextUrl.pathname === '/sw.js' ||
request.nextUrl.pathname === '/manifest.webmanifest'
) {
return NextResponse.next();
}
// Check if user is authenticated using NextAuth
const token = await getToken({
req: request,
secret: process.env.NEXTAUTH_SECRET,
});
// Redirect to login if not authenticated
if (!token && !request.nextUrl.pathname.startsWith('/auth')) {
const url = request.nextUrl.clone();
url.pathname = '/auth/login';
url.searchParams.set('callbackUrl', request.nextUrl.pathname);
return NextResponse.redirect(url);
}
return NextResponse.next();
}
export const config = {
matcher: [
/*
* Match all request paths except:
* - api/auth/* (NextAuth endpoints)
* - _next/static (static files)
* - _next/image (image optimization)
* - favicon.ico
*/
'/((?!_next/static|_next/image|favicon.ico).*)',
],
};