Skip to content

Commit

Permalink
Merge branch 'develop' into feature/360
Browse files Browse the repository at this point in the history
  • Loading branch information
HamBP committed Jan 12, 2025
2 parents 29514c9 + 5e41055 commit b8fae1b
Show file tree
Hide file tree
Showing 100 changed files with 2,030 additions and 1,437 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.nexters.boolti.data.datasource

import javax.inject.Inject

internal class AuthTokenDataSource @Inject constructor(
private val authDataSource: AuthDataSource,
private val tokenDataSource: TokenDataSource,
) {
suspend fun getNewAccessToken(): String? {
val response = authDataSource.refresh()
val newToken = response.getOrNull()
return newToken?.let {
tokenDataSource.saveTokens(
accessToken = it.accessToken,
refreshToken = it.refreshToken,
)
it.accessToken
} ?: run {
authDataSource.logout()
null
}
}
}
11 changes: 11 additions & 0 deletions data/src/main/java/com/nexters/boolti/data/di/DataSourceModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.nexters.boolti.data.di
import android.content.Context
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
import com.nexters.boolti.data.datasource.AuthDataSource
import com.nexters.boolti.data.datasource.AuthTokenDataSource
import com.nexters.boolti.data.datasource.PolicyDataSource
import com.nexters.boolti.data.datasource.RemoteConfigDataSource
import com.nexters.boolti.data.datasource.TokenDataSource
Expand Down Expand Up @@ -33,6 +34,16 @@ internal object DataSourceModule {
@Provides
fun provideTokenDataSource(@ApplicationContext context: Context): TokenDataSource = TokenDataSource(context)

@Singleton
@Provides
fun provideAuthTokenDataSource(
authDataSource: AuthDataSource,
tokenDataSource: TokenDataSource,
): AuthTokenDataSource = AuthTokenDataSource(
authDataSource = authDataSource,
tokenDataSource = tokenDataSource,
)

@Singleton
@Provides
fun providePolicyDataSource(@ApplicationContext context: Context): PolicyDataSource = PolicyDataSource(context)
Expand Down
27 changes: 17 additions & 10 deletions data/src/main/java/com/nexters/boolti/data/di/NetworkModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.nexters.boolti.data.di

import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import com.nexters.boolti.data.BuildConfig
import com.nexters.boolti.data.datasource.AuthDataSource
import com.nexters.boolti.data.datasource.AuthTokenDataSource
import com.nexters.boolti.data.datasource.TokenDataSource
import com.nexters.boolti.data.network.AuthAuthenticator
import com.nexters.boolti.data.network.AuthInterceptor
Expand Down Expand Up @@ -114,7 +114,8 @@ internal object NetworkModule {

@Singleton
@Provides
fun provideTicketingService(@Named("auth") retrofit: Retrofit): TicketingService = retrofit.create()
fun provideTicketingService(@Named("auth") retrofit: Retrofit): TicketingService =
retrofit.create()

@Singleton
@Provides
Expand All @@ -126,28 +127,34 @@ internal object NetworkModule {

@Singleton
@Provides
fun provideReservationService(@Named("auth") retrofit: Retrofit): ReservationService = retrofit.create()
fun provideReservationService(@Named("auth") retrofit: Retrofit): ReservationService =
retrofit.create()

@Singleton
@Provides
fun provideHostService(@Named("auth") retrofit: Retrofit): HostService = retrofit.create()

@Singleton
@Provides
fun provideAuthFileService(@Named("auth") retrofit: Retrofit): AuthFileService = retrofit.create()
fun provideAuthFileService(@Named("auth") retrofit: Retrofit): AuthFileService =
retrofit.create()

@Singleton
@Provides
fun provideFileService(@Named("non-auth") retrofit: Retrofit): FileService = retrofit.create()

@Singleton
@Provides
fun provideMemberService(@Named("non-auth") retrofit: Retrofit): MemberService = retrofit.create()
fun provideMemberService(@Named("non-auth") retrofit: Retrofit): MemberService =
retrofit.create()

@Singleton
@Provides
@Named("auth")
fun provideAuthOkHttpClient(interceptor: AuthInterceptor, authenticator: AuthAuthenticator): OkHttpClient {
fun provideAuthOkHttpClient(
interceptor: AuthInterceptor,
authenticator: AuthAuthenticator
): OkHttpClient {
val loggingInterceptor = HttpLoggingInterceptor().apply {
level = if (BuildConfig.DEBUG) {
HttpLoggingInterceptor.Level.BODY
Expand Down Expand Up @@ -202,12 +209,12 @@ internal object NetworkModule {

@Singleton
@Provides
fun provideAuthInterceptor(tokenDataSource: TokenDataSource): AuthInterceptor = AuthInterceptor(tokenDataSource)
fun provideAuthInterceptor(tokenDataSource: TokenDataSource): AuthInterceptor =
AuthInterceptor(tokenDataSource)

@Singleton
@Provides
fun provideAuthenticator(
tokenDataSource: TokenDataSource,
authDataSource: AuthDataSource,
): AuthAuthenticator = AuthAuthenticator(tokenDataSource, authDataSource)
authTokenDataSource: AuthTokenDataSource
): AuthAuthenticator = AuthAuthenticator(authTokenDataSource)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.nexters.boolti.data.network

import com.nexters.boolti.data.datasource.AuthDataSource
import com.nexters.boolti.data.datasource.TokenDataSource
import com.nexters.boolti.data.datasource.AuthTokenDataSource
import kotlinx.coroutines.runBlocking
import okhttp3.Authenticator
import okhttp3.Request
Expand All @@ -10,27 +9,11 @@ import okhttp3.Route
import javax.inject.Inject

internal class AuthAuthenticator @Inject constructor(
private val tokenDataSource: TokenDataSource,
private val authDataSource: AuthDataSource,
private val authTokenDataSource: AuthTokenDataSource,
) : Authenticator {
override fun authenticate(route: Route?, response: Response): Request? {
val accessToken = runBlocking { getNewAccessToken() } ?: return null
val accessToken = runBlocking { authTokenDataSource.getNewAccessToken() } ?: return null

return response.request.newBuilder().header("Authorization", "Bearer $accessToken").build()
}

private suspend fun getNewAccessToken(): String? {
val response = authDataSource.refresh()
val newToken = response.getOrNull()
return newToken?.let {
tokenDataSource.saveTokens(
accessToken = it.accessToken,
refreshToken = it.refreshToken,
)
it.accessToken
} ?: run {
authDataSource.logout()
null
}
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package com.nexters.boolti.data.repository

import com.nexters.boolti.data.datasource.AuthDataSource
import com.nexters.boolti.data.datasource.AuthTokenDataSource
import com.nexters.boolti.data.datasource.DeviceTokenDataSource
import com.nexters.boolti.data.datasource.SignUpDataSource
import com.nexters.boolti.data.datasource.TokenDataSource
import com.nexters.boolti.data.datasource.UserDataSource
import com.nexters.boolti.data.network.response.LoginResponse
import com.nexters.boolti.domain.model.AccessToken
import com.nexters.boolti.domain.model.LoginUserState
import com.nexters.boolti.domain.model.TokenPair
import com.nexters.boolti.domain.model.TokenPairs
import com.nexters.boolti.domain.model.User
import com.nexters.boolti.domain.repository.AuthRepository
import com.nexters.boolti.domain.request.EditProfileRequest
Expand All @@ -23,6 +25,7 @@ import javax.inject.Inject
internal class AuthRepositoryImpl @Inject constructor(
private val authDataSource: AuthDataSource,
private val tokenDataSource: TokenDataSource,
private val authTokenDataSource: AuthTokenDataSource,
private val signUpDataSource: SignUpDataSource,
private val userDateSource: UserDataSource,
private val deviceTokenDataSource: DeviceTokenDataSource,
Expand Down Expand Up @@ -72,7 +75,13 @@ internal class AuthRepositoryImpl @Inject constructor(
.onSuccess { authDataSource.updateUser(it) }
.mapCatching {}

override fun getTokens(): Flow<TokenPair> = authDataSource.getTokens().map {
TokenPair(it.first, it.second)
override fun getTokens(): Flow<TokenPairs> = authDataSource.getTokens().map {
TokenPairs(it.first, it.second)
}

override fun refreshToken(): Flow<AccessToken> = flow {
authTokenDataSource.getNewAccessToken()?.let {
emit(AccessToken(it))
}
}
}
3 changes: 3 additions & 0 deletions domain/src/main/java/com/nexters/boolti/domain/model/Sns.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.nexters.boolti.domain.model

import kotlinx.serialization.Serializable

data class Sns(
val id: String,
val type: SnsType,
val username: String,
) {
@Serializable
enum class SnsType {
INSTAGRAM, YOUTUBE;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package com.nexters.boolti.domain.model

data class TokenPair(
data class TokenPairs(
val accessToken: String,
val refreshToken: String,
) {
val isLoggedIn: Boolean = accessToken.isNotBlank() && refreshToken.isNotBlank()
}

@JvmInline
value class AccessToken(val token: String)

@JvmInline
value class RefreshToken(val token: String)
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package com.nexters.boolti.domain.repository

import com.nexters.boolti.domain.model.AccessToken
import com.nexters.boolti.domain.model.LoginUserState
import com.nexters.boolti.domain.model.TokenPair
import com.nexters.boolti.domain.model.TokenPairs
import com.nexters.boolti.domain.model.User
import com.nexters.boolti.domain.request.EditProfileRequest
import com.nexters.boolti.domain.request.LoginRequest
Expand Down Expand Up @@ -30,5 +31,7 @@ interface AuthRepository {

suspend fun editProfile(editProfileRequest: EditProfileRequest): Result<Unit>

fun getTokens(): Flow<TokenPair>
fun getTokens(): Flow<TokenPairs>
fun refreshToken(): Flow<AccessToken>
}

6 changes: 4 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[versions]
minSdk = "26"
targetSdk = "34"
versionCode = "31"
versionName = "1.9.1"
versionCode = "32"
versionName = "1.9.2"
packageName = "com.nexters.boolti"
compileSdk = "34"
targetJvm = "17"
Expand Down Expand Up @@ -48,6 +48,7 @@ timber = "5.0.1"
mockk = "1.13.8"
tosspayments = "0.1.15"
immutable = "0.3.7"
reorderable = "0.9.6"

[libraries]
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "activity-ktx" }
Expand Down Expand Up @@ -115,6 +116,7 @@ retrofit2-kotlinx-serialization-converter = { module = "com.jakewharton.retrofit
timber = { module = "com.jakewharton.timber:timber", version.ref = "timber" }
mockk = { group = "io.mockk", name = "mockk", version.ref = "mockk" }
immutable = { group = "org.jetbrains.kotlinx", name = "kotlinx-collections-immutable", version.ref = "immutable" }
reorderable = { group = "org.burnoutcrew.composereorderable", name = "reorderable", version.ref = "reorderable" }

[plugins]
android-application = { id = "com.android.application", version.ref = "android" }
Expand Down
5 changes: 5 additions & 0 deletions presentation/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.hilt)
alias(libs.plugins.kotlin.serialization)
id("kotlin-kapt")
id("kotlin-parcelize")
}
Expand Down Expand Up @@ -78,17 +79,21 @@ dependencies {

implementation(libs.hilt.android)
implementation(libs.androidx.hilt.navigation.compose)
implementation(libs.kotlinx.serialization.json)
implementation(libs.androidx.material3.android)
implementation(libs.zoomable)
kapt(libs.hilt.compiler)

implementation(libs.kotlinx.serialization.json)

implementation(libs.lottie)
implementation(libs.bundles.coil)
api(libs.kakao.login)
implementation(libs.kakao.share)

implementation(libs.timber)
implementation(libs.zxing.android.embedded)
implementation(libs.reorderable)

androidTestImplementation(libs.bundles.android.test)
androidTestImplementation(platform(libs.andoridx.compose.compose.bom))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ import android.Manifest
import android.content.Context
import android.hardware.Camera
import android.os.Build
import android.graphics.Color
import android.os.Bundle
import android.os.VibrationEffect
import android.os.Vibrator
import android.os.VibratorManager
import android.view.KeyEvent
import androidx.activity.ComponentActivity
import androidx.activity.SystemBarStyle
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
Expand Down Expand Up @@ -76,6 +79,8 @@ class QrScanActivity : ComponentActivity() {

requestPermission(Manifest.permission.CAMERA, 100)

enableEdgeToEdge(statusBarStyle = SystemBarStyle.dark(Color.TRANSPARENT))

setContent {
BooltiTheme {
QrScanScreen(
Expand Down
Loading

0 comments on commit b8fae1b

Please sign in to comment.