Authentication Flow

Learn how CareNova handles user authentication, session management, email confirmation, and the pending approval workflow.

Written By Dev010

Last updated 19 days ago

CareNova uses Supabase Auth for user authentication combined with application-level session validation, role enforcement, and an admin approval workflow. This guide explains the complete authentication flow from signup through to dashboard access.

Authentication Method

CareNova uses email and password authentication for all staff accounts. There is no social login or SSO in the current version.

All authentication requests are processed through Supabase Auth. CareNova then handles session validation, role assignment, and permission enforcement at the application level.

Login Flow

When a staff member logs in, the following sequence occurs:

User submits email + password
        ↓
Supabase validates credentials
        ↓
Rate limit check (by email + IP)
        ↓
Session token generated
        ↓
Session stored in HTTP-only cookie
        ↓
CareNova middleware validates session
        ↓
Role and permissions loaded
        ↓
User redirected to /dashboard

Login page:

https://yourdomain.com/login

After successful login:

https://yourdomain.com/dashboard

What Happens on the Server

After Supabase validates credentials, CareNova performs additional checks before granting dashboard access:

  1. Confirms the user exists in the users table

  2. Checks that approved_at is not null (account has been approved by admin)

  3. Loads the user's role from the users table

  4. Loads the role's permissions from role_permissions

  5. Renders the dashboard filtered to the user's role and permissions

If any of these checks fail, the user is redirected appropriately β€” either back to login or to the pending approval screen.

Session Management

CareNova stores sessions in HTTP-only cookies managed by @supabase/ssr.

Property

Value

Storage

HTTP-only cookie

Accessible to JavaScript

❌ No

Refreshed automatically

βœ… Yes (via middleware)

Validated on every request

βœ… Yes

Timeout on auth check

6 seconds

On every request to a /dashboard route, the middleware calls updateSession() which:

  • Validates the current session cookie

  • Refreshes the token if it is close to expiry

  • Redirects to /login if the session is missing or invalid

Because sessions are stored in HTTP-only cookies, they are not accessible to client-side JavaScript. This protects session tokens from XSS attacks.

Signup and Approval Flow

CareNova uses a two-step account activation process for new staff members:

Staff member signs up at /signup
        ↓
Email confirmation sent via Resend/SMTP
        ↓
Staff member confirms email address
        ↓
Account created with approved_at = null
        ↓
Staff member sees "Pending Approval" screen
        ↓
Admin approves account in dashboard
        ↓
approved_at set to current timestamp
        ↓
Staff member can now log in

Pending Approval Screen

After a staff member confirms their email, they will see a pending approval message when attempting to log in. This screen appears when approved_at is null on their account.

The URL will include ?pending=1:

https://yourdomain.com/login?pending=1

As Admin, approve waiting accounts at:

Dashboard β†’ Pending Approval

Click Approve next to the user and assign them their correct role. Once approved, the staff member can log in immediately.

Rejected accounts are not deleted β€” they are simply not approved. The admin can approve them later if needed.

Rate Limiting and Brute-Force Protection

CareNova enforces rate limiting on the login endpoint to prevent brute-force attacks.

Rule

Limit

Failed attempts by email

5 within 15 minutes

Failed attempts by IP

10 within 15 minutes

Lockout duration

Until oldest attempt is >15 min old

Lockout message

"Too many failed login attempts. Please try again in 15 minutes."

When a lockout is triggered:

  • Further login attempts are blocked

  • The event is recorded in auth_audit_log

  • The lockout lifts automatically after the 15-minute window passes

Rate limiting is enforced separately by both email address and IP address. This means an attacker cannot bypass the email lockout by rotating email addresses from the same IP.

Password Policy

All passwords must meet the following requirements:

Rule

Requirement

Minimum length

8 characters

Uppercase letter

At least one

Lowercase letter

At least one

Number

At least one

Special character

At least one (@$!%*?&)

The following common passwords are explicitly blocked regardless of meeting the above rules: password, password123, 123456789, admin123, clinic123, carenova123, welcome1

Authentication Audit Log

Every authentication event is recorded in the auth_audit_log table:

Event

Recorded

Successful login

βœ…

Failed login

βœ…

Logout

βœ…

Rate limit triggered

βœ…

Account approved

βœ…

Account rejected

βœ…

Each log entry captures:

  • User ID and email

  • Event type

  • IP address

  • User agent

  • Timestamp

Admins can review this log directly in Supabase under Table Editor β†’ auth_audit_log.

The cron job at /api/cron/cleanup-auth deletes audit log entries older than 24 hours to keep the table lean. See the Cron Setup guide for configuration details.

Session Tracking

In addition to cookie-based sessions, CareNova tracks active sessions in the user_sessions table. This enables:

  • Visibility into active sessions per user

  • Session revocation by admins

  • Device and IP tracking per session

Sessions are recorded on login with:

  • Session token (hashed)

  • IP address

  • User agent

  • Device info

  • Expiry timestamp

The session ping is throttled β€” activity is updated at most every 5 minutes to avoid unnecessary database writes.

Middleware Route Protection

The Next.js middleware enforces authentication on every request:

Route

Behavior

/login, /signup

If already logged in β†’ redirect to /dashboard

/dashboard/*

Requires valid session β†’ else redirect to /login

/setup

If already licensed β†’ redirect to /dashboard

All other routes

Public β€” no auth required

The middleware has a 6-second timeout on auth checks. If Supabase does not respond within 6 seconds, the user is redirected to /login as a fail-safe.

Relationship With Role-Based Access Control

Authentication confirms who the user is. Role-Based Access Control determines what they can do.

After a successful login:

  1. The user's role is loaded from users

  2. The role's permissions are loaded from role_permissions

  3. The dashboard navigation is filtered to show only permitted modules

  4. Every server action re-validates the role before executing any mutation

Authentication and RBAC are always enforced together β€” a valid session alone is not sufficient to access protected data.

For full details on roles and permissions, see the Roles Overview and Role-Based Access Control guides.

Troubleshooting

"Too many login attempts" error:

  • Wait 15 minutes for the lockout to expire

  • The lockout applies per email and per IP

  • Contact your admin if you are locked out in a production environment

Stuck on "Pending Approval" screen:

  • Your email is confirmed but an admin has not yet approved your account

  • Contact your clinic administrator to approve your account in Dashboard β†’ Pending Approval

Redirected to login immediately after logging in:

  • Your session may have expired β€” try logging in again

  • Check that cookies are enabled in your browser

  • Confirm the Supabase project is active and not paused (free tier projects pause after 1 week of inactivity)

Email confirmation link not working:

  • Confirm redirect URLs are configured in Supabase β†’ Authentication β†’ URL Configuration

  • Confirm NEXT_PUBLIC_SITE_URL matches your actual domain

  • Check the Supabase Setup guide for SMTP configuration

Next Step

Continue to Rate Limiting & Security for a deeper look at CareNova's brute-force protection, audit logging, and session security architecture.