Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/mz 150 kakao login #19

Merged
merged 60 commits into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
d7cf053
chore: Timber Tree ์‹ฌ๊ธฐ
yangsooplus Dec 20, 2023
9e628a0
feat: kakao user sdk ์„ค์ •
yangsooplus Dec 20, 2023
c7fabab
feat: SplashContract ์ •์˜ ํ›„ SplashViewModel ๊ตฌํ˜„
yangsooplus Dec 20, 2023
136f96f
feat: kakao login ๊ตฌํ˜„
yangsooplus Dec 21, 2023
2570023
feat: ์ˆ˜์ˆ˜ auth api ์ธ์ฆ
yangsooplus Dec 21, 2023
7001066
refactor: domain์— KakaoLoginProvider ์ธํ„ฐํŽ˜์ด์Šค ์ถ”๊ฐ€
yangsooplus Dec 21, 2023
10497e5
fix: ์ˆ˜์ˆ˜ auth ๊ด€๋ จ ๋ˆ„๋ฝ ํŒŒ์ผ ์ถ”๊ฐ€
yangsooplus Dec 21, 2023
2f08e65
fix: ์ž˜๋ชป ์ž…๋ ฅํ•œ api ๋ช…์„ธ ์ˆ˜์ •
yangsooplus Dec 21, 2023
1af5735
fix: api ๋ณ€๊ฒฝ์— ๋”ฐ๋ฅธ user ํ”„๋กœํผํ‹ฐ ๋ณ€๊ฒฝ
yangsooplus Dec 21, 2023
5c04416
feat: SplashViewModel ์ˆ˜์ˆ˜ ํ† ํฐ ๋กœ์ง ์ถ”๊ฐ€
yangsooplus Dec 21, 2023
f7cdfbd
refactor: TokenRepository ์ €์žฅ ์‹œ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ Token ์‚ฌ์šฉ
yangsooplus Dec 21, 2023
a08f9d7
chore: AuthRepository.kt -> AuthRepositoryImpl.kt rename
yangsooplus Dec 21, 2023
323935e
chore: KakaoLoginProvider.kt -> KakaoLoginProviderImpl.kt rename
yangsooplus Dec 21, 2023
732dba5
feat: LoginContract, LoginViewModel ์ถ”๊ฐ€
yangsooplus Dec 21, 2023
e6ae3c3
feat: Kakao di Module ์ถ”๊ฐ€
yangsooplus Dec 21, 2023
0a42e76
chore: feature plugin์— hilt.navigation.compose ์˜์กด์„ฑ ์ถ”๊ฐ€
yangsooplus Dec 21, 2023
230df72
fix: Repository di ๋ถˆ๊ฐ€ ์˜ค๋ฅ˜ ํ•ด๊ฒฐ
yangsooplus Dec 22, 2023
2b9d07e
feat: ์นด์นด์˜ค accessToken ์ ‘๊ทผ ์ฝ”๋“œ ์ถ”๊ฐ€
yangsooplus Dec 22, 2023
2972865
refactor: Splash์™€ Login์„ Login์— ํ†ตํ•ฉ
yangsooplus Dec 22, 2023
765bc7f
fix: Authenticator๋ฅผ token ์žฌ๋ฐœํ–‰์„ authRepository๋กœ ์ด๋™ํ•จ์— ๋”ฐ๋ผ ์ˆ˜์ •
yangsooplus Dec 22, 2023
9e17f10
feat: ๊ธฐ๋Šฅ ํ…Œ์ŠคํŠธ UI ์ถ”๊ฐ€
yangsooplus Dec 22, 2023
5f72d06
fix: hilt ์ˆœํ™˜ ์ฐธ์กฐ ์ œ๊ฑฐ
yangsooplus Dec 22, 2023
6960045
chore: ์นด์นด์˜ค ๋กœ๊ทธ์ธ ํ…Œ์ŠคํŠธ์šฉ ๋กœ๊ทธ ์ถ”๊ฐ€
yangsooplus Dec 22, 2023
7a2867e
fix: api ๋ช…์„ธ ํ˜•์‹ ํ‹€๋ฆฐ ๋ถ€๋ถ„ ์ˆ˜์ •
yangsooplus Dec 22, 2023
5bcd5dd
fix: ActivityContext๊ฐ€ ํ•„์š”ํ•œ ๋กœ๊ทธ์ธ ๋™์ž‘์„ ๋ถ„๋ฆฌ
yangsooplus Dec 22, 2023
cebb823
fix: token ์ €์žฅ์„ ์™„๋ฃŒํ•  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ
yangsooplus Dec 26, 2023
7f09a87
refactor: encrpted-datastore๋กœ ๊ต์ฒด
yangsooplus Dec 26, 2023
2cc691a
fix: kakao token ๋งŒ๋ฃŒ ์ฒดํฌ ํ›„ ์ˆ˜์ˆ˜ ๋กœ๊ทธ์ธ ์‹œ๋„ํ•˜๋„๋ก ์ˆ˜์ •
yangsooplus Dec 26, 2023
5d533b9
feat: ApiService์— ์ˆ˜์ˆ˜ ํšŒ์› ํƒˆํ‡ด ์ถ”๊ฐ€
yangsooplus Dec 26, 2023
ca2e3f5
feat: login, signup nested navigation ์ง€์ •
yangsooplus Dec 26, 2023
286ac14
fix: ์ˆ˜์ˆ˜ ํ† ํฐ ํ—ค๋” ํ˜•์‹ ์ˆ˜์ •
yangsooplus Dec 26, 2023
2c8aad0
feat: ๊ธฐ๋Šฅ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ์ž„์‹œ UI ์ฝ”๋“œ
yangsooplus Dec 26, 2023
04d9e01
chore: hilt-navigation-compose ์˜์กด์„ฑ ์œ„์น˜ ๋ณ€๊ฒฝ
yangsooplus Dec 26, 2023
1a7748d
chore: kakao sdk ๊ด€๋ จ ํŒŒ์ผ social ํŒจํ‚ค์ง€๋กœ ์ด๋™
yangsooplus Dec 26, 2023
08dde4e
chore: ๊ธฐ์กด ์•”ํ˜ธํ™” DataStore ์ฝ”๋“œ ์‚ญ์ œ
yangsooplus Dec 26, 2023
076999a
chore: detekt ํ˜•์‹ ๋งž์ถค
yangsooplus Dec 26, 2023
98c82af
chore: gitignore์— report, google-service.json ์ถ”๊ฐ€
yangsooplus Dec 26, 2023
3d4db6c
chore: ktlint trailing comma check
yangsooplus Dec 26, 2023
66a84c9
chore: ktlint Import order check
yangsooplus Dec 26, 2023
3a3a014
chore: local.properties๋กœ ์นด์นด์˜ค ์•ฑ ํ‚ค ์ด๋™
yangsooplus Dec 31, 2023
74f23eb
fix: mergeํ•˜๋ฉฐ ๋ˆ„๋ฝ๋œ plugin ๋ณต๊ตฌ
yangsooplus Dec 31, 2023
1dc7860
feat: LoggingInterceptor level ์„ค์ • ๋ฐ di
yangsooplus Dec 31, 2023
84df3e7
refactor: kakao sdk ์‹ฑ๊ธ€ํ†ค ๊ต์ฒด ๋ฐ di ์ฝ”๋“œ ์‚ญ์ œ
yangsooplus Dec 31, 2023
2e18684
refactor: NetworkModule์—์„œ service ๋ถ„๋ฆฌ
yangsooplus Dec 31, 2023
af6d54f
refactor: Service ๋„ค์ด๋ฐ ์ˆ˜์ •
yangsooplus Dec 31, 2023
5d585ab
chore: Contract ํƒ€์ž… class -> sealed interface
yangsooplus Dec 31, 2023
6128d67
chore: sns -> oauth ๋„ค์ด๋ฐ ๋ณ€๊ฒฝ
yangsooplus Dec 31, 2023
9f16e97
chore: gitignore์— idea ํด๋” ์ถ”๊ฐ€
yangsooplus Dec 31, 2023
67a4348
refactor: TokenEntity -> TokenResponse ๋„ค์ด๋ฐ ๋ณ€๊ฒฝ๊ณผ ์œ ํšจ๊ธฐ๊ฐ„ ํ”„๋กœํผํ‹ฐ ์ œ๊ฑฐ
yangsooplus Jan 2, 2024
449c04c
refactor: UserEntity -> UserRequest
yangsooplus Jan 2, 2024
4ad776b
refactor: AuthRepository๋ฅผ Login๊ณผ SignUp์œผ๋กœ ๋ถ„๋ฆฌ
yangsooplus Jan 2, 2024
722b085
refactor: ๋กœ๊ทธ์ธ/ํšŒ์›๊ฐ€์ž… ๋™์ž‘ ๊ด€๋ จ Usecase ์ถ”๊ฐ€
yangsooplus Jan 2, 2024
60675d5
feat: SplashScreen Api ์ ์šฉ
yangsooplus Jan 2, 2024
5f5b40e
feat: ์•ฑ ์‹คํ–‰ ๋ฐ์ดํ„ฐ ์ž‘์—… ์ค‘์— SplashScreen์„ ๊ณ„์† ๋ณด์ด๋„๋ก ์„ค์ •
yangsooplus Jan 2, 2024
e21b8a0
feat: Splash๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ  ๋‚œ ๋’ค, ์œ ์ € ๋ฐ์ดํ„ฐ์— ๋”ฐ๋ผ ํ™”๋ฉด ์ด๋™
yangsooplus Jan 2, 2024
8928f59
refactor: TestScreen์˜ ๋™์ž‘์„ MyPage๋กœ ์˜ฎ๊น€
yangsooplus Jan 2, 2024
846ade5
feat: ์นด์นด์˜ค ๋กœ๊ทธ์ธ ํ›„ ํšŒ์›๊ฐ€์ž… ์ดํƒˆ ์œ ์ €๋Š” ํšŒ์›๊ฐ€์ž… ํ™”๋ฉด์œผ๋กœ ์ด๋™
yangsooplus Jan 2, 2024
d4e1d00
chore: detekt๊ฐ€ apiKey๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ null check ๋ฌด์‹œ
yangsooplus Jan 2, 2024
d0c87bb
fix: ์นด์นด์˜ค๊ณ„์ • ๋กœ๊ทธ์ธ ํ›„ ์ง„ํ–‰ ์•ˆ๋˜๋Š” ๋ฌธ์ œ ์ˆ˜์ •
yangsooplus Jan 2, 2024
d6f69ac
chore: detekt ์ˆ˜์ •์‚ฌํ•ญ ๋ฐ˜์˜
yangsooplus Jan 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ obj/
/out/

# User-specific configurations
/.idea
.idea/caches/
.idea/libraries/
.idea/shelf/
Expand Down Expand Up @@ -153,4 +154,7 @@ fabric.properties

!/gradle/wrapper/gradle-wrapper.jar

# End of https://www.toptal.com/developers/gitignore/api/androidstudio,kotlin
# Compose-Report
/report

# End of https://www.toptal.com/developers/gitignore/api/androidstudio,kotlin
3 changes: 2 additions & 1 deletion app/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/build
/build
google-services.json
14 changes: 14 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties

@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
plugins {
alias(libs.plugins.susu.android.application)
Expand All @@ -13,15 +15,27 @@ android {
applicationId = "com.oksusu.susu"
versionCode = 1
versionName = "1.0"
buildConfigField("String", "KAKAO_APP_KEY", getApiKey("KAKAO_APP_KEY"))
}

buildFeatures {
buildConfig = true
}
}

dependencies {
implementation(projects.feature.navigator)
implementation(projects.data)
implementation(libs.kakao.sdk.user)

implementation(platform(libs.firebase.bom))
implementation(libs.firebase.crashlytics)
implementation(libs.firebase.analytics)

implementation(libs.timber)
}

@Suppress
fun getApiKey(propertyKey: String): String {
return gradleLocalProperties(rootDir).getProperty(propertyKey)
}
3 changes: 2 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
xmlns:tools="http://schemas.android.com/tools"
package="com.oksusu.susu">
yangsooplus marked this conversation as resolved.
Show resolved Hide resolved
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:name=".SUSUApplication"
Expand Down
9 changes: 9 additions & 0 deletions app/src/main/java/com/oksusu/susu/CustomTimberTree.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.oksusu.susu

import timber.log.Timber

class CustomTimberTree : Timber.DebugTree() {
override fun createStackElementTag(element: StackTraceElement): String? {
return "${element.className}:${element.lineNumber}#${element.methodName}"
}
}
14 changes: 13 additions & 1 deletion app/src/main/java/com/oksusu/susu/SUSUApplication.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
package com.oksusu.susu

import android.app.Application
import com.kakao.sdk.common.KakaoSdk
import dagger.hilt.android.HiltAndroidApp
import timber.log.Timber

@HiltAndroidApp
class SUSUApplication : Application()
class SUSUApplication : Application() {
override fun onCreate() {
super.onCreate()

if (BuildConfig.DEBUG) {
Timber.plant(CustomTimberTree())
}

KakaoSdk.init(this, BuildConfig.KAKAO_APP_KEY)
}
}
6 changes: 6 additions & 0 deletions core/model/src/main/java/com/susu/core/model/Token.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.susu.core.model

data class Token(
val accessToken: String,
val refreshToken: String,
)
7 changes: 7 additions & 0 deletions core/model/src/main/java/com/susu/core/model/User.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.susu.core.model

data class User(
val name: String,
val gender: String,
val birth: Int,
)
27 changes: 27 additions & 0 deletions data/src/main/java/com/susu/data/di/DataStoreModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ import androidx.datastore.preferences.core.PreferenceDataStoreFactory
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.emptyPreferences
import androidx.datastore.preferences.preferencesDataStoreFile
import com.susu.data.security.SecurityPreferences
import com.susu.data.security.generateSecurityPreferences
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import tech.thdev.useful.encrypted.data.store.preferences.security.generateUsefulSecurity
import javax.inject.Qualifier
import javax.inject.Singleton

@InstallIn(SingletonComponent::class)
Expand All @@ -29,5 +33,28 @@ object DataStoreModule {
)
}

@EncryptedDataStore
@Singleton
@Provides
fun providedEncryptedDataStore(@ApplicationContext context: Context): DataStore<Preferences> {
return PreferenceDataStoreFactory.create(
corruptionHandler = ReplaceFileCorruptionHandler(
produceNewData = { emptyPreferences() },
),
produceFile = { context.preferencesDataStoreFile(ENCRYPTED_DATASTORE_NAME) },
)
}

@Singleton
@Provides
fun provideSecurityPreference(
@EncryptedDataStore dataStore: DataStore<Preferences>,
): SecurityPreferences = dataStore.generateSecurityPreferences(generateUsefulSecurity())

private const val DATASTORE_NAME = "susu-datastore"
private const val ENCRYPTED_DATASTORE_NAME = "susu-datastore-encrypted"
}

@Qualifier
@Retention(AnnotationRetention.BINARY)
internal annotation class EncryptedDataStore
67 changes: 45 additions & 22 deletions data/src/main/java/com/susu/data/di/NetworkModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,36 +23,38 @@ import javax.inject.Singleton
@InstallIn(SingletonComponent::class)
object NetworkModule {

private const val BASE_URL = ""
private const val BASE_URL = "https://api.oksusu.site/api/v1/"

@Singleton
@Provides
fun provideOkHttpClient(
tokenInterceptor: TokenInterceptor,
tokenAuthenticator: TokenAuthenticator,
fun provideLoggingInterceptor(
json: Json,
): OkHttpClient {
val loggingInterceptor = HttpLoggingInterceptor { message ->
when {
!message.isJsonObject() && !message.isJsonArray() ->
Timber.tag(RETROFIT_TAG).d("CONNECTION INFO -> $message")
): HttpLoggingInterceptor = HttpLoggingInterceptor { message ->
when {
!message.isJsonObject() && !message.isJsonArray() ->
Timber.tag(RETROFIT_TAG).d("CONNECTION INFO -> $message")

else -> kotlin.runCatching {
json.encodeToString(Json.parseToJsonElement(message))
}.onSuccess {
Timber.tag(RETROFIT_TAG).d(it)
}.onFailure {
Timber.tag(RETROFIT_TAG).d(message)
}
else -> kotlin.runCatching {
json.encodeToString(Json.parseToJsonElement(message))
}.onSuccess {
Timber.tag(RETROFIT_TAG).d(it)
}.onFailure {
Timber.tag(RETROFIT_TAG).d(message)
}
}
}.apply { level = HttpLoggingInterceptor.Level.BODY }

return OkHttpClient.Builder()
.addInterceptor(tokenInterceptor)
.addInterceptor(loggingInterceptor)
.authenticator(tokenAuthenticator)
.build()
}
@Singleton
@Provides
fun provideOkHttpClient(
tokenInterceptor: TokenInterceptor,
tokenAuthenticator: TokenAuthenticator,
loggingInterceptor: HttpLoggingInterceptor,
): OkHttpClient = OkHttpClient.Builder()
.addInterceptor(tokenInterceptor)
.addInterceptor(loggingInterceptor)
.authenticator(tokenAuthenticator)
.build()

@Singleton
@Provides
Expand All @@ -65,6 +67,27 @@ object NetworkModule {
.client(okHttpClient)
.build()

@Singleton
@Provides
@AuthOkHttpClient
fun provideAuthOkHttpClient(
loggingInterceptor: HttpLoggingInterceptor,
): OkHttpClient = OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.build()

@Singleton
@Provides
@AuthRetrofit
fun provideAuthRetrofit(
@AuthOkHttpClient okHttpClient: OkHttpClient,
json: Json,
): Retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
.client(okHttpClient)
.build()
yangsooplus marked this conversation as resolved.
Show resolved Hide resolved

@Singleton
@Provides
fun provideJson(): Json {
Expand Down
11 changes: 11 additions & 0 deletions data/src/main/java/com/susu/data/di/Qualifier.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.susu.data.di

import javax.inject.Qualifier

@Qualifier
@Retention(AnnotationRetention.BINARY)
internal annotation class AuthOkHttpClient

@Qualifier
@Retention(AnnotationRetention.BINARY)
internal annotation class AuthRetrofit
14 changes: 14 additions & 0 deletions data/src/main/java/com/susu/data/di/RepositoryModule.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.susu.data.di

import com.susu.data.repository.LoginRepositoryImpl
import com.susu.data.repository.SignUpRepositoryImpl
import com.susu.data.repository.TokenRepositoryImpl
import com.susu.domain.repository.LoginRepository
import com.susu.domain.repository.SignUpRepository
import com.susu.domain.repository.TokenRepository
import dagger.Binds
import dagger.Module
Expand All @@ -15,4 +19,14 @@ abstract class RepositoryModule {
abstract fun bindTokenRepository(
tokenRepositoryImpl: TokenRepositoryImpl,
): TokenRepository

@Binds
abstract fun bindSignUpRepository(
signUpRepositoryImpl: SignUpRepositoryImpl,
): SignUpRepository

@Binds
abstract fun bindLoginRepository(
loginRepositoryImpl: LoginRepositoryImpl,
): LoginRepository
}
34 changes: 34 additions & 0 deletions data/src/main/java/com/susu/data/di/ServiceModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.susu.data.di

import com.susu.data.network.service.UserService
import com.susu.data.network.service.TokenService
import com.susu.data.network.service.SignUpService
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import retrofit2.Retrofit
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object ServiceModule {

@Singleton
@Provides
fun provideUserService(retrofit: Retrofit): UserService {
return retrofit.create(UserService::class.java)
}

@Singleton
@Provides
fun provideSignUpService(retrofit: Retrofit): SignUpService {
return retrofit.create(SignUpService::class.java)
}

@Singleton
@Provides
fun provideTokenService(@AuthRetrofit retrofit: Retrofit): TokenService {
return retrofit.create(TokenService::class.java)
}
}
35 changes: 0 additions & 35 deletions data/src/main/java/com/susu/data/extension/DataStoreExtension.kt

This file was deleted.

5 changes: 5 additions & 0 deletions data/src/main/java/com/susu/data/model/SnsProviders.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.susu.data.model

enum class SnsProviders(val path: String) {
Kakao("KAKAO"),
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.susu.data.model.request

import kotlinx.serialization.Serializable

@Serializable
data class AccessTokenRequest(
val accessToken: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.susu.data.model.request

import kotlinx.serialization.Serializable

@Serializable
data class RefreshTokenRequest(
val refreshToken: String,
)
17 changes: 17 additions & 0 deletions data/src/main/java/com/susu/data/model/request/UserRequest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.susu.data.model.request

import com.susu.core.model.User
import kotlinx.serialization.Serializable

@Serializable
data class UserRequest(
val name: String,
val gender: String,
val birth: Int,
)

fun User.toData() = UserRequest(
name = name,
gender = gender,
birth = birth,
)
Loading
Loading