Trang này ghi lại luồng vận hành thật của module auth hiện tại: token được tạo ở đâu, refresh token được lưu và rotate ra sao, middleware chặn request thế nào, email verification/reset password đi qua queue nào. Swagger vẫn là nguồn cho payload chi tiết; tài liệu này tập trung vào flow và dependency.
user.idsessionIdUserStatusACCESS_EXPIRESAuth hiện tại chia thành ba lớp: HTTP route/controller, domain service/repository, và hạ tầng token/Redis/queue.
Routes validate body/query bằng Zod trước, controller lấy IP/user-agent rồi gọi service. Các route cần phiên dùng middleware authorization.
Service xử lý register/login/refresh/logout/email/reset. Repository bọc Prisma cho users, refresh_tokens, verification_codes.
JWT ký access token, refresh token là random hex được hash SHA-256 trước khi lưu DB. Redis giữ blacklist và Bloom filter, queue xử lý email/Bloom async.
Flow chart này gom toàn bộ auth module theo lớp chạy thật: client đi vào route/controller, request cần quyền đi qua guard, service xử lý session/token, state nằm ở MySQL/Redis, còn email và Bloom filter chạy qua BullMQ worker.
Đây là đường đi chính từ lúc tạo tài khoản tới khi refresh/logout. Tài liệu cố ý không ghi payload chi tiết vì Swagger đã cover phần đó.
bcrypt.hashSync(password, 10).users với email, username, password.jwtService.generateTokenPair tạo access token và refresh token.refresh_tokens cùng sessionId, IP, user-agent, expireAt.OR email/username.bcrypt.compareSync.refresh_tokens.token.revokedAt = now.sessionId, lưu refresh token mới đã hash.req.accessToken.bl:at:<accessToken> với TTL 15 phút.Mọi route dùng middleware authorization đi qua cùng một cửa kiểm tra.
Đọc Authorization, lấy phần sau dấu cách. Thiếu token thì Unauthorized.
Kiểm tra bl:at:<token>. Nếu tồn tại, token bị coi là invalid.
jwt.verify bằng JWT_SECRET, payload cần có sub.
Tìm user theo sub. Không có user thì invalid token.
Nếu user không bị BANNED, gắn req.user và req.accessToken.
Hai luồng email dùng cùng pattern: sinh token random, hash token lưu DB, gửi token raw qua email worker.
verification_codes với type VERIFY_ACCOUNT.SEND_VERIFICATION_EMAIL render template/verify-email.ejs và gửi link /verify-email?token=....expiresAt, rồi set users.verified_at = now.FORGOT_PASSWORD, gửi email reset qua queue.template/forgot-password.ejs và gửi link /reset-password?token=....Validate email/username hiện đọc Redis Bloom filter thay vì query trực tiếp database.
User được tạo trong DB trước.
Register enqueue job GENERATE_BLOOM.
Worker thêm username vào filter:usernames và email vào filter:emails.
Validate trả available = !exists.
Bloom filter nhanh, nhưng về bản chất có thể false positive.
Các điểm dưới đây là mô tả hiện trạng để team nắm rõ. Tài liệu không sửa behavior.
id, email, username, password verified_at, status profile fields created_at, updated_at
token = sha256(raw refresh) session_id expire_at revoked_at ip, user_agent
token_hash = sha256(raw token) type = VERIFY_ACCOUNT | FORGOT_PASSWORD expires_at used_at currently not updated
register tạo token pair và enqueue Bloom job, nhưng không tự gửi verification email. Verification email hiện đi qua route resend.
updateProfile hiện trả { updated: true } theo input, chưa persist profile xuống database.
validateResetPasswordToken hiện luôn trả { valid: true }, chưa kiểm tra verification_codes.
Verification code expiry đang dùng ACCESS_EXPIRES khi lưu DB; text hiển thị trong email dùng config riêng cho verify/reset.
Middleware auth chỉ block rõ trạng thái BANNED. Các trạng thái khác như SUSPENDED hoặc DEACTIVATED chưa có nhánh xử lý riêng trong guard.
jwtService.requestAuthToken dùng cho optional auth verify JWT trực tiếp, không kiểm Redis blacklist như middleware authorization.