From a9367b588021d86d556f1c842aeb6a9be37dc3f4 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 10:56:14 +0900 Subject: [PATCH 01/56] =?UTF-8?q?=F0=9F=94=A5=20::=20un=20used=20dto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/dto/request/CodeRequest.kt | 5 -- .../feign/google/dto/OAuthTokenResponse.kt | 8 --- .../onui/infra/oauth/apple/AppleUtils.kt | 69 ------------------- 3 files changed, 82 deletions(-) delete mode 100644 src/main/kotlin/com/example/onui/domain/auth/presentation/dto/request/CodeRequest.kt delete mode 100644 src/main/kotlin/com/example/onui/infra/feign/google/dto/OAuthTokenResponse.kt delete mode 100644 src/main/kotlin/com/example/onui/infra/oauth/apple/AppleUtils.kt diff --git a/src/main/kotlin/com/example/onui/domain/auth/presentation/dto/request/CodeRequest.kt b/src/main/kotlin/com/example/onui/domain/auth/presentation/dto/request/CodeRequest.kt deleted file mode 100644 index e87e58a..0000000 --- a/src/main/kotlin/com/example/onui/domain/auth/presentation/dto/request/CodeRequest.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.example.onui.domain.auth.presentation.dto.request - -data class CodeRequest( - val code: String -) \ No newline at end of file diff --git a/src/main/kotlin/com/example/onui/infra/feign/google/dto/OAuthTokenResponse.kt b/src/main/kotlin/com/example/onui/infra/feign/google/dto/OAuthTokenResponse.kt deleted file mode 100644 index 9d4f65d..0000000 --- a/src/main/kotlin/com/example/onui/infra/feign/google/dto/OAuthTokenResponse.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.example.onui.infra.feign.google.dto - -import com.fasterxml.jackson.annotation.JsonProperty - -data class OAuthTokenResponse ( - @JsonProperty("access_token") - val accessToken: String -) diff --git a/src/main/kotlin/com/example/onui/infra/oauth/apple/AppleUtils.kt b/src/main/kotlin/com/example/onui/infra/oauth/apple/AppleUtils.kt deleted file mode 100644 index ecff8b6..0000000 --- a/src/main/kotlin/com/example/onui/infra/oauth/apple/AppleUtils.kt +++ /dev/null @@ -1,69 +0,0 @@ -package com.example.onui.infra.oauth.apple - -import com.example.onui.infra.feign.apple.AppleClient -import com.example.onui.infra.feign.apple.ApplePublicKey -import com.example.onui.infra.feign.apple.env.AppleProperty -import org.springframework.stereotype.Service -import org.springframework.transaction.annotation.Transactional - - -@Service -@Transactional(readOnly = true) -class AppleUtils( - private val appleClient: AppleClient, - private val appleProperty: AppleProperty -) { - - fun test(): MutableList { - return appleClient.applePublicKeys().keys - } - - companion object{ - private const val SIGN_ALGORITHM_HEADER_KEY = "alg" - private const val KEY_ID_HEADER_KEY = "kid" - } - -// fun generatePublicKey(headers: Map, applePublicKeys: ApplePublicKeys): PublicKey { -// -// val applePublicKey = applePublicKeys.matchesKey( -// headers[SIGN_ALGORITHM_HEADER_KEY]!!, -// headers[KEY_ID_HEADER_KEY]!! -// ) ?: throw IllegalStateException("") -// -// return generatePublicKeyWithApplePublicKey(applePublicKey) -// } -// -// private fun generatePublicKeyWithApplePublicKey(publicKey: ApplePublicKey) = try { -// -// KeyFactory.getInstance(publicKey.kty).generatePublic(publicKey.getPublicKeySpec()) -// -// } catch (exception: NoSuchAlgorithmException) { -// throw IllegalStateException("Apple OAuth 로그인 중 public key 생성에 문제가 발생했습니다.") -// -// } catch (exception: InvalidKeySpecException) { -// throw IllegalStateException("Apple OAuth 로그인 중 public key 생성에 문제가 발생했습니다.") -// -// } -// -// fun parsePublicKeyAndGetClaims(idToken: String, publicKey: PublicKey): Claims { -// return try { -// Jwts.parser() -// .setSigningKey(publicKey) -// .parseClaimsJws(idToken) -// .body -// } catch (e: ExpiredJwtException) { -// throw ExpiredTokenException -// } catch (e: UnsupportedJwtException) { -// throw InvalidTokenException -// } catch (e: MalformedJwtException) { -// throw InvalidTokenException -// } catch (e: SignatureException) { -// throw InvalidTokenException -// } catch (e: IllegalArgumentException) { -// throw InvalidTokenException -// } -// } -// -// fun validate(claims: Claims): Boolean = claims.issuer.contains(appleProperty.iss) && -// claims.audience.equals(appleProperty.clientId) && claims.get("nonce", String::class.java) == appleProperty.nonce -} \ No newline at end of file From 58d7bdedc64e0df664f7743e42c7f57adfd054e2 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 11:00:15 +0900 Subject: [PATCH 02/56] =?UTF-8?q?=F0=9F=93=9D=20::=20CI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d9ebab0..f6cca90 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,25 +15,13 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Set up JDK 17 uses: actions/setup-java@v3 with: java-version: '17' - distribution: 'zulu' - - - name: Run ktlint - run: ./gradlew ktlintCheck - - - name: Set up application.yml - run: | - mkdir -p src/main/resources - echo "${{ secrets.MAIN_APPLICATION }}" | base64 --decode > src/main/resources/application.yml - mkdir -p src/test/resources - echo "${{ secrets.TEST_APPLICATION }}" | base64 --decode > src/test/resources/application.yml - - - name: run test - run: ./gradlew test - - - name: run build - run: ./gradlew clean build -x test \ No newline at end of file + distribution: 'temurin' + + - name: Build with Gradle + uses: gradle/gradle-build-action@bd5760595778326ba7f1441bcf7e88b49de61a25 # v2.6.0 + with: + arguments: build From a4e25aa78ed3ed12e2a90a3c5a225cfe5d103c99 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 11:46:21 +0900 Subject: [PATCH 03/56] =?UTF-8?q?=F0=9F=94=A5=20::=20line?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d4543d0..50dc12a 100644 --- a/.gitignore +++ b/.gitignore @@ -40,4 +40,4 @@ out/ .env ### copose ### -Docker-compose.yml +Docker-compose.yml \ No newline at end of file From 803621842d98605d3c401e1c75a70f6155773288 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 11:47:43 +0900 Subject: [PATCH 04/56] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20::=20google=20oauth?= =?UTF-8?q?=20=EA=B0=9C=ED=8E=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/auth/service/GoogleAuthService.kt | 5 +-- .../auth/service/GoogleAuthServiceImpl.kt | 44 ++++++------------- 2 files changed, 14 insertions(+), 35 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/auth/service/GoogleAuthService.kt b/src/main/kotlin/com/example/onui/domain/auth/service/GoogleAuthService.kt index 3389609..4a4e68b 100644 --- a/src/main/kotlin/com/example/onui/domain/auth/service/GoogleAuthService.kt +++ b/src/main/kotlin/com/example/onui/domain/auth/service/GoogleAuthService.kt @@ -1,11 +1,8 @@ package com.example.onui.domain.auth.service -import com.example.onui.domain.auth.presentation.dto.response.OauthLinkResponse import com.example.onui.domain.auth.presentation.dto.response.TokenResponse interface GoogleAuthService { - fun getGoogleLoginLink(): OauthLinkResponse - - fun oauthGoogleSignIn(code: String): TokenResponse + fun oauthGoogleSignIn(token: String): TokenResponse } \ No newline at end of file diff --git a/src/main/kotlin/com/example/onui/domain/auth/service/GoogleAuthServiceImpl.kt b/src/main/kotlin/com/example/onui/domain/auth/service/GoogleAuthServiceImpl.kt index 0d42f47..d5e2992 100644 --- a/src/main/kotlin/com/example/onui/domain/auth/service/GoogleAuthServiceImpl.kt +++ b/src/main/kotlin/com/example/onui/domain/auth/service/GoogleAuthServiceImpl.kt @@ -1,6 +1,5 @@ package com.example.onui.domain.auth.service -import com.example.onui.domain.auth.presentation.dto.response.OauthLinkResponse import com.example.onui.domain.auth.presentation.dto.response.TokenResponse import com.example.onui.domain.auth.repository.RefreshTokenRepository import com.example.onui.domain.user.entity.User @@ -8,7 +7,6 @@ import com.example.onui.domain.user.repository.UserRepository import com.example.onui.global.config.jwt.TokenProvider import com.example.onui.infra.feign.google.GoogleAuthClient import com.example.onui.infra.feign.google.GoogleInfoClient -import com.example.onui.infra.feign.google.env.GoogleProperty import mu.KotlinLogging import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional @@ -18,42 +16,22 @@ import org.springframework.transaction.annotation.Transactional class GoogleAuthServiceImpl( private val googleAuth: GoogleAuthClient, private val googleInfo: GoogleInfoClient, - private val googleProperty: GoogleProperty, private val userRepository: UserRepository, private val tokenProvider: TokenProvider, private val refreshTokenRepository: RefreshTokenRepository -): GoogleAuthService { +) : GoogleAuthService { private companion object { - const val GOOGLE_URL = "%s" + - "?client_id=%s" + - "&redirect_uri=%s" + - "&response_type=code&scope=https://www.googleapis.com/auth/userinfo.email+https://www.googleapis.com/auth/userinfo.profile" const val ALT = "json" - const val GRANT_TYPE = "authorization_code" - val logger = KotlinLogging.logger{} + val logger = KotlinLogging.logger {} } - override fun getGoogleLoginLink() = OauthLinkResponse( - GOOGLE_URL.format( - googleProperty.baseUrl, - googleProperty.clientId, - googleProperty.redirectUrl - ) - ) - @Transactional - override fun oauthGoogleSignIn(code: String): TokenResponse { + override fun oauthGoogleSignIn(token: String): TokenResponse { - val accessToken = googleAuth.googleAuth( - code, - googleProperty.clientId, - googleProperty.clientSecret, - googleProperty.redirectUrl, - GRANT_TYPE - ).accessToken + logger.info { token } - val response = googleInfo.googleInfo(ALT, accessToken) + val response = googleInfo.googleInfo(ALT, token) refreshTokenRepository.findBySub(response.sub)?.let { refreshTokenRepository.delete(it) @@ -62,10 +40,14 @@ class GoogleAuthServiceImpl( val tokenResponse = tokenProvider.receiveToken(response.sub) userRepository.findBySub(response.sub) - ?: userRepository.save(User( - response.sub, - response.name - )) + ?: userRepository.save( + User( + response.sub, + response.name + ) + ) + + googleAuth.revokeToken(token) return tokenResponse } From 19552a14b7fdf530b0436246e49bcbcb3cfc6cde Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 11:48:20 +0900 Subject: [PATCH 05/56] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20::=20apple=20oauth?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/auth/service/AppleAuthService.kt | 8 ++ .../auth/service/AppleAuthServiceImpl.kt | 104 ++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 src/main/kotlin/com/example/onui/domain/auth/service/AppleAuthService.kt create mode 100644 src/main/kotlin/com/example/onui/domain/auth/service/AppleAuthServiceImpl.kt diff --git a/src/main/kotlin/com/example/onui/domain/auth/service/AppleAuthService.kt b/src/main/kotlin/com/example/onui/domain/auth/service/AppleAuthService.kt new file mode 100644 index 0000000..c8cc940 --- /dev/null +++ b/src/main/kotlin/com/example/onui/domain/auth/service/AppleAuthService.kt @@ -0,0 +1,8 @@ +package com.example.onui.domain.auth.service + +interface AppleAuthService { + + fun test(): Any + + fun signUp(code: String): Any +} \ No newline at end of file diff --git a/src/main/kotlin/com/example/onui/domain/auth/service/AppleAuthServiceImpl.kt b/src/main/kotlin/com/example/onui/domain/auth/service/AppleAuthServiceImpl.kt new file mode 100644 index 0000000..68e069f --- /dev/null +++ b/src/main/kotlin/com/example/onui/domain/auth/service/AppleAuthServiceImpl.kt @@ -0,0 +1,104 @@ +package com.example.onui.domain.auth.service + +import com.example.onui.global.config.error.exception.InvalidTokenException +import com.example.onui.global.config.jwt.AppleJwtParser +import com.example.onui.global.config.jwt.TokenProvider +import com.example.onui.global.env.AppleProperty +import com.example.onui.infra.feign.apple.AppleClient +import com.example.onui.infra.feign.apple.dto.ApplePublicKey +import com.example.onui.infra.feign.apple.dto.ApplePublicKeys +import io.jsonwebtoken.Jwts +import io.jsonwebtoken.SignatureAlgorithm +import mu.KLogger +import mu.KotlinLogging +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo +import org.bouncycastle.jce.provider.BouncyCastleProvider +import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter +import org.springframework.stereotype.Service +import java.security.* +import java.security.spec.InvalidKeySpecException +import java.time.LocalDateTime +import java.time.ZoneId +import java.util.* + + +@Service +class AppleAuthServiceImpl( + private val appleClient: AppleClient, + private val jwtProvider: TokenProvider, + private val jwtParser: AppleJwtParser, + private val appleProperty: AppleProperty +) : AppleAuthService { + + private companion object { + val logger: KLogger = KotlinLogging.logger { } + const val ALG_HEADER_KEY = "alg" + const val KID_HEADER_KEY = "kid" + const val ALG = "ES256" + const val AUD = "https://appleid.apple.com" + } + + override fun test(): Any { + return "$AUD/auth/authorize" + + "?client_id=${appleProperty.clientId}" + + "&redirect_uri=http://127.0.0.1/auth/oauth/apple/token" + + "&response_type=code" + + "&scope=name%20email" + + "&response_mode=form_post" + } + + override fun signUp(code: String): Any { + + logger.error { parseIdToken(code) } + + return parseIdToken( + appleClient.getToken( + code, + appleProperty.clientId, + makeClientSecret() + ).idToken + ) + } + + fun parseIdToken(idToken: String): Any = jwtProvider.parseClaims( + idToken, generatePublicKey(jwtParser.parseHeaders(idToken), appleClient.applePublicKeys()) + ) + + fun generatePublicKey(tokenHeaders: MutableMap, applePublicKeys: ApplePublicKeys): PublicKey { + + val publicKey: ApplePublicKey = + applePublicKeys.matchesKey(tokenHeaders[ALG_HEADER_KEY]!!, tokenHeaders[KID_HEADER_KEY]!!) + ?: throw InvalidTokenException + + return try { + KeyFactory.getInstance(publicKey.kty).generatePublic(publicKey.publicKeySpec()) + } catch (e: NoSuchAlgorithmException) { + throw IllegalStateException("Apple OAuth 로그인 중 public key 생성에 문제가 발생했습니다.") + } catch (e: InvalidKeySpecException) { + throw IllegalStateException("Apple OAuth 로그인 중 public key 생성에 문제가 발생했습니다.") + } + } + + fun makeClientSecret(): String = Jwts.builder() + .setHeaderParam(KID_HEADER_KEY, appleProperty.keyId) + .setHeaderParam(ALG_HEADER_KEY, ALG) + .setIssuer(appleProperty.issuer) + .setIssuedAt(Date(System.currentTimeMillis())) + .setExpiration(Date.from(LocalDateTime.now().plusDays(30).atZone(ZoneId.systemDefault()).toInstant())) + .setAudience(AUD) + .setSubject(appleProperty.clientId) + .signWith(SignatureAlgorithm.ES256, getPrivateKey()) + .compact() + + private fun getPrivateKey(): PrivateKey { + Security.addProvider(BouncyCastleProvider()) + val converter = JcaPEMKeyConverter().setProvider("BC") + return try { + val privateKeyBytes: ByteArray = Base64.getDecoder().decode(appleProperty.authKey) + val privateKeyInfo = PrivateKeyInfo.getInstance(privateKeyBytes) + converter.getPrivateKey(privateKeyInfo) + } catch (e: Exception) { + throw RuntimeException("Error converting private key from String", e) + } + } +} \ No newline at end of file From b84498e6cd9cd95c0af18fe4be1d6dbb46ee9dd0 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 11:49:23 +0900 Subject: [PATCH 06/56] =?UTF-8?q?=E2=9C=A8=20::=20google=20oauth=20?= =?UTF-8?q?=EA=B0=9C=ED=8E=B8,=20apple=20oauth?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/presentation/AuthController.kt | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/auth/presentation/AuthController.kt b/src/main/kotlin/com/example/onui/domain/auth/presentation/AuthController.kt index b1685ba..1bb8e05 100644 --- a/src/main/kotlin/com/example/onui/domain/auth/presentation/AuthController.kt +++ b/src/main/kotlin/com/example/onui/domain/auth/presentation/AuthController.kt @@ -1,8 +1,8 @@ package com.example.onui.domain.auth.presentation import com.example.onui.domain.auth.presentation.dto.request.ReissueRequest -import com.example.onui.domain.auth.presentation.dto.response.OauthLinkResponse import com.example.onui.domain.auth.presentation.dto.response.TokenResponse +import com.example.onui.domain.auth.service.AppleAuthService import com.example.onui.domain.auth.service.AuthService import com.example.onui.domain.auth.service.GoogleAuthService import org.springframework.validation.annotation.Validated @@ -14,21 +14,28 @@ import javax.validation.Valid @RequestMapping("/auth") class AuthController( private val googleAuthService: GoogleAuthService, - private val authService: AuthService + private val authService: AuthService, + private val appleAuthService: AppleAuthService ) { - @GetMapping("/google/link") - fun getGoogleClientId(): OauthLinkResponse = googleAuthService.getGoogleLoginLink() - @GetMapping("/oauth/google/token") fun oauthSignIn( - @RequestParam(name = "code", required = true) - code: String - ): TokenResponse = googleAuthService.oauthGoogleSignIn(code) + @RequestParam(name = "token", required = true) + token: String + ): TokenResponse = googleAuthService.oauthGoogleSignIn(token) @PutMapping("/token") fun reissue( @RequestBody @Valid req: ReissueRequest ): TokenResponse = authService.reissue(req.refreshToken!!) + + @PostMapping("/oauth/apple/token") + fun oauthSignInWithApple( + @RequestParam(name = "code", required = true) + code: String + ) = appleAuthService.signUp(code) + + @GetMapping("/test") + fun test() = appleAuthService.test() } \ No newline at end of file From 8db7634dcc8077139dbf1dd3bef7add9b8033aa8 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 11:50:12 +0900 Subject: [PATCH 07/56] =?UTF-8?q?=F0=9F=94=A5=20::=20title?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/onui/domain/diary/entity/Diary.kt | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/diary/entity/Diary.kt b/src/main/kotlin/com/example/onui/domain/diary/entity/Diary.kt index 93dc950..e94874b 100644 --- a/src/main/kotlin/com/example/onui/domain/diary/entity/Diary.kt +++ b/src/main/kotlin/com/example/onui/domain/diary/entity/Diary.kt @@ -12,16 +12,16 @@ import javax.persistence.* class Diary( user: User, - title: String, content: String, mood: Mood, tag: MutableList, createdAt: LocalDateTime, image: String? = null, id: UUID? = null -): BaseTimeEntity(createdAt) { +) : BaseTimeEntity(createdAt) { - @Id @GeneratedValue(strategy = GenerationType.AUTO) + @Id + @GeneratedValue(strategy = GenerationType.AUTO) @Column(columnDefinition = "BINARY(16)", nullable = false) var id: UUID? = id protected set @@ -31,10 +31,6 @@ Diary( var user: User = user protected set - @Column(name = "title", length = 30, nullable = false) - var title: String= title - protected set - @Column(name = "content", length = 1500, nullable = false) var content: String = content protected set @@ -45,7 +41,7 @@ Diary( protected set @ElementCollection(fetch = FetchType.EAGER) - @CollectionTable(name = "diary_tag", joinColumns = [JoinColumn(name= "diary_id", referencedColumnName = "id")]) + @CollectionTable(name = "diary_tag", joinColumns = [JoinColumn(name = "diary_id", referencedColumnName = "id")]) var tag: MutableList = tag protected set @@ -61,7 +57,6 @@ Diary( fun toDetailResponse() = DiaryDetailResponse( this.id!!, - this.title, this.content, this.mood, this.tag, From 1c4b8c41e521bdcd22cfa96c595482be6b4f2651 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 11:50:29 +0900 Subject: [PATCH 08/56] =?UTF-8?q?=F0=9F=94=A5=20::=20title?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../diary/presentation/response/DiaryDetailResponse.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/diary/presentation/response/DiaryDetailResponse.kt b/src/main/kotlin/com/example/onui/domain/diary/presentation/response/DiaryDetailResponse.kt index 73f96c2..915e543 100644 --- a/src/main/kotlin/com/example/onui/domain/diary/presentation/response/DiaryDetailResponse.kt +++ b/src/main/kotlin/com/example/onui/domain/diary/presentation/response/DiaryDetailResponse.kt @@ -2,14 +2,13 @@ import com.example.onui.domain.diary.entity.Mood import java.time.LocalDate -import java.util.UUID +import java.util.* data class DiaryDetailResponse( val id: UUID, - val title: String, val content: String, val mood: Mood, - val tag: MutableList, + val tagList: MutableList, val createdAt: LocalDate, val image: String? ) From fdd3c7d0721f17f9587f561f82d6bf38e9eb3bfd Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 11:50:48 +0900 Subject: [PATCH 09/56] =?UTF-8?q?=F0=9F=94=A5=20::=20title?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/diary/service/DiaryServiceImpl.kt | 78 ++++++++++++------- 1 file changed, 48 insertions(+), 30 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/diary/service/DiaryServiceImpl.kt b/src/main/kotlin/com/example/onui/domain/diary/service/DiaryServiceImpl.kt index 3ffecb6..fdf9c84 100644 --- a/src/main/kotlin/com/example/onui/domain/diary/service/DiaryServiceImpl.kt +++ b/src/main/kotlin/com/example/onui/domain/diary/service/DiaryServiceImpl.kt @@ -8,6 +8,7 @@ import com.example.onui.domain.diary.presentation.request.UpdateDiaryRequest import com.example.onui.domain.diary.presentation.response.DiaryDetailResponse import com.example.onui.domain.diary.presentation.response.DiaryListResponse import com.example.onui.domain.diary.repository.DiaryRepository +import com.example.onui.domain.diary.repository.QDiaryRepository import com.example.onui.domain.timeline.entity.Timeline import com.example.onui.domain.timeline.repository.TimelineRepository import com.example.onui.global.common.facade.UserFacade @@ -23,8 +24,9 @@ import java.util.* class DiaryServiceImpl( private val diaryRepository: DiaryRepository, private val userFacade: UserFacade, - private val timelineRepository: TimelineRepository -): DiaryService { + private val timelineRepository: TimelineRepository, + private val qDiaryRepository: QDiaryRepository +) : DiaryService { @Transactional override fun createDiary(req: CreateDiaryRequest): DiaryDetailResponse { @@ -32,17 +34,23 @@ class DiaryServiceImpl( val user = userFacade.getCurrentUser() val now = LocalDateTime.now() - if (diaryRepository.existsByUserAndYearAndMonth(user, now.year, now.monthValue)) throw AlreadyWroteDiaryException - - val diary = diaryRepository.save(Diary( - user, - req.title!!, - req.content!!, - req.mood!!, - req.tagList!!, - now, - req.image - )) + if (diaryRepository.existsByUserAndYearAndMonth( + user, + now.year, + now.monthValue + ) + ) throw AlreadyWroteDiaryException + + val diary = diaryRepository.save( + Diary( + user, + req.content!!, + req.mood!!, + req.tagList!!, + now, + req.image + ) + ) user.diaryList.add(diary) @@ -71,29 +79,39 @@ class DiaryServiceImpl( var diary = diaryRepository.findByIdOrNull(req.id) ?: throw DiaryNotFoundException - if(diary.user != user) throw PermissionDeniedException + if (diary.user != user) throw PermissionDeniedException - diary = diaryRepository.save(Diary( - diary.user, - req.title!!, - req.content!!, - req.mood!!, - req.tagList!!, - diary.createdAt, - req.image, - diary.id - )) + diary = diaryRepository.save( + Diary( + diary.user, + req.content!!, + req.mood!!, + req.tagList!!, + diary.createdAt, + req.image, + diary.id + ) + ) timelineRepository.findByIdOrNull(diary.id) ?.run { - timelineRepository.save(Timeline( - diary, - diary.createdAt, - id, - true, - )) + timelineRepository.save( + Timeline( + diary, + diary.createdAt, + id, + true, + ) + ) } return diary.toDetailResponse() } + + override fun getSevenDaysAgo(): DiaryListResponse { + + val diaries = qDiaryRepository.findSevenDayAgoByUser(userFacade.getCurrentUser()) + + return DiaryListResponse(if (diaries.isEmpty()) null else diaries) + } } \ No newline at end of file From d6aa5ae66a80fa13f92874717146a1abd1094ed6 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 11:52:54 +0900 Subject: [PATCH 10/56] =?UTF-8?q?=F0=9F=94=A5=20::=20google=20property?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onui/infra/feign/google/env/GoogleProperty.kt | 13 ------------- src/main/resources/application.yml | 13 ++++--------- 2 files changed, 4 insertions(+), 22 deletions(-) delete mode 100644 src/main/kotlin/com/example/onui/infra/feign/google/env/GoogleProperty.kt diff --git a/src/main/kotlin/com/example/onui/infra/feign/google/env/GoogleProperty.kt b/src/main/kotlin/com/example/onui/infra/feign/google/env/GoogleProperty.kt deleted file mode 100644 index f8e99e6..0000000 --- a/src/main/kotlin/com/example/onui/infra/feign/google/env/GoogleProperty.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.example.onui.infra.feign.google.env - -import org.springframework.boot.context.properties.ConfigurationProperties -import org.springframework.boot.context.properties.ConstructorBinding - -@ConfigurationProperties("oauth.google") -@ConstructorBinding -data class GoogleProperty ( - val baseUrl: String, - val clientId: String, - val clientSecret: String, - val redirectUrl: String -) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index d3d96d4..cb1a274 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -50,15 +50,10 @@ logging: # oauth oauth: apple: - iss: ${APPLE_BASE_URL} - client-id: ${APPLE_CLIENT_ID} - nonce: ${APPLE_NONCE} - - google: - base-url: ${GOOGLE_BASE_URL} - client-id: ${GOOGLE_CLIENT} - client-secret: ${GOOGLE_SECRET} - redirect-url: ${GOOGLE_REDIRECT_URL} + client-id: ${APPLE_CLIENT} + issuer: ${APPLE_TEAM_ID} + key-id: ${APPLE_KEY_ID} + auth-key: ${APPLE_AUTH_KEY} # jwt jwt: From 4980998dc43dbe895de5b4a1b26289a7577ffc32 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 11:53:15 +0900 Subject: [PATCH 11/56] =?UTF-8?q?=F0=9F=93=9D=20::=20rename=20args?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onui/infra/feign/apple/ApplePublicKey.kt | 21 ------------------- .../infra/feign/apple/dto/ApplePublicKey.kt | 21 +++++++++++++++++++ 2 files changed, 21 insertions(+), 21 deletions(-) delete mode 100644 src/main/kotlin/com/example/onui/infra/feign/apple/ApplePublicKey.kt create mode 100644 src/main/kotlin/com/example/onui/infra/feign/apple/dto/ApplePublicKey.kt diff --git a/src/main/kotlin/com/example/onui/infra/feign/apple/ApplePublicKey.kt b/src/main/kotlin/com/example/onui/infra/feign/apple/ApplePublicKey.kt deleted file mode 100644 index fd2e78d..0000000 --- a/src/main/kotlin/com/example/onui/infra/feign/apple/ApplePublicKey.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.example.onui.infra.feign.apple - -import org.springframework.util.Base64Utils -import java.math.BigInteger -import java.security.spec.RSAPublicKeySpec - -data class ApplePublicKey( - val kty: String, - val kid: String, - val use: String, - val alg: String, - val n: String, - val e: String -) { - - private fun getN() = BigInteger(1, Base64Utils.decodeFromUrlSafeString(this.n)) - - private fun getE() = BigInteger(1, Base64Utils.decodeFromUrlSafeString(this.e)) - - fun getPublicKeySpec() = RSAPublicKeySpec(getN(), getE()) -} diff --git a/src/main/kotlin/com/example/onui/infra/feign/apple/dto/ApplePublicKey.kt b/src/main/kotlin/com/example/onui/infra/feign/apple/dto/ApplePublicKey.kt new file mode 100644 index 0000000..57f4e71 --- /dev/null +++ b/src/main/kotlin/com/example/onui/infra/feign/apple/dto/ApplePublicKey.kt @@ -0,0 +1,21 @@ +package com.example.onui.infra.feign.apple.dto + +import org.springframework.util.Base64Utils +import java.math.BigInteger +import java.security.spec.RSAPublicKeySpec + +data class ApplePublicKey( + val kty: String, + val kid: String, + val use: String, + val alg: String, + val n: String, + val e: String +) { + + private fun nBytes() = BigInteger(1, Base64Utils.decodeFromUrlSafeString(this.n)) + + private fun eBytes() = BigInteger(1, Base64Utils.decodeFromUrlSafeString(this.e)) + + fun publicKeySpec() = RSAPublicKeySpec(nBytes(), eBytes()) +} From 5318c56c20fd6b8cd22205751e5cf1fafd86e6aa Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 11:54:15 +0900 Subject: [PATCH 12/56] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20::=20first=20->=20si?= =?UTF-8?q?ngleOrNull?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onui/infra/feign/apple/ApplePublicKeys.kt | 17 ----------------- .../infra/feign/apple/dto/ApplePublicKeys.kt | 8 ++++++++ 2 files changed, 8 insertions(+), 17 deletions(-) delete mode 100644 src/main/kotlin/com/example/onui/infra/feign/apple/ApplePublicKeys.kt create mode 100644 src/main/kotlin/com/example/onui/infra/feign/apple/dto/ApplePublicKeys.kt diff --git a/src/main/kotlin/com/example/onui/infra/feign/apple/ApplePublicKeys.kt b/src/main/kotlin/com/example/onui/infra/feign/apple/ApplePublicKeys.kt deleted file mode 100644 index d503327..0000000 --- a/src/main/kotlin/com/example/onui/infra/feign/apple/ApplePublicKeys.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.example.onui.infra.feign.apple - -data class ApplePublicKeys( - val keys: MutableList -) { - - fun matchesKey(alg: String, kid: String): ApplePublicKey? { - - return try { - keys.first { - it.alg == alg && it.kid == kid - } - }catch (e: NoSuchElementException) { - null - } - } -} diff --git a/src/main/kotlin/com/example/onui/infra/feign/apple/dto/ApplePublicKeys.kt b/src/main/kotlin/com/example/onui/infra/feign/apple/dto/ApplePublicKeys.kt new file mode 100644 index 0000000..382747d --- /dev/null +++ b/src/main/kotlin/com/example/onui/infra/feign/apple/dto/ApplePublicKeys.kt @@ -0,0 +1,8 @@ +package com.example.onui.infra.feign.apple.dto + +data class ApplePublicKeys( + val keys: MutableList +) { + + fun matchesKey(alg: String, kid: String): ApplePublicKey? = keys.singleOrNull { it.alg == alg && it.kid == kid } +} From bc6cc3c91b2758eb2cffd18be3d21d420e52b223 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 11:54:50 +0900 Subject: [PATCH 13/56] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20::=20AppleTokenReque?= =?UTF-8?q?st?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/presentation/dto/request/AppleTokenRequest.kt | 9 +++++++++ .../auth/presentation/dto/request/GoogleCodeRequest.kt | 9 --------- 2 files changed, 9 insertions(+), 9 deletions(-) create mode 100644 src/main/kotlin/com/example/onui/domain/auth/presentation/dto/request/AppleTokenRequest.kt delete mode 100644 src/main/kotlin/com/example/onui/domain/auth/presentation/dto/request/GoogleCodeRequest.kt diff --git a/src/main/kotlin/com/example/onui/domain/auth/presentation/dto/request/AppleTokenRequest.kt b/src/main/kotlin/com/example/onui/domain/auth/presentation/dto/request/AppleTokenRequest.kt new file mode 100644 index 0000000..32a57f2 --- /dev/null +++ b/src/main/kotlin/com/example/onui/domain/auth/presentation/dto/request/AppleTokenRequest.kt @@ -0,0 +1,9 @@ +package com.example.onui.domain.auth.presentation.dto.request + +data class AppleTokenRequest( + val clientId: String, + val clientSecret: String, + val code: String, + val redirectUri: String, + val grantType: String = "authorization_code" +) diff --git a/src/main/kotlin/com/example/onui/domain/auth/presentation/dto/request/GoogleCodeRequest.kt b/src/main/kotlin/com/example/onui/domain/auth/presentation/dto/request/GoogleCodeRequest.kt deleted file mode 100644 index 1a401f2..0000000 --- a/src/main/kotlin/com/example/onui/domain/auth/presentation/dto/request/GoogleCodeRequest.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.example.onui.domain.auth.presentation.dto.request - -data class GoogleCodeRequest( - val code: String, - val clientId: String, - val clientSecret: String, - val redirectUri: String, - val grantType: String -) \ No newline at end of file From 807fc3de439777b7c44b75dd423c9ac4d8cf2e99 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 12:00:20 +0900 Subject: [PATCH 14/56] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20::=20getSevenDaysAgo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/diary/presentation/DiaryController.kt | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/diary/presentation/DiaryController.kt b/src/main/kotlin/com/example/onui/domain/diary/presentation/DiaryController.kt index 347fec0..fb173cf 100644 --- a/src/main/kotlin/com/example/onui/domain/diary/presentation/DiaryController.kt +++ b/src/main/kotlin/com/example/onui/domain/diary/presentation/DiaryController.kt @@ -7,15 +7,8 @@ import com.example.onui.domain.diary.presentation.response.DiaryListResponse import com.example.onui.domain.diary.service.DiaryService import org.springframework.http.HttpStatus import org.springframework.validation.annotation.Validated -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.PostMapping -import org.springframework.web.bind.annotation.PutMapping -import org.springframework.web.bind.annotation.RequestBody -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RequestParam -import org.springframework.web.bind.annotation.ResponseStatus -import org.springframework.web.bind.annotation.RestController -import java.util.UUID +import org.springframework.web.bind.annotation.* +import java.util.* import javax.validation.Valid import javax.validation.constraints.Max import javax.validation.constraints.Min @@ -53,5 +46,8 @@ class DiaryController( fun updateDiary( @RequestBody @Valid req: UpdateDiaryRequest - ) : DiaryDetailResponse = diaryService.update(req) + ): DiaryDetailResponse = diaryService.update(req) + + @GetMapping("/ago") + fun getSevenDaysAgo() = diaryService.getSevenDaysAgo() } \ No newline at end of file From 49cf384e4c712e85510e925a1856a2473eb74cc0 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 12:00:31 +0900 Subject: [PATCH 15/56] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20::=20getSevenDaysAgo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/diary/repository/QDiaryRepository.kt | 4 +++- .../diary/repository/QDiaryRepositoryImpl.kt | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/diary/repository/QDiaryRepository.kt b/src/main/kotlin/com/example/onui/domain/diary/repository/QDiaryRepository.kt index 13e7dc9..4858ba9 100644 --- a/src/main/kotlin/com/example/onui/domain/diary/repository/QDiaryRepository.kt +++ b/src/main/kotlin/com/example/onui/domain/diary/repository/QDiaryRepository.kt @@ -1,8 +1,10 @@ package com.example.onui.domain.diary.repository import com.example.onui.domain.diary.entity.Diary +import com.example.onui.domain.diary.presentation.response.DiaryResponse import com.example.onui.domain.user.entity.User interface QDiaryRepository { - fun find3DayAgoByUser(user: User): Diary? + fun findThreeDayAgoByUser(user: User): Diary? + fun findSevenDayAgoByUser(user: User): MutableList } \ No newline at end of file diff --git a/src/main/kotlin/com/example/onui/domain/diary/repository/QDiaryRepositoryImpl.kt b/src/main/kotlin/com/example/onui/domain/diary/repository/QDiaryRepositoryImpl.kt index 248b519..c8e1782 100644 --- a/src/main/kotlin/com/example/onui/domain/diary/repository/QDiaryRepositoryImpl.kt +++ b/src/main/kotlin/com/example/onui/domain/diary/repository/QDiaryRepositoryImpl.kt @@ -2,6 +2,7 @@ import com.example.onui.domain.diary.entity.Diary import com.example.onui.domain.diary.entity.QDiary.diary +import com.example.onui.domain.diary.presentation.response.DiaryResponse import com.example.onui.domain.user.entity.User import com.querydsl.jpa.impl.JPAQueryFactory import org.springframework.stereotype.Repository @@ -14,9 +15,9 @@ import java.time.LocalDateTime @Repository class QDiaryRepositoryImpl( private val queryFactory: JPAQueryFactory -): QDiaryRepository { +) : QDiaryRepository { - override fun find3DayAgoByUser(user: User): Diary? { + override fun findThreeDayAgoByUser(user: User): Diary? { val ago = LocalDateTime.now().minusDays(3) @@ -26,4 +27,14 @@ class QDiaryRepositoryImpl( .limit(1) .fetchOne() } + + override fun findSevenDayAgoByUser(user: User): MutableList { + + val ago = LocalDateTime.now().minusDays(7) + + return queryFactory.selectFrom(diary) + .orderBy(diary.createdAt.desc()) + .where(diary.user.eq(user).and(diary.createdAt.after(ago))) + .fetch().map { it.toResponse() }.toMutableList() + } } \ No newline at end of file From 6582a0677d596f0f181bd2765ad52e38479b949e Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 12:01:35 +0900 Subject: [PATCH 16/56] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20::=20Mission=20Entit?= =?UTF-8?q?ies?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/mission/entity/AssignMission.kt | 24 +++++++++++++ .../onui/domain/mission/entity/Assigned.kt | 34 +++++++++++++++++++ .../domain/mission/entity/GeneralMission.kt | 18 ++++++++++ .../onui/domain/mission/entity/Mission.kt | 21 +++++++----- .../domain/mission/entity/RandomMission.kt | 18 ++++++++++ 5 files changed, 106 insertions(+), 9 deletions(-) create mode 100644 src/main/kotlin/com/example/onui/domain/mission/entity/AssignMission.kt create mode 100644 src/main/kotlin/com/example/onui/domain/mission/entity/Assigned.kt create mode 100644 src/main/kotlin/com/example/onui/domain/mission/entity/GeneralMission.kt create mode 100644 src/main/kotlin/com/example/onui/domain/mission/entity/RandomMission.kt diff --git a/src/main/kotlin/com/example/onui/domain/mission/entity/AssignMission.kt b/src/main/kotlin/com/example/onui/domain/mission/entity/AssignMission.kt new file mode 100644 index 0000000..4c95398 --- /dev/null +++ b/src/main/kotlin/com/example/onui/domain/mission/entity/AssignMission.kt @@ -0,0 +1,24 @@ +package com.example.onui.domain.mission.entity + +import org.hibernate.annotations.OnDelete +import org.hibernate.annotations.OnDeleteAction +import java.util.* +import javax.persistence.Column +import javax.persistence.DiscriminatorValue +import javax.persistence.Entity + +@Entity +@DiscriminatorValue("assigned") +@OnDelete(action = OnDeleteAction.CASCADE) +class AssignMission( + name: String, + goal: String, + coast: Int, + message: String, + id: UUID? = null +): Mission(name, goal, message, id) { + + @Column(name = "coast", nullable = false) + var coast: Int = coast + protected set +} \ No newline at end of file diff --git a/src/main/kotlin/com/example/onui/domain/mission/entity/Assigned.kt b/src/main/kotlin/com/example/onui/domain/mission/entity/Assigned.kt new file mode 100644 index 0000000..ce4e676 --- /dev/null +++ b/src/main/kotlin/com/example/onui/domain/mission/entity/Assigned.kt @@ -0,0 +1,34 @@ +package com.example.onui.domain.mission.entity + +import com.example.onui.domain.user.entity.User +import org.springframework.data.domain.Persistable +import java.io.Serializable +import java.util.UUID +import javax.persistence.* + +@Entity(name = "assigned_table") +@IdClass(Assigned.IdClass::class) +class Assigned( + user: User, + mission: Mission +): Persistable { + + @Id @ManyToOne + @JoinColumn(name = "mission_id", nullable = false) + var mission: Mission = mission + protected set + + @Id @ManyToOne + @JoinColumn(name = "user_id", nullable = false) + var user: User = user + protected set + + data class IdClass( + var mission: UUID? =null, + var user: UUID? = null + ): Serializable + + override fun getId() = IdClass(this.mission.id, this.user.id) + + override fun isNew() = mission.id == null || user.id == null +} \ No newline at end of file diff --git a/src/main/kotlin/com/example/onui/domain/mission/entity/GeneralMission.kt b/src/main/kotlin/com/example/onui/domain/mission/entity/GeneralMission.kt new file mode 100644 index 0000000..a681010 --- /dev/null +++ b/src/main/kotlin/com/example/onui/domain/mission/entity/GeneralMission.kt @@ -0,0 +1,18 @@ +package com.example.onui.domain.mission.entity + +import org.hibernate.annotations.OnDelete +import org.hibernate.annotations.OnDeleteAction +import java.util.* +import javax.persistence.DiscriminatorValue +import javax.persistence.Entity + +@Entity +@DiscriminatorValue("general") +@OnDelete(action = OnDeleteAction.CASCADE) +class GeneralMission( + name: String, + goal: String, + message: String, + id: UUID? = null +): Mission(name, goal, message, id) { +} \ No newline at end of file diff --git a/src/main/kotlin/com/example/onui/domain/mission/entity/Mission.kt b/src/main/kotlin/com/example/onui/domain/mission/entity/Mission.kt index de0d81e..e26af5e 100644 --- a/src/main/kotlin/com/example/onui/domain/mission/entity/Mission.kt +++ b/src/main/kotlin/com/example/onui/domain/mission/entity/Mission.kt @@ -1,16 +1,15 @@ package com.example.onui.domain.mission.entity import java.util.UUID -import javax.persistence.Column -import javax.persistence.Entity -import javax.persistence.GeneratedValue -import javax.persistence.GenerationType -import javax.persistence.Id +import javax.persistence.* @Entity(name = "mission") -class Mission ( +@Inheritance(strategy = InheritanceType.JOINED) +@DiscriminatorColumn(name = "mission_type") +abstract class Mission ( + name: String, goal: String, - coast: Int, + message: String, id: UUID? = null ) { @Id @GeneratedValue(strategy = GenerationType.AUTO) @@ -18,11 +17,15 @@ class Mission ( var id = id protected set + @Column(name = "name", nullable = false) + var name: String = name + protected set + @Column(name = "goal", nullable = false) var goal: String = goal protected set - @Column(name = "coast", nullable = false) - var coast: Int = coast + @Column(name = "message", nullable = false) + var message: String = message protected set } \ No newline at end of file diff --git a/src/main/kotlin/com/example/onui/domain/mission/entity/RandomMission.kt b/src/main/kotlin/com/example/onui/domain/mission/entity/RandomMission.kt new file mode 100644 index 0000000..a772b8a --- /dev/null +++ b/src/main/kotlin/com/example/onui/domain/mission/entity/RandomMission.kt @@ -0,0 +1,18 @@ +package com.example.onui.domain.mission.entity + +import org.hibernate.annotations.OnDelete +import org.hibernate.annotations.OnDeleteAction +import java.util.* +import javax.persistence.DiscriminatorValue +import javax.persistence.Entity + +@Entity +@DiscriminatorValue("general") +@OnDelete(action = OnDeleteAction.CASCADE) +class RandomMission( + name: String, + goal: String, + message: String, + id: UUID? = null +): Mission(name, goal, message, id) { +} \ No newline at end of file From d554c3bc19b9b1ad062eb82c4d0551359cb43463 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 12:01:57 +0900 Subject: [PATCH 17/56] =?UTF-8?q?=F0=9F=90=9B=20::?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/example/onui/domain/diary/entity/Mood.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/com/example/onui/domain/diary/entity/Mood.kt b/src/main/kotlin/com/example/onui/domain/diary/entity/Mood.kt index 527843e..f5f3a2e 100644 --- a/src/main/kotlin/com/example/onui/domain/diary/entity/Mood.kt +++ b/src/main/kotlin/com/example/onui/domain/diary/entity/Mood.kt @@ -1,7 +1,7 @@ package com.example.onui.domain.diary.entity enum class Mood( - coast: Int + val coast: Int ) { WORST(-10), BAD(-5), From c1572a0784533a57db027f4c27e15b5135e0fbb2 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 12:02:07 +0900 Subject: [PATCH 18/56] =?UTF-8?q?=F0=9F=94=A5=20::=20title?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/diary/presentation/request/CreateDiaryRequest.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/diary/presentation/request/CreateDiaryRequest.kt b/src/main/kotlin/com/example/onui/domain/diary/presentation/request/CreateDiaryRequest.kt index 090e354..a50c80e 100644 --- a/src/main/kotlin/com/example/onui/domain/diary/presentation/request/CreateDiaryRequest.kt +++ b/src/main/kotlin/com/example/onui/domain/diary/presentation/request/CreateDiaryRequest.kt @@ -7,9 +7,6 @@ import javax.validation.constraints.NotNull data class CreateDiaryRequest( - @field:NotBlank - val title: String?, - @field:NotBlank val content: String?, From c69b1521cfcd114946cd4bb98e75625ef86ffee2 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 12:02:57 +0900 Subject: [PATCH 19/56] =?UTF-8?q?=F0=9F=94=A5=20::=20title?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/diary/presentation/request/UpdateDiaryRequest.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/diary/presentation/request/UpdateDiaryRequest.kt b/src/main/kotlin/com/example/onui/domain/diary/presentation/request/UpdateDiaryRequest.kt index 9787f0b..42f3356 100644 --- a/src/main/kotlin/com/example/onui/domain/diary/presentation/request/UpdateDiaryRequest.kt +++ b/src/main/kotlin/com/example/onui/domain/diary/presentation/request/UpdateDiaryRequest.kt @@ -11,9 +11,6 @@ data class UpdateDiaryRequest( @field:NotNull val id: UUID?, - @field:NotBlank - val title: String?, - @field:NotBlank val content: String?, From 12330cc5e24be5218c31f761dec64e71311ddf18 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 12:12:46 +0900 Subject: [PATCH 20/56] =?UTF-8?q?=F0=9F=93=9D=20::=20content=20not=20null?= =?UTF-8?q?=20->=20null=20able?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/example/onui/domain/diary/entity/Diary.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/diary/entity/Diary.kt b/src/main/kotlin/com/example/onui/domain/diary/entity/Diary.kt index e94874b..a7c40d9 100644 --- a/src/main/kotlin/com/example/onui/domain/diary/entity/Diary.kt +++ b/src/main/kotlin/com/example/onui/domain/diary/entity/Diary.kt @@ -12,7 +12,7 @@ import javax.persistence.* class Diary( user: User, - content: String, + content: String?, mood: Mood, tag: MutableList, createdAt: LocalDateTime, @@ -31,8 +31,8 @@ Diary( var user: User = user protected set - @Column(name = "content", length = 1500, nullable = false) - var content: String = content + @Column(name = "content", length = 1500) + var content: String? = content protected set @Column(name = "mood", nullable = false) From 3b1287f96c18a98562830acc7866a681763bfbb8 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 12:12:51 +0900 Subject: [PATCH 21/56] =?UTF-8?q?=F0=9F=93=9D=20::=20content=20not=20null?= =?UTF-8?q?=20->=20null=20able?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/diary/presentation/request/CreateDiaryRequest.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/diary/presentation/request/CreateDiaryRequest.kt b/src/main/kotlin/com/example/onui/domain/diary/presentation/request/CreateDiaryRequest.kt index a50c80e..8c6ae8e 100644 --- a/src/main/kotlin/com/example/onui/domain/diary/presentation/request/CreateDiaryRequest.kt +++ b/src/main/kotlin/com/example/onui/domain/diary/presentation/request/CreateDiaryRequest.kt @@ -1,13 +1,11 @@ package com.example.onui.domain.diary.presentation.request import com.example.onui.domain.diary.entity.Mood -import javax.validation.constraints.NotBlank import javax.validation.constraints.NotEmpty import javax.validation.constraints.NotNull data class CreateDiaryRequest( - @field:NotBlank val content: String?, @field:NotNull(message = "null일 수 없습니다.") From f4157c3a3e86b73bb0bdd09b0f8700df2e4f4f4b Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 12:12:56 +0900 Subject: [PATCH 22/56] =?UTF-8?q?=F0=9F=93=9D=20::=20content=20not=20null?= =?UTF-8?q?=20->=20null=20able?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/diary/presentation/request/UpdateDiaryRequest.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/diary/presentation/request/UpdateDiaryRequest.kt b/src/main/kotlin/com/example/onui/domain/diary/presentation/request/UpdateDiaryRequest.kt index 42f3356..1caecb9 100644 --- a/src/main/kotlin/com/example/onui/domain/diary/presentation/request/UpdateDiaryRequest.kt +++ b/src/main/kotlin/com/example/onui/domain/diary/presentation/request/UpdateDiaryRequest.kt @@ -2,7 +2,6 @@ import com.example.onui.domain.diary.entity.Mood import java.util.* -import javax.validation.constraints.NotBlank import javax.validation.constraints.NotEmpty import javax.validation.constraints.NotNull @@ -11,7 +10,6 @@ data class UpdateDiaryRequest( @field:NotNull val id: UUID?, - @field:NotBlank val content: String?, @field:NotNull(message = "null일 수 없습니다.") From 92411455296bb3a2c258c498f0009a7a2a61f96d Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 12:13:03 +0900 Subject: [PATCH 23/56] =?UTF-8?q?=F0=9F=93=9D=20::=20content=20not=20null?= =?UTF-8?q?=20->=20null=20able?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/diary/presentation/response/DiaryDetailResponse.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/com/example/onui/domain/diary/presentation/response/DiaryDetailResponse.kt b/src/main/kotlin/com/example/onui/domain/diary/presentation/response/DiaryDetailResponse.kt index 915e543..4e59600 100644 --- a/src/main/kotlin/com/example/onui/domain/diary/presentation/response/DiaryDetailResponse.kt +++ b/src/main/kotlin/com/example/onui/domain/diary/presentation/response/DiaryDetailResponse.kt @@ -6,7 +6,7 @@ import java.util.* data class DiaryDetailResponse( val id: UUID, - val content: String, + val content: String?, val mood: Mood, val tagList: MutableList, val createdAt: LocalDate, From 06a1c087b599c499b98f89780d06bdf9844c7537 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 12:13:11 +0900 Subject: [PATCH 24/56] =?UTF-8?q?=F0=9F=93=9D=20::=20content=20not=20null?= =?UTF-8?q?=20->=20null=20able?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/onui/domain/diary/service/DiaryServiceImpl.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/diary/service/DiaryServiceImpl.kt b/src/main/kotlin/com/example/onui/domain/diary/service/DiaryServiceImpl.kt index fdf9c84..fbfc958 100644 --- a/src/main/kotlin/com/example/onui/domain/diary/service/DiaryServiceImpl.kt +++ b/src/main/kotlin/com/example/onui/domain/diary/service/DiaryServiceImpl.kt @@ -44,7 +44,7 @@ class DiaryServiceImpl( val diary = diaryRepository.save( Diary( user, - req.content!!, + req.content, req.mood!!, req.tagList!!, now, @@ -84,7 +84,7 @@ class DiaryServiceImpl( diary = diaryRepository.save( Diary( diary.user, - req.content!!, + req.content, req.mood!!, req.tagList!!, diary.createdAt, From f573fbbdf04decb806f16fbaea22adfac55ebba0 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 12:13:33 +0900 Subject: [PATCH 25/56] =?UTF-8?q?=F0=9F=93=9D=20::=20content=20not=20null?= =?UTF-8?q?=20->=20null=20able?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../timeline/presentation/dto/response/TimelineResponse.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/timeline/presentation/dto/response/TimelineResponse.kt b/src/main/kotlin/com/example/onui/domain/timeline/presentation/dto/response/TimelineResponse.kt index 6fb3875..21a61be 100644 --- a/src/main/kotlin/com/example/onui/domain/timeline/presentation/dto/response/TimelineResponse.kt +++ b/src/main/kotlin/com/example/onui/domain/timeline/presentation/dto/response/TimelineResponse.kt @@ -3,12 +3,11 @@ import com.example.onui.domain.diary.entity.Mood import java.time.DayOfWeek import java.time.LocalDateTime -import java.util.UUID +import java.util.* -data class TimelineResponse ( +data class TimelineResponse( val id: UUID, - val title: String, - val content: String, + val content: String?, val mood: Mood, val tag: MutableList, val image: String?, From c146626c83d6e85a8ae886d5baac419f3e49e6c9 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 12:13:47 +0900 Subject: [PATCH 26/56] =?UTF-8?q?=F0=9F=93=9D=20::=20content=20not=20null?= =?UTF-8?q?=20->=20null=20able?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/onui/domain/timeline/entity/Timeline.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/timeline/entity/Timeline.kt b/src/main/kotlin/com/example/onui/domain/timeline/entity/Timeline.kt index 3b15fb1..54358d9 100644 --- a/src/main/kotlin/com/example/onui/domain/timeline/entity/Timeline.kt +++ b/src/main/kotlin/com/example/onui/domain/timeline/entity/Timeline.kt @@ -20,7 +20,8 @@ class Timeline( var id: UUID? = id protected set - @OneToOne(fetch = FetchType.LAZY) @MapsId + @OneToOne(fetch = FetchType.LAZY) + @MapsId @JoinColumn(name = "id", columnDefinition = "BINARY(16)") var diary: Diary = diary protected set @@ -33,9 +34,8 @@ class Timeline( var isUpdated: Boolean = isUpdated protected set - fun toResponse() = TimelineResponse ( + fun toResponse() = TimelineResponse( this.id!!, - this.diary.title, this.diary.content, this.diary.mood, this.diary.tag, From aa8e9ce6e914127b5330c3a54861fb0d8937e2d3 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 12:14:05 +0900 Subject: [PATCH 27/56] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20::=20getSevenDaysAgo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/onui/domain/diary/service/DiaryService.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/kotlin/com/example/onui/domain/diary/service/DiaryService.kt b/src/main/kotlin/com/example/onui/domain/diary/service/DiaryService.kt index b054223..454a7b8 100644 --- a/src/main/kotlin/com/example/onui/domain/diary/service/DiaryService.kt +++ b/src/main/kotlin/com/example/onui/domain/diary/service/DiaryService.kt @@ -15,4 +15,6 @@ interface DiaryService { fun getDetailById(id: UUID): DiaryDetailResponse fun update(req: UpdateDiaryRequest): DiaryDetailResponse + + fun getSevenDaysAgo(): DiaryListResponse } From 4590e40e98f8e111c7424c47cc1a96937869fa91 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 12:14:25 +0900 Subject: [PATCH 28/56] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20::=20HEIC=20?= =?UTF-8?q?=ED=99=95=EC=9E=A5=EC=9E=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/example/onui/domain/img/entity/FileType.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/com/example/onui/domain/img/entity/FileType.kt b/src/main/kotlin/com/example/onui/domain/img/entity/FileType.kt index 62ff30c..e22bc99 100644 --- a/src/main/kotlin/com/example/onui/domain/img/entity/FileType.kt +++ b/src/main/kotlin/com/example/onui/domain/img/entity/FileType.kt @@ -7,5 +7,6 @@ enum class FileType( JPG("jpg"), JPEG("jpeg"), PDF("pdf"), - SVG("svg") + SVG("svg"), + HEIC("HEIC") } \ No newline at end of file From c73c796d132ba725bc8c2435a13f3d668d4c67ff Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 12:14:41 +0900 Subject: [PATCH 29/56] =?UTF-8?q?=F0=9F=93=9D=20::=20imports?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/onui/domain/img/service/ImageServiceImpl.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/img/service/ImageServiceImpl.kt b/src/main/kotlin/com/example/onui/domain/img/service/ImageServiceImpl.kt index 20771e1..e788022 100644 --- a/src/main/kotlin/com/example/onui/domain/img/service/ImageServiceImpl.kt +++ b/src/main/kotlin/com/example/onui/domain/img/service/ImageServiceImpl.kt @@ -8,11 +8,10 @@ import com.example.onui.domain.img.entity.FileType import com.example.onui.domain.img.exception.InvalidFileExtensionException import com.example.onui.domain.img.presentation.dto.response.FileUrlResponse import com.example.onui.global.common.facade.UserFacade -import com.example.onui.global.config.s3.env.S3Property +import com.example.onui.global.env.S3Property import org.springframework.stereotype.Service import org.springframework.web.multipart.MultipartFile import java.io.ByteArrayInputStream -import java.util.Base64 import java.util.UUID @Service From 5c78c036f86c5ece72721ba49ad05b4d18564d81 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 12:14:55 +0900 Subject: [PATCH 30/56] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20::=20mission=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mission/controller/MissionController.kt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/main/kotlin/com/example/onui/domain/mission/controller/MissionController.kt diff --git a/src/main/kotlin/com/example/onui/domain/mission/controller/MissionController.kt b/src/main/kotlin/com/example/onui/domain/mission/controller/MissionController.kt new file mode 100644 index 0000000..c3cb1d9 --- /dev/null +++ b/src/main/kotlin/com/example/onui/domain/mission/controller/MissionController.kt @@ -0,0 +1,17 @@ +package com.example.onui.domain.mission.controller + +import com.example.onui.domain.mission.service.MissionService +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/mission") +class MissionController( + private val missionService: MissionService +) { + + @GetMapping("/test") + fun test() = missionService.test() + +} \ No newline at end of file From 5576f25a01932316b7f606659fc4219d3437923b Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 12:15:21 +0900 Subject: [PATCH 31/56] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20::=20findAllByUser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/mission/repository/AssignedRepository.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/main/kotlin/com/example/onui/domain/mission/repository/AssignedRepository.kt diff --git a/src/main/kotlin/com/example/onui/domain/mission/repository/AssignedRepository.kt b/src/main/kotlin/com/example/onui/domain/mission/repository/AssignedRepository.kt new file mode 100644 index 0000000..99d9342 --- /dev/null +++ b/src/main/kotlin/com/example/onui/domain/mission/repository/AssignedRepository.kt @@ -0,0 +1,12 @@ +package com.example.onui.domain.mission.repository + +import com.example.onui.domain.mission.entity.Assigned +import com.example.onui.domain.user.entity.User +import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.stereotype.Repository + +@Repository +interface AssignedRepository: JpaRepository { + + fun findAllByUser(user: User): List? +} \ No newline at end of file From 735b1af198bb9fc4a605cb6d6b0dc06148c2c2d4 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 12:15:44 +0900 Subject: [PATCH 32/56] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20::=20generic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/onui/domain/mission/repository/MissionRepository.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/com/example/onui/domain/mission/repository/MissionRepository.kt b/src/main/kotlin/com/example/onui/domain/mission/repository/MissionRepository.kt index 5c7155c..0e58bb8 100644 --- a/src/main/kotlin/com/example/onui/domain/mission/repository/MissionRepository.kt +++ b/src/main/kotlin/com/example/onui/domain/mission/repository/MissionRepository.kt @@ -6,5 +6,5 @@ import org.springframework.stereotype.Repository import java.util.UUID @Repository -interface MissionRepository: JpaRepository { +interface MissionRepository: JpaRepository { } \ No newline at end of file From 976a2c62dfba5b0e9e2d1d622d437f74bf4d2d78 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 12:16:46 +0900 Subject: [PATCH 33/56] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20::=20findAssignByCoa?= =?UTF-8?q?st?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onui/domain/mission/repository/QMissionRepository.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/kotlin/com/example/onui/domain/mission/repository/QMissionRepository.kt b/src/main/kotlin/com/example/onui/domain/mission/repository/QMissionRepository.kt index 64b136f..9f951c7 100644 --- a/src/main/kotlin/com/example/onui/domain/mission/repository/QMissionRepository.kt +++ b/src/main/kotlin/com/example/onui/domain/mission/repository/QMissionRepository.kt @@ -1,4 +1,8 @@ package com.example.onui.domain.mission.repository +import com.example.onui.domain.mission.entity.Mission + interface QMissionRepository { + + fun findAssignByCoast(coast: Int): List } \ No newline at end of file From 033c829584c087c0a359b28adde8d8f462355147 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:21:57 +0900 Subject: [PATCH 34/56] =?UTF-8?q?=F0=9F=93=9D=20::=20uri=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/presentation/AuthController.kt | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/auth/presentation/AuthController.kt b/src/main/kotlin/com/example/onui/domain/auth/presentation/AuthController.kt index 1bb8e05..ac96a88 100644 --- a/src/main/kotlin/com/example/onui/domain/auth/presentation/AuthController.kt +++ b/src/main/kotlin/com/example/onui/domain/auth/presentation/AuthController.kt @@ -1,13 +1,11 @@ package com.example.onui.domain.auth.presentation -import com.example.onui.domain.auth.presentation.dto.request.ReissueRequest import com.example.onui.domain.auth.presentation.dto.response.TokenResponse import com.example.onui.domain.auth.service.AppleAuthService import com.example.onui.domain.auth.service.AuthService import com.example.onui.domain.auth.service.GoogleAuthService import org.springframework.validation.annotation.Validated import org.springframework.web.bind.annotation.* -import javax.validation.Valid @Validated @RestController @@ -18,24 +16,21 @@ class AuthController( private val appleAuthService: AppleAuthService ) { - @GetMapping("/oauth/google/token") + @GetMapping("/google") fun oauthSignIn( @RequestParam(name = "token", required = true) token: String ): TokenResponse = googleAuthService.oauthGoogleSignIn(token) - @PutMapping("/token") + @PutMapping("/re-issue") fun reissue( - @RequestBody @Valid - req: ReissueRequest - ): TokenResponse = authService.reissue(req.refreshToken!!) + @RequestParam("token", required = true) + token: String + ): TokenResponse = authService.reissue(token) - @PostMapping("/oauth/apple/token") + @PostMapping("/apple") fun oauthSignInWithApple( - @RequestParam(name = "code", required = true) - code: String - ) = appleAuthService.signUp(code) - - @GetMapping("/test") - fun test() = appleAuthService.test() + @RequestParam(name = "token", required = true) + token: String + ) = appleAuthService.signUp(token) } \ No newline at end of file From 875ae9d41c440499c91c181a22eefb226d7e9378 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:22:12 +0900 Subject: [PATCH 35/56] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20::=20apple=20login?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/onui/domain/auth/service/AppleAuthService.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/auth/service/AppleAuthService.kt b/src/main/kotlin/com/example/onui/domain/auth/service/AppleAuthService.kt index c8cc940..1c7f393 100644 --- a/src/main/kotlin/com/example/onui/domain/auth/service/AppleAuthService.kt +++ b/src/main/kotlin/com/example/onui/domain/auth/service/AppleAuthService.kt @@ -2,7 +2,5 @@ interface AppleAuthService { - fun test(): Any - - fun signUp(code: String): Any + fun signUp(idToken: String): Any } \ No newline at end of file From 89e874a879b437fbdfc4c4f2a912220114ef30fb Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:22:21 +0900 Subject: [PATCH 36/56] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20::=20apple=20login?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/service/AppleAuthServiceImpl.kt | 86 +++++++------------ 1 file changed, 29 insertions(+), 57 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/auth/service/AppleAuthServiceImpl.kt b/src/main/kotlin/com/example/onui/domain/auth/service/AppleAuthServiceImpl.kt index 68e069f..fe43131 100644 --- a/src/main/kotlin/com/example/onui/domain/auth/service/AppleAuthServiceImpl.kt +++ b/src/main/kotlin/com/example/onui/domain/auth/service/AppleAuthServiceImpl.kt @@ -1,24 +1,20 @@ package com.example.onui.domain.auth.service +import com.example.onui.domain.auth.presentation.dto.response.TokenResponse +import com.example.onui.domain.user.entity.User +import com.example.onui.domain.user.repository.UserRepository import com.example.onui.global.config.error.exception.InvalidTokenException import com.example.onui.global.config.jwt.AppleJwtParser import com.example.onui.global.config.jwt.TokenProvider -import com.example.onui.global.env.AppleProperty import com.example.onui.infra.feign.apple.AppleClient import com.example.onui.infra.feign.apple.dto.ApplePublicKey import com.example.onui.infra.feign.apple.dto.ApplePublicKeys -import io.jsonwebtoken.Jwts -import io.jsonwebtoken.SignatureAlgorithm -import mu.KLogger -import mu.KotlinLogging -import org.bouncycastle.asn1.pkcs.PrivateKeyInfo -import org.bouncycastle.jce.provider.BouncyCastleProvider -import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter import org.springframework.stereotype.Service -import java.security.* +import org.springframework.transaction.annotation.Transactional +import java.security.KeyFactory +import java.security.NoSuchAlgorithmException +import java.security.PublicKey import java.security.spec.InvalidKeySpecException -import java.time.LocalDateTime -import java.time.ZoneId import java.util.* @@ -27,44 +23,43 @@ class AppleAuthServiceImpl( private val appleClient: AppleClient, private val jwtProvider: TokenProvider, private val jwtParser: AppleJwtParser, - private val appleProperty: AppleProperty + private val userRepository: UserRepository ) : AppleAuthService { private companion object { - val logger: KLogger = KotlinLogging.logger { } const val ALG_HEADER_KEY = "alg" const val KID_HEADER_KEY = "kid" - const val ALG = "ES256" - const val AUD = "https://appleid.apple.com" + const val NAME = "user-" } - override fun test(): Any { - return "$AUD/auth/authorize" + - "?client_id=${appleProperty.clientId}" + - "&redirect_uri=http://127.0.0.1/auth/oauth/apple/token" + - "&response_type=code" + - "&scope=name%20email" + - "&response_mode=form_post" - } + @Transactional + override fun signUp(idToken: String): TokenResponse { + + val token = parseIdToken(idToken) - override fun signUp(code: String): Any { + val sub = token.subject - logger.error { parseIdToken(code) } - return parseIdToken( - appleClient.getToken( - code, - appleProperty.clientId, - makeClientSecret() - ).idToken - ) + val user = userRepository.findBySub(sub) + ?: userRepository.save( + User( + sub, + token.get("email", String::class.java) + ?: (NAME + UUID.randomUUID().toString().replace("-", "")) + ) + ) + + return jwtProvider.receiveToken(user.sub) } - fun parseIdToken(idToken: String): Any = jwtProvider.parseClaims( + private fun parseIdToken(idToken: String) = jwtProvider.parseClaims( idToken, generatePublicKey(jwtParser.parseHeaders(idToken), appleClient.applePublicKeys()) ) - fun generatePublicKey(tokenHeaders: MutableMap, applePublicKeys: ApplePublicKeys): PublicKey { + private fun generatePublicKey( + tokenHeaders: MutableMap, + applePublicKeys: ApplePublicKeys + ): PublicKey { val publicKey: ApplePublicKey = applePublicKeys.matchesKey(tokenHeaders[ALG_HEADER_KEY]!!, tokenHeaders[KID_HEADER_KEY]!!) @@ -78,27 +73,4 @@ class AppleAuthServiceImpl( throw IllegalStateException("Apple OAuth 로그인 중 public key 생성에 문제가 발생했습니다.") } } - - fun makeClientSecret(): String = Jwts.builder() - .setHeaderParam(KID_HEADER_KEY, appleProperty.keyId) - .setHeaderParam(ALG_HEADER_KEY, ALG) - .setIssuer(appleProperty.issuer) - .setIssuedAt(Date(System.currentTimeMillis())) - .setExpiration(Date.from(LocalDateTime.now().plusDays(30).atZone(ZoneId.systemDefault()).toInstant())) - .setAudience(AUD) - .setSubject(appleProperty.clientId) - .signWith(SignatureAlgorithm.ES256, getPrivateKey()) - .compact() - - private fun getPrivateKey(): PrivateKey { - Security.addProvider(BouncyCastleProvider()) - val converter = JcaPEMKeyConverter().setProvider("BC") - return try { - val privateKeyBytes: ByteArray = Base64.getDecoder().decode(appleProperty.authKey) - val privateKeyInfo = PrivateKeyInfo.getInstance(privateKeyBytes) - converter.getPrivateKey(privateKeyInfo) - } catch (e: Exception) { - throw RuntimeException("Error converting private key from String", e) - } - } } \ No newline at end of file From 954629a532f59ba2dc16e40ab5e3dcf10a13a3c3 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:23:57 +0900 Subject: [PATCH 37/56] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20::=20findByUserAndYe?= =?UTF-8?q?arAndMonthAndDay?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/onui/domain/diary/repository/DiaryRepository.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/diary/repository/DiaryRepository.kt b/src/main/kotlin/com/example/onui/domain/diary/repository/DiaryRepository.kt index 38236c9..453adf6 100644 --- a/src/main/kotlin/com/example/onui/domain/diary/repository/DiaryRepository.kt +++ b/src/main/kotlin/com/example/onui/domain/diary/repository/DiaryRepository.kt @@ -4,12 +4,12 @@ import com.example.onui.domain.diary.entity.Diary import com.example.onui.domain.user.entity.User import org.springframework.data.jpa.repository.JpaRepository import org.springframework.stereotype.Repository -import java.util.UUID +import java.util.* @Repository -interface DiaryRepository: JpaRepository { +interface DiaryRepository : JpaRepository { fun findAllByUserAndYearAndMonth(user: User, year: Int, month: Int): MutableList? - fun existsByUserAndYearAndMonth(user: User, year: Int, month: Int): Boolean + fun findByUserAndYearAndMonthAndDay(user: User, year: Int, month: Int, day: Int): Diary? } \ No newline at end of file From 3162313cdb6230f416d3ad38169d0dc4debcdf26 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:24:09 +0900 Subject: [PATCH 38/56] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20::=20line?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/onui/domain/diary/repository/QDiaryRepository.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/kotlin/com/example/onui/domain/diary/repository/QDiaryRepository.kt b/src/main/kotlin/com/example/onui/domain/diary/repository/QDiaryRepository.kt index 4858ba9..a747353 100644 --- a/src/main/kotlin/com/example/onui/domain/diary/repository/QDiaryRepository.kt +++ b/src/main/kotlin/com/example/onui/domain/diary/repository/QDiaryRepository.kt @@ -5,6 +5,8 @@ import com.example.onui.domain.diary.presentation.response.DiaryResponse import com.example.onui.domain.user.entity.User interface QDiaryRepository { + fun findThreeDayAgoByUser(user: User): Diary? + fun findSevenDayAgoByUser(user: User): MutableList } \ No newline at end of file From 0d516c653061d6bb582b6e3c45406eadc6ac564d Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:24:53 +0900 Subject: [PATCH 39/56] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20::=20=EC=84=B1?= =?UTF-8?q?=EB=8A=A5=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/diary/service/DiaryServiceImpl.kt | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/diary/service/DiaryServiceImpl.kt b/src/main/kotlin/com/example/onui/domain/diary/service/DiaryServiceImpl.kt index fbfc958..74f857c 100644 --- a/src/main/kotlin/com/example/onui/domain/diary/service/DiaryServiceImpl.kt +++ b/src/main/kotlin/com/example/onui/domain/diary/service/DiaryServiceImpl.kt @@ -1,7 +1,6 @@ package com.example.onui.domain.diary.service import com.example.onui.domain.diary.entity.Diary -import com.example.onui.domain.diary.exception.AlreadyWroteDiaryException import com.example.onui.domain.diary.exception.DiaryNotFoundException import com.example.onui.domain.diary.presentation.request.CreateDiaryRequest import com.example.onui.domain.diary.presentation.request.UpdateDiaryRequest @@ -34,24 +33,22 @@ class DiaryServiceImpl( val user = userFacade.getCurrentUser() val now = LocalDateTime.now() - if (diaryRepository.existsByUserAndYearAndMonth( + val diary = Diary( + user, + req.content, + req.mood!!, + req.tagList!!, + now, + req.image, + diaryRepository.findByUserAndYearAndMonthAndDay( user, now.year, - now.monthValue - ) - ) throw AlreadyWroteDiaryException - - val diary = diaryRepository.save( - Diary( - user, - req.content, - req.mood!!, - req.tagList!!, - now, - req.image - ) + now.monthValue, + now.dayOfMonth + )?.id ) + diaryRepository.save(diary) user.diaryList.add(diary) return diary.toDetailResponse() From 708946d0a1ab7f68d6c9c54558f03209b7cf14b5 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:25:11 +0900 Subject: [PATCH 40/56] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20::=20findAssignByCoa?= =?UTF-8?q?st?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mission/repository/QMissionRepositoryImpl.kt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/mission/repository/QMissionRepositoryImpl.kt b/src/main/kotlin/com/example/onui/domain/mission/repository/QMissionRepositoryImpl.kt index ef4e9b2..d273310 100644 --- a/src/main/kotlin/com/example/onui/domain/mission/repository/QMissionRepositoryImpl.kt +++ b/src/main/kotlin/com/example/onui/domain/mission/repository/QMissionRepositoryImpl.kt @@ -2,16 +2,19 @@ import com.example.onui.domain.mission.entity.Mission import com.example.onui.domain.mission.entity.QMission.mission +import com.example.onui.domain.mission.entity.QAssignMission.assignMission import com.querydsl.jpa.impl.JPAQueryFactory import org.springframework.stereotype.Service @Service class QMissionRepositoryImpl(private val queryFactory: JPAQueryFactory): QMissionRepository { - fun findByMinusCoast(coast: Int): List { - return queryFactory.select(mission) - .from(mission) - .where(mission.coast.eq(coast.plus(1)).or(mission.coast.eq(coast.minus(1)))) - .fetch() - } + override fun findAssignByCoast(coast: Int): List = queryFactory + .select(assignMission) + .from(assignMission) + .where( + assignMission.coast.eq(coast.plus(1)) + .or(assignMission.coast.eq(coast.minus(1)) + .or(assignMission.coast.eq(coast))) + ).fetch() } \ No newline at end of file From f2ec482d5ccbaf6d30f4caea758f4ded53ffbf5a Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:27:07 +0900 Subject: [PATCH 41/56] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20::=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/mission/service/MissionService.kt | 6 +++ .../mission/service/MissionServiceImpl.kt | 40 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/main/kotlin/com/example/onui/domain/mission/service/MissionService.kt create mode 100644 src/main/kotlin/com/example/onui/domain/mission/service/MissionServiceImpl.kt diff --git a/src/main/kotlin/com/example/onui/domain/mission/service/MissionService.kt b/src/main/kotlin/com/example/onui/domain/mission/service/MissionService.kt new file mode 100644 index 0000000..ff18ffc --- /dev/null +++ b/src/main/kotlin/com/example/onui/domain/mission/service/MissionService.kt @@ -0,0 +1,6 @@ +package com.example.onui.domain.mission.service + +interface MissionService { + + fun test(): Any +} \ No newline at end of file diff --git a/src/main/kotlin/com/example/onui/domain/mission/service/MissionServiceImpl.kt b/src/main/kotlin/com/example/onui/domain/mission/service/MissionServiceImpl.kt new file mode 100644 index 0000000..a0ae9d6 --- /dev/null +++ b/src/main/kotlin/com/example/onui/domain/mission/service/MissionServiceImpl.kt @@ -0,0 +1,40 @@ +package com.example.onui.domain.mission.service + +import com.example.onui.domain.mission.entity.AssignMission +import com.example.onui.domain.mission.entity.GeneralMission +import com.example.onui.domain.mission.repository.MissionRepository +import com.example.onui.domain.mission.repository.QMissionRepository +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional + +@Service +@Transactional(readOnly = true) +class MissionServiceImpl( + private val generalMissionRepository: MissionRepository, + private val assignMissionRepository: MissionRepository, + private val qMissionRepository: QMissionRepository +) : MissionService { + + @Transactional + override fun test(): Any { + + assignMissionRepository.save( + AssignMission( + "물 마시기", + "오늘 하루 물 2L(생수병 한병) 마시기", + -5, + "우울한 기분을 물한잔으로 전환해봐요!, %s님! 우울한 하루의 시작을 물한잔만으로 활기찬 아침을 시작해봐요!" + ) + ) + + generalMissionRepository.save( + GeneralMission( + "오늘 하루 감정 기록하기", + "오늘 하루도 꾸준히 기록해봐요!", + "감정 기록 잊으신건 아니죠..? 저희 오누이를 찾아주세요!" + ) + ) + + return qMissionRepository.findAssignByCoast(-5) + } +} \ No newline at end of file From d29247ae2b1c2770c571e81509aec010123e140d Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:27:27 +0900 Subject: [PATCH 42/56] =?UTF-8?q?=F0=9F=93=9D=20::=20length=2030=20->=2060?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/example/onui/domain/user/entity/User.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/example/onui/domain/user/entity/User.kt b/src/main/kotlin/com/example/onui/domain/user/entity/User.kt index 03416a9..1c5db18 100644 --- a/src/main/kotlin/com/example/onui/domain/user/entity/User.kt +++ b/src/main/kotlin/com/example/onui/domain/user/entity/User.kt @@ -14,12 +14,13 @@ class User( id: UUID? = null ) { - @Id @GeneratedValue(strategy = GenerationType.AUTO) + @Id + @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id", columnDefinition = "BINARY(16)") var id: UUID? = id protected set - @Column(name = "sub", nullable = false, length = 30, unique = true) + @Column(name = "sub", nullable = false, length = 60, unique = true) var sub: String = sub protected set From 10505e1031502a7715a424f9a1410703b6c47798 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:27:39 +0900 Subject: [PATCH 43/56] =?UTF-8?q?=F0=9F=93=9D=20::=20add=20log?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/onui/global/config/feign/FeignClientErrorDecoder.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/kotlin/com/example/onui/global/config/feign/FeignClientErrorDecoder.kt b/src/main/kotlin/com/example/onui/global/config/feign/FeignClientErrorDecoder.kt index 6a1b2db..eb00b68 100644 --- a/src/main/kotlin/com/example/onui/global/config/feign/FeignClientErrorDecoder.kt +++ b/src/main/kotlin/com/example/onui/global/config/feign/FeignClientErrorDecoder.kt @@ -17,6 +17,7 @@ class FeignClientErrorDecoder: ErrorDecoder { override fun decode(methodKey: String, response: Response): Exception { + logger.error { methodKey } logger.error { response.status() } logger.error { response.body() } logger.error { response.reason() } From bf4514851a1b47ecf6a617d6bfdf56cdb002fbc2 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:29:12 +0900 Subject: [PATCH 44/56] =?UTF-8?q?=F0=9F=93=9D=20::?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/onui/global/config/jwt/AppleJwtParser.kt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/com/example/onui/global/config/jwt/AppleJwtParser.kt b/src/main/kotlin/com/example/onui/global/config/jwt/AppleJwtParser.kt index cde200c..fb5d390 100644 --- a/src/main/kotlin/com/example/onui/global/config/jwt/AppleJwtParser.kt +++ b/src/main/kotlin/com/example/onui/global/config/jwt/AppleJwtParser.kt @@ -17,15 +17,14 @@ class AppleJwtParser( private const val HEADER_INDEX = 0 } - fun parseHeaders(identityToken: String): MutableMap<*, *> { + @Suppress("unchecked_cast") + fun parseHeaders(token: String): MutableMap { return try { - - val encodedHeader = identityToken.split(IDENTITY_TOKEN_VALUE_DELIMITER.toRegex())[HEADER_INDEX] - objectMapper.readValue(String(Base64Utils.decodeFromUrlSafeString(encodedHeader)), MutableMap::class.java) - + val encodedHeader: String = token.split(IDENTITY_TOKEN_VALUE_DELIMITER.toRegex())[HEADER_INDEX] + val decodedHeader = String(Base64Utils.decodeFromUrlSafeString(encodedHeader)) + objectMapper.readValue(decodedHeader, MutableMap::class.java) as MutableMap } catch (e: JsonProcessingException) { throw InvalidTokenException - } catch (e: ArrayIndexOutOfBoundsException) { throw InvalidTokenException } From 8d4da95ab92beaa1ff5d1a134673458e0e573184 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:32:03 +0900 Subject: [PATCH 45/56] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20::=20code=20style?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onui/global/config/jwt/TokenProvider.kt | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/main/kotlin/com/example/onui/global/config/jwt/TokenProvider.kt b/src/main/kotlin/com/example/onui/global/config/jwt/TokenProvider.kt index 5e47b89..c0e2b6a 100644 --- a/src/main/kotlin/com/example/onui/global/config/jwt/TokenProvider.kt +++ b/src/main/kotlin/com/example/onui/global/config/jwt/TokenProvider.kt @@ -5,9 +5,9 @@ import com.example.onui.domain.auth.presentation.dto.response.TokenResponse import com.example.onui.domain.auth.repository.RefreshTokenRepository import com.example.onui.global.config.error.exception.ExpiredTokenException import com.example.onui.global.config.error.exception.InvalidTokenException -import com.example.onui.global.config.jwt.env.TokenProperty import com.example.onui.global.config.security.principal.AuthDetails import com.example.onui.global.config.security.principal.AuthDetailsService +import com.example.onui.global.env.TokenProperty import io.jsonwebtoken.ExpiredJwtException import io.jsonwebtoken.Jwts import io.jsonwebtoken.SignatureAlgorithm @@ -46,7 +46,7 @@ class TokenProvider( return rfToken } - fun receiveToken(sub: String) = TokenResponse ( + fun receiveToken(sub: String) = TokenResponse( generateAccessToken(sub), getExp(property.accessExp), generateRefreshToken(sub), @@ -56,15 +56,15 @@ class TokenProvider( private fun getExp(exp: Long) = LocalDateTime.now().withNano(0).plusSeconds(exp / 1000) private fun getSubject(token: String) = try { - Jwts.parser() - .setSigningKey(property.secretKey) - .parseClaimsJws(token).body.subject - } catch (e: Exception) { - when (e) { - is ExpiredJwtException -> throw ExpiredTokenException - else -> throw InvalidTokenException - } + Jwts.parser() + .setSigningKey(property.secretKey) + .parseClaimsJws(token).body.subject + } catch (e: Exception) { + when (e) { + is ExpiredJwtException -> throw ExpiredTokenException + else -> throw InvalidTokenException } + } fun getAuthentication(token: String): Authentication { @@ -76,12 +76,12 @@ class TokenProvider( } fun reissue(token: String): TokenResponse { - - val sub = (refreshTokenRepository.findByIdOrNull(token) ?: throw InvalidTokenException) - .let { + + val sub = refreshTokenRepository.findByIdOrNull(token) + ?.let { refreshTokenRepository.delete(it) return@let it.sub - } + } ?: throw InvalidTokenException return receiveToken(sub) } From d294cb7b3c57b2ab6ff3b602775e7d4a030f4b16 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:32:21 +0900 Subject: [PATCH 46/56] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20::=20parseClaim?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/service/AppleAuthServiceImpl.kt | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/com/example/onui/domain/auth/service/AppleAuthServiceImpl.kt b/src/main/kotlin/com/example/onui/domain/auth/service/AppleAuthServiceImpl.kt index fe43131..ab80adf 100644 --- a/src/main/kotlin/com/example/onui/domain/auth/service/AppleAuthServiceImpl.kt +++ b/src/main/kotlin/com/example/onui/domain/auth/service/AppleAuthServiceImpl.kt @@ -3,12 +3,16 @@ import com.example.onui.domain.auth.presentation.dto.response.TokenResponse import com.example.onui.domain.user.entity.User import com.example.onui.domain.user.repository.UserRepository +import com.example.onui.global.config.error.exception.ExpiredTokenException import com.example.onui.global.config.error.exception.InvalidTokenException import com.example.onui.global.config.jwt.AppleJwtParser import com.example.onui.global.config.jwt.TokenProvider import com.example.onui.infra.feign.apple.AppleClient import com.example.onui.infra.feign.apple.dto.ApplePublicKey import com.example.onui.infra.feign.apple.dto.ApplePublicKeys +import io.jsonwebtoken.Claims +import io.jsonwebtoken.ExpiredJwtException +import io.jsonwebtoken.Jwts import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import java.security.KeyFactory @@ -52,7 +56,7 @@ class AppleAuthServiceImpl( return jwtProvider.receiveToken(user.sub) } - private fun parseIdToken(idToken: String) = jwtProvider.parseClaims( + private fun parseIdToken(idToken: String) = parseClaims( idToken, generatePublicKey(jwtParser.parseHeaders(idToken), appleClient.applePublicKeys()) ) @@ -73,4 +77,18 @@ class AppleAuthServiceImpl( throw IllegalStateException("Apple OAuth 로그인 중 public key 생성에 문제가 발생했습니다.") } } + + private fun parseClaims(token: String, publicKey: PublicKey): Claims { + return try { + Jwts.parser() + .setSigningKey(publicKey) + .parseClaimsJws(token) + .body + } catch (e: Exception) { + when (e) { + is ExpiredJwtException -> throw ExpiredTokenException + else -> throw InvalidTokenException + } + } + } } \ No newline at end of file From 8a75c8656775b1785089cc7306227ea0c15be173 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:32:32 +0900 Subject: [PATCH 47/56] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20::=20redis=20config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onui/global/config/redis/RedisConfig.kt | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/main/kotlin/com/example/onui/global/config/redis/RedisConfig.kt diff --git a/src/main/kotlin/com/example/onui/global/config/redis/RedisConfig.kt b/src/main/kotlin/com/example/onui/global/config/redis/RedisConfig.kt new file mode 100644 index 0000000..b34a0ad --- /dev/null +++ b/src/main/kotlin/com/example/onui/global/config/redis/RedisConfig.kt @@ -0,0 +1,33 @@ +package com.example.onui.global.config.redis + +import com.example.onui.global.env.RedisProperty +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.data.redis.connection.RedisConnectionFactory +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory +import org.springframework.data.redis.core.RedisKeyValueAdapter +import org.springframework.data.redis.repository.configuration.EnableRedisRepositories + +@EnableRedisRepositories(enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP) +@Configuration +class RedisConfig( + private val property: RedisProperty +) { + + @Bean + fun redisConnectionFactory(): RedisConnectionFactory = LettuceConnectionFactory(property.host, property.port) + +// @Bean +// fun redisTemplate(): RedisTemplate { +// +// val template: RedisTemplate = RedisTemplate() +// +// template.let { +// it.keySerializer = StringRedisSerializer() +// it.valueSerializer = StringRedisSerializer() +// it.setConnectionFactory(redisConnectionFactory()) +// } +// +// return template +// } +} \ No newline at end of file From 43e0500180734467eba847cf7d373fdc140f3036 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:32:52 +0900 Subject: [PATCH 48/56] =?UTF-8?q?=F0=9F=93=9D=20::=20auto=20wired?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/example/onui/global/config/s3/S3Config.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/example/onui/global/config/s3/S3Config.kt b/src/main/kotlin/com/example/onui/global/config/s3/S3Config.kt index df41ccb..c142b59 100644 --- a/src/main/kotlin/com/example/onui/global/config/s3/S3Config.kt +++ b/src/main/kotlin/com/example/onui/global/config/s3/S3Config.kt @@ -4,13 +4,13 @@ import com.amazonaws.auth.AWSStaticCredentialsProvider import com.amazonaws.auth.BasicAWSCredentials import com.amazonaws.services.s3.AmazonS3Client import com.amazonaws.services.s3.AmazonS3ClientBuilder -import com.example.onui.global.config.s3.env.S3Property +import com.example.onui.global.env.S3Property import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration @Configuration class S3Config( - val s3Property: S3Property + private val s3Property: S3Property ) { @Bean From ba980703130f264ca01300ad1262d45e935cfdfb Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:33:03 +0900 Subject: [PATCH 49/56] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20::=20permit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/onui/global/config/security/SecurityConfig.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/kotlin/com/example/onui/global/config/security/SecurityConfig.kt b/src/main/kotlin/com/example/onui/global/config/security/SecurityConfig.kt index a892aa2..28d625d 100644 --- a/src/main/kotlin/com/example/onui/global/config/security/SecurityConfig.kt +++ b/src/main/kotlin/com/example/onui/global/config/security/SecurityConfig.kt @@ -38,6 +38,7 @@ class SecurityConfig( .and() .authorizeRequests() + .antMatchers("/**/test").permitAll() .antMatchers("/auth/**").permitAll() .anyRequest().authenticated() .and() From bc9a3c151d738287801d250c64bb02735668f962 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:33:15 +0900 Subject: [PATCH 50/56] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20::=20redisProperty?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/onui/global/env/RedisProperty.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/kotlin/com/example/onui/global/env/RedisProperty.kt diff --git a/src/main/kotlin/com/example/onui/global/env/RedisProperty.kt b/src/main/kotlin/com/example/onui/global/env/RedisProperty.kt new file mode 100644 index 0000000..9710fb4 --- /dev/null +++ b/src/main/kotlin/com/example/onui/global/env/RedisProperty.kt @@ -0,0 +1,11 @@ +package com.example.onui.global.env + +import org.springframework.boot.context.properties.ConfigurationProperties +import org.springframework.boot.context.properties.ConstructorBinding + +@ConstructorBinding +@ConfigurationProperties("spring.redis") +data class RedisProperty( + val host: String, + val port: Int +) From a7329c1e39d7d030e506b949a1edcadcb6336200 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:33:31 +0900 Subject: [PATCH 51/56] =?UTF-8?q?=F0=9F=9A=9A=20::=20to=20env?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/onui/global/{config/s3 => }/env/S3Property.kt | 2 +- .../example/onui/global/{config/jwt => }/env/TokenProperty.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/main/kotlin/com/example/onui/global/{config/s3 => }/env/S3Property.kt (88%) rename src/main/kotlin/com/example/onui/global/{config/jwt => }/env/TokenProperty.kt (86%) diff --git a/src/main/kotlin/com/example/onui/global/config/s3/env/S3Property.kt b/src/main/kotlin/com/example/onui/global/env/S3Property.kt similarity index 88% rename from src/main/kotlin/com/example/onui/global/config/s3/env/S3Property.kt rename to src/main/kotlin/com/example/onui/global/env/S3Property.kt index 4256605..a05d88a 100644 --- a/src/main/kotlin/com/example/onui/global/config/s3/env/S3Property.kt +++ b/src/main/kotlin/com/example/onui/global/env/S3Property.kt @@ -1,4 +1,4 @@ -package com.example.onui.global.config.s3.env +package com.example.onui.global.env import org.springframework.boot.context.properties.ConfigurationProperties import org.springframework.boot.context.properties.ConstructorBinding diff --git a/src/main/kotlin/com/example/onui/global/config/jwt/env/TokenProperty.kt b/src/main/kotlin/com/example/onui/global/env/TokenProperty.kt similarity index 86% rename from src/main/kotlin/com/example/onui/global/config/jwt/env/TokenProperty.kt rename to src/main/kotlin/com/example/onui/global/env/TokenProperty.kt index 5a09496..e73a4a6 100644 --- a/src/main/kotlin/com/example/onui/global/config/jwt/env/TokenProperty.kt +++ b/src/main/kotlin/com/example/onui/global/env/TokenProperty.kt @@ -1,4 +1,4 @@ -package com.example.onui.global.config.jwt.env +package com.example.onui.global.env import org.springframework.boot.context.properties.ConfigurationProperties import org.springframework.boot.context.properties.ConstructorBinding From 831a2ecea86d8b6ba80b6629e4f131685aa50a17 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:33:43 +0900 Subject: [PATCH 52/56] =?UTF-8?q?=F0=9F=94=A5=20::=20apple=20property?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onui/infra/feign/apple/env/AppleProperty.kt | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 src/main/kotlin/com/example/onui/infra/feign/apple/env/AppleProperty.kt diff --git a/src/main/kotlin/com/example/onui/infra/feign/apple/env/AppleProperty.kt b/src/main/kotlin/com/example/onui/infra/feign/apple/env/AppleProperty.kt deleted file mode 100644 index b08992d..0000000 --- a/src/main/kotlin/com/example/onui/infra/feign/apple/env/AppleProperty.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.example.onui.infra.feign.apple.env - -import org.springframework.boot.context.properties.ConfigurationProperties -import org.springframework.boot.context.properties.ConstructorBinding - -@ConfigurationProperties("oauth.apple") -@ConstructorBinding -data class AppleProperty ( - val iss: String, - val clientId: String, - val nonce: String -) \ No newline at end of file From 748101d7ef8c1bc3a94b8784240dd3925a387d66 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:34:42 +0900 Subject: [PATCH 53/56] =?UTF-8?q?=F0=9F=93=9D=20::=20rename?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/example/onui/infra/feign/apple/AppleClient.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/com/example/onui/infra/feign/apple/AppleClient.kt b/src/main/kotlin/com/example/onui/infra/feign/apple/AppleClient.kt index 241c88d..5fc8d4d 100644 --- a/src/main/kotlin/com/example/onui/infra/feign/apple/AppleClient.kt +++ b/src/main/kotlin/com/example/onui/infra/feign/apple/AppleClient.kt @@ -1,11 +1,12 @@ package com.example.onui.infra.feign.apple import com.example.onui.global.config.feign.FeignConfig +import com.example.onui.infra.feign.apple.dto.ApplePublicKeys import org.springframework.cloud.openfeign.FeignClient import org.springframework.web.bind.annotation.GetMapping -@FeignClient(name = "apple-public-key-client", url = "https://appleid.apple.com/auth", configuration = [FeignConfig::class]) +@FeignClient(name = "apple-client", url = "https://appleid.apple.com/auth", configuration = [FeignConfig::class]) interface AppleClient { @GetMapping("/keys") From 29457dcca37eb95a0c45094b2f96df651639042c Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:34:56 +0900 Subject: [PATCH 54/56] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20::=20revoke?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onui/infra/feign/google/GoogleAuthClient.kt | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/com/example/onui/infra/feign/google/GoogleAuthClient.kt b/src/main/kotlin/com/example/onui/infra/feign/google/GoogleAuthClient.kt index de4a7dc..7a7d09b 100644 --- a/src/main/kotlin/com/example/onui/infra/feign/google/GoogleAuthClient.kt +++ b/src/main/kotlin/com/example/onui/infra/feign/google/GoogleAuthClient.kt @@ -1,21 +1,16 @@ package com.example.onui.infra.feign.google import com.example.onui.global.config.feign.FeignConfig -import com.example.onui.infra.feign.google.dto.OAuthTokenResponse import org.springframework.cloud.openfeign.FeignClient import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestParam -@FeignClient(name = "GoogleAuthClient", url = "https://oauth2.googleapis.com/token", configuration = [FeignConfig::class]) +@FeignClient(name = "GoogleAuthClient", url = "https://oauth2.googleapis.com", configuration = [FeignConfig::class]) interface GoogleAuthClient { - @PostMapping(headers = ["Content-Length=0"]) - fun googleAuth( - @RequestParam(name = "code") code: String, - @RequestParam(name = "clientId") clientId: String, - @RequestParam(name = "clientSecret") clientSecret: String, - @RequestParam(name = "redirectUri") redirectUri: String, - @RequestParam(name = "grantType") grantType: String - ): OAuthTokenResponse + @PostMapping("/revoke") + fun revokeToken( + @RequestParam(name = "token") token: String + ) } \ No newline at end of file From b5a172204cb45812df4b9fb936503d126d46749a Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:35:14 +0900 Subject: [PATCH 55/56] =?UTF-8?q?=E2=AD=90=EF=B8=8F=20::=20basePackages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/example/onui/OnuiApplication.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/com/example/onui/OnuiApplication.kt b/src/main/kotlin/com/example/onui/OnuiApplication.kt index a235624..871f7bb 100644 --- a/src/main/kotlin/com/example/onui/OnuiApplication.kt +++ b/src/main/kotlin/com/example/onui/OnuiApplication.kt @@ -4,7 +4,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.context.properties.ConfigurationPropertiesScan import org.springframework.boot.runApplication -@ConfigurationPropertiesScan +@ConfigurationPropertiesScan(basePackages = ["com.example.onui.global.env"]) @SpringBootApplication class OnuiApplication From d39940e9df316d296cd695f9fe1b67e19f0d1534 Mon Sep 17 00:00:00 2001 From: gurdl7011 Date: Thu, 9 Nov 2023 23:35:35 +0900 Subject: [PATCH 56/56] =?UTF-8?q?=F0=9F=94=A5=20::=20apple=20property?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index cb1a274..d77bb1e 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -47,14 +47,6 @@ logging: level: root: info -# oauth -oauth: - apple: - client-id: ${APPLE_CLIENT} - issuer: ${APPLE_TEAM_ID} - key-id: ${APPLE_KEY_ID} - auth-key: ${APPLE_AUTH_KEY} - # jwt jwt: secret-key: ${JWT_SECRET}