Security

Authentication

LearnHub uses NextAuth v5 for secure, flexible authentication with support for OAuth providers and credentials-based login.

NextAuth Configuration

Authentication is configured in src/lib/auth.ts.

Key Configuration

// src/lib/auth.ts
import NextAuth from "next-auth";
import { PrismaAdapter } from "@auth/prisma-adapter";

export const { handlers, auth, signIn, signOut } = NextAuth({
  adapter: PrismaAdapter(prisma),
  session: { strategy: "jwt" },
  pages: {
    signIn: "/login",
    error: "/login",
  },
  providers: [
    Google({ ... }),
    GitHub({ ... }),
    Credentials({ ... }),
  ],
  callbacks: {
    async jwt({ token, user }) { ... },
    async session({ session, token }) { ... },
  },
});

OAuth Providers

Configure Google and GitHub OAuth for social login.

Google OAuth Setup

  1. Go to Google Cloud Console
  2. Create a new project or select existing
  3. Enable Google+ API
  4. Create OAuth 2.0 credentials
  5. Add authorized redirect URI: https://your-domain.com/api/auth/callback/google
  6. Copy Client ID and Secret to environment variables

GitHub OAuth Setup

  1. Go to GitHub Developer Settings
  2. Click "New OAuth App"
  3. Set Homepage URL to your domain
  4. Set Authorization callback URL: https://your-domain.com/api/auth/callback/github
  5. Copy Client ID and Secret to environment variables

Credentials Authentication

Email/password authentication using bcrypt for secure password hashing.

Credentials Provider

Credentials({
  credentials: {
    email: { label: "Email", type: "email" },
    password: { label: "Password", type: "password" },
  },
  async authorize(credentials) {
    const user = await prisma.user.findUnique({
      where: { email: credentials.email },
      include: { role: true },
    });

    if (!user?.password) return null;

    const isValid = await bcrypt.compare(
      credentials.password,
      user.password
    );

    if (!isValid) return null;

    return {
      id: user.id,
      email: user.email,
      name: user.name,
      role: user.role.name,
    };
  },
})

Password Requirements

  • Minimum 8 characters
  • Hashed using bcrypt with 12 rounds
  • Stored securely in database
  • Never transmitted in plain text