Skip to content

Commit

Permalink
fix: adjust client connect server
Browse files Browse the repository at this point in the history
  • Loading branch information
lcaohoanq committed Dec 7, 2024
1 parent 823b9ca commit 66f1d7e
Show file tree
Hide file tree
Showing 18 changed files with 101 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,17 @@ public ResponseEntity<ApiResponse<LoginResponse>> login(

String token = authService.login(userLoginDTO.email(), userLoginDTO.password());
String userAgent = request.getHeader("User-Agent");
User userDetail = authService.getUserDetailsFromToken(token);
Token jwtToken = tokenService.addToken(userDetail, token, isMobileDevice(userAgent));
UserResponse userDetail = authService.getUserDetailsFromToken(token);
Token jwtToken = tokenService.addToken(userDetail.id(), token, isMobileDevice(userAgent));

log.info("User logged in successfully");

LoginResponse response = new LoginResponse(
jwtToken.getToken(),
jwtToken.getRefreshToken(),
jwtToken.getTokenType() == null ? "Bearer" : jwtToken.getTokenType(),
userDetail.getId(),
userDetail.getUsername(),
userDetail.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.toList()
jwtToken.getRefreshExpirationDate(),
jwtToken.getExpirationDate(),
userDetail
);

return ResponseEntity.ok(ApiResponse.<LoginResponse>builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public ResponseEntity<PageResponse<ProductResponse>> getAllProducts(
productService.getAll(
PageRequest.of(page,
limit,
Sort.by("createdAt").ascending())));
Sort.by("createdAt").descending())));
}

@GetMapping("/{id}")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,37 @@
package com.lcaohoanq.shoppe.dtos.responses;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import java.time.LocalDateTime;
import java.util.List;

@JsonPropertyOrder({"token", "refresh_token", "tokenType", "id", "username", "roles"})
@JsonPropertyOrder({
"access_token",
"refresh_token",
"expires_refresh_token",
"expires",
"user"
})
@JsonInclude(Include.NON_NULL)
public record LoginResponse (
@JsonProperty("token")
public record LoginResponse(
@JsonProperty("access_token")
String token,

@JsonProperty("refresh_token")
String refreshToken,

String tokenType,
//user's detail
Long id,
String username,
@JsonProperty("expires_refresh_token")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSSSSS")
LocalDateTime expiresRefreshToken,

@JsonProperty("expires")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSSSSS")
LocalDateTime expires,

List<String> roles
//user's detail
UserResponse user
) {}
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@ public record UserResponse(
@JsonProperty("is_active") boolean isActive,
@JsonProperty("status") UserStatus status,
@JsonProperty("date_of_birth") String dob,
@JsonProperty("phoneNumber") String phone,
@JsonProperty("phone_number") String phone,
@JsonProperty("address") String address,
@JsonProperty("avatar") String avatar,
@JsonProperty("role_name") String roleName,
@JsonIgnore
@JsonProperty("wallet_id") Long walletId,
@JsonIgnore @JsonProperty("wallet_id") Long walletId,
@JsonProperty ("preferred_language") String preferredLanguage,
@JsonProperty ("preferred_currency") String preferredCurrency,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

public interface TokenRepository extends JpaRepository<Token, Long> {

List<Token> findByUser(User user);
List<Token> findByUserId(Long userId);

Token findByToken(String token);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.lcaohoanq.shoppe.components.LocalizationUtils;
import com.lcaohoanq.shoppe.constants.Regex;
import com.lcaohoanq.shoppe.dtos.request.AccountRegisterDTO;
import com.lcaohoanq.shoppe.dtos.responses.UserResponse;
import com.lcaohoanq.shoppe.enums.Country;
import com.lcaohoanq.shoppe.enums.Currency;
import com.lcaohoanq.shoppe.enums.UserStatus;
Expand All @@ -23,6 +24,7 @@
import com.lcaohoanq.shoppe.services.role.RoleService;
import com.lcaohoanq.shoppe.services.token.TokenService;
import com.lcaohoanq.shoppe.services.user.UserService;
import com.lcaohoanq.shoppe.utils.DTOConverter;
import com.lcaohoanq.shoppe.utils.MessageKey;
import io.reactivex.rxjava3.core.Single;
import io.reactivex.rxjava3.schedulers.Schedulers;
Expand All @@ -44,7 +46,7 @@
@Slf4j
@Service
@RequiredArgsConstructor
public class AuthService implements IAuthService {
public class AuthService implements IAuthService, DTOConverter {


private final UserRepository userRepository;
Expand Down Expand Up @@ -158,15 +160,15 @@ public String login(String email, String password) throws Exception {

//Token
@Override
public User getUserDetailsFromToken(String token) throws Exception {
public UserResponse getUserDetailsFromToken(String token) throws Exception {
if (jwtTokenUtils.isTokenExpired(token)) {
throw new ExpiredTokenException("Token is expired");
}
String email = jwtTokenUtils.extractEmail(token);
Optional<User> user = userRepository.findByEmail(email);

if (user.isPresent()) {
return user.get();
return toUserResponse(user.get());
} else {
throw new Exception(
localizationUtils.getLocalizedMessage(MessageKey.USER_NOT_FOUND)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package com.lcaohoanq.shoppe.services.auth;

import com.lcaohoanq.shoppe.dtos.request.AccountRegisterDTO;
import com.lcaohoanq.shoppe.dtos.responses.UserResponse;
import com.lcaohoanq.shoppe.models.User;

public interface IAuthService {

User register(AccountRegisterDTO accountRegisterDTO) throws Exception;
String login(String email, String password) throws Exception;
User getUserDetailsFromToken(String token) throws Exception;
UserResponse getUserDetailsFromToken(String token) throws Exception;
void logout(String token, User user) throws Exception;
void verifyOtpToVerifyUser(Long userId, String otp) throws Exception;
void verifyOtpIsCorrect(Long userId, String otp) throws Exception;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
@Service

public interface ITokenService {
Token addToken(User user, String token, boolean isMobileDevice);
Token addToken(long userId, String token, boolean isMobileDevice);
Token refreshToken(String refreshToken, User user) throws Exception;
void deleteToken(String token, User user) throws DataNotFoundException;
Token findUserByToken(String token) throws DataNotFoundException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.lcaohoanq.shoppe.models.Token;
import com.lcaohoanq.shoppe.models.User;
import com.lcaohoanq.shoppe.repositories.TokenRepository;
import com.lcaohoanq.shoppe.services.user.UserService;
import jakarta.transaction.Transactional;
import java.time.LocalDateTime;
import java.util.List;
Expand All @@ -22,6 +23,7 @@
@RequiredArgsConstructor
public class TokenService implements ITokenService{
private static final int MAX_TOKENS = 3;
private final UserService userService;
@Value("${jwt.expiration}")
private int expiration; //save to an environment variable

Expand Down Expand Up @@ -73,8 +75,9 @@ public Token findUserByToken(String token) throws DataNotFoundException {

@Transactional
@Override
public Token addToken(User user,String token, boolean isMobileDevice) {
List<Token> userTokens = tokenRepository.findByUser(user);
public Token addToken(long userId, String token, boolean isMobileDevice) {
User existingUser = userService.findUserById(userId);
List<Token> userTokens = tokenRepository.findByUserId(existingUser.getId());
int tokenCount = userTokens.size();
// Số lượng token vượt quá giới hạn, xóa một token cũ
if (tokenCount >= MAX_TOKENS) {
Expand All @@ -98,7 +101,7 @@ public Token addToken(User user,String token, boolean isMobileDevice) {
LocalDateTime expirationDateTime = LocalDateTime.now().plusSeconds(expirationInSeconds);
// Tạo mới một token cho người dùng
Token newToken = Token.builder()
.user(user)
.user(existingUser)
.token(token)
.revoked(false)
.expired(false)
Expand Down
2 changes: 1 addition & 1 deletion client/src/apis/auth.api.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { AuthResponse } from 'src/types/auth.type'
import http from 'src/utils/http'

export const URL_LOGIN = 'login'
export const URL_LOGIN = 'auth/login'
export const URL_REGISTER = 'register'
export const URL_LOGOUT = 'logout'
export const URL_REFRESH_TOKEN = 'refresh-access-token'
Expand Down
1 change: 1 addition & 0 deletions client/src/components/NavHeader/NavHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export default function NavHeader() {
<Link to={path.login} className='mx-3 capitalize hover:text-white/70'>
Đăng nhập
</Link>
<Link to={'https://help.shopee.vn/portal/4'}>Bạn cần giúp đỡ</Link>
</div>
)}
</div>
Expand Down
10 changes: 7 additions & 3 deletions client/src/pages/ProductList/ProductList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ export default function ProductList() {
}
})

// Debugging: log the categoryData and productData
console.log('categoriesData:', categoriesData?.data.data)
console.log('productsData:', productsData)

return (
<div className='bg-gray-200 py-6'>
<Helmet>
Expand All @@ -41,15 +45,15 @@ export default function ProductList() {
<AsideFilter queryConfig={queryConfig} categories={categoriesData?.data.data || []} />
</div>
<div className='col-span-9'>
<SortProductList queryConfig={queryConfig} pageSize={productsData.data.data.pagination.page_size} />
<SortProductList queryConfig={queryConfig} pageSize={productsData.data.pagination.page_size} />
<div className='mt-6 grid grid-cols-2 gap-3 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5'>
{productsData.data.data.products.map((product) => (
{productsData.data.data.map((product) => (
<div className='col-span-1' key={product._id}>
<Product product={product} />
</div>
))}
</div>
<Pagination queryConfig={queryConfig} pageSize={productsData.data.data.pagination.page_size} />
<Pagination queryConfig={queryConfig} pageSize={productsData.data.pagination.page_size} />
</div>
</div>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,15 @@ export default function AsideFilter({ queryConfig, categories }: Props) {
<div className='my-4 h-[1px] bg-gray-300' />
<ul>
{categories.map((categoryItem) => {
const isActive = category === categoryItem._id
const isActive = category === categoryItem.id
return (
<li className='py-2 pl-2' key={categoryItem._id}>
<li className='py-2 pl-2' key={categoryItem.id}>
<Link
to={{
pathname: path.home,
search: createSearchParams({
...queryConfig,
category: categoryItem._id
category: categoryItem.id
}).toString()
}}
className={classNames('relative px-2', {
Expand Down
7 changes: 7 additions & 0 deletions client/src/types/api.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export type ApiResponse<Data> = {
message: string
data: Data
status_code: number
is_success: boolean
reason: string
}
10 changes: 2 additions & 8 deletions client/src/types/auth.type.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import { User } from './user.type'
import { LoginResponse, User } from './user.type'
import { SuccessResponse } from './utils.type'

export type AuthResponse = SuccessResponse<{
access_token: string
refresh_token: string
expires_refresh_token: number
expires: number
user: User
}>
export type AuthResponse = SuccessResponse<LoginResponse>

export type RefreshTokenReponse = SuccessResponse<{ access_token: string }>
6 changes: 5 additions & 1 deletion client/src/types/category.type.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { ApiResponse } from './api.type'

export interface Category {
_id: string
id: string
name: string
}

export type CategoryResponse = ApiResponse<Category[]>
26 changes: 26 additions & 0 deletions client/src/types/user.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,29 @@ export interface User {
createdAt: string
updatedAt: string
}

export type UserResponse = {
id: number
email: string
name: string
gender: string
is_active: boolean
status: string
date_of_birth: string
phone_number: string
address: string
avatar: string
role_name: string
preferred_language: string
preferred_currency: string
created_at: string
updated_at: string
}

export type LoginResponse = {
access_token: string
refresh_token: string
expires_refresh_token: string
expires: string
user: UserResponse
}
5 changes: 5 additions & 0 deletions client/src/types/utils.type.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
export interface SuccessResponse<Data> {
message: string
data: Data
status_code: number
is_success: boolean
}
export interface ErrorResponse<Data> {
message: string
data?: Data
reason?: string
status_code?: number
is_success?: boolean
}

// cú pháp `-?` sẽ loại bỏ undefiend của key optional
Expand Down

0 comments on commit 66f1d7e

Please sign in to comment.