src/lib/auth.js and is mounted at /api/auth/[...nextauth]. The edge proxy (src/proxy.js) enforces a session on /dashboard, /form, /view, /admin, and /api (except /api/public and NextAuth).
Roles and access
What each level can view and edit on a plan.
Role preview
Super Admin JWT impersonation of demo Principal and AP accounts.
Sign-in rules
A Google account can enter the app only when all of the following are true:- Email ends with
@schools.nyc.gov(Googlehdis set to that domain; the callback still checks the suffix). - A matching
Userdocument exists (emaillowercase, unique). isActiveis notfalse.- NextAuth
signIncallback returnstrue.
/login. Inactive accounts cannot sign in even if the Google mailbox is valid.
prompt is select_account. Cookies are Secure when NEXTAUTH_URL starts with https://.
Level is not self-service. Only Super Admin (5) can create level 4–5 users. Principals (4) may create levels 1–3 for their school. Demo
d79.demo.* users cannot Google-sign-in.Session
JWT callback copies from MongoDB onto the token. Session callback exposes:
getServerSession(authOptions) and then re-load User by session email for authorization. During role preview, that email is the demo user.
Each token has a jti. On signOut, Redis stores sess:deny:{jti} until expiry so the cookie cannot be reused. Proxy rejects denied tokens with 401.
Client usage
/, /about) still fetch /api/public/overview without a session. If status === 'authenticated', the portal CTA becomes Open dashboard.