A login and session management demo built with Next.js 15, Supabase, and TypeScript. Supports email/password and Google OAuth, with a protected dashboard, idle detection, hard session limit, and automatic token refresh.
Topics: nextjs typescript supabase authentication session-management refresh-token idle-detection oauth tailwindcss
- Next.js 15 App Router + Server Actions
- TypeScript strict mode
- Supabase SSR (
@supabase/ssr) — auth + Postgres database - Tailwind v4 CSS-first — tokens in
globals.css @theme - Zod — form validation
- Email/password sign-in
- Google OAuth
- Protected
/dashboardroute (middleware + layout guard) - Session stored in
user_sessionstable with 30-minute hard limit - Idle detection — 10 min inactivity shows a warning modal
- 60-second countdown with "Stay signed in" / "Sign out"
- Token refresh on activity via
supabase.auth.refreshSession() - Automatic redirect on session expiry
git clone <repo-url>
cd auth-flow
pnpm installCopy .env.local.example to .env.local and fill in:
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
NEXT_PUBLIC_ORIGIN=http://localhost:3000Run this SQL in the Supabase SQL Editor:
create table user_sessions (
id uuid primary key default gen_random_uuid(),
user_id uuid references auth.users(id) on delete cascade,
last_active_at timestamptz default now(),
created_at timestamptz default now(),
expires_at timestamptz default (now() + interval '30 minutes')
);
alter table user_sessions enable row level security;
create policy "Users manage own sessions"
on user_sessions for all
using (auth.uid() = user_id)
with check (auth.uid() = user_id);Authentication → Providers → Email: enabled, confirm email: off (dev)
Authentication → Providers → Google: enabled, add Client ID + Secret
Authentication → URL Configuration → Site URL: http://localhost:3000
Authentication → URL Configuration → Redirect URLs: http://localhost:3000/auth/callback
Authentication → Sessions → JWT expiry: 1800
pnpm devOpen http://localhost:3000.
app/
login/ — sign-in form + Google OAuth button
auth/callback/ — OAuth code exchange handler
dashboard/ — protected area (layout guard + SessionProvider)
profile/ — example protected sub-route
components/
ui/ — Button, Input primitives
session/ — SessionProvider, IdleWarningModal, useIdleSession
lib/
session.ts — createSession, extendSession, invalidateSession, getSession
supabase/ — server + browser Supabase clients
middleware.ts — session refresh + route guard