The application supports two authentication methods for maximum flexibility:
- Email/Password - Traditional username/password authentication with bcrypt hashing
- LDAP - Enterprise directory authentication with auto-provisioning
Username: root
Password: Must-Changed
Note: You will be prompted to change the password on first login.
Local database authentication:
- Passwords hashed with bcrypt
- Stored in PostgreSQL users table
- Supports password change flow
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
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- Generated on successful login
- Stored in localStorage
- Default expiration: 7 days
- Included in all authenticated requests
// 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 requestsPages check for authentication token:
useEffect(() => {
const token = localStorage.getItem('authToken');
if (!token) {
router.push('/login');
}
}, [router]);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 } });
});Users with mustChangePassword: true:
- Log in with initial password
- See password change form
- Set new password (min 8 characters)
- Access application
For more details, see:
- Login Verification - Complete login flow verification
- Authentication Flow - Detailed authentication diagrams
- LDAP Setup - LDAP configuration guide
✅ 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
- Minimum 8 characters for password changes
- Consider adding complexity requirements in production
trpc.auth.login.mutate({
username: string,
password: string,
authType: 'email' | 'ldap',
})trpc.auth.changePassword.mutate({
token: string,
newPassword: string,
})trpc.auth.verifyToken.query({
token: string,
})