From fdcaff608046a92dc0ad047f961e5aab61fc56ff Mon Sep 17 00:00:00 2001 From: lsakee <93514333+lsakee@users.noreply.github.com> Date: Tue, 7 Nov 2023 15:01:06 +0900 Subject: [PATCH] Refactor/#416 core network (#423) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [ADD]: init core module #416 * [ADD]: core network logic #416 * [ADD]: core network logic data store #416 * [REFACTOR]: app 로직 수정 #416 * [ADD]: flipper release/debug set #416 * [DELETE]: Delete Network File #416 cause Move Core Net * [CHORE]: Code Formating #416 * [FEAT]: Intent Provider #416 core network need Intent(auth activity) * [REFACTOR]: Naming & Navigator #416 core/network AuthService -> RefreshService Navigator 분리 * [DELETE]: 불필요 파일 제거 #416 proguard-rules.pro , ExampleInstrumentedTest.kt ,ExampleUnitTest.kt * [FEAT]: domain auth mapper #416 * [MOVE]: MOVE #416 OAuthToken,AuthResponse into core/network * [CHORE]: Git Ignore #416 * [CHORE]: name set #416 * [Refactor]: service 구분 #416 * [Refactor]: @Auth Annotation 제거 #416 * [CHORE]: 변수 이름 수정 #416 * [CHORE]: 변수 이름 수정 #416 * [CHORE]: 변수 이름 수정 #416 * [CHORE]: 변수 이름 수정 #416 * Spotless Apply * Fix runtime error --------- Co-authored-by: HyunWoo Lee --- app/build.gradle.kts | 1 + app/src/main/java/org/sopt/official/App.kt | 3 +- .../messaging/SoptFirebaseMessagingService.kt | 2 +- .../sopt/official/data/mapper/AuthMapper.kt | 41 ++++++++++++++ .../data/repository/AuthRepositoryImpl.kt | 5 +- .../sopt/official/data/service/AuthService.kt | 9 +-- .../source/api/auth/RemoteAuthDataSource.kt | 4 +- .../source/impl/DefaultLocalAuthDataSource.kt | 2 +- .../impl/DefaultRemoteAuthDataSource.kt | 15 ++--- .../java/org/sopt/official/di/AuthModule.kt | 12 ---- .../org/sopt/official/di/NavigatorModule.kt | 41 ++++++++++++++ .../official/feature/auth/AuthActivity.kt | 10 ++-- .../official/feature/home/HomeActivity.kt | 2 +- .../navigator/NavigatorProviderIntent.kt | 39 +++++++++++++ .../main/java/org/sopt/official/util/Auth.kt | 2 +- .../official/datastore/SoptDataStoreTest.kt | 2 +- .../org/sopt/official/common/di/Qualifiers.kt | 2 +- .../common/navigator/NavigatorProvider.kt | 31 +++++++++++ core/network/.gitignore | 0 core/network/build.gradle.kts | 49 +++++++++++++++++ core/network/consumer-rules.pro | 0 .../official/network}/FlipperInitializer.kt | 5 +- core/network/src/main/AndroidManifest.xml | 27 +++++++++ .../authenticator/SoptAuthenticator.kt | 20 +++---- .../sopt/official/network/di/AuthModule.kt | 55 +++++++++++++++++++ .../sopt/official/network}/di/NetModule.kt | 18 +++--- .../official/network}/di/SecurityModule.kt | 5 +- .../network}/interceptor/AuthInterceptor.kt | 4 +- .../network}/model/request/RefreshRequest.kt | 2 +- .../network}/model/response/AuthResponse.kt | 14 +---- .../network}/model/response/OauthToken.kt | 2 +- .../network}/persistence/SoptDataStore.kt | 11 ++-- .../network/service/RefreshService.kt | 38 +++++++++++++ .../official/network}/FlipperInitializer.kt | 2 +- feature/auth/build.gradle.kts | 1 + .../org/sopt/official/auth/PlaygroundAuth.kt | 2 +- .../auth/data/PlaygroundAuthDatasource.kt | 2 +- .../data/RemotePlaygroundAuthDatasource.kt | 2 +- .../official/auth/data/remote/AuthService.kt | 2 +- settings.gradle.kts | 9 +-- 40 files changed, 395 insertions(+), 98 deletions(-) create mode 100644 app/src/main/java/org/sopt/official/data/mapper/AuthMapper.kt create mode 100644 app/src/main/java/org/sopt/official/di/NavigatorModule.kt create mode 100644 app/src/main/java/org/sopt/official/feature/navigator/NavigatorProviderIntent.kt create mode 100644 core/common/src/main/java/org/sopt/official/common/navigator/NavigatorProvider.kt create mode 100644 core/network/.gitignore create mode 100644 core/network/build.gradle.kts create mode 100644 core/network/consumer-rules.pro rename {app/src/debug/java/org/sopt/official => core/network/src/debug/java/org/sopt/official/network}/FlipperInitializer.kt (98%) create mode 100644 core/network/src/main/AndroidManifest.xml rename {app/src/main/java/org/sopt/official/data => core/network/src/main/java/org/sopt/official/network}/authenticator/SoptAuthenticator.kt (79%) create mode 100644 core/network/src/main/java/org/sopt/official/network/di/AuthModule.kt rename {app/src/main/java/org/sopt/official => core/network/src/main/java/org/sopt/official/network}/di/NetModule.kt (87%) rename {app/src/main/java/org/sopt/official => core/network/src/main/java/org/sopt/official/network}/di/SecurityModule.kt (92%) rename {app/src/main/java/org/sopt/official/data => core/network/src/main/java/org/sopt/official/network}/interceptor/AuthInterceptor.kt (95%) rename {app/src/main/java/org/sopt/official/data => core/network/src/main/java/org/sopt/official/network}/model/request/RefreshRequest.kt (96%) rename {app/src/main/java/org/sopt/official/data => core/network/src/main/java/org/sopt/official/network}/model/response/AuthResponse.kt (78%) rename {feature/auth/src/main/java/org/sopt/official/auth/data/remote => core/network/src/main/java/org/sopt/official/network}/model/response/OauthToken.kt (96%) rename {app/src/main/java/org/sopt/official/data => core/network/src/main/java/org/sopt/official/network}/persistence/SoptDataStore.kt (92%) create mode 100644 core/network/src/main/java/org/sopt/official/network/service/RefreshService.kt rename {app/src/release/java/org/sopt/official => core/network/src/release/java/org/sopt/official/network}/FlipperInitializer.kt (97%) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b2415f929..eb25feb54 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -112,6 +112,7 @@ dependencies { implementation(projects.data.soptamp) implementation(projects.core.common) implementation(projects.core.analytics) + implementation(projects.core.network) implementation(projects.feature.auth) implementation(libs.kotlin.coroutines.google.play) implementation(platform(libs.compose.bom)) diff --git a/app/src/main/java/org/sopt/official/App.kt b/app/src/main/java/org/sopt/official/App.kt index 02c984711..d94d3891b 100644 --- a/app/src/main/java/org/sopt/official/App.kt +++ b/app/src/main/java/org/sopt/official/App.kt @@ -35,7 +35,8 @@ import com.google.firebase.messaging.FirebaseMessaging import dagger.hilt.android.HiltAndroidApp import kotlinx.coroutines.launch import kotlinx.coroutines.tasks.await -import org.sopt.official.data.persistence.SoptDataStore +import org.sopt.official.network.FlipperInitializer +import org.sopt.official.network.persistence.SoptDataStore import timber.log.Timber import javax.inject.Inject diff --git a/app/src/main/java/org/sopt/official/config/messaging/SoptFirebaseMessagingService.kt b/app/src/main/java/org/sopt/official/config/messaging/SoptFirebaseMessagingService.kt index 96a940839..0fce3db24 100644 --- a/app/src/main/java/org/sopt/official/config/messaging/SoptFirebaseMessagingService.kt +++ b/app/src/main/java/org/sopt/official/config/messaging/SoptFirebaseMessagingService.kt @@ -38,7 +38,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import org.sopt.official.R -import org.sopt.official.data.persistence.SoptDataStore +import org.sopt.official.network.persistence.SoptDataStore import org.sopt.official.domain.entity.auth.UserStatus import org.sopt.official.domain.usecase.notification.RegisterPushTokenUseCase import org.sopt.official.feature.auth.AuthActivity diff --git a/app/src/main/java/org/sopt/official/data/mapper/AuthMapper.kt b/app/src/main/java/org/sopt/official/data/mapper/AuthMapper.kt new file mode 100644 index 000000000..70a93bdb1 --- /dev/null +++ b/app/src/main/java/org/sopt/official/data/mapper/AuthMapper.kt @@ -0,0 +1,41 @@ +/* + * MIT License + * Copyright 2023 SOPT - Shout Our Passion Together + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.sopt.official.data.mapper + +import org.sopt.official.domain.entity.auth.Auth +import org.sopt.official.domain.entity.auth.Token +import org.sopt.official.domain.entity.auth.UserStatus +import org.sopt.official.network.model.response.AuthResponse + +class AuthMapper { + fun toEntity(responseItem:AuthResponse) = Auth( + Token( + accessToken = responseItem.accessToken, + refreshToken = responseItem.refreshToken, + playgroundToken = responseItem.playgroundToken + ), + UserStatus.of(responseItem.status) + ) +} diff --git a/app/src/main/java/org/sopt/official/data/repository/AuthRepositoryImpl.kt b/app/src/main/java/org/sopt/official/data/repository/AuthRepositoryImpl.kt index 6089d2fd7..f84c68f47 100644 --- a/app/src/main/java/org/sopt/official/data/repository/AuthRepositoryImpl.kt +++ b/app/src/main/java/org/sopt/official/data/repository/AuthRepositoryImpl.kt @@ -24,14 +24,15 @@ */ package org.sopt.official.data.repository +import org.sopt.official.data.mapper.AuthMapper import org.sopt.official.data.model.request.LogOutRequest -import org.sopt.official.data.model.request.RefreshRequest import org.sopt.official.data.model.response.LogOutResponse import org.sopt.official.data.source.api.auth.LocalAuthDataSource import org.sopt.official.data.source.api.auth.RemoteAuthDataSource import org.sopt.official.domain.entity.auth.Token import org.sopt.official.domain.entity.auth.UserStatus import org.sopt.official.domain.repository.AuthRepository +import org.sopt.official.network.model.request.RefreshRequest import javax.inject.Inject class AuthRepositoryImpl @Inject constructor( @@ -39,7 +40,7 @@ class AuthRepositoryImpl @Inject constructor( private val localAuthDataSource: LocalAuthDataSource, ) : AuthRepository { override suspend fun refresh(token: String) = runCatching { - remoteAuthDataSource.refresh(RefreshRequest(token)).toEntity() + AuthMapper().toEntity(remoteAuthDataSource.refresh(RefreshRequest(token))) } override fun save(token: Token) { diff --git a/app/src/main/java/org/sopt/official/data/service/AuthService.kt b/app/src/main/java/org/sopt/official/data/service/AuthService.kt index 35d1bbfed..7c7603475 100644 --- a/app/src/main/java/org/sopt/official/data/service/AuthService.kt +++ b/app/src/main/java/org/sopt/official/data/service/AuthService.kt @@ -26,13 +26,11 @@ package org.sopt.official.data.service import org.sopt.official.data.model.request.AuthRequest import org.sopt.official.data.model.request.LogOutRequest -import org.sopt.official.data.model.request.RefreshRequest -import org.sopt.official.data.model.response.AuthResponse +import org.sopt.official.network.model.response.AuthResponse import org.sopt.official.data.model.response.LogOutResponse import retrofit2.http.Body import retrofit2.http.DELETE import retrofit2.http.HTTP -import retrofit2.http.PATCH import retrofit2.http.POST interface AuthService { @@ -41,11 +39,6 @@ interface AuthService { @Body body: AuthRequest ): AuthResponse - @PATCH("auth/refresh") - suspend fun refresh( - @Body body: RefreshRequest - ): AuthResponse - @DELETE("user") suspend fun withdraw() diff --git a/app/src/main/java/org/sopt/official/data/source/api/auth/RemoteAuthDataSource.kt b/app/src/main/java/org/sopt/official/data/source/api/auth/RemoteAuthDataSource.kt index 55b096fbe..039c39d88 100644 --- a/app/src/main/java/org/sopt/official/data/source/api/auth/RemoteAuthDataSource.kt +++ b/app/src/main/java/org/sopt/official/data/source/api/auth/RemoteAuthDataSource.kt @@ -25,9 +25,9 @@ package org.sopt.official.data.source.api.auth import org.sopt.official.data.model.request.LogOutRequest -import org.sopt.official.data.model.request.RefreshRequest -import org.sopt.official.data.model.response.AuthResponse +import org.sopt.official.network.model.response.AuthResponse import org.sopt.official.data.model.response.LogOutResponse +import org.sopt.official.network.model.request.RefreshRequest interface RemoteAuthDataSource { suspend fun refresh(token: RefreshRequest): AuthResponse diff --git a/app/src/main/java/org/sopt/official/data/source/impl/DefaultLocalAuthDataSource.kt b/app/src/main/java/org/sopt/official/data/source/impl/DefaultLocalAuthDataSource.kt index 39c1d2c02..4034ce0e3 100644 --- a/app/src/main/java/org/sopt/official/data/source/impl/DefaultLocalAuthDataSource.kt +++ b/app/src/main/java/org/sopt/official/data/source/impl/DefaultLocalAuthDataSource.kt @@ -24,7 +24,7 @@ */ package org.sopt.official.data.source.impl -import org.sopt.official.data.persistence.SoptDataStore +import org.sopt.official.network.persistence.SoptDataStore import org.sopt.official.data.source.api.auth.LocalAuthDataSource import org.sopt.official.domain.entity.auth.Token import org.sopt.official.domain.entity.auth.UserStatus diff --git a/app/src/main/java/org/sopt/official/data/source/impl/DefaultRemoteAuthDataSource.kt b/app/src/main/java/org/sopt/official/data/source/impl/DefaultRemoteAuthDataSource.kt index 852de8487..26d5ecf96 100644 --- a/app/src/main/java/org/sopt/official/data/source/impl/DefaultRemoteAuthDataSource.kt +++ b/app/src/main/java/org/sopt/official/data/source/impl/DefaultRemoteAuthDataSource.kt @@ -26,26 +26,27 @@ package org.sopt.official.data.source.impl import org.sopt.official.common.di.Auth import org.sopt.official.data.model.request.LogOutRequest -import org.sopt.official.data.model.request.RefreshRequest -import org.sopt.official.data.model.response.AuthResponse +import org.sopt.official.network.model.response.AuthResponse import org.sopt.official.data.model.response.LogOutResponse import org.sopt.official.data.service.AuthService import org.sopt.official.data.source.api.auth.RemoteAuthDataSource +import org.sopt.official.network.model.request.RefreshRequest +import org.sopt.official.network.service.RefreshService import javax.inject.Inject class DefaultRemoteAuthDataSource @Inject constructor( - @Auth private val service: AuthService, - @Auth(false) private val noneAuthService: AuthService, + @Auth private val authService: AuthService, + private val refreshService: RefreshService, ) : RemoteAuthDataSource { override suspend fun refresh(token: RefreshRequest): AuthResponse { - return noneAuthService.refresh(token) + return refreshService.refresh(token) } override suspend fun withdraw() { - service.withdraw() + authService.withdraw() } override suspend fun logout(request: LogOutRequest): LogOutResponse { - return service.logOut(request) + return authService.logOut(request) } } diff --git a/app/src/main/java/org/sopt/official/di/AuthModule.kt b/app/src/main/java/org/sopt/official/di/AuthModule.kt index e1da14908..e6ef0bbf6 100644 --- a/app/src/main/java/org/sopt/official/di/AuthModule.kt +++ b/app/src/main/java/org/sopt/official/di/AuthModule.kt @@ -29,10 +29,8 @@ import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent -import okhttp3.Interceptor import org.sopt.official.common.di.AppRetrofit import org.sopt.official.common.di.Auth -import org.sopt.official.data.interceptor.AuthInterceptor import org.sopt.official.data.repository.AuthRepositoryImpl import org.sopt.official.data.service.AuthService import org.sopt.official.data.source.api.auth.LocalAuthDataSource @@ -51,11 +49,6 @@ object AuthModule { @Auth fun provideAuthService(@AppRetrofit retrofit: Retrofit): AuthService = retrofit.create(AuthService::class.java) - @Provides - @Singleton - @Auth(false) - fun provideNoneAuthService(@AppRetrofit(false) retrofit: Retrofit): AuthService = retrofit.create(AuthService::class.java) - @Module @InstallIn(SingletonComponent::class) interface Binder { @@ -63,11 +56,6 @@ object AuthModule { @Singleton fun bindAuthRepository(repository: AuthRepositoryImpl): AuthRepository - @Binds - @Singleton - @Auth - fun bindAuthInterceptor(interceptor: AuthInterceptor): Interceptor - @Binds @Singleton fun bindRemoteAuthDataSource(dataSource: DefaultRemoteAuthDataSource): RemoteAuthDataSource diff --git a/app/src/main/java/org/sopt/official/di/NavigatorModule.kt b/app/src/main/java/org/sopt/official/di/NavigatorModule.kt new file mode 100644 index 000000000..ad7c64388 --- /dev/null +++ b/app/src/main/java/org/sopt/official/di/NavigatorModule.kt @@ -0,0 +1,41 @@ +/* + * MIT License + * Copyright 2023 SOPT - Shout Our Passion Together + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.sopt.official.di + +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import org.sopt.official.common.navigator.NavigatorProvider +import org.sopt.official.feature.navigator.NavigatorProviderIntent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +interface NavigationModule { + @Binds + @Singleton + fun bindNavigatorIntent(navigatorProviderIntent: NavigatorProviderIntent): NavigatorProvider +} diff --git a/app/src/main/java/org/sopt/official/feature/auth/AuthActivity.kt b/app/src/main/java/org/sopt/official/feature/auth/AuthActivity.kt index 0d2a26d42..40e44dc24 100644 --- a/app/src/main/java/org/sopt/official/feature/auth/AuthActivity.kt +++ b/app/src/main/java/org/sopt/official/feature/auth/AuthActivity.kt @@ -25,10 +25,10 @@ package org.sopt.official.feature.auth import android.animation.ObjectAnimator -import android.content.Context -import android.content.Intent import android.app.NotificationChannel import android.app.NotificationManager +import android.content.Context +import android.content.Intent import android.graphics.Paint import android.os.Bundle import android.view.animation.AnimationUtils @@ -46,16 +46,16 @@ import org.sopt.official.BuildConfig import org.sopt.official.R import org.sopt.official.auth.PlaygroundAuth import org.sopt.official.auth.data.PlaygroundAuthDatasource -import org.sopt.official.auth.data.remote.model.response.OAuthToken +import org.sopt.official.network.model.response.OAuthToken +import org.sopt.official.common.di.Auth import org.sopt.official.config.messaging.SoptFirebaseMessagingService.Companion.REMOTE_MESSAGE_EVENT_LINK import org.sopt.official.config.messaging.SoptFirebaseMessagingService.Companion.REMOTE_MESSAGE_EVENT_TYPE -import org.sopt.official.common.di.Auth import org.sopt.official.data.model.request.AuthRequest -import org.sopt.official.data.persistence.SoptDataStore import org.sopt.official.data.service.AuthService import org.sopt.official.databinding.ActivityAuthBinding import org.sopt.official.domain.entity.auth.UserStatus import org.sopt.official.feature.home.HomeActivity +import org.sopt.official.network.persistence.SoptDataStore import org.sopt.official.util.dp import org.sopt.official.util.setOnAnimationEndListener import org.sopt.official.util.setOnSingleClickListener diff --git a/app/src/main/java/org/sopt/official/feature/home/HomeActivity.kt b/app/src/main/java/org/sopt/official/feature/home/HomeActivity.kt index 7b52b7ab1..c9969f339 100644 --- a/app/src/main/java/org/sopt/official/feature/home/HomeActivity.kt +++ b/app/src/main/java/org/sopt/official/feature/home/HomeActivity.kt @@ -71,8 +71,8 @@ import org.sopt.official.util.setOnSingleClickListener import org.sopt.official.util.stringOf import org.sopt.official.util.ui.setVisible import org.sopt.official.util.viewBinding -import javax.inject.Inject import java.io.Serializable +import javax.inject.Inject @AndroidEntryPoint class HomeActivity : AppCompatActivity() { diff --git a/app/src/main/java/org/sopt/official/feature/navigator/NavigatorProviderIntent.kt b/app/src/main/java/org/sopt/official/feature/navigator/NavigatorProviderIntent.kt new file mode 100644 index 000000000..f1d68b392 --- /dev/null +++ b/app/src/main/java/org/sopt/official/feature/navigator/NavigatorProviderIntent.kt @@ -0,0 +1,39 @@ +/* + * MIT License + * Copyright 2023 SOPT - Shout Our Passion Together + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.sopt.official.feature.navigator + +import android.content.Context +import android.content.Intent +import dagger.hilt.android.qualifiers.ApplicationContext +import org.sopt.official.common.navigator.NavigatorProvider +import org.sopt.official.feature.auth.AuthActivity +import javax.inject.Inject + +class NavigatorProviderIntent @Inject constructor( + @ApplicationContext private val context: Context +) : NavigatorProvider { + override fun getAuthActivityIntent(): Intent = + AuthActivity.newInstance(context) +} diff --git a/app/src/main/java/org/sopt/official/util/Auth.kt b/app/src/main/java/org/sopt/official/util/Auth.kt index cfdfee2d2..8051f4263 100644 --- a/app/src/main/java/org/sopt/official/util/Auth.kt +++ b/app/src/main/java/org/sopt/official/util/Auth.kt @@ -24,7 +24,7 @@ */ package org.sopt.official.util -import org.sopt.official.auth.data.remote.model.response.OAuthToken +import org.sopt.official.network.model.response.OAuthToken import org.sopt.official.domain.entity.auth.Auth import org.sopt.official.domain.entity.auth.Token import org.sopt.official.domain.entity.auth.UserStatus diff --git a/app/src/test/java/org/sopt/official/datastore/SoptDataStoreTest.kt b/app/src/test/java/org/sopt/official/datastore/SoptDataStoreTest.kt index ab2ed0fce..abc3d9afb 100644 --- a/app/src/test/java/org/sopt/official/datastore/SoptDataStoreTest.kt +++ b/app/src/test/java/org/sopt/official/datastore/SoptDataStoreTest.kt @@ -34,7 +34,7 @@ import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner import org.robolectric.RuntimeEnvironment import org.robolectric.annotation.Config -import org.sopt.official.data.persistence.SoptDataStore +import org.sopt.official.network.persistence.SoptDataStore import org.sopt.official.datastore.fake.FakeAndroidKeyStore @RunWith(RobolectricTestRunner::class) diff --git a/core/common/src/main/java/org/sopt/official/common/di/Qualifiers.kt b/core/common/src/main/java/org/sopt/official/common/di/Qualifiers.kt index 454fba3d9..25a91410d 100644 --- a/core/common/src/main/java/org/sopt/official/common/di/Qualifiers.kt +++ b/core/common/src/main/java/org/sopt/official/common/di/Qualifiers.kt @@ -32,7 +32,7 @@ annotation class Logging @Qualifier @Retention(AnnotationRetention.BINARY) -annotation class Auth(val needed: Boolean = true) +annotation class Auth() @Qualifier @Retention(AnnotationRetention.BINARY) diff --git a/core/common/src/main/java/org/sopt/official/common/navigator/NavigatorProvider.kt b/core/common/src/main/java/org/sopt/official/common/navigator/NavigatorProvider.kt new file mode 100644 index 000000000..715605fc4 --- /dev/null +++ b/core/common/src/main/java/org/sopt/official/common/navigator/NavigatorProvider.kt @@ -0,0 +1,31 @@ +/* + * MIT License + * Copyright 2023 SOPT - Shout Our Passion Together + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.sopt.official.common.navigator + +import android.content.Intent + +interface NavigatorProvider { + fun getAuthActivityIntent(): Intent +} diff --git a/core/network/.gitignore b/core/network/.gitignore new file mode 100644 index 000000000..e69de29bb diff --git a/core/network/build.gradle.kts b/core/network/build.gradle.kts new file mode 100644 index 000000000..8a7a55321 --- /dev/null +++ b/core/network/build.gradle.kts @@ -0,0 +1,49 @@ +/* + * MIT License + * Copyright 2023 SOPT - Shout Our Passion Together + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed +plugins { + id("org.sopt.official.feature") +} + +android { + namespace = "org.sopt.official.network" + +} + +dependencies { + implementation(projects.core.common) + implementation(libs.security) + implementation(libs.retrofit) + implementation(libs.retrofit.kotlin.serialization.converter) + implementation(platform(libs.okhttp.bom)) + implementation(libs.okhttp.logging.interceptor) + implementation(libs.process.phoenix) + implementation(libs.timber) + debugImplementation(libs.bundles.flipper) + releaseImplementation(libs.flipper.noop) + debugImplementation(libs.flipper.network) { + exclude(group = "com.squareup.okhttp3", module = "okhttp") + } +} \ No newline at end of file diff --git a/core/network/consumer-rules.pro b/core/network/consumer-rules.pro new file mode 100644 index 000000000..e69de29bb diff --git a/app/src/debug/java/org/sopt/official/FlipperInitializer.kt b/core/network/src/debug/java/org/sopt/official/network/FlipperInitializer.kt similarity index 98% rename from app/src/debug/java/org/sopt/official/FlipperInitializer.kt rename to core/network/src/debug/java/org/sopt/official/network/FlipperInitializer.kt index 28fc209b5..2ec6a37e4 100644 --- a/app/src/debug/java/org/sopt/official/FlipperInitializer.kt +++ b/core/network/src/debug/java/org/sopt/official/network/FlipperInitializer.kt @@ -22,16 +22,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.sopt.official +package org.sopt.official.network import android.app.Application +import okhttp3.OkHttpClient + import com.facebook.flipper.android.AndroidFlipperClient import com.facebook.flipper.plugins.inspector.DescriptorMapping import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor import com.facebook.flipper.plugins.network.NetworkFlipperPlugin import com.facebook.soloader.SoLoader -import okhttp3.OkHttpClient object FlipperInitializer { private val flipperNetworkPlugin = NetworkFlipperPlugin() diff --git a/core/network/src/main/AndroidManifest.xml b/core/network/src/main/AndroidManifest.xml new file mode 100644 index 000000000..92859325b --- /dev/null +++ b/core/network/src/main/AndroidManifest.xml @@ -0,0 +1,27 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/java/org/sopt/official/data/authenticator/SoptAuthenticator.kt b/core/network/src/main/java/org/sopt/official/network/authenticator/SoptAuthenticator.kt similarity index 79% rename from app/src/main/java/org/sopt/official/data/authenticator/SoptAuthenticator.kt rename to core/network/src/main/java/org/sopt/official/network/authenticator/SoptAuthenticator.kt index 713aa4a59..6224df818 100644 --- a/app/src/main/java/org/sopt/official/data/authenticator/SoptAuthenticator.kt +++ b/core/network/src/main/java/org/sopt/official/network/authenticator/SoptAuthenticator.kt @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.sopt.official.data.authenticator +package org.sopt.official.network.authenticator import android.content.Context import com.jakewharton.processphoenix.ProcessPhoenix @@ -32,11 +32,10 @@ import okhttp3.Authenticator import okhttp3.Request import okhttp3.Response import okhttp3.Route -import org.sopt.official.common.di.Auth -import org.sopt.official.data.model.request.RefreshRequest -import org.sopt.official.data.persistence.SoptDataStore -import org.sopt.official.data.service.AuthService -import org.sopt.official.feature.auth.AuthActivity +import org.sopt.official.common.navigator.NavigatorProvider +import org.sopt.official.network.model.request.RefreshRequest +import org.sopt.official.network.persistence.SoptDataStore +import org.sopt.official.network.service.RefreshService import timber.log.Timber import javax.inject.Inject import javax.inject.Singleton @@ -44,15 +43,16 @@ import javax.inject.Singleton @Singleton class SoptAuthenticator @Inject constructor( private val dataStore: SoptDataStore, - @Auth(false) private val service: AuthService, - @ApplicationContext private val context: Context + private val refreshService: RefreshService, + @ApplicationContext private val context: Context, + private val navigatorProvider: NavigatorProvider ) : Authenticator { override fun authenticate(route: Route?, response: Response): Request? { if (response.code == 401) { val refreshToken = dataStore.refreshToken val newTokens = runCatching { runBlocking { - service.refresh(RefreshRequest(refreshToken)) + refreshService.refresh(RefreshRequest(refreshToken)) } }.onSuccess { dataStore.refreshToken = it.refreshToken @@ -61,7 +61,7 @@ class SoptAuthenticator @Inject constructor( }.onFailure { dataStore.clear() Timber.e(it) - ProcessPhoenix.triggerRebirth(context, AuthActivity.newInstance(context)) + ProcessPhoenix.triggerRebirth(context, navigatorProvider.getAuthActivityIntent()) }.getOrThrow() return response.request.newBuilder() diff --git a/core/network/src/main/java/org/sopt/official/network/di/AuthModule.kt b/core/network/src/main/java/org/sopt/official/network/di/AuthModule.kt new file mode 100644 index 000000000..86c0bf202 --- /dev/null +++ b/core/network/src/main/java/org/sopt/official/network/di/AuthModule.kt @@ -0,0 +1,55 @@ +/* + * MIT License + * Copyright 2022-2023 SOPT - Shout Our Passion Together + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.sopt.official.network.di + +import dagger.Binds +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import okhttp3.Interceptor +import org.sopt.official.common.di.AppRetrofit +import org.sopt.official.common.di.Auth +import org.sopt.official.network.interceptor.AuthInterceptor +import org.sopt.official.network.service.RefreshService +import retrofit2.Retrofit +import javax.inject.Singleton + +@InstallIn(SingletonComponent::class) +@Module +object AuthModule { + @Provides + @Singleton + fun provideNoneAuthService(@AppRetrofit(false) retrofit: Retrofit): RefreshService = retrofit.create(RefreshService::class.java) + + @Module + @InstallIn(SingletonComponent::class) + interface Binder { + @Binds + @Singleton + @Auth + fun bindAuthInterceptor(interceptor: AuthInterceptor): Interceptor + } +} diff --git a/app/src/main/java/org/sopt/official/di/NetModule.kt b/core/network/src/main/java/org/sopt/official/network/di/NetModule.kt similarity index 87% rename from app/src/main/java/org/sopt/official/di/NetModule.kt rename to core/network/src/main/java/org/sopt/official/network/di/NetModule.kt index d235bdf9a..cc602d121 100644 --- a/app/src/main/java/org/sopt/official/di/NetModule.kt +++ b/core/network/src/main/java/org/sopt/official/network/di/NetModule.kt @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.sopt.official.di +package org.sopt.official.network.di import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory import dagger.Module @@ -34,13 +34,13 @@ import okhttp3.Interceptor import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor -import org.sopt.official.BuildConfig -import org.sopt.official.FlipperInitializer +import org.sopt.official.common.BuildConfig import org.sopt.official.common.di.AppRetrofit import org.sopt.official.common.di.Auth import org.sopt.official.common.di.Logging import org.sopt.official.common.di.OperationRetrofit -import org.sopt.official.data.authenticator.SoptAuthenticator +import org.sopt.official.network.FlipperInitializer +import org.sopt.official.network.authenticator.SoptAuthenticator import retrofit2.Converter import retrofit2.Retrofit import javax.inject.Singleton @@ -48,6 +48,7 @@ import javax.inject.Singleton @InstallIn(SingletonComponent::class) @Module object NetModule { + @Logging @Provides @Singleton @@ -71,7 +72,6 @@ object NetModule { @Provides @Singleton - @Auth(false) fun provideNonAuthOkHttpClient( @Logging loggingInterceptor: Interceptor, ): OkHttpClient = OkHttpClient.Builder() @@ -100,19 +100,19 @@ object NetModule { ): Retrofit = Retrofit.Builder() .client(client) .addConverterFactory(converter) - .baseUrl(if (BuildConfig.DEBUG) BuildConfig.devApi else BuildConfig.newApi) + .baseUrl(if (BuildConfig.DEBUG) BuildConfig.SOPT_DEV_BASE_URL else BuildConfig.SOPT_BASE_URL) .build() @AppRetrofit(false) @Provides @Singleton fun provideNoneAuthAppRetrofit( - @Auth(false) client: OkHttpClient, + client: OkHttpClient, converter: Converter.Factory ): Retrofit = Retrofit.Builder() .client(client) .addConverterFactory(converter) - .baseUrl(if (BuildConfig.DEBUG) BuildConfig.devApi else BuildConfig.newApi) + .baseUrl(if (BuildConfig.DEBUG) BuildConfig.SOPT_DEV_BASE_URL else BuildConfig.SOPT_BASE_URL) .build() @OperationRetrofit @@ -124,6 +124,6 @@ object NetModule { ): Retrofit = Retrofit.Builder() .client(client) .addConverterFactory(converter) - .baseUrl(if (BuildConfig.DEBUG) BuildConfig.devOperationApi else BuildConfig.operationApi) + .baseUrl(if (BuildConfig.DEBUG) BuildConfig.SOPT_DEV_OPERATION_BASE_URL else BuildConfig.SOPT_OPERATION_BASE_URL) .build() } diff --git a/app/src/main/java/org/sopt/official/di/SecurityModule.kt b/core/network/src/main/java/org/sopt/official/network/di/SecurityModule.kt similarity index 92% rename from app/src/main/java/org/sopt/official/di/SecurityModule.kt rename to core/network/src/main/java/org/sopt/official/network/di/SecurityModule.kt index 65e14ee82..9f1e86b1f 100644 --- a/app/src/main/java/org/sopt/official/di/SecurityModule.kt +++ b/core/network/src/main/java/org/sopt/official/network/di/SecurityModule.kt @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.sopt.official.di +package org.sopt.official.network.di import android.content.Context import androidx.security.crypto.MasterKey @@ -31,7 +31,6 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent -import org.sopt.official.BuildConfig import org.sopt.official.common.di.LocalStore import javax.inject.Singleton @@ -49,5 +48,5 @@ object SecurityModule { @Provides @Singleton @LocalStore - fun provideSoptDataStoreName(): String = BuildConfig.persistenceStoreName + fun provideSoptDataStoreName(): String = "sampleKey" } diff --git a/app/src/main/java/org/sopt/official/data/interceptor/AuthInterceptor.kt b/core/network/src/main/java/org/sopt/official/network/interceptor/AuthInterceptor.kt similarity index 95% rename from app/src/main/java/org/sopt/official/data/interceptor/AuthInterceptor.kt rename to core/network/src/main/java/org/sopt/official/network/interceptor/AuthInterceptor.kt index f4a3bf681..73a4bd8b1 100644 --- a/app/src/main/java/org/sopt/official/data/interceptor/AuthInterceptor.kt +++ b/core/network/src/main/java/org/sopt/official/network/interceptor/AuthInterceptor.kt @@ -22,12 +22,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.sopt.official.data.interceptor +package org.sopt.official.network.interceptor import okhttp3.Interceptor import okhttp3.Request import okhttp3.Response -import org.sopt.official.data.persistence.SoptDataStore +import org.sopt.official.network.persistence.SoptDataStore import javax.inject.Inject class AuthInterceptor @Inject constructor( diff --git a/app/src/main/java/org/sopt/official/data/model/request/RefreshRequest.kt b/core/network/src/main/java/org/sopt/official/network/model/request/RefreshRequest.kt similarity index 96% rename from app/src/main/java/org/sopt/official/data/model/request/RefreshRequest.kt rename to core/network/src/main/java/org/sopt/official/network/model/request/RefreshRequest.kt index 97b40e402..c4e3b800d 100644 --- a/app/src/main/java/org/sopt/official/data/model/request/RefreshRequest.kt +++ b/core/network/src/main/java/org/sopt/official/network/model/request/RefreshRequest.kt @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.sopt.official.data.model.request +package org.sopt.official.network.model.request import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable diff --git a/app/src/main/java/org/sopt/official/data/model/response/AuthResponse.kt b/core/network/src/main/java/org/sopt/official/network/model/response/AuthResponse.kt similarity index 78% rename from app/src/main/java/org/sopt/official/data/model/response/AuthResponse.kt rename to core/network/src/main/java/org/sopt/official/network/model/response/AuthResponse.kt index 95b69426f..4de77ab79 100644 --- a/app/src/main/java/org/sopt/official/data/model/response/AuthResponse.kt +++ b/core/network/src/main/java/org/sopt/official/network/model/response/AuthResponse.kt @@ -22,14 +22,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.sopt.official.data.model.response +package org.sopt.official.network.model.response import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import org.sopt.official.auth.data.remote.model.response.OAuthToken -import org.sopt.official.domain.entity.auth.Auth -import org.sopt.official.domain.entity.auth.Token -import org.sopt.official.domain.entity.auth.UserStatus @Serializable data class AuthResponse( @@ -38,14 +34,6 @@ data class AuthResponse( @SerialName("playgroundToken") val playgroundToken: String, @SerialName("status") val status: String ) { - fun toEntity() = Auth( - Token( - accessToken = accessToken, - refreshToken = refreshToken, - playgroundToken = playgroundToken - ), - UserStatus.of(status) - ) fun toOAuthToken() = OAuthToken( accessToken = accessToken, diff --git a/feature/auth/src/main/java/org/sopt/official/auth/data/remote/model/response/OauthToken.kt b/core/network/src/main/java/org/sopt/official/network/model/response/OauthToken.kt similarity index 96% rename from feature/auth/src/main/java/org/sopt/official/auth/data/remote/model/response/OauthToken.kt rename to core/network/src/main/java/org/sopt/official/network/model/response/OauthToken.kt index b8be38bac..72fe2d3da 100644 --- a/feature/auth/src/main/java/org/sopt/official/auth/data/remote/model/response/OauthToken.kt +++ b/core/network/src/main/java/org/sopt/official/network/model/response/OauthToken.kt @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.sopt.official.auth.data.remote.model.response +package org.sopt.official.network.model.response import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable diff --git a/app/src/main/java/org/sopt/official/data/persistence/SoptDataStore.kt b/core/network/src/main/java/org/sopt/official/network/persistence/SoptDataStore.kt similarity index 92% rename from app/src/main/java/org/sopt/official/data/persistence/SoptDataStore.kt rename to core/network/src/main/java/org/sopt/official/network/persistence/SoptDataStore.kt index a249374fb..eb474d584 100644 --- a/app/src/main/java/org/sopt/official/data/persistence/SoptDataStore.kt +++ b/core/network/src/main/java/org/sopt/official/network/persistence/SoptDataStore.kt @@ -22,16 +22,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.sopt.official.data.persistence +package org.sopt.official.network.persistence import android.content.Context import androidx.core.content.edit import androidx.security.crypto.EncryptedSharedPreferences import androidx.security.crypto.MasterKey import dagger.hilt.android.qualifiers.ApplicationContext -import org.sopt.official.BuildConfig +import org.sopt.official.common.BuildConfig import org.sopt.official.common.di.LocalStore -import org.sopt.official.domain.entity.auth.UserStatus import timber.log.Timber import java.security.KeyStore import javax.inject.Inject @@ -87,7 +86,7 @@ class SoptDataStore @Inject constructor( } private fun deleteEncryptedPreference() { - context.deleteSharedPreferences(BuildConfig.persistenceStoreName) + context.deleteSharedPreferences("sampleKey") } fun clear() { @@ -110,7 +109,7 @@ class SoptDataStore @Inject constructor( var userStatus: String set(value) = store.edit { putString(USER_STATUS, value) } - get() = store.getString(USER_STATUS, UserStatus.UNAUTHENTICATED.value) ?: UserStatus.UNAUTHENTICATED.value + get() = store.getString(USER_STATUS, UNAUTHENTICATED) ?: UNAUTHENTICATED var pushToken: String set(value) = store.edit { putString(PUSH_TOKEN, value) } @@ -125,5 +124,7 @@ class SoptDataStore @Inject constructor( private const val KEY_ALIAS_AUTH = "alias.preferences.auth_token" private const val ANDROID_KEY_STORE = "AndroidKeyStore" private const val PUSH_TOKEN = "push_token" + private const val UNAUTHENTICATED="UNAUTHENTICATED" + } } diff --git a/core/network/src/main/java/org/sopt/official/network/service/RefreshService.kt b/core/network/src/main/java/org/sopt/official/network/service/RefreshService.kt new file mode 100644 index 000000000..762be185c --- /dev/null +++ b/core/network/src/main/java/org/sopt/official/network/service/RefreshService.kt @@ -0,0 +1,38 @@ +/* + * MIT License + * Copyright 2023 SOPT - Shout Our Passion Together + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.sopt.official.network.service + + +import org.sopt.official.network.model.request.RefreshRequest +import org.sopt.official.network.model.response.AuthResponse +import retrofit2.http.Body +import retrofit2.http.PATCH + +interface RefreshService { + @PATCH("auth/refresh") + suspend fun refresh( + @Body body: RefreshRequest + ): AuthResponse +} diff --git a/app/src/release/java/org/sopt/official/FlipperInitializer.kt b/core/network/src/release/java/org/sopt/official/network/FlipperInitializer.kt similarity index 97% rename from app/src/release/java/org/sopt/official/FlipperInitializer.kt rename to core/network/src/release/java/org/sopt/official/network/FlipperInitializer.kt index e4794d8dd..7413f9678 100644 --- a/app/src/release/java/org/sopt/official/FlipperInitializer.kt +++ b/core/network/src/release/java/org/sopt/official/network/FlipperInitializer.kt @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package org.sopt.official +package org.sopt.official.network import android.app.Application import okhttp3.OkHttpClient diff --git a/feature/auth/build.gradle.kts b/feature/auth/build.gradle.kts index 0d22769ef..c7d6d897a 100644 --- a/feature/auth/build.gradle.kts +++ b/feature/auth/build.gradle.kts @@ -34,6 +34,7 @@ android { dependencies { implementation(projects.core.common) + implementation(projects.core.network) implementation(libs.customtab) implementation(libs.retrofit) implementation(libs.retrofit.kotlin.serialization.converter) diff --git a/feature/auth/src/main/java/org/sopt/official/auth/PlaygroundAuth.kt b/feature/auth/src/main/java/org/sopt/official/auth/PlaygroundAuth.kt index 386428d65..21984fc53 100644 --- a/feature/auth/src/main/java/org/sopt/official/auth/PlaygroundAuth.kt +++ b/feature/auth/src/main/java/org/sopt/official/auth/PlaygroundAuth.kt @@ -33,7 +33,7 @@ import kotlinx.coroutines.launch import org.sopt.official.auth.data.PlaygroundApiManager import org.sopt.official.auth.data.PlaygroundAuthDatasource import org.sopt.official.auth.data.RemotePlaygroundAuthDatasource -import org.sopt.official.auth.data.remote.model.response.OAuthToken +import org.sopt.official.network.model.response.OAuthToken import org.sopt.official.auth.utils.PlaygroundUriProvider object PlaygroundAuth { diff --git a/feature/auth/src/main/java/org/sopt/official/auth/data/PlaygroundAuthDatasource.kt b/feature/auth/src/main/java/org/sopt/official/auth/data/PlaygroundAuthDatasource.kt index 51f1cce8a..648d39d34 100644 --- a/feature/auth/src/main/java/org/sopt/official/auth/data/PlaygroundAuthDatasource.kt +++ b/feature/auth/src/main/java/org/sopt/official/auth/data/PlaygroundAuthDatasource.kt @@ -24,7 +24,7 @@ */ package org.sopt.official.auth.data -import org.sopt.official.auth.data.remote.model.response.OAuthToken +import org.sopt.official.network.model.response.OAuthToken interface PlaygroundAuthDatasource { suspend fun oauth(code: String): Result diff --git a/feature/auth/src/main/java/org/sopt/official/auth/data/RemotePlaygroundAuthDatasource.kt b/feature/auth/src/main/java/org/sopt/official/auth/data/RemotePlaygroundAuthDatasource.kt index d7483b18f..31df17ad4 100644 --- a/feature/auth/src/main/java/org/sopt/official/auth/data/RemotePlaygroundAuthDatasource.kt +++ b/feature/auth/src/main/java/org/sopt/official/auth/data/RemotePlaygroundAuthDatasource.kt @@ -27,7 +27,7 @@ package org.sopt.official.auth.data import org.sopt.official.auth.PlaygroundError import org.sopt.official.auth.data.remote.AuthService import org.sopt.official.auth.data.remote.model.request.RequestToken -import org.sopt.official.auth.data.remote.model.response.OAuthToken +import org.sopt.official.network.model.response.OAuthToken import org.sopt.official.common.di.Auth import java.net.UnknownHostException diff --git a/feature/auth/src/main/java/org/sopt/official/auth/data/remote/AuthService.kt b/feature/auth/src/main/java/org/sopt/official/auth/data/remote/AuthService.kt index 1aae99cdd..d0f41b812 100644 --- a/feature/auth/src/main/java/org/sopt/official/auth/data/remote/AuthService.kt +++ b/feature/auth/src/main/java/org/sopt/official/auth/data/remote/AuthService.kt @@ -25,7 +25,7 @@ package org.sopt.official.auth.data.remote import org.sopt.official.auth.data.remote.model.request.RequestToken -import org.sopt.official.auth.data.remote.model.response.OAuthToken +import org.sopt.official.network.model.response.OAuthToken import retrofit2.http.Body import retrofit2.http.POST diff --git a/settings.gradle.kts b/settings.gradle.kts index 585858f55..8bd48ddc9 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -18,10 +18,11 @@ dependencyResolutionManagement { rootProject.name = "SOPT" include( ":app", - ":feature:soptamp", + ":domain:soptamp", + ":data:soptamp", + ":core:network", ":core:analytics", ":core:common", - ":feature:auth" + ":feature:auth", + ":feature:soptamp" ) -include(":data:soptamp") -include(":domain:soptamp")