# GoodGo Platform - Tham chiếu nhanh Authentication ## 🔑 Các điểm chính trong nháy mắt ### Hash mật khẩu ``` Algorithm: bcrypt Salt Rounds: 12 (env: BCRYPT_ROUNDS) Min Length: 8 characters Example: bcrypt.hash('password', 12) ``` ### Số điện thoại (Việt Nam) ``` Valid Formats: 0900000001, 84900000001, +84900000001 Normalized: +84900000001 Regex: /^(?:\+84|84|0)(3[2-9]|5[2689]|7[06-9]|8[1-9]|9[0-9])\d{7}$/ File: apps/api/src/modules/shared/utils/vietnam-phone.validator.ts ``` ### Email ``` Regex: /^[^\s@]+@[^\s@]+\.[^\s@]+$/ Normalization: lowercase + trim Storage: admin@goodgo.vn ``` ### Mã hoá PII ``` Algorithm: AES-256-GCM Key: 32 bytes (64 hex chars) Encrypted: email, phone, kycData Searchable: email → emailHash (HMAC-SHA256) phone → phoneHash (HMAC-SHA256) Env Var: FIELD_ENCRYPTION_KEY ``` ### Đăng nhập User ``` Username: phone (normalized) Password: plain text Lookup: by phoneHash (unique index) Required: isActive = true, passwordHash ≠ null Response: tokens (or MFA challenge) ``` ### Vai trò người dùng ``` BUYER - Search, inquire, offer (default) SELLER - Create listings AGENT - Professional agent ADMIN - Full access ``` ### MFA ``` TOTP: otplib (RFC 6238) Period: 30 seconds Digits: 6 Backup Codes: 10 × 8 chars (A-Z no OI, 2-9 no 01) Hashing: HMAC-SHA256 (not bcrypt) ``` --- ## 📋 Tạo người dùng Admin có thể đăng nhập ### Quy trình 5 bước **1. Chuẩn hoá số điện thoại** ```typescript phone = '0900000001' → '+84900000001' ``` **2. Tạo HMAC key** ```typescript hmacKey = crypto.hkdfSync('sha256', Buffer.from(encryptionKey, 'hex'), Buffer.alloc(0), Buffer.from('goodgo-field-hash', 'utf8'), 32) ``` **3. Tính các hash** ```typescript phoneHash = crypto.createHmac('sha256', hmacKey).update('+84900000001').digest('hex') emailHash = crypto.createHmac('sha256', hmacKey).update('admin@goodgo.vn').digest('hex') ``` **4. Hash mật khẩu** ```typescript passwordHash = await bcrypt.hash('AdminPassword123', 12) ``` **5. Tạo user** ```typescript await prisma.user.create({ data: { id: 'admin-seed-001', phone: '+84900000001', phoneHash, email: 'admin@goodgo.vn', emailHash, passwordHash, fullName: 'Admin', role: 'ADMIN', kycStatus: 'VERIFIED', isActive: true, totpEnabled: false, totpBackupCodes: [], }, }); ``` --- ## 🧪 Test đăng nhập ```bash curl -X POST http://localhost:3000/auth/login \ -H "Content-Type: application/json" \ -d '{ "phone": "0900000001", "password": "AdminPassword123" }' ``` **Response thành công:** ```json { "requiresMfa": false, "tokens": { "accessToken": "eyJ...", "refreshToken": "eyJ...", "expiresIn": 3600 } } ``` --- ## ⚠️ Vấn đề thường gặp | Vấn đề | Cách sửa | |-------|-----| | User không đăng nhập được | Kiểm tra: `passwordHash` ≠ null, `isActive` = true | | "Invalid phone" | Phone phải khớp regex (chỉ mobile) | | Hash không khớp | Xác minh `FIELD_ENCRYPTION_KEY` nhất quán | | Vấn đề MFA | Xác minh biến môi trường `MFA_BACKUP_CODE_SECRET` | | PII không được mã hoá | Xác minh key đúng 32 bytes (64 ký tự hex) | --- ## 📁 Các file chính | File | Mục đích | |------|---------| | `hashed-password.vo.ts` | Hash bcrypt | | `vietnam-phone.validator.ts` | Validation số điện thoại | | `field-encryption.ts` | Mã hoá AES-256-GCM | | `local.strategy.ts` | Endpoint đăng nhập | | `mfa.service.ts` | TOTP / backup code | | `user.entity.ts` | Domain model User | | `prisma-user.repository.ts` | Persistence User | | `seed.ts` | Script seed | --- ## 🔐 Checklist cho Seed User - [ ] Mật khẩu ≥ 8 ký tự - [ ] Phone khớp regex - [ ] Phone đã chuẩn hoá: +84... - [ ] Phone đã hash: HMAC-SHA256 - [ ] Email đã chuyển lowercase - [ ] Email đã hash: HMAC-SHA256 - [ ] Password đã hash: bcrypt (12 rounds) - [ ] `isActive: true` - [ ] `passwordHash` ≠ null - [ ] `totpEnabled: false` - [ ] `totpBackupCodes: []` --- ## 📚 Các file tài liệu đầy đủ 1. **AUTHENTICATION_GUIDE.md** - Tham chiếu kỹ thuật đầy đủ 2. **AUTH_IMPLEMENTATION_CHECKLIST.md** - Checklist triển khai & troubleshoot 3. **SEED_GENERATION_SCRIPT.ts** - Script seed sẵn sàng dùng 4. **QUICK_REFERENCE.md** - File này --- **Cập nhật cuối:** 12 tháng 4, 2026 **Trạng thái:** ✅ Sẵn sàng Production