@rs-tech-hub/nestjs-auth-starter

Complete authentication system for NestJS applications with GraphQL support. Handles user registration, login, email verification, password management, and JWT token refresh with integrated account, profile, and user management.


📚 Table of Contents


🔑 License

This package requires a valid commercial license. A valid license key must be configured to use this package.

Visit https://rstechhub.gumroad.com to purchase a license.

✨ Features

  • 🔐 Complete JWT authentication with access & refresh tokens
  • 📧 Email verification with activation tokens
  • 👤 User registration with automatic account & profile creation
  • 🔄 Token refresh mechanism
  • 🔒 Password update functionality
  • 🚪 Secure login and logout
  • ✉️ Activation token renewal
  • 📊 GraphQL API with resolvers
  • 🛡️ Role-based access control with guards

📋 Prerequisites

  • Node.js >= 18
  • TypeScript >= 5.1.0
  • NestJS >= 11.1.6
  • Prisma ORM v7.0+
  • GraphQL support configured in your NestJS application
  • Required RS-Tech-Hub packages (see installation)

🚀 Quick Start

Installation

# npm
npm install @rs-tech-hub/nestjs-auth-starter \
  @rs-tech-hub/nestjs-account-starter \
  @rs-tech-hub/nestjs-activation-token \
  @rs-tech-hub/nestjs-auth-core \
  @rs-tech-hub/nestjs-clock \
  @rs-tech-hub/nestjs-common-interceptors \
  @rs-tech-hub/nestjs-prisma \
  @rs-tech-hub/nestjs-profile \
  @rs-tech-hub/nestjs-refresh-token \
  @rs-tech-hub/nestjs-service-operation \
  @rs-tech-hub/nestjs-user

# yarn
yarn add @rs-tech-hub/nestjs-auth-starter \
  @rs-tech-hub/nestjs-account-starter \
  @rs-tech-hub/nestjs-activation-token \
  @rs-tech-hub/nestjs-auth-core \
  @rs-tech-hub/nestjs-clock \
  @rs-tech-hub/nestjs-common-interceptors \
  @rs-tech-hub/nestjs-prisma \
  @rs-tech-hub/nestjs-profile \
  @rs-tech-hub/nestjs-refresh-token \
  @rs-tech-hub/nestjs-service-operation \
  @rs-tech-hub/nestjs-user

# pnpm
pnpm add @rs-tech-hub/nestjs-auth-starter \
  @rs-tech-hub/nestjs-account-starter \
  @rs-tech-hub/nestjs-activation-token \
  @rs-tech-hub/nestjs-auth-core \
  @rs-tech-hub/nestjs-clock \
  @rs-tech-hub/nestjs-common-interceptors \
  @rs-tech-hub/nestjs-prisma \
  @rs-tech-hub/nestjs-profile \
  @rs-tech-hub/nestjs-refresh-token \
  @rs-tech-hub/nestjs-service-operation \
  @rs-tech-hub/nestjs-user

Environment Variables

# JWT Configuration
JWT_SECRET=your-secret-key-here
JWT_REFRESH_SECRET=your-refresh-secret-here

# Database
DATABASE_URL=your-database-url

# Optional: Service authentication
SERVICE_TOKEN=internal-service-token

Module Registration

import { Module } from "@nestjs/common";
import { AuthStarterModule } from "@rs-tech-hub/nestjs-auth-starter";

@Module({
  imports: [AuthStarterModule],
})
export class AppModule {}

📖 GraphQL API

Queries

Verify Email Exists

query {
  auth_verifyEmail(verifyEmailInput: { email: "user@example.com" }) {
    success
    email
  }
}

Get Current User

query {
  auth_currentUser {
    user {
      id
      email
      Status
      isVerified
    }
  }
}

Mutations

Sign Up

mutation {
  auth_signUp(
    signUpInput: {
      email: "user@example.com"
      password: "SecurePassword123!"
      firstName: "John"
      lastName: "Doe"
    }
  ) {
    token
    refreshToken
    activationKey
    user {
      id
      email
      isVerified
    }
  }
}

Login

mutation {
  auth_login(
    loginInput: { email: "user@example.com", password: "SecurePassword123!" }
  ) {
    token
    refreshToken
    user {
      id
      email
      Status
    }
  }
}

Activate User

mutation {
  auth_activateUser(
    input: { email: "user@example.com", activationKey: "activation-key-here" }
  )
}

Renew Activation Token

mutation {
  auth_renewActivationToken(input: { email: "user@example.com" }) {
    activationKey
  }
}

Refresh Token

mutation {
  auth_refreshToken(refreshTokenInput: "refresh-token-here") {
    token
    refreshToken
    user {
      id
      email
    }
  }
}

Update Password

mutation {
  auth_updatePassword(
    updatePasswordInput: {
      oldPassword: "OldPassword123!"
      newPassword: "NewPassword123!"
    }
  ) {
    success
  }
}

Logout

mutation {
  auth_logout {
    success
  }
}

🔧 Service Usage

Inject the service in your own modules:

import { Injectable } from "@nestjs/common";
import { AuthStarterService } from "@rs-tech-hub/nestjs-auth-starter";

@Injectable()
export class YourAuthService {
  constructor(private authService: AuthStarterService) {}

  async registerUser(
    email: string,
    password: string,
    firstName: string,
    lastName: string
  ) {
    return await this.authService.signUp({
      email,
      password,
      firstName,
      lastName,
    });
  }

  async loginUser(email: string, password: string) {
    return await this.authService.login({ email, password });
  }

  async activateAccount(email: string, activationKey: string) {
    return await this.authService.activateUser({ email, activationKey });
  }

  async refreshUserToken(userId: string, token: string) {
    return await this.authService.refreshToken({ userId, token });
  }

  async logoutUser(userId: string) {
    return await this.authService.logout({ userId });
  }

  async changePassword(
    userId: string,
    oldPassword: string,
    newPassword: string
  ) {
    return await this.authService.updatePassword({
      userId,
      oldPassword,
      newPassword,
    });
  }

  async getUserInfo(userId: string) {
    return await this.authService.getCurrentUser(userId);
  }
}

🔐 Using Guards

Protect GraphQL Resolvers

import { Resolver, Query, UseGuards } from "@nestjs/graphql";
import {
  GqlAuthGuard,
  CurrentUser,
  AuthenticatedUser,
} from "@rs-tech-hub/nestjs-auth-starter";

@Resolver()
@UseGuards(GqlAuthGuard)
export class ProtectedResolver {
  @Query(() => String)
  async protectedQuery(@CurrentUser() user: AuthenticatedUser) {
    return `Hello ${user.email}`;
  }
}

Role-Based Access Control

import { Resolver, Query, UseGuards } from "@nestjs/graphql";
import {
  GqlAuthGuard,
  Roles,
  RolesGuard,
} from "@rs-tech-hub/nestjs-auth-starter";

@Resolver()
@UseGuards(GqlAuthGuard, RolesGuard)
export class AdminResolver {
  @Query(() => String)
  @Roles("admin")
  async adminOnly() {
    return "Admin content";
  }

  @Query(() => String)
  @Roles("admin", "moderator")
  async staffOnly() {
    return "Staff content";
  }
}

🔄 Complete Authentication Flow

1. User Registration

// 1. User signs up
const signupResult = await authService.signUp({
  email: "user@example.com",
  password: "SecurePass123!",
  firstName: "John",
  lastName: "Doe",
});

// Returns: token, refreshToken, user, activationKey
// Send activationKey to user's email

2. Email Verification

// 2. User clicks activation link with activationKey
const activated = await authService.activateUser({
  email: "user@example.com",
  activationKey: "key-from-email",
});

// User account is now verified and active

3. Login

// 3. User logs in
const loginResult = await authService.login({
  email: "user@example.com",
  password: "SecurePass123!",
});

// Returns: token, refreshToken, user
// Store tokens securely (httpOnly cookies recommended)

4. Token Refresh

// 4. When access token expires, refresh it
const refreshed = await authService.refreshToken({
  userId: "user-id",
  token: "refresh-token",
});

// Returns new access and refresh tokens

📝 Data Types

Sign Up Input

FieldTypeRequiredDescription
emailstringValid email address
passwordstringStrong password
firstNamestringUser's first name
lastNamestringUser's last name

Login Input

FieldTypeRequiredDescription
emailstringUser's email
passwordstringUser's password

Update Password Input

FieldTypeRequiredDescription
oldPasswordstringCurrent password
newPasswordstringNew password

Activate User Input

FieldTypeRequiredDescription
emailstringUser's email
activationKeystringActivation key from email

⚠️ Error Codes

Error CodeDescription
auth-error:invalid-credentialsInvalid email or password
auth-error:user-not-foundUser does not exist
auth-error:user-inactiveUser account is inactive
auth-error:user-already-verifiedUser already verified
auth-error:user-already-activeUser account already active
auth-error:invalid-activation-tokenInvalid or expired activation key
auth-error:account-create-failedAccount creation failed
auth-error:user-create-failedUser creation failed
auth-error:profile-create-failedProfile creation failed
auth-error:expired-tokenJWT token has expired
auth-error:invalid-tokenJWT token is invalid

💡 Best Practices

  1. Strong passwords: Enforce password requirements on the client side
  2. Secure token storage: Store JWT tokens in httpOnly cookies, not localStorage
  3. Token expiration: Keep access tokens short-lived (15-60 minutes)
  4. Email verification: Always verify email before granting full access
  5. Rate limiting: Implement rate limiting on auth endpoints
  6. HTTPS only: Always use HTTPS in production
  7. Password hashing: Package uses bcrypt for secure password storage
  8. Activation tokens: Send activation keys via secure email delivery

🔄 Scheduled Tasks

The package includes automatic cleanup of expired tokens:

import { Module } from "@nestjs/common";
import { AuthStarterSchedulerModule } from "@rs-tech-hub/nestjs-auth-starter";

@Module({
  imports: [AuthStarterSchedulerModule],
})
export class AppModule {}

This enables automatic cleanup of:

  • Expired refresh tokens
  • Expired activation tokens

📄 License

This package requires a valid commercial license. See LICENSE.txt for details. By using this software, you agree to the terms outlined in the Software License Agreement (SLA.md). The license grants you specific rights to use, modify, and deploy the software within the scope defined in the agreement. For full terms, conditions, and restrictions, please refer to the Software License Agreement.

📋 Release Notes

1.0.0

  • Initial release

1.0.1

  • Updates dependencies

1.0.2

  • Updates dependencies

1.0.3

  • Fixes unnecessary exports from AuthStarterModule

🆘 Support

For technical support and inquiries: