npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@flycatch/auth-core

v1.4.0

Published

A unified authentication module for Express.js, NestJS frameworks, supporting JWT, session-based, and Google OAuth login.

Readme

Auth-Core

Auth-Core is a unified authentication middleware for Node.js applications, supporting JWT-based authentication, session-based authentication, and OAuth 2.0 authentication. This package simplifies authentication management by providing middleware functions that handle authentication flows seamlessly.

Features

  • JWT Authentication with optional token blacklisting and logout
  • Session-based Authentication with multiple sessions per user
  • OAuth 2.0 Authentication (Google, GitHub, and custom providers)
  • Two-Factor Authentication (2FA) integrated with JWT and session-based authentication
  • User Service Integration
  • Customizable Password Checker
  • Role & Permission-Based Access Control

Installation

npm install @flycatch/auth-core

Usage

Import and Configure Auth-Core

const express = require("express");
const { config, verify } = require("@flycatch/auth-core");
const bcrypt = require("bcrypt");

const app = express();

const userRepository = {
  async find(email) {
    return {
      id: "123",
      email,
      username: "exampleUser",
      grants: ["read_user"],
      is2faEnabled: false,
    };
  },
};

app.use(
  config({
    jwt: {
      enabled: true,
      secret: "my_jwt_secret",
      expiresIn: "1h",
      refresh: true,
      prefix: "/auth/jwt",
      tokenBlacklist: {
        enabled: false, // Set to true for server-side logout
      },
    },
    session: {
      enabled: false,
      prefix: "/auth/session",
      secret: "my_session_secret",
      resave: false,
      saveUninitialized: true,
      cookie: { secure: false, maxAge: 60000 },
    },
    oauth2: {
      enabled: true,
      baseURL: "http://localhost:3000",
      prefix: "/auth",
      successRedirect: "http://localhost:3000/oauth-success",
      failureRedirect: "http://localhost:3000/oauth-failure",
      defaultRole: "ROLE_USER",
      onSuccess(info)=>{
        const {profile, existingUser,} =info;
        if(existingUser){
          return existingUser;
        }

        // Logic to create new user
        reateUser(profile)
      },
      onfailure(info)=>{
      // Logic to be executed onFailure
      },
      providers: {
        google: {
          clientID: "GOOGLE_CLIENT_ID",
          clientSecret: "GOOGLE_CLIENT_SECRET",
          callbackURL: "/auth/google/callback",
          scope: ["profile", "email"],
        },
      },
    },
    twoFA: {
      enabled: false,
      prefix: "/auth/2fa",
      otpLength: 6,
      otpExpiresIn: "5m",
      storeOtp: async (userId, otp, expiresInMs) => {
        // Implement OTP storage logic
        console.log(
          `Storing OTP ${otp} for user ${userId}, expires in ${expiresInMs}ms`
        );
      },
      getStoredOtp: async (userId) => {
        // Implement OTP retrieval logic
        return null;
      },
    },
    userService: {
      loadUser: async (email) => userRepository.find(email),
      createUser: async (profile) => {
        return {
          id: "new-user-id",
          email: profile.email,
          username: profile.username,
          grants: [profile.defaultRole || "ROLE_USER"],
        };
      },
    },
    passwordChecker: async (inputPassword, storedPassword) =>
      bcrypt.compare(inputPassword, storedPassword),
    logs: true,
  })
);

// Protected Route
app.get("/user", verify(), (req, res) => {
  res.json({ message: "Access granted", user: req.user });
});

// Protected Route with specific permission
app.get("/admin", verify("admin"), (req, res) => {
  res.json({ message: "Admin access granted", user: req.user });
});

app.listen(3000, () => {
  console.log("Server running on http://localhost:3000");
});

Configuration Options

JWT Authentication

jwt: {
  enabled: true,
  secret: "my_jwt_secret",
  expiresIn: "1h",
  refresh: true,
  refreshExpiresIn: "7d",
  prefix: "/auth/jwt",
  revokeOnRefresh: true,
  tokenBlacklist: {
    enabled: false,
    storageService: {
      add: async (token, expiresAt) => { /* Custom add logic */ },
      has: async (token) => { /* Custom check logic */ },
      remove: async (token) => { /* Custom remove logic */ },
      clear: async () => { /* Custom clear logic */ },
    },
    onLogoutAll: async (userId) => { /* Custom logout all logic */ },
  }
}
  • enabled: Enables or disables JWT authentication.
  • secret: The secret key used to sign JWT tokens.
  • expiresIn: Access token expiration time.
  • refresh: Enables refresh token support.
  • refreshExpiresIn: Refresh token expiration time.
  • prefix: The route prefix for JWT authentication endpoints.
  • tokenBlacklist: Optional token blacklisting for secure logout.
    • enabled: Enables server-side token blacklisting.
    • storageService: Custom storage for blacklisted tokens.
    • onLogoutAll: Callback for custom cleanup on logout-all.

Session-Based Authentication

session: {
  enabled: true,
  prefix: "/auth/session",
  secret: "my_session_secret",
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: false,
    maxAge: 24 * 60 * 60 * 1000 // 24 hours
  }
}
  • enabled: Enables session-based authentication.
  • prefix: Route prefix for session authentication endpoints.
  • secret: Session secret key.
  • resave/saveUninitialized: Express session options.
  • cookie: Session cookie configuration.

Note: Session authentication supports multiple concurrent sessions per user. Each login creates a new independent session.

OAuth 2.0 Authentication

oauth2: {
  enabled: true,
  baseURL: "http://localhost:3000",
  prefix: "/auth",
  successRedirect: "http://localhost:3000/oauth-success",
  failureRedirect: "http://localhost:3000/oauth-failure",
  onSuccess(info)=>{
    const {profile, existingUser,} =info;
    if(existingUser){
      return existingUser;
    }

    // Logic to create new user
    createUser(profile)
  },
  onfailure(info)=>{
    // Logic to be executed onFailure
  }
  defaultRole: "ROLE_USER",
  setRefreshCookie: true,
  appendTokensInRedirect: false,
  providers: {
    google: {
      clientID: "GOOGLE_CLIENT_ID",
      clientSecret: "GOOGLE_CLIENT_SECRET",
      callbackURL: "/auth/google/callback",
      scope: ["profile", "email"],
    },
    github: {
      clientID: "GITHUB_CLIENT_ID",
      clientSecret: "GITHUB_CLIENT_SECRET",
      callbackURL: "/auth/github/callback",
    },
  },
}
  • enabled: Enables OAuth 2.0 authentication.
  • baseURL: Base URL for callback redirects.
  • prefix: Route prefix for OAuth authentication endpoints.
  • successRedirect: URL to redirect after successful OAuth authentication.
  • failureRedirect: URL to redirect after failed OAuth authentication.
  • onSuccess: Callback executed on successful OAuth2 authentication, This is where user registration/creation logic should be implemented
  • onFailure: Callback executed on OAuth2 authentication failure
  • defaultRole: Default role assigned to new users.
  • providers: Supported providers (e.g., Google, GitHub).

Two-Factor Authentication

twoFA: {
  enabled: true,
  otpLength: 6,
  otpType: "numeric",
  otpExpiresIn: "5m",
  transport: async (otp, user) => {
    console.log(`Send OTP ${otp} to ${user.email}`);
  },
  storeOtp: async (userId, otp, expiresInMs) => {
    // Implement OTP storage
  },
  getStoredOtp: async (userId) => {
    // Implement OTP retrieval
    return null;
  },
  clearOtp: async (userId) => {
    // Implement OTP cleanup
  },
}
  • enabled: Enables 2FA for JWT or session-based authentication.
  • otpLength: Length of the OTP.
  • otpType: Type of OTP (numeric or alphanumeric).
  • otpExpiresIn: OTP expiration time.
  • transport: Function to send OTP to the user.
  • storeOtp: Function to store OTP securely.
  • getStoredOtp: Function to retrieve stored OTP.
  • clearOtp: Optional function to clear OTP after verification.

User Service Integration

userService: {
  loadUser: async (email) => userRepository.find(email),
  createUser: async (profile) => {
    // Create new user during OAuth flow
    return {
      id: "new-user-id",
      email: profile.email,
      username: profile.username,
      grants: [profile.defaultRole || "ROLE_USER"],
    };
  },
}
  • loadUser: Load user by email (required).
  • createUser: Create new user during OAuth auto-provisioning (required for OAuth).

Custom Password Checker

passwordChecker: async (inputPassword, storedPassword) =>
  bcrypt.compare(inputPassword, storedPassword);

API Endpoints

All endpoints use the configured prefix. Default prefixes shown below:

JWT Authentication

  • POST /auth/jwt/login - Initiate user login (sends OTP if 2FA enabled, else returns tokens)
  • POST /auth/jwt/verify - Verify OTP for 2FA and return tokens
  • POST /auth/jwt/refresh - Refresh access token
  • POST /auth/jwt/logout - Logout (simple or with blacklisting)
  • POST /auth/jwt/logout-all - Logout all sessions (requires blacklisting enabled)

Session Authentication

  • POST /auth/session/login - Initiate user login (sends OTP if 2FA enabled, else creates session)
  • POST /auth/session/verify - Verify OTP for 2FA and create session
  • POST /auth/session/logout - Logout current session

OAuth 2.0 Authentication

  • GET /auth/{provider} - Initiate OAuth login
  • GET /auth/{provider}/callback - OAuth callback
  • GET /auth/error - OAuth error redirect
  • POST /auth/token - to get token from temporary code

Two-Factor Authentication

  • Integrated with JWT and session authentication flows.
  • If enabled, /login endpoints trigger OTP generation and transport.
  • Use /verify endpoints to validate OTP and complete login.

Authentication Flow

JWT Authentication

  1. User sends login request to /auth/jwt/login.
  2. If 2FA is enabled, server sends OTP and user submits it to /auth/jwt/verify.
  3. On successful verification (or directly if 2FA is disabled), server returns JWT tokens (access + refresh if enabled).
  4. Client includes token in Authorization: Bearer <token> header.
  5. Middleware verifies token and grants access.
  6. Optional: Token blacklisting for secure server-side logout.

Session Authentication

  1. User sends login request to /auth/session/login.
  2. If 2FA is enabled, server sends OTP and user submits it to /auth/session/verify.
  3. On successful verification (or directly if 2FA is disabled), server creates a new session.
  4. Session cookie is automatically sent with requests.
  5. Middleware validates session and grants access.
  6. Supports multiple concurrent sessions per user.

OAuth 2.0 Authentication

  1. User initiates OAuth flow with provider via /auth/{provider}.
  2. After successful authentication, provider redirects to /auth/{provider}/callback.
  3. Server processes authentication and auto-creates user if add any logic onSuccess.
  4. Server redirects to success URL with tokens as cookies.
  5. Subsequent requests use JWT or session authentication.
  6. After successful provider authentication, the temporary code will be set as a query parameter on the redirect URL.
  7. Frontend can then trigger {prefix}/token with a POST request and payload:
{
  "code": "code-from-redirect-url"
}

Logout Behavior

JWT Logout

  • Simple Logout (default): Client removes tokens, server logs event.
  • Advanced Logout (with blacklisting): Server invalidates tokens.
  • Logout All: Invalidates all tokens for a user (requires blacklisting).

Session Logout

  • Destroys current session only.
  • Other sessions remain active (multi-session support).

Middleware Usage

// Protect any route
app.get("/protected", verify(), (req, res) => {
  res.json({ user: req.user });
});

// Require specific permission
app.get("/admin", verify("admin_access"), (req, res) => {
  res.json({ message: "Admin only" });
});

Contributing

Contributions are welcome! Please fork the repository and submit a pull request with your improvements.

License

This project is licensed under the GPL-3.0 License.

More