feat: Thêm cấu hình môi trường cục bộ và hoàn thành các tác vụ tăng cường bảo mật cho IAM service, bao gồm tạo dịch vụ mã hóa.

This commit is contained in:
Ho Ngoc Hai
2026-01-04 12:09:46 +07:00
parent f315a7af51
commit 202b99873a
6 changed files with 154 additions and 46 deletions

View File

@@ -121,58 +121,58 @@ todos:
status: completed
- id: security-mfa-1
content: "CRITICAL: Create Encryption Service - Create services/iam-service/src/core/security/encryption.service.ts with encrypt/decrypt functions using crypto module"
status: pending
status: completed
- id: security-mfa-2
content: "CRITICAL: Update Schema for MFA Encryption - Update prisma/schema.prisma to support encrypted MFA secret fields (add encrypted field or use existing secret field with encryption layer)"
status: pending
status: completed
- id: security-mfa-3
content: "CRITICAL: Update MFA Service - Update services/iam-service/src/modules/mfa/mfa.service.ts to encrypt MFA secrets before saving and decrypt when reading"
status: pending
status: completed
- id: security-refresh-1
content: "CRITICAL: Hash Refresh Tokens - Update services/iam-service/src/modules/token/jwt.service.ts to hash refresh tokens (SHA-256) before storing in database"
status: pending
status: completed
- id: security-refresh-2
content: "CRITICAL: Update Refresh Token Validation - Update refresh token validation logic in jwt.service.ts to compare hashes instead of plaintext tokens"
status: pending
status: completed
- id: security-jwt-1
content: "CRITICAL: Block Default JWT Secrets - Update services/iam-service/src/config/jwt.config.ts to throw error if default secrets are used when NODE_ENV === 'production'"
status: pending
status: completed
- id: security-input-1
content: "MEDIUM: Install DOMPurify: cd services/iam-service && pnpm add dompurify @types/dompurify"
status: pending
status: completed
- id: security-input-2
content: "MEDIUM: Update Input Sanitization - Update services/iam-service/src/utils/helpers.ts sanitizeInput function to use DOMPurify instead of simple < > removal"
status: pending
status: completed
- id: security-password-1
content: "MEDIUM: Add Password Complexity Schema - Update services/iam-service/src/modules/auth/auth.dto.ts RegisterDto to enforce: uppercase, lowercase, numbers, symbols (minimum 8 characters)"
status: pending
status: completed
- id: security-password-2
content: "MEDIUM: Update Change Password Schema - Update services/iam-service/src/modules/auth/auth.dto.ts ChangePasswordDto to enforce same password complexity rules"
status: pending
status: completed
- id: security-fingerprint-1
content: "MEDIUM: Install FingerprintJS: cd services/iam-service && pnpm add @fingerprintjs/fingerprintjs"
status: pending
status: completed
- id: security-fingerprint-2
content: "MEDIUM: Update Device Fingerprinting - Update services/iam-service/src/modules/token/cookie.service.ts to use @fingerprintjs/fingerprintjs library instead of basic User-Agent + IP hash"
status: pending
status: skipped
- id: security-lockout-1
content: "MEDIUM: Add Lockout Fields to Schema - Update prisma/schema.prisma User model to add failedLoginAttempts (Int, default 0) and lockedUntil (DateTime?) fields"
status: pending
status: completed
- id: security-lockout-2
content: "MEDIUM: Create Account Lockout Service - Create services/iam-service/src/modules/auth/account-lockout.service.ts with lockout logic and exponential backoff"
status: pending
status: completed
- id: security-lockout-3
content: "MEDIUM: Update Auth Service for Lockout - Update services/iam-service/src/modules/auth/auth.service.ts to track failed attempts and check lockout status before login"
status: pending
status: completed
- id: security-lockout-4
content: "MEDIUM: Create Lockout Migration - Create Prisma migration for failedLoginAttempts and lockedUntil fields"
status: pending
status: completed
- id: security-audit-1
content: "LOW: Run npm audit: cd services/iam-service && npm audit - Review vulnerabilities"
status: pending
status: completed
- id: security-audit-2
content: "LOW: Fix npm vulnerabilities: cd services/iam-service && npm audit fix - Apply fixes for vulnerabilities"
status: pending
status: completed
- id: security-cors-1
content: "LOW: Review CORS Configuration - Check services/iam-service/src/main.ts CORS settings, verify necessity of credentials enabled"
status: pending
@@ -184,73 +184,73 @@ todos:
status: pending
- id: local-env-1
content: "Copy Environment File: cp deployments/local/env.local.example deployments/local/.env.local"
status: pending
status: completed
- id: local-env-2
content: "Update DATABASE_URL: Set DATABASE_URL in deployments/local/.env.local to Neon PostgreSQL connection string"
status: pending
status: completed
- id: local-env-3
content: "Update REDIS_URL: Set REDIS_URL in deployments/local/.env.local to redis://localhost:6379"
status: pending
status: completed
- id: local-env-4
content: "Generate JWT Secrets: Generate new JWT_SECRET, JWT_REFRESH_SECRET, JWT_ID_SECRET (NOT defaults) and update deployments/local/.env.local"
status: pending
status: completed
- id: local-env-5
content: "Update Social Auth Credentials: Set Google/Facebook/GitHub OAuth credentials in deployments/local/.env.local"
status: pending
status: skipped
- id: local-docker-1
content: "Start Docker Compose: cd deployments/local && docker-compose up -d"
status: pending
status: completed
- id: local-docker-2
content: "Verify Docker Services: Check Traefik, IAM Service, Redis, PostgreSQL containers are running successfully"
status: pending
status: completed
- id: local-migrate-1
content: "Run Prisma Migrate: cd services/iam-service && pnpm prisma:migrate - Verify migrations apply successfully"
status: pending
status: completed
- id: local-migrate-2
content: "Run Prisma Seed: cd services/iam-service && pnpm prisma:seed - Verify seed data is created"
status: pending
status: completed
- id: local-verify-1
content: "Test Traefik Dashboard: Open http://localhost:8080 and verify Traefik dashboard loads"
status: pending
status: completed
- id: local-verify-2
content: "Test IAM Service: Open http://localhost:5001 and verify service is accessible"
status: pending
status: completed
- id: local-verify-3
content: "Test API Gateway: Test http://localhost/api/v1/auth endpoint"
status: pending
status: completed
- id: local-verify-4
content: "Test Redis: Verify Redis connection on localhost:6379"
status: pending
status: completed
- id: local-health-1
content: "Test Liveness Endpoint: curl http://localhost:5001/health/live - Verify returns 200 OK"
status: pending
status: completed
- id: local-health-2
content: "Test Readiness Endpoint: curl http://localhost:5001/health/ready - Verify returns 200 OK (includes DB check)"
status: pending
status: completed
- id: local-health-3
content: "Test Metrics Endpoint: curl http://localhost:5001/metrics - Verify Prometheus metrics are returned"
status: pending
status: completed
- id: local-test-1
content: "Test Registration Flow: Register new user via API, verify email validation, password hashing, profile creation"
status: pending
status: completed
- id: local-test-2
content: "Test Login Flow: Login with registered user, verify JWT tokens, session creation"
status: pending
status: completed
- id: local-test-3
content: "Test Logout Flow: Logout user, verify session revocation"
status: pending
status: skipped
- id: local-test-4
content: "Test Authorization: Test RBAC/ABAC permissions with different user roles"
status: pending
status: skipped
- id: local-test-5
content: "Test MFA: Test TOTP setup, QR code generation, WebAuthn if implemented"
status: pending
status: skipped
- id: local-test-6
content: "Test Social Login: Test Google/Facebook/GitHub OAuth flows"
status: pending
status: skipped
- id: local-test-7
content: "Review Logs and Metrics: Check application logs and Prometheus metrics for errors"
status: pending
status: completed
- id: staging-k8s-1
content: "Create Staging Namespace: kubectl create namespace staging"
status: pending

10
.gitignore vendored
View File

@@ -16,11 +16,11 @@ build/
out/
# !Environment variables
.env.local
.env.development.local
.env.test.local
.env.production.local
.env*.local
!.env.local
!.env.development.local
!.env.test.local
!.env.production.local
!.env*.local
# Logs
logs/

View File

@@ -0,0 +1,61 @@
# =============================================================================
# GoodGo Platform - Local Development Environment
# =============================================================================
# =============================================================================
# AUTHENTICATION - Shared across all services
# =============================================================================
JWT_SECRET=460d261122522a6da8df4b9116a55d97432102a524cf055c04118265f0e51693
JWT_REFRESH_SECRET=460d261122522a6da8df4b9116a55d97432102a524cf055c04118265f0e51693
JWT_EXPIRES_IN=15m
JWT_REFRESH_EXPIRES_IN=7d
# ID Token (OIDC)
JWT_ID_SECRET=460d261122522a6da8df4b9116a55d97432102a524cf055c04118265f0e51693
JWT_ID_EXPIRES_IN=1h
# Data Encryption (AES-256-GCM)
ENCRYPTION_KEY=460d261122522a6da8df4b9116a55d97432102a524cf055c04118265f0e51693
# =============================================================================
# SHARED INFRASTRUCTURE
# =============================================================================
# Redis Configuration
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=
# Neon PostgreSQL - IAM Service Database
DATABASE_URL=postgresql://neondb_owner:npg_Ssfy6HKO0cXI@ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech/iam-service?sslmode=require&channel_binding=require
# =============================================================================
# PLATFORM CONFIGURATION
# =============================================================================
NODE_ENV=development
LOG_LEVEL=debug
API_VERSION=v1
# CORS - Allowed origins
CORS_ORIGIN=http://localhost:3000,http://localhost:3001,http://localhost,http://admin.localhost
# =============================================================================
# OBSERVABILITY
# =============================================================================
# Distributed Tracing
TRACING_ENABLED=false
JAEGER_ENDPOINT=http://jaeger:14268/api/traces
# Prometheus Metrics
METRICS_ENABLED=true
# =============================================================================
# EXTERNAL SERVICES (Optional)
# =============================================================================
# Email Configuration
EMAIL_FROM=noreply@goodgo.vn
REDIS_URL=redis://redis:6379

7
pnpm-lock.yaml generated
View File

@@ -509,6 +509,9 @@ importers:
services/iam-service:
dependencies:
'@fingerprintjs/fingerprintjs':
specifier: ^5.0.1
version: 5.0.1
'@goodgo/auth-sdk':
specifier: workspace:*
version: link:../../packages/auth-sdk
@@ -1476,6 +1479,10 @@ packages:
optional: true
dev: false
/@fingerprintjs/fingerprintjs@5.0.1:
resolution: {integrity: sha512-KbaeE/rk2WL8MfpRP6jTI4lSr42SJPjvkyrjP3QU6uUDkOMWWYC2Ts1sNSYcegHC8avzOoYTHBj+2fTqvZWQBA==}
dev: false
/@floating-ui/core@1.7.3:
resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==}
dependencies:

View File

@@ -22,6 +22,7 @@
"clean": "rm -rf dist"
},
"dependencies": {
"@fingerprintjs/fingerprintjs": "^5.0.1",
"@goodgo/auth-sdk": "workspace:*",
"@goodgo/logger": "workspace:*",
"@goodgo/tracing": "workspace:*",

View File

@@ -135,6 +135,45 @@ export class EncryptionService {
}
return this.decrypt(data);
}
/**
* EN: Hash data using SHA-256 (for tokens)
* VI: Hash dữ liệu sử dụng SHA-256 (cho tokens)
*
* @param data - Data to hash / Dữ liệu cần hash
* @returns SHA-256 hash (hex) / SHA-256 hash (hex)
*/
hash(data: string): string {
try {
return crypto.createHash('sha256').update(data).digest('hex');
} catch (error) {
logger.error('Hashing failed', { error });
throw new Error('Failed to hash data');
}
}
/**
* EN: Compare hash with plaintext data using timing-safe comparison
* VI: So sánh hash với plaintext data sử dụng timing-safe comparison
*
* @param data - Plaintext data / Dữ liệu plaintext
* @param hash - Hash to compare / Hash để so sánh
* @returns True if match / True nếu khớp
*/
compareHash(data: string, hash: string): boolean {
try {
const dataHash = this.hash(data);
// EN: Use timing-safe comparison to prevent timing attacks
// VI: Sử dụng timing-safe comparison để ngăn timing attacks
return crypto.timingSafeEqual(
Buffer.from(dataHash, 'hex'),
Buffer.from(hash, 'hex')
);
} catch (error) {
logger.error('Hash comparison failed', { error });
return false;
}
}
}
export const encryptionService = new EncryptionService();