Skip to content

Build Reusable Identity System with authId + OTP & Auth Middlewares (Universal Access Control)Β #14

@abhishek-nexgen-dev

Description

@abhishek-nexgen-dev

🧩 Description

Build a reusable identity system with support for:

  • βœ… authId (safe external identifier)

  • βœ… internalAuthId (private DB reference)

  • βœ… OTP verification middleware (isOtpVerified)

  • βœ… verifyToken middleware for JWT/session validation

  • βœ… Middleware for isBlocked, isDeleted, isValidated, etc.

  • βœ… Global access in all modules (Todo, Product, Contact, etc.)

  • This is the foundation of FastKit’s identity and access management, allowing you to plug in access control to any route.

🧱 Why This Is Important

  • πŸ’Ό Used in every application that needs secure user logic

  • πŸ“¦ Easy to reuse across multiple features/modules

  • πŸ” Centralizes authId, flags, and token/OTP verification

  • πŸ” Prevents boilerplate in every controller or route

🟒 Difficulty Level: Intermediate – Advanced

You should be comfortable with:

  • TypeScript + Express

  • JWT & token handling

  • Writing middleware

  • Using flags (boolean access control)

  • OTP flows (via DB or cache)

βœ… Tasks

πŸ“ Proposed File Structure

src/
 |
β”‚   
β”œβ”€β”€ features/
β”‚   └── Otp/
β”‚       └── v1/
β”‚           β”œβ”€β”€ Otp.model.ts
β”‚           β”œβ”€β”€ Otp.middleware.ts # Middle Ware to Verify Otp , restrictToOwner.ts
β”‚           └── Otp.constant.ts
              └── Otp.utils.ts
               # other 

πŸ“œ Auth.model.ts (Partial)

export interface IAuthUser {
  authId: string;
  internalAuthId: string;
  isEmailVerified: boolean;
  isOtpVerified: boolean;
  isValidated: boolean;
  isBlocked: boolean;
  isDeleted: boolean;
  ...
}

vExample Usage:

router.get(
  '/dashboard',
  verifyToken,
  FlagsUtils.check({ isValidated: true, isBlocked: false }),
  dashboardController.show
);

πŸ” restrictToOwner.ts Middleware

export const restrictToOwner = (getOwnerAuthIdFn: (req) => string) => {
  return (req, res, next) => {
    if (req.user?.authId !== getOwnerAuthIdFn(req)) {
      return res.status(403).json({ message: 'Unauthorized access' });
    }
    next();
  };
};

Use in any module like Todo:

router.delete(
  '/todo/:id',
  verifyToken,
  restrictToOwner(req => req.todo.authId),
  todoController.delete
);

πŸ“¦ Auth.constant.ts

export const AUTH_ERRORS = {
  BLOCKED: 'Account is blocked',
  OTP_REQUIRED: 'OTP verification required',
  VALIDATION_REQUIRED: 'User not validated',
  UNAUTHORIZED: 'Unauthorized',
};

πŸ“˜ README.md for This Module

βœ… Include:

  • How authId works

  • When to use verifyToken

  • How to plug checkFlags middleware

  • How to restrict a route to logged-in, verified users

Example:

import {
  verifyToken,
  checkFlags,
  verifyOtp,
  restrictToOwner,
} from 'fastkit-auth';

router.get(
  '/user/profile',
  verifyToken,
  checkFlags({ isValidated: true }),
  userController.getProfile
);

🎯 Expected Outcome

[x] Every feature uses authId for ownership checks

[x] Middleware for all common identity checks

[x] OTP validation logic fully reusable

[x] Cleaner, secure route protection

[x] Easy extension to new modules


πŸ™‹πŸ»β€β™‚οΈ Looking For

  • Help adding rate-limiting for OTP

  • Option to use Redis for OTP/session store

  • authId indexing support (Mongoose)

  • Tests for middleware logic

  • Add support for 2FA, IP/device validation in future

πŸ” Final Usage Pattern

router.post(
  '/secure-data',
  verifyToken,
  verifyOtp,
  checkFlags({ isValidated: true, isBlocked: false }),
  SecureController.handle
);

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions