Skip to content

A credentials-based auth solution for Next.js (and other Node projects) with IP rate-limiting, account lockouts, and sessions in DB.

License

Notifications You must be signed in to change notification settings

Simon-Fontaine/aegis-auth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

77 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Aegis Auth

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.

Features

  • 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.

Installation

Install the package via npm, Yarn, or pnpm:

npm install aegis-auth
# or
yarn add aegis-auth
# or
pnpm add aegis-auth

Prerequisites

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 and KV_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.

Configuration

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.

Usage

Initializing Aegis Auth

import { PrismaClient } from "@prisma/client";
import { AegisAuth } from "aegis-auth";

const prisma = new PrismaClient();
const auth = new AegisAuth(prisma);

Registering a New User

// 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);
}

Logging In

// 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);
}

Managing Sessions

  • 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);
}

Password Reset

Initiate Password Reset

// 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 Password Reset

// 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);
}

Email Verification

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);
}

Role Management & Banning

Update User Roles

// 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);
}

Ban a User

// 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);
}

Unban a User

// 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).

Testing

Aegis Auth includes a comprehensive suite of tests using Jest. To run the tests:

npm test

Development

To build the project, run:

npm run build

Lint your code with:

npm run lint

Security

Security is a top priority. If you discover any vulnerabilities, please refer to our SECURITY.md for instructions on reporting issues.

License

Aegis Auth is licensed under the MIT License. See the LICENSE file for details.

Contact

For questions, support, or contributions, please open an issue on GitHub or email [email protected].


Happy coding!

About

A credentials-based auth solution for Next.js (and other Node projects) with IP rate-limiting, account lockouts, and sessions in DB.

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published