Aegis Auth is a secure, feature-rich authentication library for Next.js and Node.js applications. It provides everything you need to handle user authentication and session management—including user registration, login/logout, email verification, password resets, rate limiting, role management, and CSRF protection—all while following best security practices.
Note: Aegis Auth uses Prisma for database interactions, Upstash Redis for rate limiting, and Resend for email delivery.
- User Registration: Secure sign-up with input validation and duplicate user prevention.
- User Login & Logout: Create and revoke sessions with rate limiting and account lockout support.
- Session Management: Create, validate, rotate, and revoke user sessions (with rolling sessions support).
- Password Reset: Initiate and complete password resets using secure verification tokens.
- Email Verification: Verify user emails during registration or upon request using customizable email templates.
- Rate Limiting: Protect endpoints against abuse by limiting the number of requests per IP using Upstash Redis.
- CSRF Protection: Generate and verify CSRF tokens to secure state-changing requests.
- Role Management: Assign and update user roles (
updateUserRoles
) and ban/unban users for added security. - Secure Password Hashing: Utilizes the scrypt algorithm for password hashing.
- Flexible Configuration: Customize every aspect of Aegis Auth via environment variables or by passing a configuration object.
Install the package via npm, Yarn, or pnpm:
npm install aegis-auth
# or
yarn add aegis-auth
# or
pnpm add aegis-auth
Before using Aegis Auth, ensure you have the following set up:
- Node.js (v14 or higher)
- Database Connection: Configure your database (PostgreSQL is supported) via the
DATABASE_URL
environment variable. - Upstash Redis: For rate limiting, provide
KV_REST_API_URL
andKV_REST_API_TOKEN
in your environment. - Resend API: For email notifications, set the
RESEND_API_KEY
environment variable. - Environment Variables: See the .env.example file for required and optional settings.
Aegis Auth is highly configurable. You can override the default settings by providing a custom configuration object when you instantiate the library. For example:
import { PrismaClient } from "@prisma/client";
import { AegisAuth } from "aegis-auth";
const prisma = new PrismaClient();
// Optionally override the default configuration
const customConfig = {
session: {
maxSessionsPerUser: 3, // Limit the number of concurrent sessions per user
},
accountSecurity: {
requireEmailVerification: true, // Force email verification on registration
},
// ...other custom settings
};
const auth = new AegisAuth(prisma, customConfig);
You can also configure most options via environment variables. See the provided .env.example
:
SESSION_TOKEN_SECRET="change-me-in-prod"
CSRF_SECRET="change-me-in-prod"
KV_REST_API_URL="https://..."
KV_REST_API_TOKEN="..."
DATABASE_URL="your_database_connection_string"
NODE_ENV="development"
RESEND_API_KEY="your-resend-api-key"
EMAIL_FROM="[email protected]"
For a full list of configuration options, refer to the configuration schema.
import { PrismaClient } from "@prisma/client";
import { AegisAuth } from "aegis-auth";
const prisma = new PrismaClient();
const auth = new AegisAuth(prisma);
// Example: Register a new user
const registrationResult = await auth.registerUser(
{ headers: request.headers },
{
username: "john_doe",
email: "[email protected]",
password: "SecurePassword123!",
}
);
if (registrationResult.success) {
console.log("User registered:", registrationResult.data.user);
} else {
console.error("Registration error:", registrationResult.message);
}
// Example: Log in a user
const loginResult = await auth.loginUser(
{ headers: request.headers },
{
usernameOrEmail: "[email protected]",
password: "SecurePassword123!",
}
);
if (loginResult.success) {
const { user, session } = loginResult.data;
console.log("Login successful for:", user);
// Use session.sessionToken to set your session cookie
} else {
console.error("Login failed:", loginResult.message);
}
- Session Creation: Performed during login.
- Session Validation & Rotation: Use
validateAndRotateSession
to verify and refresh sessions. - Logout: Revoke the current session.
// Example: Log out a user
const logoutResult = await auth.logoutUser({ sessionToken: "user_session_token" });
if (logoutResult.success) {
console.log("User logged out successfully");
} else {
console.error("Logout error:", logoutResult.message);
}
// Initiate the password reset process (sends an email with a verification token)
const initiateResult = await auth.initiatePasswordReset(
{ headers: request.headers },
{ email: "[email protected]" }
);
console.log(initiateResult.message);
// Complete the password reset using the token sent via email
const completeResult = await auth.completePasswordReset(
{ headers: request.headers },
{
token: "verification_token_from_email",
newPassword: "NewSecurePassword123!",
}
);
if (completeResult.success) {
console.log("Password reset successful");
} else {
console.error("Password reset error:", completeResult.message);
}
When email verification is enabled, a verification email is sent upon registration. To verify the email:
const verificationResult = await auth.verifyEmail(
{ headers: request.headers },
{ token: "verification_token_from_email" }
);
if (verificationResult.success) {
console.log("Email verified successfully");
} else {
console.error("Email verification failed:", verificationResult.message);
}
// Example: Assign or update user roles
const updateRolesResult = await auth.updateUserRoles({
userId: "some_user_id",
roles: ["admin", "moderator"],
});
if (updateRolesResult.success) {
console.log("Roles updated successfully");
} else {
console.error("Failed to update roles:", updateRolesResult.message);
}
// Example: Ban a user
const banResult = await auth.banUser({ userId: "some_user_id" });
if (banResult.success) {
console.log("User banned successfully");
} else {
console.error("Ban error:", banResult.message);
}
// Example: Unban a user
const unbanResult = await auth.unbanUser({ userId: "some_user_id" });
if (unbanResult.success) {
console.log("User unbanned successfully");
} else {
console.error("Unban error:", unbanResult.message);
}
These actions are not automatically restricted to administrators. In your application, you should implement your own checks (e.g., only call banUser
if the current user is an admin).
Aegis Auth includes a comprehensive suite of tests using Jest. To run the tests:
npm test
To build the project, run:
npm run build
Lint your code with:
npm run lint
Security is a top priority. If you discover any vulnerabilities, please refer to our SECURITY.md for instructions on reporting issues.
Aegis Auth is licensed under the MIT License. See the LICENSE file for details.
For questions, support, or contributions, please open an issue on GitHub or email [email protected].
Happy coding!