diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 069204e..2417cbb 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -11,6 +11,7 @@ **Purpose**: JWT-based authentication and authorization for NestJS apps ### Responsibilities: + - User authentication (login, register) - JWT token generation and validation - Role-based access control (RBAC) @@ -57,6 +58,7 @@ src/ **Dependency Flow:** `api → application → domain ← infrastructure` **Guards & Decorators:** + - **Exported guards** → `api/guards/` (used globally by apps) - Example: `JwtAuthGuard`, `RolesGuard` - Apps import: `import { JwtAuthGuard } from '@ciscode/authentication-kit'` @@ -65,19 +67,20 @@ src/ - Exported for app use **Module Exports:** + ```typescript // src/index.ts - Public API -export { AuthModule } from './auth-kit.module'; +export { AuthModule } from "./auth-kit.module"; // DTOs (public contracts) -export { LoginDto, RegisterDto, UserDto } from './api/dto'; +export { LoginDto, RegisterDto, UserDto } from "./api/dto"; // Guards & Decorators -export { JwtAuthGuard, RolesGuard } from './api/guards'; -export { CurrentUser, Roles } from './api/decorators'; +export { JwtAuthGuard, RolesGuard } from "./api/guards"; +export { CurrentUser, Roles } from "./api/decorators"; // Services (if needed by apps) -export { AuthService } from './application/auth.service'; +export { AuthService } from "./application/auth.service"; // ❌ NEVER export entities directly // export { User } from './domain/user.entity'; // FORBIDDEN @@ -88,6 +91,7 @@ export { AuthService } from './application/auth.service'; ## 📝 Naming Conventions **Files**: `kebab-case` + suffix + - `auth.controller.ts` - `login.dto.ts` - `user.entity.ts` @@ -99,6 +103,7 @@ export { AuthService } from './application/auth.service'; ### Path Aliases Configured in `tsconfig.json`: + ```typescript "@/*" → "src/*" "@api/*" → "src/api/*" @@ -108,11 +113,12 @@ Configured in `tsconfig.json`: ``` Use aliases for cleaner imports: + ```typescript -import { LoginDto } from '@api/dto'; -import { LoginUseCase } from '@application/use-cases'; -import { User } from '@domain/user.entity'; -import { UserRepository } from '@infrastructure/user.repository'; +import { LoginDto } from "@api/dto"; +import { LoginUseCase } from "@application/use-cases"; +import { User } from "@domain/user.entity"; +import { UserRepository } from "@infrastructure/user.repository"; ``` --- @@ -122,20 +128,24 @@ import { UserRepository } from '@infrastructure/user.repository'; ### Coverage Target: 80%+ **Unit Tests - MANDATORY:** + - ✅ All use-cases - ✅ All domain logic - ✅ All utilities - ✅ Guards and decorators **Integration Tests:** + - ✅ Controllers (full request/response) - ✅ JWT generation/validation - ✅ Database operations (with test DB) **E2E Tests:** + - ✅ Complete auth flows (register → login → protected route) **Test file location:** + ``` src/ └── application/ @@ -150,7 +160,7 @@ src/ ### JSDoc/TSDoc - ALWAYS for: -```typescript +````typescript /** * Authenticates a user with email and password * @param email - User email address @@ -163,14 +173,16 @@ src/ * ``` */ async login(email: string, password: string): Promise -``` +```` **Required for:** + - All exported functions/methods - All public classes - All DTOs (with property descriptions) ### API Documentation: + - Swagger decorators on all controllers - README with usage examples - CHANGELOG for all releases @@ -180,40 +192,44 @@ async login(email: string, password: string): Promise ## 🚀 Module Development Principles ### 1. Exportability + **Export ONLY public API (Services + DTOs + Guards + Decorators):** + ```typescript // src/index.ts - Public API -export { AuthModule } from './auth-kit.module'; +export { AuthModule } from "./auth-kit.module"; // DTOs (public contracts - what apps consume) -export { LoginDto, RegisterDto, UserDto, AuthTokensDto } from './api/dto'; +export { LoginDto, RegisterDto, UserDto, AuthTokensDto } from "./api/dto"; // Guards (for protecting routes in apps) -export { JwtAuthGuard, RolesGuard, PermissionsGuard } from './api/guards'; +export { JwtAuthGuard, RolesGuard, PermissionsGuard } from "./api/guards"; // Decorators (for extracting data in apps) -export { CurrentUser, Roles, Permissions } from './api/decorators'; +export { CurrentUser, Roles, Permissions } from "./api/decorators"; // Services (if apps need direct access) -export { AuthService } from './application/auth.service'; +export { AuthService } from "./application/auth.service"; // Types (TypeScript interfaces for configuration) -export type { AuthModuleOptions, JwtConfig } from './types'; +export type { AuthModuleOptions, JwtConfig } from "./types"; ``` **❌ NEVER export:** + ```typescript // ❌ Entities - internal domain models -export { User } from './domain/user.entity'; // FORBIDDEN +export { User } from "./domain/user.entity"; // FORBIDDEN // ❌ Repositories - infrastructure details -export { UserRepository } from './infrastructure/user.repository'; // FORBIDDEN +export { UserRepository } from "./infrastructure/user.repository"; // FORBIDDEN // ❌ Use-cases directly - use services instead -export { LoginUseCase } from './application/use-cases/login.use-case'; // FORBIDDEN +export { LoginUseCase } from "./application/use-cases/login.use-case"; // FORBIDDEN ``` **Rationale:** + - DTOs = stable public contract - Entities = internal implementation (can change) - Apps work with DTOs, never entities @@ -222,6 +238,7 @@ export { LoginUseCase } from './application/use-cases/login.use-case'; // FORBID ### Path Aliases Configured in `tsconfig.json`: + ```typescript "@/*" → "src/*" "@api/*" → "src/api/*" @@ -231,15 +248,18 @@ Configured in `tsconfig.json`: ``` Use aliases for cleaner imports: + ```typescript -import { LoginDto } from '@api/dto'; -import { LoginUseCase } from '@application/use-cases'; -import { User } from '@domain/user.entity'; -import { UserRepository } from '@infrastructure/user.repository'; +import { LoginDto } from "@api/dto"; +import { LoginUseCase } from "@application/use-cases"; +import { User } from "@domain/user.entity"; +import { UserRepository } from "@infrastructure/user.repository"; ``` ### 2. Configuration + **Flexible module registration:** + ```typescript @Module({}) export class AuthModule { @@ -247,14 +267,14 @@ export class AuthModule { return { module: AuthModule, providers: [ - { provide: 'AUTH_OPTIONS', useValue: options }, + { provide: "AUTH_OPTIONS", useValue: options }, AuthService, JwtService, ], exports: [AuthService], }; } - + static forRootAsync(options: AuthModuleAsyncOptions): DynamicModule { // Async configuration (from ConfigService, etc.) } @@ -262,6 +282,7 @@ export class AuthModule { ``` ### 3. Zero Business Logic Coupling + - No hardcoded business rules specific to one app - Configurable behavior via options - Repository abstraction (database-agnostic) @@ -274,6 +295,7 @@ export class AuthModule { ### Task-Driven Development (Module Specific) **1. Branch Creation:** + ```bash feature/MODULE-123-add-refresh-token bugfix/MODULE-456-fix-jwt-validation @@ -282,49 +304,101 @@ refactor/MODULE-789-extract-password-service **2. Task Documentation:** Create task file at branch start: + ``` docs/tasks/active/MODULE-123-add-refresh-token.md ``` **Task file structure** (same as main app): + ```markdown # MODULE-123: Add Refresh Token Support ## Description + Add refresh token rotation for enhanced security ## Implementation Details + - What was done - Why (technical/security reasons) - Key decisions made ## Files Modified + - src/api/dto/auth-tokens.dto.ts - src/application/use-cases/refresh-token.use-case.ts ## Breaking Changes + - `login()` now returns `AuthTokensDto` instead of `string` - Apps need to update response handling ## Notes + Decision: Token rotation over sliding window for security ``` **3. On Release:** Move to archive: + ``` docs/tasks/archive/by-release/v2.0.0/MODULE-123-add-refresh-token.md ``` +### Git Flow - Module Specific + +**Branch Structure:** + +- `master` - Production releases only +- `develop` - Active development +- `feature/MODULE-*` - New features +- `bugfix/MODULE-*` - Bug fixes + +**Workflow:** + +```bash +# 1. Detach from develop +git checkout develop +git pull origin develop +git checkout -b feature/MODULE-123-add-refresh-token + +# 2. Development +# ... implement, test, document ... + +# 3. Bump version and push +npm version minor +git push origin feature/MODULE-123-add-refresh-token --tags + +# 4. PR to develop +gh pr create --base develop + +# 5. After merge in develop, for release: +git checkout master +git merge develop +git push origin master --tags +npm publish +``` + +**⚠️ IMPORTANT:** + +- ✅ Feature branch from `develop` +- ✅ PR to `develop` +- ✅ `master` only for release +- ❌ NEVER direct PR to `master` + ### Development Workflow **Simple changes** (bug fix, small improvements): + - Read context → Implement directly → Update docs → Update CHANGELOG **Complex changes** (new features, breaking changes): + - Read context → Discuss approach → Implement step-by-step → Update docs → Update CHANGELOG → Update version **When blocked or uncertain:** + - **DO**: Ask for clarification immediately - **DON'T**: Make breaking changes without approval @@ -333,6 +407,7 @@ docs/tasks/archive/by-release/v2.0.0/MODULE-123-add-refresh-token.md ## �🔐 Security Best Practices **ALWAYS:** + - ✅ Input validation on all DTOs - ✅ Password hashing (bcrypt, min 10 rounds) - ✅ JWT secret from env (never hardcoded) @@ -347,43 +422,70 @@ docs/tasks/archive/by-release/v2.0.0/MODULE-123-add-refresh-token.md ### Semantic Versioning (Strict) **MAJOR** (x.0.0) - Breaking changes: + - Changed function signatures - Removed public methods - Changed DTOs structure - Changed module configuration **MINOR** (0.x.0) - New features: + - New endpoints/methods - New optional parameters - New decorators/guards **PATCH** (0.0.x) - Bug fixes: + - Internal fixes - Performance improvements - Documentation updates ### CHANGELOG Required + ```markdown # Changelog ## [2.0.0] - 2026-01-30 + ### BREAKING CHANGES + - `login()` now returns `AuthTokens` instead of string - Removed deprecated `validateUser()` method ### Added + - Refresh token support - Role-based guards ### Fixed + - Token expiration validation ``` +### Version Bump Command + +**ALWAYS run before pushing:** + +```bash +npm version patch # Bug fixes (0.0.x) +npm version minor # New features (0.x.0) +npm version major # Breaking changes (x.0.0) + +# This automatically: +# - Updates package.json version +# - Creates git commit "vX.X.X" +# - Creates git tag + +# Then push: +git push && git push --tags +``` + --- ## 🚫 Restrictions - Require Approval **NEVER without approval:** + - Breaking changes to public API - Changing exported DTOs/interfaces - Removing exported functions @@ -391,6 +493,7 @@ docs/tasks/archive/by-release/v2.0.0/MODULE-123-add-refresh-token.md - Security-related changes **CAN do autonomously:** + - Bug fixes (no breaking changes) - Internal refactoring - Adding new features (non-breaking) @@ -402,6 +505,7 @@ docs/tasks/archive/by-release/v2.0.0/MODULE-123-add-refresh-token.md ## ✅ Release Checklist Before publishing: + - [ ] All tests passing (100% of test suite) - [ ] Coverage >= 80% - [ ] No ESLint warnings @@ -413,20 +517,35 @@ Before publishing: - [ ] Breaking changes highlighted - [ ] Integration tested with sample app +### Pre-Publish Hook (Recommended) + +Add to `package.json` to block publishing on errors: + +```json +"scripts": { + "prepublishOnly": "npm run verify && npm run test:cov" +} +``` + +This automatically runs all checks before `npm publish` and blocks if anything fails. + --- ## 🔄 Development Workflow ### Working on Module: + 1. Clone module repo -2. Create branch: `feature/TASK-123-description` +2. Create branch: `feature/MODULE-123-description` 3. Implement with tests 4. Verify checklist 5. Update CHANGELOG -6. Bump version in package.json -7. Create PR +6. **Bump version**: `npm version patch` (or `minor`/`major`) +7. Push: `git push && git push --tags` +8. Create PR ### Testing in App: + ```bash # In module npm link @@ -445,6 +564,7 @@ npm unlink @ciscode/authentication-kit ## 🎨 Code Style **Same as app:** + - ESLint `--max-warnings=0` - Prettier formatting - TypeScript strict mode @@ -456,21 +576,23 @@ npm unlink @ciscode/authentication-kit ## 🐛 Error Handling **Custom domain errors:** + ```typescript export class InvalidCredentialsError extends Error { constructor() { - super('Invalid email or password'); - this.name = 'InvalidCredentialsError'; + super("Invalid email or password"); + this.name = "InvalidCredentialsError"; } } ``` **Structured logging:** + ```typescript -this.logger.error('Authentication failed', { +this.logger.error("Authentication failed", { email, - reason: 'invalid_password', - timestamp: new Date().toISOString() + reason: "invalid_password", + timestamp: new Date().toISOString(), }); ``` @@ -488,6 +610,7 @@ this.logger.error('Authentication failed', { ## 📋 Summary **Module Principles:** + 1. Reusability over specificity 2. Comprehensive testing (80%+) 3. Complete documentation @@ -500,5 +623,5 @@ this.logger.error('Authentication failed', { --- -*Last Updated: January 30, 2026* -*Version: 1.0.0* +_Last Updated: January 30, 2026_ +_Version: 1.0.0_ diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..43e85ba --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,185 @@ +# Changelog + +All notable changes to the AuthKit authentication library will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +--- + +## [1.5.0] - 2026-01-31 + +### Added + +- Full API documentation in README with request/response examples +- Complete Copilot development instructions for module maintainers +- Contribution guidelines with module-specific setup instructions +- Enhanced SECURITY.md with vulnerability reporting procedures +- Troubleshooting and FAQ sections in documentation +- TypeScript type definitions for all public APIs + +### Changed + +- Improved error handling and error message consistency +- Enhanced JWT payload structure documentation +- Optimized admin route filtering capabilities +- Updated CONTRIBUTING.md with module-specific requirements + +### Fixed + +- Translation of Italian text in Copilot instructions to English +- JWT refresh token validation edge cases +- Admin decorator permission checking + +### Security + +- Added security best practices section to documentation +- Documented JWT secret rotation procedures +- Enhanced password reset token expiration guidelines + +--- + +## [1.4.0] - 2026-01-15 + +### Added + +- Support for Facebook OAuth provider +- Microsoft Entra ID OAuth with JWKS verification +- Role-based permission management system +- Admin routes for user, role, and permission management +- User banning/unbanning functionality + +### Changed + +- Refresh token implementation now uses JWT instead of database storage +- Password change now invalidates all existing refresh tokens +- User model now supports optional jobTitle and company fields + +### Fixed + +- OAuth provider token validation improvements +- Email verification token expiration handling +- Microsoft tenant ID configuration flexibility + +--- + +## [1.3.0] - 2025-12-20 + +### Added + +- Email verification requirement before login +- Password reset functionality with JWT-secured reset links +- Resend verification email feature +- User profile endpoint (`GET /api/auth/me`) +- Account deletion endpoint (`DELETE /api/auth/account`) +- Auto-generated usernames when not provided (fname-lname format) + +### Changed + +- Authentication flow now requires email verification +- User model schema restructuring for better organization +- Improved password hashing with bcryptjs + +### Security + +- Implemented httpOnly cookies for refresh token storage +- Added password change tracking with `passwordChangedAt` timestamp +- Enhanced input validation on all auth endpoints + +--- + +## [1.2.0] - 2025-11-10 + +### Added + +- JWT refresh token implementation +- Token refresh endpoint (`POST /api/auth/refresh-token`) +- Automatic token refresh via cookies +- Configurable token expiration times + +### Changed + +- Access token now shorter-lived (15 minutes by default) +- Refresh token implementation for better security posture +- JWT payload structure refined + +### Fixed + +- Token expiration validation during refresh + +--- + +## [1.1.0] - 2025-10-05 + +### Added + +- Google OAuth provider integration +- OAuth mobile exchange endpoints (ID Token and Authorization Code) +- OAuth web redirect flow with Passport.js +- Automatic user registration for OAuth providers + +### Changed + +- Authentication controller refactored for OAuth support +- Module configuration to support multiple OAuth providers + +### Security + +- Google ID Token validation implementation +- Authorization Code exchange with PKCE support + +--- + +## [1.0.0] - 2025-09-01 + +### Added + +- Initial release of AuthKit authentication library +- Local authentication (email + password) +- User registration and login +- JWT access token generation and validation +- Role-Based Access Control (RBAC) system +- Admin user management routes +- Email service integration (SMTP) +- Host app independent - uses host app's Mongoose connection +- Seed service for default roles and permissions +- Admin decorator and authenticate guard + +### Features + +- Local auth strategy with password hashing +- JWT-based authentication +- Role and permission models +- Default admin, user roles with configurable permissions +- Email sending capability for future notifications +- Clean Architecture implementation +- Production-ready error handling + +--- + +## Future Roadmap + +### Planned for v2.0.0 + +- [ ] Two-factor authentication (2FA) support +- [ ] API key authentication for service-to-service communication +- [ ] Audit logging for security-critical operations +- [ ] Session management with concurrent login limits +- [ ] OpenID Connect (OIDC) provider support +- [ ] Breaking change: Restructure module exports for better tree-shaking +- [ ] Migration guide for v1.x → v2.0.0 + +### Planned for v1.6.0 + +- [ ] Rate limiting built-in helpers +- [ ] Request signing and verification for webhooks +- [ ] Enhanced logging with structured JSON output +- [ ] Support for more OAuth providers (LinkedIn, GitHub) + +--- + +## Support + +For version support timeline and security updates, please refer to the [SECURITY.md](SECURITY) policy. + +For issues, questions, or contributions, please visit: https://github.com/CISCODE-MA/AuthKit diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 75544b6..9bc815a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,40 +1,488 @@ # Contributing -Thank you for your interest in contributing to this project. +Thank you for your interest in contributing to AuthKit! This is a reusable NestJS authentication library used across CISCODE projects, so we maintain high standards for quality and documentation. -Contributions of all kinds are welcome, including bug reports, feature requests, documentation improvements, and code contributions. +Contributions of all kinds are welcome: bug reports, feature requests, documentation improvements, and code contributions. --- -## How to Contribute +## 📋 Before You Start -1. Fork the repository -2. Create a new branch from `main` -3. Make your changes -4. Add or update tests where applicable -5. Ensure existing tests pass -6. Open a pull request with a clear description +**Please read:** + +1. [.github/copilot-instructions.md](.github/copilot-instructions.md) - **CRITICAL** - Module development principles +2. [README.md](README.md) - Feature overview and API documentation +3. [SECURITY.md](SECURITY.md) - Security best practices and vulnerability reporting + +--- + +## 🏗️ Development Setup + +### Prerequisites + +- Node.js 18+ (LTS recommended) +- npm 9+ +- MongoDB 5+ (local or remote) +- Git + +### Environment Setup + +```bash +# 1. Clone repository +git clone https://github.com/CISCODE-MA/AuthKit.git +cd AuthKit + +# 2. Install dependencies +npm install + +# 3. Create .env from example +cp .env.example .env + +# 4. Configure environment +# Edit .env with your local MongoDB URI and secrets +# See README.md for all required variables +``` + +### Running Locally + +```bash +# Build TypeScript + resolve aliases +npm run build + +# Run standalone (if applicable) +npm run start + +# Run tests +npm run test + +# Watch mode (during development) +npm run build:watch +``` + +--- + +## 🌳 Git Workflow + +### Branch Naming + +Follow the naming convention from copilot-instructions.md: + +``` +feature/MODULE-123-add-refresh-token +bugfix/MODULE-456-fix-jwt-validation +refactor/MODULE-789-extract-password-service +docs/MODULE-XXX-update-readme +``` + +### Workflow + +1. **Create branch from `develop`:** + + ```bash + git checkout develop + git pull origin develop + git checkout -b feature/MODULE-123-your-feature + ``` + +2. **Implement with tests:** + - Make changes with comprehensive test coverage (80%+ target) + - Follow code style guidelines (see below) + - Update documentation + +3. **Commit with clear messages:** + + ```bash + git commit -m "MODULE-123: Add refresh token support + + - Implement JWT refresh token rotation + - Add refresh token endpoint + - Update user model with token tracking + - Add tests for token refresh flow" + ``` + +4. **Push and create PR:** + + ```bash + git push origin feature/MODULE-123-your-feature + gh pr create --base develop + ``` + +5. **After merge to `develop`, for releases:** + ```bash + # Only after PR approval and merge + git checkout master + git pull + git merge develop + npm version patch # or minor/major + git push origin master --tags + npm publish + ``` + +### Important Rules + +- ✅ Feature branches **FROM** `develop` +- ✅ PRs **TO** `develop` +- ✅ `master` **ONLY** for releases +- ❌ **NEVER** direct PR to `master` + +--- + +## 📝 Code Guidelines + +### Architecture + +**Follow Clean Architecture (4 layers):** + +``` +src/ + ├── api/ # HTTP layer (controllers, guards, decorators) + ├── application/ # Business logic (use-cases, services) + ├── domain/ # Entities (User, Role, Permission) + └── infrastructure/ # Repositories, external services +``` + +**Dependency Flow:** `api → application → domain ← infrastructure` + +### File Naming + +- Files: `kebab-case` + suffix + - `auth.controller.ts` + - `login.use-case.ts` + - `user.repository.ts` + +- Classes/Interfaces: `PascalCase` + - `AuthService` + - `LoginDto` + - `User` + +- Functions/Variables: `camelCase` + - `generateToken()` + - `userEmail` + +- Constants: `UPPER_SNAKE_CASE` + - `JWT_EXPIRATION_HOURS` + - `MAX_LOGIN_ATTEMPTS` + +### TypeScript + +- Always use `strict` mode (required) +- Use path aliases for cleaner imports: + ```typescript + import { LoginDto } from "@api/dto"; + import { AuthService } from "@application/auth.service"; + import { User } from "@domain/user.entity"; + ``` + +### Documentation + +**Every exported function/class MUST have JSDoc:** + +````typescript +/** + * Authenticates user with email and password + * @param email - User email address + * @param password - Plain text password (will be hashed) + * @returns Access and refresh tokens + * @throws {UnauthorizedException} If credentials invalid + * @example + * ```typescript + * const tokens = await authService.login('user@example.com', 'password123'); + * ``` + */ +async login(email: string, password: string): Promise { + // implementation +} +```` + +### Code Style + +- ESLint with `--max-warnings=0` +- Prettier formatting +- No magic numbers (use constants) +- Prefer functional programming for logic +- Use dependency injection via constructor + +```bash +# Format and lint before committing +npm run format +npm run lint +``` --- -## Guidelines +## 🧪 Testing Requirements + +### Coverage Target: 80%+ + +**MANDATORY unit tests for:** + +- All use-cases in `src/application/use-cases/` +- All domain logic in `src/domain/` +- All utilities in `src/utils/` +- All guards and decorators in `src/api/` + +**Integration tests for:** + +- Controllers (full request/response flow) +- Repository operations +- External service interactions (mail, OAuth) + +**Test file location:** + +``` +src/ + └── application/ + └── use-cases/ + ├── login.use-case.ts + └── login.use-case.spec.ts ← Same directory +``` + +**Running tests:** + +```bash +npm run test # Run all tests +npm run test:watch # Watch mode +npm run test:cov # With coverage report +``` + +--- + +## 🔐 Security + +### Password & Secrets + +- ✅ Use environment variables for all secrets +- ❌ **NEVER** commit secrets, API keys, or credentials +- ❌ **NEVER** hardcode JWT secrets or OAuth credentials + +### Input Validation + +```typescript +// Use class-validator on all DTOs +import { IsEmail, MinLength } from "class-validator"; + +export class LoginDto { + @IsEmail() + email: string; + + @MinLength(6) + password: string; +} +``` + +### Password Hashing + +```typescript +import * as bcrypt from "bcryptjs"; -- Keep changes focused and minimal -- Follow existing code style and conventions -- Avoid breaking backward compatibility when possible -- Write clear commit messages -- Do not include secrets, credentials, or tokens +// Hash with minimum 10 rounds +const hashedPassword = await bcrypt.hash(password, 10); +``` --- -## Reporting Bugs +## 📚 Documentation Requirements -When reporting bugs, please include: -- A clear description of the issue +Before submitting PR: + +- [ ] Update README.md if adding new features +- [ ] Update CHANGELOG.md with your changes +- [ ] Add JSDoc comments to all public APIs +- [ ] Add inline comments for complex logic +- [ ] Document breaking changes prominently + +### Documenting Breaking Changes + +In PR description and CHANGELOG: + +````markdown +## ⚠️ BREAKING CHANGES + +- `login()` now returns `AuthTokens` instead of string +- Apps must update to: + ```typescript + const { accessToken, refreshToken } = await authService.login(...); + ``` +```` + +- See migration guide in README + +```` + +--- + +## 📦 Versioning & Release + +### Version Bumping + +```bash +# Bug fixes (1.0.0 → 1.0.1) +npm version patch + +# New features (1.0.0 → 1.1.0) +npm version minor + +# Breaking changes (1.0.0 → 2.0.0) +npm version major + +# This creates commit + tag automatically +git push origin master --tags +npm publish +```` + +### Before Release + +Complete the **Release Checklist** in [copilot-instructions.md](.github/copilot-instructions.md): + +- [ ] All tests passing (100%) +- [ ] Coverage >= 80% +- [ ] No ESLint warnings +- [ ] TypeScript strict mode passing +- [ ] All public APIs documented +- [ ] README updated +- [ ] CHANGELOG updated with version & date +- [ ] Version bumped (semantic) +- [ ] Breaking changes documented + +--- + +## 🐛 Reporting Bugs + +Include in bug reports: + +- Clear description of the issue - Steps to reproduce - Expected vs actual behavior -- Relevant logs or error messages (redacted if needed) +- Relevant error logs (redacted if needed) +- Node.js version, OS, MongoDB version +- Which OAuth providers (if applicable) + +**Example:** + +```markdown +## Bug: JWT validation fails on token refresh + +### Steps to Reproduce + +1. Register user +2. Login successfully +3. Call /api/auth/refresh-token after 1 hour + +### Expected + +New access token returned + +### Actual + +401 Unauthorized - "Invalid token" + +### Error Log + +JwtError: jwt malformed... + +### Environment + +- Node: 18.12.0 +- MongoDB: 5.0 +- AuthKit: 1.5.0 +``` + +--- + +## 💡 Feature Requests + +When requesting features: + +- Explain the use case +- How it benefits multiple apps (not just one) +- Suggested implementation approach (optional) +- Any security implications + +**Example:** + +```markdown +## Feature: API Key Authentication + +### Use Case + +Service-to-service communication without user accounts + +### Benefit + +Enables webhook signing and service integration across CISCODE platform + +### Suggested Approach + +- New API key model with user reference +- New ApiKeyGuard for protecting routes +- Rate limiting by key +``` + +--- + +## 🔄 Pull Request Process + +1. **Create PR with clear title & description** + + ``` + MODULE-123: Add refresh token support + + ## Changes + - Implement JWT refresh token rotation + - Add refresh endpoint + - Add token tests + + ## Breaking Changes + - login() now returns AuthTokens instead of string + + ## Checklist + - [x] Tests passing + - [x] Coverage >= 80% + - [x] Documentation updated + - [x] No breaking changes without approval + ``` + +2. **Link to issue if applicable** + + ``` + Closes #123 + ``` + +3. **Address review feedback** + +4. **Squash commits for cleaner history** (if requested) + +5. **Merge only after approval** + +--- + +## 🚫 What NOT to Do + +- ❌ Break backward compatibility without MAJOR version bump +- ❌ Commit secrets or credentials +- ❌ Add undocumented public APIs +- ❌ Remove exported functions without MAJOR bump +- ❌ Make PRs directly to `master` +- ❌ Skip tests or reduce coverage +- ❌ Ignore ESLint or TypeScript errors +- ❌ Use magic strings/numbers without constants + +--- + +## ❓ Questions? + +- Check [copilot-instructions.md](.github/copilot-instructions.md) for module standards +- Read existing code in `src/` for examples +- Check closed PRs for discussion patterns +- Open a discussion issue with `[question]` tag + +--- + +## 📜 License + +By contributing, you agree your contributions are licensed under the same license as the project (MIT). --- -By contributing, you agree that your contributions will be licensed under the same license as the project. +**Last Updated:** January 31, 2026 +**Version:** 1.0.0 diff --git a/SECURITY b/SECURITY deleted file mode 100644 index 785ce46..0000000 --- a/SECURITY +++ /dev/null @@ -1,31 +0,0 @@ -# Security Policy - -Security is taken seriously in this project. - -If you discover a security vulnerability, please **do not open a public issue**. - ---- - -## Reporting a Vulnerability - -Please report security issues privately by contacting the maintainers using one of the following methods: - -- Email the address listed in the repository’s contact or maintainer information -- Use private disclosure channels if available on the hosting platform - -When reporting, please include: -- A description of the vulnerability -- Steps to reproduce -- Potential impact -- Any suggested mitigations (if known) - ---- - -## Security Best Practices - -- Never commit secrets or credentials -- Use strong, rotated secrets for JWT signing -- Run services behind HTTPS -- Apply rate limiting and monitoring in production environments - -We appreciate responsible disclosure and will work to address issues promptly. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..0ce478d --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,324 @@ +# Security Policy + +Security is critical to AuthKit, a reusable authentication library used across CISCODE projects. We take vulnerabilities seriously and appreciate responsible disclosure. + +--- + +## 🔐 Supported Versions + +| Version | Status | Security Updates Until | +| ------- | ----------- | ---------------------- | +| 1.5.x | Current | January 2027 | +| 1.4.x | LTS | January 2026 | +| 1.0-1.3 | Unsupported | End of life | +| 0.x | Unsupported | End of life | + +--- + +## 🚨 Reporting Security Vulnerabilities + +**DO NOT open public GitHub issues for security vulnerabilities.** + +### How to Report + +1. **Email (Preferred)** + - Send to: security@ciscode.ma + - Subject: `[AuthKit Security] Vulnerability Report` + - Include all details below + +2. **Private Disclosure** + - GitHub Security Advisory (if available) + - Private message to maintainers + +### What to Include + +- **Vulnerability Description:** Clear explanation of the issue +- **Affected Versions:** Which AuthKit versions are vulnerable? +- **Steps to Reproduce:** Detailed reproduction steps +- **Impact Assessment:** + - Severity (critical/high/medium/low) + - What data/functionality is at risk? + - Can unprivileged users exploit this? +- **Suggested Fix:** (Optional) If you have a mitigation idea +- **Your Contact Info:** So we can follow up +- **Disclosure Timeline:** Your preferred timeline for public disclosure + +### Example Report + +``` +Title: JWT Secret Not Validated on Module Import + +Description: +AuthKit fails to validate JWT_SECRET environment variable during module +initialization, allowing the module to start with undefined secret. + +Affected Versions: 1.4.0, 1.5.0 + +Reproduction: +1. Skip setting JWT_SECRET in .env +2. Import AuthModule in NestJS app +3. Module initializes successfully (should fail) +4. All JWTs generated are vulnerable + +Impact: CRITICAL +- All tokens generated without proper secret +- Tokens can be forged by attackers +- Authentication completely broken + +Suggested Fix: +- Validate JWT_SECRET in AuthModule.forRoot() +- Throw error during module initialization if missing + +Timeline: 30 days preferred (embargo until patch released) + +Reporter: security@example.com +``` + +--- + +## ⏱️ Response Timeline + +- **Acknowledgment:** Within 24 hours +- **Triage:** Within 72 hours +- **Fix Timeline:** + - Critical: 7 days + - High: 14 days + - Medium: 30 days + - Low: Next regular release +- **Public Disclosure:** 90 days after fix released (or sooner if already public) + +--- + +## 🔑 Security Best Practices + +### For AuthKit Maintainers + +1. **Secrets Management** + + ```bash + # ✅ DO - Use environment variables + const jwtSecret = process.env.JWT_SECRET; + + # ❌ DON'T - Hardcode secrets + const jwtSecret = "my-secret-key"; // NEVER + ``` + +2. **Dependency Security** + + ```bash + # Check for vulnerabilities + npm audit + npm audit fix + + # Keep dependencies updated + npm update + npm outdated + ``` + +3. **Code Review** + - Security review for all PRs + - Focus on authentication/authorization changes + - Check for SQL injection, XSS, CSRF risks + - Validate input on all endpoints + +4. **Testing** + - Test with malformed/invalid tokens + - Test permission boundaries + - Test with expired tokens + - Test OAuth token validation + +### For Host Applications Using AuthKit + +1. **Environment Variables - CRITICAL** + + ```env + # ✅ Use strong, unique secrets (minimum 32 characters) + JWT_SECRET=your_very_long_random_secret_key_minimum_32_chars + JWT_REFRESH_SECRET=another_long_random_secret_key + JWT_EMAIL_SECRET=third_long_random_secret_key + JWT_RESET_SECRET=fourth_long_random_secret_key + + # ✅ Rotate secrets periodically + # ✅ Use different secrets for different token types + + # ❌ DON'T share secrets between environments + # ❌ DON'T commit .env to git (use .env.example) + ``` + +2. **Token Configuration** + + ```env + # Access tokens - SHORT expiration + JWT_ACCESS_TOKEN_EXPIRES_IN=15m + + # Refresh tokens - LONGER expiration + JWT_REFRESH_TOKEN_EXPIRES_IN=7d + + # Email verification - SHORT expiration + JWT_EMAIL_TOKEN_EXPIRES_IN=1d + + # Password reset - SHORT expiration + JWT_RESET_TOKEN_EXPIRES_IN=1h + ``` + +3. **HTTPS/TLS - MANDATORY in Production** + + ```typescript + // ✅ DO - Use HTTPS in production + // ❌ DON'T - Allow HTTP connections with sensitive data + ``` + +4. **Rate Limiting - HIGHLY RECOMMENDED** + + ```typescript + // Protect against brute force attacks on auth endpoints + import { ThrottlerModule } from '@nestjs/throttler'; + + @Post('/auth/login') + @UseGuards(ThrottlerGuard) // Max 5 attempts per 15 minutes + async login(@Body() dto: LoginDto) { + // implementation + } + ``` + +5. **CORS Configuration** + + ```typescript + // ✅ DO - Whitelist specific origins + app.enableCors({ + origin: process.env.FRONTEND_URL, + credentials: true, + }); + + // ❌ DON'T - Allow all origins with credentials + app.enableCors({ + origin: "*", + credentials: true, // BAD + }); + ``` + +6. **Input Validation** + + ```typescript + // ✅ DO - Validate all inputs + @Post('/auth/login') + async login(@Body() dto: LoginDto) { + // DTO validation happens automatically + } + + // ❌ DON'T - Skip validation + ``` + +7. **Logging & Monitoring** + + ```typescript + // ✅ DO - Log authentication failures + // ❌ DON'T - Log passwords or tokens + ``` + +8. **CORS & Credentials** + - httpOnly cookies (refresh tokens) + - Secure flag in production + - SameSite=Strict policy + +--- + +## 🔍 Security Vulnerability Types We Track + +### High Priority + +- ✋ Arbitrary code execution +- 🔓 Authentication bypass +- 🔑 Secret key exposure +- 💾 Database injection (NoSQL) +- 🛡️ Cross-site scripting (XSS) +- 🚪 Privilege escalation +- 📝 Sensitive data disclosure + +### Medium Priority + +- 🔐 Weak cryptography +- 🚫 CORS misconfiguration +- ⏱️ Race conditions +- 📦 Dependency vulnerabilities +- 🎯 Insecure defaults + +### Low Priority + +- 📋 Typos in documentation +- ⚠️ Missing error messages +- 🧹 Code cleanup suggestions + +--- + +## ✅ Security Checklist for Releases + +Before publishing any version: + +- [ ] Run `npm audit` - zero vulnerabilities +- [ ] All tests passing (100% of test suite) +- [ ] No hardcoded secrets in code +- [ ] No credentials in logs +- [ ] JWT validation working correctly +- [ ] Password hashing uses bcryptjs (10+ rounds) +- [ ] Refresh tokens are invalidated on password change +- [ ] All user input is validated +- [ ] CSRF protection considered +- [ ] XSS prevention in place +- [ ] Rate limiting documented for applications +- [ ] Security review completed +- [ ] CHANGELOG documents security fixes +- [ ] Version bumped appropriately (MAJOR if security fix) + +--- + +## 🔄 Known Security Considerations + +1. **JWT Secret Rotation** + - Currently not supported for zero-downtime rotation + - Plan: v2.0.0 will support key versioning + +2. **Token Invalidation** + - Refresh tokens invalidated on password change ✅ + - No ability to revoke all tokens (stateless design) + - Plan: Optional Redis-backed token blacklist in v2.0.0 + +3. **OAuth Provider Security** + - Depends on provider security implementations + - We validate tokens but trust provider attestations + - Review provider security policies regularly + +4. **Rate Limiting** + - Not built-in (app responsibility) + - Recommended: Use `@nestjs/throttler` with strict limits on auth endpoints + +--- + +## 📚 Security Resources + +- [OWASP Authentication Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html) +- [OWASP Password Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html) +- [JWT Best Current Practices (RFC 8725)](https://tools.ietf.org/html/rfc8725) +- [NestJS Security Documentation](https://docs.nestjs.com/security) +- [OWASP Top 10](https://owasp.org/www-project-top-ten/) + +--- + +## 📞 Security Contact + +- **Email:** security@ciscode.ma +- **Response SLA:** 24-72 hours for vulnerability acknowledgment +- **Maintainers:** Listed in repository + +--- + +## 📜 Acknowledgments + +We appreciate and publicly credit security researchers who responsibly disclose vulnerabilities. + +We follow the [Coordinated Vulnerability Disclosure](https://en.wikipedia.org/wiki/Coordinated_vulnerability_disclosure) process. + +--- + +**Last Updated:** January 31, 2026 +**Version:** 1.0.0 diff --git a/TROUBLESHOOTING.md b/TROUBLESHOOTING.md new file mode 100644 index 0000000..6ad78d2 --- /dev/null +++ b/TROUBLESHOOTING.md @@ -0,0 +1,619 @@ +# Troubleshooting Guide + +Common issues and solutions for AuthKit integration and usage. + +--- + +## 🚀 Installation & Setup Issues + +### Issue: Module fails to initialize - "JWT_SECRET is not set" + +**Error:** + +``` +Error: JWT_SECRET environment variable is not set +``` + +**Solution:** + +1. Check `.env` file exists in your project root +2. Add JWT_SECRET variable: + ```env + JWT_SECRET=your_very_long_random_secret_key_minimum_32_chars + JWT_REFRESH_SECRET=another_long_random_secret_key + JWT_EMAIL_SECRET=third_long_random_secret_key + JWT_RESET_SECRET=fourth_long_random_secret_key + ``` +3. Restart your application +4. Ensure `dotenv` is loaded before importing modules + +**Prevention:** + +- Copy `.env.example` to `.env` +- Never commit `.env` files +- Use CI/CD secrets for production + +--- + +### Issue: MongoDB connection fails - "connect ECONNREFUSED" + +**Error:** + +``` +MongooseError: connect ECONNREFUSED 127.0.0.1:27017 +``` + +**Solution:** + +**Local Development:** + +1. Start MongoDB locally: + + ```bash + # macOS (with Homebrew) + brew services start mongodb-community + + # Docker + docker run -d -p 27017:27017 --name mongodb mongo + + # Manual start + mongod + ``` + +2. Verify MongoDB is running: + ```bash + mongo --eval "db.adminCommand('ping')" + ``` + +**Remote MongoDB:** + +1. Check connection string in `.env`: + ```env + MONGO_URI=mongodb://username:password@host:port/database + ``` +2. Verify credentials and host are correct +3. Check firewall allows connection to MongoDB +4. Verify IP whitelist if using MongoDB Atlas + +--- + +### Issue: Package not found - "Cannot find module '@ciscode/authentication-kit'" + +**Error:** + +``` +ModuleNotFoundError: Cannot find module '@ciscode/authentication-kit' +``` + +**Solution:** + +1. **If package not installed:** + + ```bash + npm install @ciscode/authentication-kit + ``` + +2. **If using npm link during development:** + + ```bash + # In AuthKit directory + npm link + + # In your app directory + npm link @ciscode/authentication-kit + + # Verify it worked + npm list @ciscode/authentication-kit + ``` + +3. **If path alias issue:** + - Verify `tsconfig.json` has correct paths + - Run `npm run build` to compile + +--- + +## 🔐 Authentication Issues + +### Issue: Login fails - "Invalid credentials" + +**Error:** + +``` +UnauthorizedException: Invalid credentials. +``` + +**Possible Causes:** + +1. **User not found:** + + ```bash + # Check if user exists in database + mongo + > use your_db_name + > db.users.findOne({email: "user@example.com"}) + ``` + + **Solution:** Register the user first + +2. **Password incorrect:** + - Verify you're entering correct password + - Passwords are case-sensitive + - Check for extra spaces + +3. **Email not verified:** + + ``` + Error: Email not verified. Please verify your email first. + ``` + + **Solution:** Check email for verification link + - If email not received, call: `POST /api/auth/resend-verification` + +4. **User is banned:** + ``` + Error: Account is banned. + ``` + **Solution:** Contact admin to unban the account + +--- + +### Issue: JWT validation fails - "Invalid token" + +**Error:** + +``` +UnauthorizedException: Invalid token +``` + +**Causes:** + +1. **Token expired:** + + ``` + JsonWebTokenError: jwt expired + ``` + + **Solution:** Refresh token using `/api/auth/refresh-token` + +2. **Token malformed:** + + ``` + JsonWebTokenError: jwt malformed + ``` + + **Solution:** + - Check Authorization header format: `Bearer ` + - Verify token wasn't truncated + +3. **Wrong secret used:** + + ``` + JsonWebTokenError: invalid signature + ``` + + **Solution:** + - Check JWT_SECRET matches what was used to sign token + - Don't change JWT_SECRET without invalidating existing tokens + +4. **Token from different environment:** + **Solution:** Each environment needs its own JWT_SECRET + +--- + +### Issue: Refresh token fails - "Invalid refresh token" + +**Error:** + +``` +UnauthorizedException: Invalid refresh token +``` + +**Causes:** + +1. **Refresh token expired:** + + ```bash + # Tokens expire based on JWT_REFRESH_TOKEN_EXPIRES_IN + # Default: 7 days + ``` + + **Solution:** User must login again + +2. **Password was changed:** + - All refresh tokens invalidate on password change (security feature) + **Solution:** User must login again with new password + +3. **Token from cookie not sent:** + + ```bash + # If using cookie-based refresh, ensure: + fetch(url, { + method: 'POST', + credentials: 'include' // Send cookies + }) + ``` + +4. **Token from body malformed:** + ```json + POST /api/auth/refresh-token + { + "refreshToken": "your-refresh-token" + } + ``` + +--- + +## 📧 Email Issues + +### Issue: Verification email not received + +**Causes:** + +1. **SMTP not configured:** + + ```bash + # Check these env variables are set + SMTP_HOST=smtp.gmail.com + SMTP_PORT=587 + SMTP_USER=your-email@gmail.com + SMTP_PASS=your-app-password + FROM_EMAIL=noreply@yourapp.com + ``` + +2. **Email in spam folder:** + - Check spam/junk folder + - Add sender to contacts + +3. **Gmail app-specific password needed:** + + ```bash + # If using Gmail, use app-specific password, not account password + SMTP_PASS=your-16-character-app-password + ``` + +4. **Resend verification email:** + + ```bash + POST /api/auth/resend-verification + Content-Type: application/json + + { + "email": "user@example.com" + } + ``` + +--- + +### Issue: "SMTP Error: 535 Authentication failed" + +**Solution:** + +1. **Verify SMTP credentials:** + + ```bash + # Test with OpenSSL + openssl s_client -connect smtp.gmail.com:587 -starttls smtp + ``` + +2. **Gmail users - use app password:** + - Go to: https://myaccount.google.com/apppasswords + - Generate app-specific password + - Use in SMTP_PASS (not your account password) + +3. **Gmail 2FA enabled:** + - App password required (see above) + +4. **SMTP_PORT incorrect:** + - Gmail: 587 (TLS) or 465 (SSL) + - Other: check your provider + +--- + +## 🔑 OAuth Issues + +### Issue: Google OAuth fails - "Invalid ID token" + +**Error:** + +``` +Error: Invalid ID token +``` + +**Causes:** + +1. **ID token already used:** + - Tokens can only be used once + **Solution:** Get new token from Google + +2. **Token expired:** + - Google ID tokens expire quickly (~1 hour) + **Solution:** Request new token before calling endpoint + +3. **GOOGLE_CLIENT_ID mismatch:** + + ```bash + # Check env variable matches Google Console + GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com + ``` + + **Solution:** Verify in Google Console + +4. **Frontend sending code instead of idToken:** + + ```typescript + // ✅ Correct - send ID token + fetch("/api/auth/oauth/google", { + method: "POST", + body: JSON.stringify({ + idToken: googleResponse.tokenId, + }), + }); + + // ❌ Wrong - using code + fetch("/api/auth/oauth/google", { + method: "POST", + body: JSON.stringify({ + code: googleResponse.code, // Wrong format + }), + }); + ``` + +--- + +### Issue: Microsoft OAuth fails - "Invalid token" + +**Error:** + +``` +Error: Invalid Microsoft token +``` + +**Causes:** + +1. **MICROSOFT_CLIENT_ID mismatch:** + + ```env + MICROSOFT_CLIENT_ID=your-azure-app-id + ``` + +2. **Token from wrong authority:** + - Ensure token is from same tenant/app + - Check MICROSOFT_TENANT_ID if using specific tenant + +3. **JWKS endpoint unreachable:** + - Microsoft provides public key endpoint + - Verify internet connectivity + +--- + +### Issue: Facebook OAuth fails - "Invalid access token" + +**Error:** + +``` +Error: Invalid Facebook token +``` + +**Causes:** + +1. **FB_CLIENT_ID or FB_CLIENT_SECRET incorrect:** + + ```bash + # Verify in Facebook Developer Console + FB_CLIENT_ID=your-app-id + FB_CLIENT_SECRET=your-app-secret + ``` + +2. **User access token:** + - Must be server access token, not user token + **Solution:** Get token from Facebook SDK correctly + +--- + +## 🛡️ Permission & Authorization Issues + +### Issue: Admin endpoint returns "Forbidden" + +**Error:** + +``` +ForbiddenException: Access denied +``` + +**Causes:** + +1. **User doesn't have admin role:** + + ```bash + # Check user roles in database + mongo + > db.users.findOne({email: "user@example.com"}, {roles: 1}) + ``` + + **Solution:** Assign admin role to user + +2. **Token doesn't include roles:** + - Verify JWT includes role IDs in payload + **Solution:** Token might be from before role assignment + +3. **@Admin() decorator not used:** + + ```typescript + // ✅ Correct + @Post('/admin/users') + @UseGuards(AuthenticateGuard) + @UseGuards(AdminGuard) + async createUser(@Body() dto: CreateUserDto) {} + + // ❌ Missing guard + @Post('/admin/users') + async createUser(@Body() dto: CreateUserDto) {} + ``` + +--- + +### Issue: Protected route returns "Unauthorized" + +**Error:** + +``` +UnauthorizedException: Unauthorized +``` + +**Causes:** + +1. **No Authorization header:** + + ```typescript + // ✅ Correct + fetch("/api/auth/me", { + headers: { + Authorization: "Bearer " + accessToken, + }, + }); + + // ❌ Wrong + fetch("/api/auth/me"); + ``` + +2. **Invalid Authorization format:** + - Must be: `Bearer ` + - Not: `JWT ` or just `` + +3. **AuthenticateGuard not applied:** + + ```typescript + // ✅ Correct + @Get('/protected-route') + @UseGuards(AuthenticateGuard) + async protectedRoute() {} + + // ❌ Missing guard + @Get('/protected-route') + async protectedRoute() {} + ``` + +--- + +## 🚫 Permission Model Issues + +### Issue: User has role but still can't access permission-based endpoint + +**Error:** + +``` +ForbiddenException: Permission denied +``` + +**Causes:** + +1. **Role doesn't have permission:** + + ```bash + # Check role permissions + mongo + > db.roles.findOne({name: "user"}, {permissions: 1}) + ``` + + **Solution:** Add permission to role + +2. **Permission doesn't exist:** + - Check permission in database + - Verify spelling matches exactly + +3. **@Permissions() not used:** + ```typescript + // ✅ Correct + @Patch('/admin/users') + @Permissions('users:manage') + async updateUser() {} + ``` + +--- + +## 🐛 Debugging + +### Enable Verbose Logging + +```typescript +// In your main.ts or app.module.ts +import { Logger } from "@nestjs/common"; + +const logger = new Logger(); +logger.debug("AuthKit initialized"); + +// For development, log JWT payload +import * as jwt from "jsonwebtoken"; +const decoded = jwt.decode(token); +logger.debug("Token payload:", decoded); +``` + +### Check JWT Payload + +```bash +# Use jwt.io website to decode token (verify only!) +# Or use CLI: +npx jwt-decode +``` + +### Database Inspection + +```bash +# MongoDB shell +mongo + +# List all users +> db.users.find() + +# Find specific user +> db.users.findOne({email: "user@example.com"}) + +# Check roles +> db.roles.find() + +# Check permissions +> db.permissions.find() +``` + +### Network Debugging + +```bash +# Check what's being sent +curl -v -X POST http://localhost:3000/api/auth/login \ + -H "Content-Type: application/json" \ + -d '{"email":"user@example.com","password":"password"}' + +# Check response headers +curl -i http://localhost:3000/api/auth/me \ + -H "Authorization: Bearer YOUR_TOKEN" +``` + +--- + +## 📞 Getting Help + +If your issue isn't listed: + +1. **Check existing issues:** https://github.com/CISCODE-MA/AuthKit/issues +2. **Read documentation:** [README.md](README.md) +3. **Check copilot instructions:** [.github/copilot-instructions.md](.github/copilot-instructions.md) +4. **Open new issue** with: + - Error message (full stack trace) + - Steps to reproduce + - Your Node/npm/MongoDB versions + - What you've already tried + +--- + +## 🔗 Useful Links + +- [NestJS Documentation](https://docs.nestjs.com/) +- [MongoDB Documentation](https://docs.mongodb.com/) +- [JWT.io (Token Decoder)](https://jwt.io) +- [OWASP Security](https://owasp.org/) +- [Node.js Best Practices](https://github.com/goldbergyoni/nodebestpractices) + +--- + +**Last Updated:** January 31, 2026 +**Version:** 1.0.0 diff --git a/package-lock.json b/package-lock.json index de28c19..ae6d160 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@ciscode/authentication-kit", - "version": "1.5.0", + "version": "1.5.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@ciscode/authentication-kit", - "version": "1.5.0", + "version": "1.5.1", "license": "MIT", "dependencies": { "axios": "^1.7.7", diff --git a/package.json b/package.json index 969b7d4..77be1d9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ciscode/authentication-kit", - "version": "1.5.0", + "version": "1.5.1", "description": "NestJS auth kit with local + OAuth, JWT, RBAC, password reset.", "publishConfig": { "access": "public"