Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
VCCI-News
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
Văn Hoàng
VCCI-News
Commits
5243b3bc
Commit
5243b3bc
authored
Aug 06, 2026
by
Lê Bảo Hồng Đức
☄
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix
parent
866bd3a3
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
41 additions
and
26 deletions
+41
-26
index.tsx
src/app/(main)/(home)/components/banner/index.tsx
+5
-5
admin-auth.ts
src/lib/auth/admin-auth.ts
+36
-21
No files found.
src/app/(main)/(home)/components/banner/index.tsx
View file @
5243b3bc
...
...
@@ -9,7 +9,7 @@ import "swiper/css";
import
{
getApiV10Banner
}
from
"@/api/endpoints/banner"
;
import
{
useQuery
}
from
"@tanstack/react-query"
;
import
{
resolveCmsFileUrl
}
from
"@/lib/api/files"
;
import
{
fetchCmsFileById
,
resolveCmsFileUrl
}
from
"@/lib/api/files"
;
import
{
Skeleton
}
from
"@/components/ui/skeleton"
;
type
ApiEnvelope
<
T
>
=
{
...
...
@@ -65,12 +65,12 @@ function BannerSlideItem({
fileId
?:
string
|
null
;
}
)
{
const
{
data
:
file
,
isPending
}
=
useQuery
({
queryKey
:
[
"file"
,
fileId
],
queryFn
:
()
=>
Promise
.
resolve
({
path
:
src
}
),
enabled
:
!!
fileId
&&
!
src
,
queryKey
:
[
"
cms-
file"
,
fileId
],
queryFn
:
()
=>
fetchCmsFileById
(
fileId
!
),
enabled
:
!!
fileId
,
});
if
(
fileId
&&
isPending
&&
!
src
)
{
if
(
isPending
)
{
return
(
<
Skeleton
className=
"w-full h-[200px] sm:h-[300px] md:h-[400px] lg:h-[500px]"
/>
);
...
...
src/lib/auth/admin-auth.ts
View file @
5243b3bc
...
...
@@ -7,7 +7,7 @@ import useAuthStore, {
}
from
"@/store/useAuthStore"
;
import
links
from
"@/links"
;
const
AUTH_BASE_URL
=
`
${
links
.
apiEndpoint
}
/auth`
;
const
AUTH_BASE_URL
=
`
${
links
.
apiEndpoint
}
/a
pi/v1.0/a
uth`
;
const
SESSION_EXPIRED_MESSAGE
=
"Phiên đăng nhập đã hết hạn. Vui lòng đăng nhập lại."
;
interface
AuthEnvelope
<
T
>
{
...
...
@@ -39,6 +39,12 @@ interface LoginResponseData {
token_type
?:
string
|
null
;
}
interface
LoginResponseEnvelope
{
responseData
?:
LoginResponseData
;
message
?:
string
|
null
;
message_en
?:
string
|
null
;
}
type
MeResponseData
=
Partial
<
AuthenticatedAdminUser
>
;
interface
RefreshResponseData
{
...
...
@@ -49,9 +55,14 @@ interface RefreshResponseData {
token_type
?:
string
|
null
;
}
interface
RefreshResponseEnvelope
{
responseData
?:
RefreshResponseData
;
}
interface
AuthRequestOptions
extends
RequestInit
{
skipAuthHeader
?:
boolean
;
authToken
?:
string
|
null
;
noEnvelope
?:
boolean
;
}
type
AuthFailureReason
=
"missing_refresh_token"
|
"refresh_failed"
;
...
...
@@ -163,7 +174,7 @@ async function requestAuth<T>(
throw
error
;
}
return
getEnvelopeData
(
data
)
as
T
;
return
init
?.
noEnvelope
?
(
data
as
T
)
:
getEnvelopeData
(
data
)
as
T
;
}
const
redirectToLogin
=
()
=>
{
...
...
@@ -191,7 +202,7 @@ export async function loginAdmin(
password
:
string
,
options
?:
{
persistSession
?:
boolean
},
)
{
const
payload
=
await
requestAuth
<
LoginResponse
Data
>
(
"/login"
,
{
const
payload
=
await
requestAuth
<
LoginResponse
Envelope
>
(
"/login"
,
{
method
:
"POST"
,
body
:
JSON
.
stringify
({
email
,
...
...
@@ -200,30 +211,32 @@ export async function loginAdmin(
skipAuthHeader
:
true
,
});
if
(
!
payload
.
access_token
||
!
payload
.
refresh_token
||
!
payload
.
expires_in
)
{
const
loginData
=
payload
?.
responseData
??
payload
as
LoginResponseData
;
if
(
!
loginData
?.
access_token
||
!
loginData
?.
refresh_token
||
!
loginData
?.
expires_in
)
{
throw
new
Error
(
"Thiếu dữ liệu phiên đăng nhập từ API."
);
}
const
me
=
await
requestAuth
<
MeResponseData
>
(
"/me"
,
{
method
:
"GET"
,
authToken
:
payload
.
access_token
,
}).
catch
(()
=>
payload
.
user
??
null
);
authToken
:
loginData
.
access_token
,
}).
catch
(()
=>
loginData
.
user
??
null
);
const
normalizedUser
=
normalizeUser
(
me
??
payload
.
user
);
const
normalizedUser
=
normalizeUser
(
me
??
loginData
.
user
);
useAuthStore
.
getState
().
setAuthSession
({
accessToken
:
payload
.
access_token
,
refreshToken
:
payload
.
refresh_token
,
expiresIn
:
payload
.
expires_in
,
accessTokenExpired
:
getJwtExpiresAt
(
payload
.
access_token
),
accessToken
:
loginData
.
access_token
,
refreshToken
:
loginData
.
refresh_token
,
expiresIn
:
loginData
.
expires_in
,
accessTokenExpired
:
getJwtExpiresAt
(
loginData
.
access_token
),
user
:
normalizedUser
,
session
:
normalizeSession
(
payload
.
session
),
session
:
normalizeSession
(
loginData
.
session
),
persistSession
:
options
?.
persistSession
===
true
,
});
useAuthStore
.
getState
().
setAppUser
(
normalizedUser
);
return
payload
;
return
loginData
;
}
export
async
function
logoutAdmin
(
options
?:
{
...
...
@@ -290,7 +303,7 @@ export async function refreshAdminAccessToken() {
store
.
setAppRefreshing
(
true
);
try
{
const
payload
=
await
requestAuth
<
RefreshResponse
Data
>
(
"/refresh"
,
{
const
payload
=
await
requestAuth
<
RefreshResponse
Envelope
>
(
"/refresh"
,
{
method
:
"POST"
,
body
:
JSON
.
stringify
({
refresh_token
:
refreshToken
,
...
...
@@ -298,19 +311,21 @@ export async function refreshAdminAccessToken() {
skipAuthHeader
:
true
,
});
if
(
!
payload
.
access_token
||
!
payload
.
expires_in
)
{
const
refreshData
=
payload
?.
responseData
??
payload
as
RefreshResponseData
;
if
(
!
refreshData
?.
access_token
||
!
refreshData
?.
expires_in
)
{
throw
new
Error
(
"Thiếu access token mới từ API."
);
}
useAuthStore
.
getState
().
updateAccessToken
({
accessToken
:
payload
.
access_token
,
expiresIn
:
payload
.
expires_in
,
accessTokenExpired
:
getJwtExpiresAt
(
payload
.
access_token
),
refreshToken
:
payload
.
refresh_token
??
refreshToken
,
session
:
normalizeSession
(
payload
.
session
),
accessToken
:
refreshData
.
access_token
,
expiresIn
:
refreshData
.
expires_in
,
accessTokenExpired
:
getJwtExpiresAt
(
refreshData
.
access_token
),
refreshToken
:
refreshData
.
refresh_token
??
refreshToken
,
session
:
normalizeSession
(
refreshData
.
session
),
});
return
payload
.
access_token
;
return
refreshData
.
access_token
;
}
catch
(
error
)
{
await
logoutAdmin
({
silent
:
true
,
reason
:
"refresh_failed"
});
throw
error
;
...
...
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