Changes: - Updated BillingLocation interface: - Added utilBillsProofOfPaymentAttachment field (BillAttachment type) - Added server action uploadUtilBillsProofOfPayment: - Validates PDF file type - Serializes file attachment to base64 - Stores attachment in BillingLocation document - Returns success/error status - Updated ViewLocationCard component: - Added file upload input with PDF-only accept - Implemented handleFileChange with immediate upload - Added upload state management (isUploading, uploadError, attachment) - Shows spinner while uploading - Input disabled during upload - Conditionally renders file input or download link - Link displayed after successful upload - Created route handler for serving proof of payment PDFs: - GET /share/proof-of-payment/[id]/route.tsx - Fetches attachment from database - Converts base64 to binary - Returns PDF with proper headers - Added not-found page for proof of payment route - Updated middleware to include proof-of-payment in public pages - Added translations: - en: "Upload proof of payment (PDF only)" - hr: "Priložite potvrdu o uplati:" File uploads immediately on selection without page reload. Only PDF files accepted with client and server-side validation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
53 lines
1.8 KiB
TypeScript
53 lines
1.8 KiB
TypeScript
/**
|
|
* @module middleware
|
|
* @description hooks-up `next-auth` into the page processing pipeline
|
|
*/
|
|
|
|
import { auth, authConfig, myAuth } from '@/app/lib/auth'
|
|
import createIntlMiddleware from 'next-intl/middleware';
|
|
import { NextRequest, NextResponse } from 'next/server';
|
|
import { locales, defaultLocale } from '@/app/i18n';
|
|
import { Session } from 'next-auth';
|
|
|
|
// http://localhost:3000/share/location/675c41b227d0df76a35f106e
|
|
const publicPages = ['/terms', '/policy', '/login', '/share/location/.*', '/share/bill/.*', '/share/attachment/.*', '/share/proof-of-payment/.*'];
|
|
|
|
const intlMiddleware = createIntlMiddleware({
|
|
locales,
|
|
localePrefix: 'as-needed',
|
|
defaultLocale
|
|
});
|
|
|
|
export default async function middleware(req: NextRequest) {
|
|
const publicPathnameRegex = RegExp(
|
|
`^(/(${locales.join('|')}))?(${publicPages
|
|
.flatMap((p) => (p === '/' ? ['', '/'] : p))
|
|
.join('|')})/?$`,
|
|
'i'
|
|
);
|
|
const isPublicPage = publicPathnameRegex.test(req.nextUrl.pathname);
|
|
|
|
// for public pages we call only localisation middleware
|
|
// this is not an official way to do it - it's a hack
|
|
// based on https://github.com/nextauthjs/next-auth/discussions/8961
|
|
// The official way of chaining middlewares in AuthJS v5 does not work and is not fully documented
|
|
if (!isPublicPage) {
|
|
|
|
const session = await myAuth();
|
|
|
|
if (!session) {
|
|
const signInUrl = `${req.nextUrl.protocol}//${req.nextUrl.hostname}${req.nextUrl.port ? `:${req.nextUrl.port}` : ''}${authConfig.pages?.signIn as string}`;
|
|
return NextResponse.redirect( signInUrl );
|
|
}
|
|
}
|
|
|
|
return intlMiddleware(req);
|
|
}
|
|
|
|
export const config = {
|
|
// for these paths middleware will not be called
|
|
// `pdf.worker.min.mjs` is a web worker code used by pdf.js
|
|
matcher: [
|
|
'/((?!api|_next/static|_next/image|.*\\.png$|pdf.worker.min.mjs$|.*\\.webm$).*)',
|
|
],
|
|
}; |