Skip to content

Commit 22c6406

Browse files
committed
Merge branch 'develop' into hotfix/#12-ktlint_annotation_contrsuctor
2 parents 367776d + 280b558 commit 22c6406

File tree

33 files changed

+1007
-22
lines changed

33 files changed

+1007
-22
lines changed

.github/workflows/develop_branch.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ jobs:
1414
- name: check out repository
1515
uses: actions/checkout@v4
1616

17+
- name: Generate local.properties
18+
env:
19+
KAKAO_NATIVE_APP_KEY: ${{ secrets.KAKAO_NATIVE_APP_KEY }}
20+
run: |
21+
echo "kakao.native.app.key=$KAKAO_NATIVE_APP_KEY" >> local.properties
22+
1723
- name: set up JDK 17
1824
uses: actions/setup-java@v4
1925
with:

app/build.gradle.kts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import java.util.Properties
2+
13
plugins {
24
alias(libs.plugins.bitnagil.android.application)
35
alias(libs.plugins.bitnagil.android.hilt)
@@ -7,16 +9,42 @@ plugins {
79
android {
810
namespace = "com.threegap.bitnagil"
911

12+
val properties =
13+
Properties().apply {
14+
val propFile = rootProject.file("local.properties")
15+
if (propFile.exists()) {
16+
load(propFile.inputStream())
17+
}
18+
}
19+
1020
defaultConfig {
1121
applicationId = "com.threegap.bitnagil"
22+
23+
val kakaoNativeAppKey =
24+
(properties["kakao.native.app.key"] as? String)
25+
?: System.getenv("KAKAO_NATIVE_APP_KEY")
26+
?: throw GradleException("KAKAO_NATIVE_APP_KEY 값이 없습니다.")
27+
28+
manifestPlaceholders["KAKAO_NATIVE_APP_KEY"] = kakaoNativeAppKey
29+
buildConfigField(
30+
type = "String",
31+
name = "KAKAO_NATIVE_APP_KEY",
32+
value = "\"$kakaoNativeAppKey\"",
33+
)
34+
}
35+
36+
buildFeatures {
37+
buildConfig = true
1238
}
1339
}
1440

1541
dependencies {
1642
implementation(projects.core.datastore)
1743
implementation(projects.core.designsystem)
1844
implementation(projects.core.network)
45+
implementation(projects.core.security)
1946
implementation(projects.data)
2047
implementation(projects.domain)
2148
implementation(projects.presentation)
49+
implementation(libs.kakao.v2.user)
2250
}

app/src/main/AndroidManifest.xml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,20 @@
2525
<category android:name="android.intent.category.LAUNCHER" />
2626
</intent-filter>
2727
</activity>
28-
</application>
2928

29+
<activity
30+
android:name="com.kakao.sdk.auth.AuthCodeHandlerActivity"
31+
android:exported="true">
32+
<intent-filter>
33+
<action android:name="android.intent.action.VIEW" />
34+
35+
<category android:name="android.intent.category.DEFAULT" />
36+
<category android:name="android.intent.category.BROWSABLE" />
37+
38+
<data
39+
android:host="oauth"
40+
android:scheme="kakao${KAKAO_NATIVE_APP_KEY}" />
41+
</intent-filter>
42+
</activity>
43+
</application>
3044
</manifest>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
package com.threegap.bitnagil
22

33
import android.app.Application
4+
import com.kakao.sdk.common.KakaoSdk
45
import dagger.hilt.android.HiltAndroidApp
56

67
@HiltAndroidApp
78
class BitnagilApplication : Application() {
89
override fun onCreate() {
910
super.onCreate()
11+
initKakaoSdk()
12+
}
13+
14+
private fun initKakaoSdk() {
15+
KakaoSdk.init(this, BuildConfig.KAKAO_NATIVE_APP_KEY)
1016
}
1117
}

app/src/main/java/com/threegap/bitnagil/MainNavHost.kt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import androidx.compose.ui.Modifier
55
import androidx.navigation.compose.NavHost
66
import androidx.navigation.compose.composable
77
import com.threegap.bitnagil.presentation.home.HomeScreen
8-
import com.threegap.bitnagil.presentation.login.LoginScreen
8+
import com.threegap.bitnagil.presentation.login.LoginScreenContainer
99

1010
@Composable
1111
fun MainNavHost(
@@ -18,9 +18,7 @@ fun MainNavHost(
1818
modifier = modifier,
1919
) {
2020
composable<Route.Login> {
21-
LoginScreen(
22-
onLoginClick = { navigator.navController.navigate(Route.Home) },
23-
)
21+
LoginScreenContainer()
2422
}
2523

2624
composable<Route.Home> {

core/datastore/build.gradle.kts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,11 @@ android {
99
}
1010

1111
dependencies {
12-
implementation(libs.androidx.datastore)
12+
implementation(projects.core.security)
13+
14+
implementation(libs.androidx.datastore.preferences)
15+
implementation(libs.kotlinx.serialization.json)
16+
17+
testImplementation(libs.androidx.junit)
18+
testImplementation(libs.kotlin.coroutines.test)
1319
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.threegap.bitnagil.datastore.di
2+
3+
import android.content.Context
4+
import androidx.datastore.core.DataStore
5+
import androidx.datastore.core.DataStoreFactory
6+
import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
7+
import androidx.datastore.dataStoreFile
8+
import com.threegap.bitnagil.datastore.model.AuthToken
9+
import com.threegap.bitnagil.datastore.serializer.AuthTokenSerializer
10+
import com.threegap.bitnagil.datastore.serializer.TokenSerializer
11+
import com.threegap.bitnagil.security.crypto.Crypto
12+
import dagger.Module
13+
import dagger.Provides
14+
import dagger.hilt.InstallIn
15+
import dagger.hilt.android.qualifiers.ApplicationContext
16+
import dagger.hilt.components.SingletonComponent
17+
import javax.inject.Singleton
18+
19+
@Module
20+
@InstallIn(SingletonComponent::class)
21+
object DataStoreModule {
22+
@Provides
23+
@Singleton
24+
fun provideTokenSerializer(crypto: Crypto): TokenSerializer = AuthTokenSerializer(crypto)
25+
26+
@Provides
27+
@Singleton
28+
fun provideAuthTokenDataStore(
29+
@ApplicationContext context: Context,
30+
tokenSerializer: TokenSerializer,
31+
): DataStore<AuthToken> =
32+
DataStoreFactory.create(
33+
serializer = tokenSerializer,
34+
produceFile = { context.dataStoreFile("auth-token.enc") },
35+
corruptionHandler = ReplaceFileCorruptionHandler { AuthToken() },
36+
)
37+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.threegap.bitnagil.datastore.model
2+
3+
import kotlinx.serialization.Serializable
4+
5+
@Serializable
6+
data class AuthToken(
7+
val accessToken: String? = null,
8+
val refreshToken: String? = null,
9+
)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.threegap.bitnagil.datastore.serializer
2+
3+
import com.threegap.bitnagil.datastore.model.AuthToken
4+
import com.threegap.bitnagil.security.crypto.Crypto
5+
import kotlinx.coroutines.Dispatchers
6+
import kotlinx.coroutines.withContext
7+
import kotlinx.serialization.json.Json
8+
import java.io.InputStream
9+
import java.io.OutputStream
10+
import java.util.Base64
11+
import javax.inject.Inject
12+
13+
internal class AuthTokenSerializer
14+
@Inject
15+
constructor(
16+
private val crypto: Crypto,
17+
) : TokenSerializer {
18+
override val defaultValue: AuthToken
19+
get() = AuthToken()
20+
21+
override suspend fun readFrom(input: InputStream): AuthToken {
22+
return try {
23+
val encryptedBytes =
24+
withContext(Dispatchers.IO) {
25+
input.use { it.readBytes() }
26+
}
27+
val decodedBytes = Base64.getDecoder().decode(encryptedBytes)
28+
val decryptedBytes = crypto.decrypt(decodedBytes)
29+
val decodedJsonString = decryptedBytes.decodeToString()
30+
Json.decodeFromString(decodedJsonString)
31+
} catch (e: Exception) {
32+
AuthToken()
33+
}
34+
}
35+
36+
override suspend fun writeTo(
37+
t: AuthToken,
38+
output: OutputStream,
39+
) {
40+
val json = Json.encodeToString(t)
41+
val bytes = json.toByteArray()
42+
val encryptedBytes = crypto.encrypt(bytes)
43+
val encryptedBytesBase64 = Base64.getEncoder().encode(encryptedBytes)
44+
withContext(Dispatchers.IO) {
45+
output.use {
46+
it.write(encryptedBytesBase64)
47+
}
48+
}
49+
}
50+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.threegap.bitnagil.datastore.serializer
2+
3+
import androidx.datastore.core.Serializer
4+
import com.threegap.bitnagil.datastore.model.AuthToken
5+
6+
interface TokenSerializer : Serializer<AuthToken>

0 commit comments

Comments
 (0)