Skip to content

Auth - Technical Map

Auto-generated bởi codebase-doc-generator ngày 2026-03-23 (verified từ code thực). Không chỉnh sửa thủ công.

Routes

RoutePathMục đích
ROUTE_LOGIN/auth/loginTrang đăng nhập email/password
ROUTE_REGISTER/auth/registerTrang đăng ký
ROUTE_FORGOT_PASSWORD/auth/forgot_passwordTrang quên mật khẩu
ItemGiá trị
MODULE_AUTHauth
Route configsROUTE_LOGIN, ROUTE_REGISTER, ROUTE_FORGOT_PASSWORD đều có config rỗng
Navigation statusnavigation: []
Public accessAuth routes được xem là public entry; guard auth nằm ở router/app bootstrap, không phải module navigation
Default FE auth providerFirebase composition đang active; JWT composition đang comment

FE Pages (4)

PageFileVai trò
EmailLoginpages/EmailLogin.tsxWrapper submit login email/password
Registerpages/Register.tsxWrapper submit register
ForgotPasswordpages/ForgotPassword.tsxFlow 3 bước xin OTP, verify OTP, đổi mật khẩu
LoginSessionpages/LoginSession.tsxModal nhập PIN cho POS, không phải route

FE Components / Compositions

Component / CompositionVai trò
LayoutShell auth page, logo, slogan, RouterView
EmailLoginFormForm login account/password, link qua forgot password
RegisterFormForm đăng ký email/password
ForgotPasswordFormForm stateful theo step = 1/2/3
useAuthFacade auth chung, cache profile, bootstrap redirect
useProfileUpdate locale, redirect route helper
firebase/service.tsFirebase auth implementation
firebase/authConfig.tsurql auth config cho Firebase token
jwt/useJwtAuth.tsJWT auth implementation (inactive)
jwt/authConfig.tsurql auth config cho JWT token
jwt/storage.tsLocalStorage token storage + subject

GraphQL Operations

File: diva-admin/src/modules/auth/graphql/profile.graphql

Profile / session

OperationMục đích
GetMeLấy profile me hiện tại
UpdateMeUpdate me để đổi locale và profile fields
VerifyPinVerify PIN session cho POS

File: diva-admin/src/modules/user/graphql/account.graphql

Password reset

OperationMục đích
requestOTPForgetPasswordXin OTP quên mật khẩu
verifyOTPForgetPasswordXác thực OTP quên mật khẩu
staffForgetPasswordĐổi mật khẩu mới sau khi verify OTP

File: diva-admin/src/modules/auth/compositions/jwt/graphql.ts

JWT auth

OperationMục đích
LoginLogin lấy access_token, refresh_token
RefreshTokenRefresh access token khi sắp hết hạn

FE Runtime logic

configureUseAuth.ts

LogicGhi chú
Platform resetNếu LOCAL_STORAGE_PLATFORM đổi, xóa cache profile/report roles/CRM extension state
Profile cacheCache LOCAL_STORAGE_MY_PROFILE TTL 1 giờ
Report role cacheCache LOCAL_STORAGE_REPORT_ROLES TTL 1 giờ
Auth gateNếu role không hợp lệ hoặc platform mismatch thì signOut và đẩy về login
Notification bootstrapSau khi auth xong sẽ notification.subscribe(profile.id)
LocaleNếu profile.language tồn tại thì set i18n.locale
RedirectNếu route hiện tại không public và là route auth hợp lệ thì redirect theo redirectRoute() / home / first visible menu

useProfile.ts

LogicGhi chú
Locale updateGọi update_me(where: {}, _set: { language })
Redirect helperCho phép route nếu moduleId === program_management hoặc module đó nằm trong role modules

EmailLogin.tsx

LogicGhi chú
Login payloadvalues.email.trim() + DivaDomain
Post-login side effectGọi createAccountActivity({ type: "L" })
Clear stateclearUserBehavior() sau login

ForgotPassword.tsx

LogicGhi chú
Step 1Gửi requestOTPForgetPassword với email ghép @diva.vn
Step 2Gửi verifyOTPForgetPassword với account_id + OTP
Step 3Gửi staffForgetPassword với account_id, otp_string, new_password
TimerInterval update seconds từ otp_expiry

LoginSession.tsx

LogicGhi chú
Mount conditionChỉ render từ AppPos.tsx khi authenticated nhưng chưa có user session
Prefill usernameĐọc localstorage_profile_cache và cắt phần trước @
SuccessglobalStore.setUserSession(result.verifyPin.user)

Auth Composition

Firebase path

LogicGhi chú
signInWithEmailAndPasswordGọi Firebase SDK trực tiếp
registerWithEmailAndPasswordGọi Firebase SDK createUserWithEmailAndPassword
sendPasswordResetEmailGọi Firebase SDK
getIdTokenPrefix token với firebase trước khi gắn vào header
didAuthErrorMatch GraphQL error chứa not found in type: 'query_root' hoặc auth hook unauthorized

JWT path

LogicGhi chú
signInWithEmailAndPasswordGọi GraphQL Login với auth_provider_type: "jwt"
Token storageLưu access_token, refresh_token, expiry vào localStorage
Refresh flowKhi token sắp hết hạn, gọi RefreshToken và ghi lại token mới
getIdTokenPrefix token với jwt
registerWithEmailAndPasswordHiện là no-op
sendPasswordResetEmailHiện là no-op

Backend Service Map

Service / handlerMục đích
POST /actionsHasura action router cho toàn bộ auth actions
POST /eventsHasura event router
GET /verify-tokenVerify token trả Hasura session vars
POST /verify-tokenVerify token qua payload headers/body
GET /healthzHealth check trả version tag/commit

Backend Actions

Core auth

ActionFileVai trò
loginaction/auth.goLogin email/phone, encode token
registeraction/auth.goCreate account theo provider
refreshTokenaction/auth.goRefresh JWT token

Password / account lifecycle

ActionFileVai trò
adminChangePasswordaction/password.goAdmin đổi password theo account_id
changePasswordaction/password.goUser đổi password của chính mình
resetPasswordaction/password.goReset password bằng email
deleteAccountaction/delete_account.goDisable account + delete Firebase user

OTP / PIN

ActionFileVai trò
requestOTPaction/otp.goXin OTP login
verifyOTPaction/otp.goVerify OTP login
request2FaOTPaction/otp.goXin OTP 2FA
verify2FaOTPaction/otp.goVerify OTP 2FA
requestOTPForgetPasswordaction/otp.goXin OTP quên mật khẩu
verifyOTPForgetPasswordaction/otp.goVerify OTP quên mật khẩu
staffForgetPasswordaction/otp.goĐổi mật khẩu sau OTP
requestOTPMergeAccountaction/otp_merge_account.goXin OTP merge account
verifyOTPMergeAccountaction/otp_merge_account.goVerify OTP merge account
adminChangePinaction/pin.goAdmin đổi PIN
verifyPinaction/pin.goVerify PIN session POS
staffChangePinaction/pin.goUser đổi PIN bằng PIN cũ

Activity / audit

ActionFileVai trò
createAccountActivityaction/create_activity.goGhi activity login/opened_at + device metadata

Backend Event

EventFileVai trò
employee_profile_updateevent/employee_profile_update.goGenerate salary, send quit notification, recalc payroll

Data model / storage

Object / keyVai trò
accountProfile gốc, role, enabled flags, provider data
account_providerProvider hiện tại của account
account_activityLưu OTP/login/merge/account events
system_configCấu hình SMS/OTP/Auth
sms_template / zns_templateTemplate gửi OTP, password reset, quit notice
role_moduleScope module theo role
group_memberNhóm quyền bổ sung như dynamic
device_user_log_inDevice binding cho platform staff
local_storage_my_profileCache profile FE
local_storage_report_rolesCache report role FE
local_storage_platformDùng để reset cache theo platform
AppAccessToken localStorageJWT token storage

Rủi ro / Findings kỹ thuật

#Note
1LoginSession không nằm trong route module, nên khi đọc map route chỉ thấy login/register/forgot_password là chưa đủ.
2JWT auth path đã có đủ login/refresh/storage/authConfig nhưng đang inactive ở compositions/index.ts.
3authorizeUser() có cache Redis theo token + platform + device_id để giảm query Hasura, nhưng vẫn fallback query đầy đủ khi cache miss hoặc cache lỗi (diva-backend/services/auth/server/auth.go:132-197).
4requestOTPMergeAccount()requestOTPForgetPassword() đều có đoạn fallback ZNS/SMS khá dài; đây là điểm lặp lớn nhất trong backend auth.
5deleteAccount() và một số action không dùng payload đầu vào, nghĩa là semantics của action phụ thuộc hoàn toàn vào session hiện tại.