<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged userservice</title>
<link>https://coderlegion.com/tag/userservice</link>
<description>Powered by Question2Answer</description>
<item>
<title>Stop Writing Auth From Scratch — One Command Does It All in NestJS</title>
<link>https://coderlegion.com/15938/stop-writing-auth-from-scratch-one-command-does-it-all-in-nestjs</link>
<description>&lt;h3 id=&quot;the-problem-every-nestjs-developer-faces-on-day-one&quot;&gt;The problem every NestJS developer faces on day one&lt;/h3&gt;
&lt;p&gt;You open a fresh NestJS project.&lt;/p&gt;
&lt;p&gt;You know what comes next.&lt;/p&gt;
&lt;p&gt;Before you write a single line of business logic, you need to build:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;User registration and login&lt;/li&gt;
&lt;li&gt;Password hashing with bcrypt&lt;/li&gt;
&lt;li&gt;JWT access and refresh tokens&lt;/li&gt;
&lt;li&gt;Guards and decorators&lt;/li&gt;
&lt;li&gt;Password reset flow&lt;/li&gt;
&lt;li&gt;Email verification&lt;/li&gt;
&lt;li&gt;Maybe OAuth (Google, GitHub...)&lt;/li&gt;
&lt;li&gt;Maybe 2FA&lt;/li&gt;
&lt;li&gt;Maybe RBAC&lt;/li&gt;
&lt;li&gt;A User entity for your ORM&lt;/li&gt;
&lt;li&gt;Docker Compose for your database&lt;/li&gt;
&lt;li&gt;Environment variables&lt;/li&gt;
&lt;li&gt;Swagger documentation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You have done this before. Multiple times. On every project.&lt;br&gt;
It takes days. Sometimes a week.&lt;br&gt;
And it is the same code every single time.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;there-is-a-better-way&quot;&gt;There is a better way&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cd your-nestjs-project
npx @mehdijony/nestjs-user-service init
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Answer a few questions. Done.&lt;/p&gt;
&lt;p&gt;You get a complete, production-ready authentication and user management &lt;br&gt;
system — installed directly into your existing NestJS project in under &lt;br&gt;
5 minutes.&lt;/p&gt;
&lt;p&gt;No boilerplate copying. No Stack Overflow rabbit holes. &lt;br&gt;
No &quot;why is my JWT strategy not working at 2am&quot; sessions.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-exactly-gets-generated-&quot;&gt;What exactly gets generated?&lt;/h3&gt;
&lt;p&gt;Let me be specific, because &quot;complete auth system&quot; is a phrase that &lt;br&gt;
gets thrown around a lot.&lt;/p&gt;
&lt;p&gt;Here is what you actually get:&lt;/p&gt;
&lt;h4 id=&quot;auth-module&quot;&gt;Auth Module&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Email + password registration and login&lt;/li&gt;
&lt;li&gt;Email OTP (passwordless)&lt;/li&gt;
&lt;li&gt;Magic link (passwordless)&lt;/li&gt;
&lt;li&gt;Mobile OTP via SMS&lt;/li&gt;
&lt;li&gt;OAuth: Google, GitHub, Facebook, Apple, Twitter, LinkedIn, Discord&lt;/li&gt;
&lt;li&gt;Enterprise: LDAP (Active Directory) and SAML SSO&lt;/li&gt;
&lt;li&gt;API key authentication&lt;/li&gt;
&lt;li&gt;JWT access tokens + refresh tokens&lt;/li&gt;
&lt;li&gt;Automatic token refresh endpoint&lt;/li&gt;
&lt;li&gt;Password reset (forgot password flow)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;security-layer&quot;&gt;Security Layer&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;bcrypt password hashing (rounds: 12)&lt;/li&gt;
&lt;li&gt;Two-factor authentication (TOTP) with QR code&lt;/li&gt;
&lt;li&gt;Rate limiting per IP with @nestjs/throttler&lt;/li&gt;
&lt;li&gt;Account lockout after failed attempts&lt;/li&gt;
&lt;li&gt;Password strength validator (custom class-validator decorator)&lt;/li&gt;
&lt;li&gt;Password history (prevent reuse)&lt;/li&gt;
&lt;li&gt;RBAC with roles and fine-grained permissions&lt;/li&gt;
&lt;li&gt;Device and session management&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;user-module&quot;&gt;User Module&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Full CRUD with pagination&lt;/li&gt;
&lt;li&gt;GET /users/me (current user profile)&lt;/li&gt;
&lt;li&gt;Safe responses (password never exposed)&lt;/li&gt;
&lt;li&gt;@CurrentUser() decorator for controllers&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;infrastructure&quot;&gt;Infrastructure&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Redis caching&lt;/li&gt;
&lt;li&gt;BullMQ / RabbitMQ / Kafka queues&lt;/li&gt;
&lt;li&gt;Email: Nodemailer, SendGrid, AWS SES, Resend, Postmark&lt;/li&gt;
&lt;li&gt;SMS: Twilio, Vonage, AWS SNS, MSG91&lt;/li&gt;
&lt;li&gt;File upload: AWS S3, Google Cloud Storage, Cloudinary, local&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;devops&quot;&gt;DevOps&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Docker Compose with all required services&lt;/li&gt;
&lt;li&gt;Environment variables auto-generated&lt;/li&gt;
&lt;li&gt;Health check endpoint&lt;/li&gt;
&lt;li&gt;Swagger / OpenAPI docs at /api/docs&lt;/li&gt;
&lt;li&gt;GitHub Actions / GitLab CI pipeline&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;which-orms-and-databases-does-it-support-&quot;&gt;Which ORMs and databases does it support?&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Database &lt;/th&gt;&lt;th&gt;ORM options&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;PostgreSQL &lt;/td&gt;&lt;td&gt;Prisma, TypeORM, Drizzle, MikroORM&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;MySQL &lt;/td&gt;&lt;td&gt;Prisma, TypeORM, Drizzle&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;SQLite &lt;/td&gt;&lt;td&gt;Prisma, TypeORM&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;SQL Server &lt;/td&gt;&lt;td&gt;TypeORM&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;MongoDB &lt;/td&gt;&lt;td&gt;Mongoose, Prisma&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;You pick the combination. It generates the right schema, &lt;br&gt;
entities, and connection config for your choice.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;how-does-it-work-with-an-existing-project-&quot;&gt;How does it work with an existing project?&lt;/h3&gt;
&lt;p&gt;This is the part that makes it different from other generators.&lt;/p&gt;
&lt;p&gt;Most generators create a new project. This one installs into what you &lt;br&gt;
already have.&lt;/p&gt;
&lt;p&gt;When you run &lt;code&gt;npx @mehdijony/nestjs-user-service init&lt;/code&gt; inside your &lt;br&gt;
existing NestJS project, it:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Detects your project&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; Detected Project Info:
────────────────────────────────────────
  NestJS Version:   10.3.2
  Package Manager:  pnpm
  Source Path:      /your-project/src
  Has Docker:       Yes
  Has Prisma:       Yes
  Has TypeORM:      No
  Has Mongoose:     No
  Has .env:         Yes
────────────────────────────────────────
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It detects your package manager, NestJS version, which ORMs you &lt;br&gt;
already have, whether Docker is configured, and whether you have &lt;br&gt;
a .env file.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Asks your preferences&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Interactive prompts let you choose exactly what you want.&lt;br&gt;
Already have Prisma? It will default to that. &lt;br&gt;
Already have Docker? It will append to your existing docker-compose.yml.&lt;br&gt;
Already have .env? It will only add new keys, never overwrite.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Creates a restore point BEFORE touching anything&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is critical. Before the installer modifies a single file, &lt;br&gt;
it backs up:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Your app.module.ts&lt;/li&gt;
&lt;li&gt;Your .env&lt;/li&gt;
&lt;li&gt;Your docker-compose.yml  &lt;/li&gt;
&lt;li&gt;Your prisma/schema.prisma&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And records every file it will create and every package it will add.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Installs everything&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Packages go into YOUR project (not a separate directory).&lt;br&gt;
Files go into src/user-service/.&lt;br&gt;
UserServiceModule gets injected into your AppModule automatically.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. If anything fails — it auto-rolls back&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The installer wraps everything in try/catch. If step 6 fails,&lt;br&gt;
steps 1-5 are automatically undone.&lt;/p&gt;
&lt;p&gt;And if you decide later you want to remove it:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npx @mehdijony/nestjs-user-service rollback
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That command:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Deletes all generated files&lt;/li&gt;
&lt;li&gt;Uninstalls all added packages  &lt;/li&gt;
&lt;li&gt;Restores your original app.module.ts, .env, docker-compose.yml&lt;/li&gt;
&lt;li&gt;Removes the backup directory&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Your project is exactly as it was before.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;let-me-show-you-the-actual-output&quot;&gt;Let me show you the actual output&lt;/h3&gt;
&lt;p&gt;After running init with PostgreSQL + Prisma + email/password + &lt;br&gt;
Google OAuth + Swagger selected, here is what your project gets:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;src/user-service/
├── user-service.module.ts
├── auth/
│   ├── auth.module.ts
│   ├── auth.service.ts
│   ├── auth.controller.ts
│   ├── guards/
│   │   └── jwt-auth.guard.ts
│   ├── strategies/
│   │   ├── jwt.strategy.ts
│   │   └── google.strategy.ts
│   └── decorators/
│       └── current-user.decorator.ts
└── user/
    ├── user.module.ts
    ├── user.service.ts
    └── user.controller.ts
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Your app.module.ts gets this injected automatically:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;import { UserServiceModule } from './user-service/user-service.module';

@Module({
  imports: [
    UserServiceModule,  // ← added automatically
    // ... your existing modules
  ],
})
export class AppModule {}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Your .env gets these appended:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-env&quot;&gt;# ─── USER SERVICE ───
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/mydb
JWT_SECRET=change-this-to-a-secure-secret-minimum-32-characters
JWT_ACCESS_EXPIRATION=15m
JWT_REFRESH_EXPIRATION=7d
APP_URL=http://localhost:3000
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_CALLBACK_URL=http://localhost:3000/api/v1/auth/google/callback
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Your prisma/schema.prisma gets the User model added:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-prisma&quot;&gt;model User {
  id         Int      @id @default(autoincrement())
  email      String?  @unique
  phone      String?  @unique
  password   String?
  firstName  String?
  lastName   String?
  avatar     String?
  isActive   Boolean  @default(true)
  isVerified Boolean  @default(false)
  provider   String?  @default(&quot;local&quot;)
  providerId String?
  createdAt  DateTime @default(now())
  updatedAt  DateTime @updatedAt

  @@map(&quot;users&quot;)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then you run:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npx prisma generate
npx prisma db push
npm run start:dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And your API is live at &lt;a rel=&quot;nofollow&quot; href=&quot;http://localhost:3000/api/v1&quot;&gt;http://localhost:3000/api/v1&lt;/a&gt; with Swagger &lt;br&gt;
at &lt;a rel=&quot;nofollow&quot; href=&quot;http://localhost:3000/api/docs&quot;&gt;http://localhost:3000/api/docs&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-api-endpoints-you-get&quot;&gt;The API endpoints you get&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;POST   /api/v1/auth/register
POST   /api/v1/auth/login
POST   /api/v1/auth/refresh
POST   /api/v1/auth/logout
POST   /api/v1/auth/forgot-password
POST   /api/v1/auth/reset-password
GET    /api/v1/auth/google
GET    /api/v1/auth/google/callback
POST   /api/v1/auth/email/otp/send
POST   /api/v1/auth/email/otp/verify
POST   /api/v1/auth/magic-link/send
GET    /api/v1/auth/magic-link/verify
GET    /api/v1/users
GET    /api/v1/users/me
GET    /api/v1/users/:id
PATCH  /api/v1/users/:id
DELETE /api/v1/users/:id
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All behind JWT guards where appropriate.&lt;br&gt;
All documented in Swagger.&lt;br&gt;
All returning a consistent response format:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;success&quot;: true,
  &quot;data&quot;: { ... },
  &quot;timestamp&quot;: &quot;2024-01-15T10:30:00.000Z&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h3 id=&quot;who-is-this-for-&quot;&gt;Who is this for?&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Solo developers and small teams&lt;/strong&gt; who need to ship fast without &lt;br&gt;
cutting corners on security.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Agencies&lt;/strong&gt; who build multiple NestJS apps and are tired of copy-pasting&lt;br&gt;
auth boilerplate between projects.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Startups&lt;/strong&gt; who need a working MVP yesterday and can not afford to spend &lt;br&gt;
a week on authentication infrastructure.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Senior developers&lt;/strong&gt; who know how auth should be built and want it &lt;br&gt;
generated correctly rather than written from scratch again.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;who-is-this-not-for-&quot;&gt;Who is this NOT for?&lt;/h3&gt;
&lt;p&gt;If you have very specific, non-standard auth requirements that do not &lt;br&gt;
fit any of the options (custom token format, exotic identity providers, &lt;br&gt;
proprietary session stores), this might not cover your edge case — &lt;br&gt;
though you can still use it as a starting point and modify the &lt;br&gt;
generated code.&lt;/p&gt;
&lt;h3 id=&quot;get-started&quot;&gt;Get started&lt;/h3&gt;
&lt;hr&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# In your existing NestJS project:
npx @mehdijony/nestjs-user-service init
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Or create a brand new project:
npx @mehdijony/nestjs-user-service init my-app
cd my-app
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GitHub: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/mehdijony/nestjs-user-service&quot;&gt;https://github.com/mehdijony/nestjs-user-service&lt;/a&gt;&lt;br&gt;
npm: &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.npmjs.com/package/@mehdijony/nestjs-user-service&quot;&gt;https://www.npmjs.com/package/@mehdijony/nestjs-user-service&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;If this saves you time, star the repo and share it with your team.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Every developer who has built auth from scratch three times &lt;br&gt;
deserves to know this exists.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
</description>
<category>Tutorials</category>
<guid isPermaLink="true">https://coderlegion.com/15938/stop-writing-auth-from-scratch-one-command-does-it-all-in-nestjs</guid>
<pubDate>Mon, 27 Apr 2026 05:41:08 +0000</pubDate>
</item>
</channel>
</rss>