AuthService.kt
package delta.codecharacter.server.auth
import delta.codecharacter.dtos.AuthStatusResponseDto
import delta.codecharacter.dtos.ForgotPasswordRequestDto
import delta.codecharacter.dtos.PasswordLoginRequestDto
import delta.codecharacter.dtos.PasswordLoginResponseDto
import delta.codecharacter.dtos.ResetPasswordRequestDto
import delta.codecharacter.server.auth.jwt.JwtService
import delta.codecharacter.server.auth.reset_password.ResetPasswordService
import delta.codecharacter.server.exception.CustomException
import delta.codecharacter.server.user.LoginType
import delta.codecharacter.server.user.UserEntity
import delta.codecharacter.server.user.UserService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.HttpStatus
import org.springframework.security.core.userdetails.UsernameNotFoundException
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
import org.springframework.stereotype.Service
@Service
class AuthService(
@Autowired private val userService: UserService,
@Autowired private val jwtService: JwtService,
@Autowired private val resetPasswordService: ResetPasswordService,
@Autowired private val passwordEncoder: BCryptPasswordEncoder,
) {
fun passwordLogin(passwordLoginRequestDto: PasswordLoginRequestDto): PasswordLoginResponseDto {
val email = passwordLoginRequestDto.email
val password = passwordLoginRequestDto.password
val user: UserEntity
try {
user = userService.loadUserByUsername(email)
} catch (e: UsernameNotFoundException) {
throw CustomException(HttpStatus.UNAUTHORIZED, "Invalid credentials")
}
if (user.loginType != LoginType.PASSWORD) {
throw CustomException(HttpStatus.UNAUTHORIZED, "Invalid credentials")
}
if (passwordEncoder.matches(password, user.password)) {
return PasswordLoginResponseDto(jwtService.generateToken(user))
} else throw CustomException(HttpStatus.UNAUTHORIZED, "Invalid credentials")
}
fun forgotPassword(forgotPasswordRequestDto: ForgotPasswordRequestDto) {
val email = forgotPasswordRequestDto.email
val user =
userService.getUserByEmail(email).orElseThrow {
throw CustomException(HttpStatus.BAD_REQUEST, "Invalid credentials")
}
if (user.loginType != LoginType.PASSWORD) {
throw CustomException(HttpStatus.BAD_REQUEST, "User not registered with password")
}
resetPasswordService.sendResetPasswordEmail(user)
}
fun resetPassword(resetPasswordRequestDto: ResetPasswordRequestDto) {
val (token, password, passwordConfirmation) = resetPasswordRequestDto
if (password != passwordConfirmation) {
throw CustomException(HttpStatus.BAD_REQUEST, "Password and Confirm Password does not match")
}
val userId = resetPasswordService.processResetPasswordTokenAndGetUserId(token)
userService.updateUserPassword(userId, password)
}
fun oAuth2Login(email: String, loginType: LoginType): String {
val user = userService.getUserByEmail(email)
val userEntity: UserEntity
if (user.isEmpty) {
userEntity = userService.createUserWithOAuth(email, loginType)
} else {
userEntity = user.get()
if (userEntity.loginType != loginType) {
throw CustomException(HttpStatus.BAD_REQUEST, "Incorrect login provider")
}
}
return jwtService.generateToken(userEntity)
}
fun getAuthStatus(user: UserEntity): AuthStatusResponseDto {
val status: AuthStatusResponseDto.Status =
if (!user.isProfileComplete) {
AuthStatusResponseDto.Status.PROFILE_INCOMPLETE
} else if (!user.isEnabled) {
AuthStatusResponseDto.Status.ACTIVATION_PENDING
} else {
AuthStatusResponseDto.Status.AUTHENTICATED
}
return AuthStatusResponseDto(status)
}
}