Major architectural upgrade preparing Echo OCR for self-hosted SaaS deployment: - Auth: Built-in Auth.js v5 with credentials + Authentik OIDC SSO, JWT sessions, middleware route protection, login/signup/setup pages, registration API - UI: Dashboard layout with collapsible sidebar nav, AppShell wrapper, route groups for (dashboard) and (auth), new pages for events/people/reports - Schema: Auth.js tables (Account, Session, VerificationToken), Organization, OrgMember, Location, CollectionDay, Invitation, SystemConfig, ApiKey models; proper User relations to ResponseCard/ActivityLog/Notification - Permissions: Role hierarchy (owner/admin/editor/reviewer/viewer) with action-based permission map and requirePermission/requireAuth helpers - Onboarding: Multi-step setup wizard for first-user bootstrap (account, org, location) with SystemConfig tracking - Events: CollectionDay model with rrule support for recurring church services - Auto-assign: Event-aware card assignment engine replacing getPreviousSunday() - Migration: seed-migration.ts script for upgrading existing deployments Made-with: Cursor
45 lines
901 B
TypeScript
45 lines
901 B
TypeScript
import { auth } from "@/auth";
|
|
import { NextResponse } from "next/server";
|
|
|
|
const publicPaths = [
|
|
"/login",
|
|
"/signup",
|
|
"/setup",
|
|
"/api/auth",
|
|
"/api/health",
|
|
"/api/setup",
|
|
];
|
|
|
|
function isPublic(pathname: string) {
|
|
return publicPaths.some(
|
|
(p) => pathname === p || pathname.startsWith(p + "/")
|
|
);
|
|
}
|
|
|
|
export default auth((req) => {
|
|
const { pathname } = req.nextUrl;
|
|
|
|
if (
|
|
pathname.startsWith("/_next") ||
|
|
pathname.startsWith("/favicon") ||
|
|
pathname.includes(".")
|
|
) {
|
|
return NextResponse.next();
|
|
}
|
|
|
|
if (isPublic(pathname)) {
|
|
return NextResponse.next();
|
|
}
|
|
|
|
if (!req.auth) {
|
|
const loginUrl = new URL("/login", req.url);
|
|
loginUrl.searchParams.set("callbackUrl", pathname);
|
|
return NextResponse.redirect(loginUrl);
|
|
}
|
|
|
|
return NextResponse.next();
|
|
});
|
|
|
|
export const config = {
|
|
matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
|
|
};
|