Skip to content

Commit aebfd45

Browse files
authored
release: 0.1.2 (#73)
2 parents defa072 + 3121af8 commit aebfd45

91 files changed

Lines changed: 600 additions & 247 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/deploy.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ jobs:
6767
DB_URL=${{ secrets.DB_URL }}
6868
DB_USERNAME=${{ secrets.DB_USERNAME }}
6969
DB_PASSWORD=${{ secrets.DB_PASSWORD }}
70+
CORS_ORIGIN_LOCAL=${{ secrets.CORS_ORIGIN_LOCAL }}
71+
CORS_ORIGIN_DEV=${{ secrets.CORS_ORIGIN_DEV }}
72+
CORS_ORIGIN_PROD=${{ secrets.CORS_ORIGIN_PROD }}
7073
KAKAO_BASE_URL=${{ secrets.KAKAO_BASE_URL }}
7174
KAKAO_CLIENT_ID=${{ secrets.KAKAO_CLIENT_ID }}
7275
KAKAO_CLIENT_SECRET=${{ secrets.KAKAO_CLIENT_SECRET }}
@@ -99,6 +102,9 @@ jobs:
99102
-e DB_URL=${{ secrets.DB_URL }} \
100103
-e DB_USER=${{ secrets.DB_USER }} \
101104
-e DB_PASSWORD=${{ secrets.DB_PASSWORD }} \
105+
-e CORS_ORIGIN_LOCAL=${{ secrets.CORS_ORIGIN_LOCAL }} \
106+
-e CORS_ORIGIN_DEV=${{ secrets.CORS_ORIGIN_DEV }} \
107+
-e CORS_ORIGIN_PROD=${{ secrets.CORS_ORIGIN_PROD }} \
102108
-e KAKAO_BASE_URL=${{ secrets.KAKAO_BASE_URL }} \
103109
-e KAKAO_CLIENT_ID=${{ secrets.KAKAO_CLIENT_ID }} \
104110
-e KAKAO_CLIENT_SECRET=${{ secrets.KAKAO_CLIENT_SECRET }} \
Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package site.techmoa.app.article.controller.v1
22

3+
import org.springframework.http.ResponseEntity
34
import org.springframework.web.bind.annotation.*
4-
import site.techmoa.app.core.article.ArticleContent
5-
import site.techmoa.app.core.article.ArticleUseCase
6-
import site.techmoa.app.core.common.Page
7-
import site.techmoa.app.core.response.ApiResponse
5+
import site.techmoa.app.article.controller.v1.response.GetArticleResponse
6+
import site.techmoa.app.common.annotation.AuthOptional
7+
import site.techmoa.app.common.article.ArticleContent
8+
import site.techmoa.app.common.article.ArticleUseCase
9+
import site.techmoa.app.common.common.Page
10+
import site.techmoa.app.common.response.ApiResponse
811

912
@RestController
1013
class ArticleController(
@@ -15,19 +18,28 @@ class ArticleController(
1518
const val PAGE_LIMIT = 20
1619
}
1720

21+
@AuthOptional
1822
@GetMapping("/v1/articles")
1923
fun getArticles(
2024
@RequestParam("cursor", required = false) cursor: Long?,
21-
): ApiResponse<Page<ArticleContent>> {
25+
): ResponseEntity<ApiResponse<Page<ArticleContent>>> {
2226
val articles = articleUseCase.getArticles(cursor, PAGE_LIMIT)
23-
return ApiResponse.success(articles)
27+
return ResponseEntity.ok(ApiResponse.success(articles))
2428
}
2529

30+
@AuthOptional
2631
@PostMapping("/v1/articles/{articleId}/views")
2732
fun increaseViewCount(
2833
@PathVariable articleId: Long
29-
): ApiResponse<Any> {
34+
): ResponseEntity<ApiResponse<Any>> {
3035
articleUseCase.increaseViewCount(articleId)
31-
return ApiResponse.success()
36+
return ResponseEntity.ok(ApiResponse.success())
37+
}
38+
39+
@AuthOptional
40+
@GetMapping("/v1/articles/{articleId}")
41+
fun getArticle(@PathVariable articleId: Long): ResponseEntity<ApiResponse<GetArticleResponse>> {
42+
val article = articleUseCase.getArticle(articleId)
43+
return ResponseEntity.ok(ApiResponse.success(GetArticleResponse(article)))
3244
}
3345
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package site.techmoa.app.article.controller.v1.response
2+
3+
import site.techmoa.app.common.article.Article
4+
5+
class GetArticleResponse(
6+
val article: Article
7+
) {
8+
}
Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package site.techmoa.app.auth.v1
22

33
import org.slf4j.LoggerFactory
4+
import org.springframework.http.HttpHeaders
5+
import org.springframework.http.HttpStatus
6+
import org.springframework.http.ResponseEntity
47
import org.springframework.web.bind.annotation.GetMapping
58
import org.springframework.web.bind.annotation.RequestParam
69
import org.springframework.web.bind.annotation.RestController
7-
import site.techmoa.app.auth.v1.response.LoginResponse
8-
import site.techmoa.app.core.auth.OauthLoginUseCase
9-
import site.techmoa.app.core.response.ApiResponse
10+
import site.techmoa.app.common.auth.OauthLoginUseCase
11+
import site.techmoa.app.common.response.ApiResponse
1012

1113
@RestController
1214
class AuthController(
@@ -18,10 +20,15 @@ class AuthController(
1820
@GetMapping("/v1/oauth/kakao/callback")
1921
fun kakaoAuthorization(
2022
@RequestParam("code") code: String,
21-
): ApiResponse<LoginResponse> {
23+
): ResponseEntity<ApiResponse<Any>> {
2224
log.info("[OAuth] Kakao authorization callback received, code length: ${code.length}")
2325
val token = oauthLoginUseCase.process(code)
2426
log.info("[OAuth] Login successful, access token issued for memberId: masked")
25-
return ApiResponse.success(LoginResponse(token.accessToken))
27+
val headers = HttpHeaders()
28+
headers.add(HttpHeaders.AUTHORIZATION, "Bearer ${token.accessToken}")
29+
return ResponseEntity(
30+
headers,
31+
HttpStatus.OK
32+
)
2633
}
2734
}

app-api/src/main/kotlin/site/techmoa/app/blog/controller/AdminBlogController.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import org.springframework.web.bind.annotation.PostMapping
44
import org.springframework.web.bind.annotation.RequestBody
55
import org.springframework.web.bind.annotation.RestController
66
import site.techmoa.app.blog.controller.request.SubscribeBlogRequest
7-
import site.techmoa.app.core.response.ApiResponse
7+
import site.techmoa.app.common.response.ApiResponse
88

99
@RestController
1010
class AdminBlogController{
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package site.techmoa.app.common.annotation
2+
3+
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
4+
@Retention(AnnotationRetention.RUNTIME)
5+
annotation class AuthOptional
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package site.techmoa.app.common.annotation
2+
3+
enum class AuthPolicy {
4+
REQUIRED,
5+
OPTIONAL,
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package site.techmoa.app.common.annotation
2+
3+
@Target(AnnotationTarget.FUNCTION)
4+
@Retention(AnnotationRetention.RUNTIME)
5+
annotation class AuthRequired {
6+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package site.techmoa.app.common.config
2+
3+
import org.springframework.boot.context.properties.ConfigurationProperties
4+
5+
@ConfigurationProperties(prefix = "cors")
6+
data class CorsProperties(
7+
val allowedOrigins: List<String> = emptyList()
8+
)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package site.techmoa.app.common.config
2+
3+
import org.springframework.boot.context.properties.EnableConfigurationProperties
4+
import org.springframework.context.annotation.Configuration
5+
import org.springframework.web.servlet.config.annotation.CorsRegistry
6+
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
7+
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
8+
import site.techmoa.app.common.interceptor.JwtInterceptor
9+
10+
@Configuration
11+
@EnableConfigurationProperties(CorsProperties::class)
12+
class WebConfig(
13+
private val jwtInterceptor: JwtInterceptor,
14+
private val corsProperties: CorsProperties
15+
) : WebMvcConfigurer {
16+
17+
override fun addCorsMappings(registry: CorsRegistry) {
18+
registry
19+
.addMapping("/**")
20+
.allowedOrigins(*corsProperties.allowedOrigins.toTypedArray())
21+
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
22+
.allowedHeaders("*")
23+
.allowCredentials(true)
24+
.maxAge(3600)
25+
}
26+
27+
override fun addInterceptors(registry: InterceptorRegistry) {
28+
registry.addInterceptor(jwtInterceptor)
29+
.excludePathPatterns("/v1/oauth/**")
30+
.addPathPatterns("/v1/**")
31+
}
32+
}

0 commit comments

Comments
 (0)