Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
finwise-miniapp-be
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ThinhNC
finwise-miniapp-be
Commits
5d8c61c1
Commit
5d8c61c1
authored
Aug 29, 2026
by
ThinhNC
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: auth service with JWT authentication, session management, and user profile functionality
parent
228e2506
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
38 additions
and
16 deletions
+38
-16
auth.dto.ts
src/modules/auth/auth.dto.ts
+3
-0
auth.service.ts
src/modules/auth/auth.service.ts
+32
-16
auth.validation.ts
src/modules/auth/auth.validation.ts
+3
-0
No files found.
src/modules/auth/auth.dto.ts
View file @
5d8c61c1
...
@@ -7,6 +7,9 @@ export interface ZaloLoginDto {
...
@@ -7,6 +7,9 @@ export interface ZaloLoginDto {
accessToken
:
string
;
// Zalo access_token từ getAccessToken() SDK
accessToken
:
string
;
// Zalo access_token từ getAccessToken() SDK
phoneToken
?:
string
;
// Mã token SĐT từ getPhoneNumber() SDK (giải mã phía server)
phoneToken
?:
string
;
// Mã token SĐT từ getPhoneNumber() SDK (giải mã phía server)
phoneNumber
?:
string
;
// SĐT thực trực tiếp (cho test/fallback)
phoneNumber
?:
string
;
// SĐT thực trực tiếp (cho test/fallback)
zaloId
?:
string
;
// User ID từ getUserInfo SDK client
name
?:
string
;
// Tên user từ getUserInfo SDK client
avatar
?:
string
;
// Avatar từ getUserInfo SDK client
}
}
export
interface
ZaloPhoneResponse
{
export
interface
ZaloPhoneResponse
{
...
...
src/modules/auth/auth.service.ts
View file @
5d8c61c1
...
@@ -449,25 +449,37 @@ export class AuthService {
...
@@ -449,25 +449,37 @@ export class AuthService {
const
{
accessToken
}
=
dto
;
const
{
accessToken
}
=
dto
;
const
appSecret
=
process
.
env
.
ZALO_APP_SECRET
||
''
;
const
appSecret
=
process
.
env
.
ZALO_APP_SECRET
||
''
;
// 1. Xác thực access_token với Zalo Graph API
// 1. Xác thực access_token và lấy thông tin Zalo profile (có fallback khi IP server ở nước ngoài)
const
appsecretProof
=
crypto
let
zaloId
=
dto
.
zaloId
||
''
;
.
createHmac
(
'sha256'
,
appSecret
)
let
zaloName
=
dto
.
name
||
'Người dùng Zalo'
;
.
update
(
accessToken
)
let
zaloAvatarUrl
:
string
|
null
=
dto
.
avatar
||
null
;
.
digest
(
'hex'
);
const
zaloProfile
=
await
this
.
fetchZaloProfile
(
accessToken
,
appsecretProof
);
try
{
if
(
!
zaloProfile
||
(
zaloProfile
.
error
!==
undefined
&&
zaloProfile
.
error
!==
0
)
||
!
zaloProfile
.
id
)
{
const
appsecretProof
=
crypto
console
.
error
(
'[ZaloAuth] fetchZaloProfile failed:'
,
zaloProfile
);
.
createHmac
(
'sha256'
,
appSecret
)
throw
new
AppError
(
.
update
(
accessToken
)
zaloProfile
?.
message
?
`Zalo Profile Error:
${
zaloProfile
.
message
}
`
:
'Invalid Zalo access token'
,
.
digest
(
'hex'
);
401
,
ERROR_CODE
.
INVALID_CREDENTIALS
,
const
zaloProfile
=
await
this
.
fetchZaloProfile
(
accessToken
,
appsecretProof
);
);
if
(
zaloProfile
&&
zaloProfile
.
id
)
{
zaloId
=
zaloProfile
.
id
;
if
(
zaloProfile
.
name
)
zaloName
=
zaloProfile
.
name
;
if
(
zaloProfile
.
picture
?.
data
?.
url
)
zaloAvatarUrl
=
zaloProfile
.
picture
.
data
.
url
;
}
else
if
(
zaloProfile
?.
error
===
-
501
)
{
console
.
warn
(
'[ZaloAuth] Server IP is outside Vietnam (-501). Using client profile info.'
);
}
else
if
(
zaloProfile
&&
zaloProfile
.
error
!==
undefined
&&
zaloProfile
.
error
!==
0
&&
!
dto
.
phoneToken
)
{
console
.
error
(
'[ZaloAuth] fetchZaloProfile failed:'
,
zaloProfile
);
throw
new
AppError
(
zaloProfile
?.
message
?
`Zalo Profile Error:
${
zaloProfile
.
message
}
`
:
'Invalid Zalo access token'
,
401
,
ERROR_CODE
.
INVALID_CREDENTIALS
,
);
}
}
catch
(
err
)
{
if
(
err
instanceof
AppError
)
throw
err
;
console
.
warn
(
'[ZaloAuth] fetchZaloProfile caught error:'
,
err
);
}
}
const
{
id
:
zaloId
,
name
:
zaloName
,
picture
}
=
zaloProfile
;
const
zaloAvatarUrl
:
string
|
null
=
picture
?.
data
?.
url
||
null
;
// 2. Lấy và chuẩn hóa số điện thoại (từ phoneToken hoặc phoneNumber)
// 2. Lấy và chuẩn hóa số điện thoại (từ phoneToken hoặc phoneNumber)
let
resolvedPhone
=
dto
.
phoneNumber
;
let
resolvedPhone
=
dto
.
phoneNumber
;
...
@@ -495,6 +507,10 @@ export class AuthService {
...
@@ -495,6 +507,10 @@ export class AuthService {
// Chuẩn hóa số điện thoại: +84... hoặc 84... -> 0...
// Chuẩn hóa số điện thoại: +84... hoặc 84... -> 0...
resolvedPhone
=
resolvedPhone
.
replace
(
/^
\+
84/
,
'0'
).
replace
(
/^84/
,
'0'
);
resolvedPhone
=
resolvedPhone
.
replace
(
/^
\+
84/
,
'0'
).
replace
(
/^84/
,
'0'
);
if
(
!
zaloId
)
{
zaloId
=
`zalo_
${
resolvedPhone
}
`
;
}
// 3. Tìm hoặc tạo user theo SĐT
// 3. Tìm hoặc tạo user theo SĐT
let
user
=
await
this
.
repository
.
findByPhone
(
resolvedPhone
);
let
user
=
await
this
.
repository
.
findByPhone
(
resolvedPhone
);
...
...
src/modules/auth/auth.validation.ts
View file @
5d8c61c1
...
@@ -18,6 +18,9 @@ export const zaloLoginSchema = z
...
@@ -18,6 +18,9 @@ export const zaloLoginSchema = z
.
string
()
.
string
()
.
regex
(
/^
(
0
[
3|5|7|8|9
])
+
([
0-9
]{8})
$/
,
'Invalid Vietnamese phone number format'
)
.
regex
(
/^
(
0
[
3|5|7|8|9
])
+
([
0-9
]{8})
$/
,
'Invalid Vietnamese phone number format'
)
.
optional
(),
.
optional
(),
zaloId
:
z
.
string
().
optional
(),
name
:
z
.
string
().
optional
(),
avatar
:
z
.
string
().
optional
(),
})
})
.
refine
((
data
)
=>
data
.
phoneToken
||
data
.
phoneNumber
,
{
.
refine
((
data
)
=>
data
.
phoneToken
||
data
.
phoneNumber
,
{
message
:
'Either phoneToken or phoneNumber must be provided'
,
message
:
'Either phoneToken or phoneNumber must be provided'
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment