Skip to content

Latest commit

 

History

History
168 lines (122 loc) · 3.45 KB

File metadata and controls

168 lines (122 loc) · 3.45 KB

Authentication

Overview

The application supports two authentication methods for maximum flexibility:

  1. Email/Password - Traditional username/password authentication with bcrypt hashing
  2. LDAP - Enterprise directory authentication with auto-provisioning

Quick Start

Default Credentials

Username: root
Password: Must-Changed

Note: You will be prompted to change the password on first login.

Authentication Methods

Email/Password

Local database authentication:

  • Passwords hashed with bcrypt
  • Stored in PostgreSQL users table
  • Supports password change flow

LDAP

Enterprise directory authentication powered by ldapts:

  • Supports OpenLDAP and Active Directory
  • Auto-creates user accounts on first login
  • Syncs user information from LDAP
  • Advanced capabilities: Query mail groups and directory objects
  • TypeScript-native with full type safety

Configuration

Set in .env:

# JWT Secret (required)
JWT_SECRET=your-secret-key-change-in-production

# LDAP (optional)
LDAP_URL=ldap://ldap.company.com:389
LDAP_BIND_DN=cn=admin,dc=company,dc=com
LDAP_BIND_PASSWORD=password
LDAP_SEARCH_BASE=ou=users,dc=company,dc=com
LDAP_USERNAME_ATTRIBUTE=uid  # or sAMAccountName for AD

Token Management

JWT Tokens

  • Generated on successful login
  • Stored in localStorage
  • Default expiration: 7 days
  • Included in all authenticated requests

Usage

// Login returns token
const { token } = await trpc.auth.login.mutate({
  username: 'user',
  password: 'pass',
  authType: 'email',
});

// Store token
localStorage.setItem('authToken', token);

// Token automatically included in subsequent requests

Protected Routes

Client-Side Protection

Pages check for authentication token:

useEffect(() => {
  const token = localStorage.getItem('authToken');
  if (!token) {
    router.push('/login');
  }
}, [router]);

Server-Side Protection

tRPC procedures use protectedProcedure:

const protectedProcedure = publicProcedure.use(async ({ ctx, next }) => {
  if (!ctx.user) {
    throw new TRPCError({ code: 'UNAUTHORIZED' });
  }
  return next({ ctx: { user: ctx.user } });
});

First Login

Users with mustChangePassword: true:

  1. Log in with initial password
  2. See password change form
  3. Set new password (min 8 characters)
  4. Access application

Detailed Documentation

For more details, see:

Security Best Practices

Production Checklist

✅ Change JWT_SECRET to a strong random value ✅ Use HTTPS in production ✅ Implement rate limiting on login attempts ✅ Add CSRF protection ✅ Use LDAPS (secure LDAP) if using LDAP ✅ Implement session timeout ✅ Add audit logging for authentication events ✅ Consider implementing MFA

Password Requirements

  • Minimum 8 characters for password changes
  • Consider adding complexity requirements in production

API Reference

Login

trpc.auth.login.mutate({
  username: string,
  password: string,
  authType: 'email' | 'ldap',
})

Change Password

trpc.auth.changePassword.mutate({
  token: string,
  newPassword: string,
})

Verify Token

trpc.auth.verifyToken.query({
  token: string,
})