Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ android {
buildConfigField("String", "KAKAO_REST_API_KEY", properties["kakao.rest.api"].toString())
buildConfigField("String", "NAVERMAP_CLIENT_SECRET", properties["NAVERMAP_CLIENT_SECRET"].toString())
buildConfigField("String", "NAVERMAP_CLIENT_ID", properties["NAVERMAP_CLIENT_ID"].toString())
buildConfigField("String","GOOGLE_WEB_CLIENT_ID",properties["google.client.id"].toString())

manifestPlaceholders["KAKAO_NATIVE_KEY"] = properties["kakao.native.key"].toString()
}
Expand All @@ -46,6 +47,7 @@ android {
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
isCoreLibraryDesugaringEnabled = true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

}
kotlinOptions {
jvmTarget = "11"
Expand Down Expand Up @@ -108,4 +110,13 @@ dependencies {

// 네이버
implementation(libs.bundles.naverMaps)

//구글
implementation(libs.androidx.credentials)
implementation(libs.googleid)
implementation(libs.androidx.credentials.play.services.auth)
coreLibraryDesugaring(libs.desugar.jdk.libs)

// 암호화
implementation(libs.androidx.security)
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
Expand Down Expand Up @@ -44,11 +43,10 @@ import androidx.compose.ui.zIndex
import coil.compose.AsyncImage
import coil.request.ImageRequest
import com.paw.key.R
import com.paw.key.core.designsystem.theme.PawKeyTheme
import com.paw.key.core.designsystem.theme.Gray100
import com.paw.key.core.util.noRippleClickable
import com.paw.key.core.designsystem.theme.PawKeyTheme
import com.paw.key.core.extension.noRippleClickable
import com.paw.key.domain.model.entity.walklist.CategoryTop3Entity
import kotlinx.serialization.json.JsonNull.content

@OptIn(ExperimentalLayoutApi::class)
@Composable
Expand Down
71 changes: 63 additions & 8 deletions app/src/main/java/com/paw/key/core/util/PreferenceDataStore.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package com.paw.key.core.util

import android.content.Context
import android.content.SharedPreferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.floatPreferencesKey
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.longPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
import com.naver.maps.geometry.LatLng
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
Expand Down Expand Up @@ -46,7 +49,6 @@ object PreferenceDataStore {
private val summaryStore
get() = appContext.summaryStore

// 기존 함수들...
suspend fun saveWalkSummary(
points: List<LatLng>,
totalDistance: Float,
Expand Down Expand Up @@ -117,7 +119,7 @@ object PreferenceDataStore {
userId: Int,
userName: String,
petId: Int,
petName: String
petName: String,
) {
summaryStore.edit {
it[USER_ID_KEY] = userId
Expand Down Expand Up @@ -147,7 +149,7 @@ object PreferenceDataStore {
val userId: Int,
val userName: String,
val petId: Int,
val petName: String
val petName: String,
)

fun getUserInfo(): Flow<UserInfo> = summaryStore.data.map {
Expand Down Expand Up @@ -177,7 +179,7 @@ object PreferenceDataStore {
guId: Int,
dongId: Int,
guName: String,
dongName: String
dongName: String,
) {
summaryStore.edit { preferences ->
preferences[SELECTED_GU_ID_KEY] = guId
Expand Down Expand Up @@ -246,7 +248,7 @@ object PreferenceDataStore {
val dongId: Int,
val guName: String,
val dongName: String,
val activeRegion: String
val activeRegion: String,
) {
val displayLocation: String
get() = if (guName.isNotEmpty() && dongName.isNotEmpty()) {
Expand Down Expand Up @@ -286,8 +288,61 @@ object PreferenceDataStore {
preferences.remove(ACTIVE_REGION_KEY)
}
}
}

object UserDataStore {
private val ACCESS_TOKEN = "ACCESS_TOKEN"
private val REFRESH_TOKEN = "REFRESH_TOKEN"
private val PREFERENCES_NAME = "user_preferences"

private fun getSharedPreferences(context: Context): SharedPreferences {
val masterKey = MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()

return EncryptedSharedPreferences.create(
context,
PREFERENCES_NAME,
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
}

fun saveAcessToken(context: Context, token: String) {
val sharedPreferences = getSharedPreferences(context)
with(sharedPreferences.edit()) {
putString(ACCESS_TOKEN, token)
commit()
}
}

fun saveRefreshToken(context: Context, token: String) {
val sharedPreferences = getSharedPreferences(context)
with(sharedPreferences.edit()) {
putString(REFRESH_TOKEN, token)
commit()
}
}

suspend fun clearAllData() {
summaryStore.edit { it.clear() }
fun getAccessToken(context: Context): String {
val sharedPreferences = getSharedPreferences(context)
return sharedPreferences.getString(ACCESS_TOKEN, "") ?: ""
}
}

fun getRefreshToken(context: Context): String {
val sharedPreferences = getSharedPreferences(context)
return sharedPreferences.getString(REFRESH_TOKEN, "") ?: ""
}

fun removeToken(context: Context) {
val sharedPreferences = getSharedPreferences(context)
with(sharedPreferences.edit()) {
remove(ACCESS_TOKEN)
remove(REFRESH_TOKEN)
commit()
}
}
}


19 changes: 19 additions & 0 deletions app/src/main/java/com/paw/key/core/util/suspendRunCating.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.paw.key.core.util

import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.ensureActive
import kotlin.coroutines.cancellation.CancellationException
import kotlin.coroutines.coroutineContext

suspend fun <R> suspendRunCatching(block: suspend () -> R): Result<R> {
return try {
Result.success(block())
} catch (t: TimeoutCancellationException) {
Result.failure(t)
} catch (c: CancellationException) {
throw c
} catch (e: Throwable) {
coroutineContext.ensureActive()
Result.failure(e)
}
}
8 changes: 8 additions & 0 deletions app/src/main/java/com/paw/key/data/di/RepositoryModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import com.paw.key.data.repositoryimpl.sharedwalk.SharedWalkRepositoryImpl
import com.paw.key.data.repositoryimpl.home.HomeRegionRepositoryImpl
import com.paw.key.data.repositoryimpl.home.RegionCurrentRepositoryImpl
import com.paw.key.data.repositoryimpl.list.PostsListRepositoryImpl
import com.paw.key.data.repositoryimpl.login.AuthRepositoryImpl
import com.paw.key.data.repositoryimpl.walklist.WalkListDetailRepositoryImpl
import com.paw.key.data.repositoryimpl.walkreview.WalkReviewRepositoryImpl
import com.paw.key.domain.repository.ArchivedListRepository
Expand All @@ -33,6 +34,7 @@ import com.paw.key.domain.repository.sharedwalk.SharedWalkRepository
import com.paw.key.domain.repository.home.HomeRegionRepository
import com.paw.key.domain.repository.home.RegionCurrentRepository
import com.paw.key.domain.repository.list.PostsListRepository
import com.paw.key.domain.repository.login.AuthRepository
import com.paw.key.domain.repository.petprofile.PetProfileRepository
import com.paw.key.domain.repository.userprofile.UserProfileRepository
import com.paw.key.domain.repository.walkcourse.WalkCourseRepository
Expand Down Expand Up @@ -165,4 +167,10 @@ interface RepositoryModule {
fun bindRegionCurrentRepository(
impl: RegionCurrentRepositoryImpl
) : RegionCurrentRepository

@Binds
@Singleton
fun bindLoginRepository(
impl: AuthRepositoryImpl
) : AuthRepository
}
14 changes: 7 additions & 7 deletions app/src/main/java/com/paw/key/data/di/ServiceModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ import com.paw.key.data.service.ArchivedListService
import com.paw.key.data.service.DummyService
import com.paw.key.data.service.LikeService
import com.paw.key.data.service.PetProfileService
import com.paw.key.data.service.onboarding.OnboardingInfoService
import com.paw.key.data.service.onboarding.OnboardingPetsService
import com.paw.key.data.service.onboarding.OnboardingRegionService
import com.paw.key.data.service.RegionService
import com.paw.key.data.service.SavedListService
import com.paw.key.data.service.UserProfileService
import com.paw.key.data.service.filter.FilterOptionService
import com.paw.key.data.service.sharedwalk.SharedWalkService
import com.paw.key.data.service.home.HomeRegionService
import com.paw.key.data.service.home.RegionCurrentService
import com.paw.key.data.service.list.PostsListService
import com.paw.key.data.service.login.LoginService
import com.paw.key.data.service.onboarding.OnboardingInfoService
import com.paw.key.data.service.onboarding.OnboardingPetsService
import com.paw.key.data.service.onboarding.OnboardingRegionService
import com.paw.key.data.service.sharedwalk.SharedWalkService
import com.paw.key.data.service.walkcourse.WalkCourseService
import com.paw.key.data.service.walklist.WalkListDetailService
import com.paw.key.data.service.walkreview.WalkReviewService
Expand Down Expand Up @@ -68,7 +68,7 @@ object ServiceModule {
@Provides
@Singleton
fun provideHomeRegionService(retrofit: Retrofit): HomeRegionService =
retrofit.create(HomeRegionService::class.java)
retrofit.create()

//마이페이지
@Provides
Expand Down Expand Up @@ -119,6 +119,6 @@ object ServiceModule {

@Provides
@Singleton
fun provideRegionCurrentService(retrofit: Retrofit): RegionCurrentService =
fun provideLoginService(retrofit: Retrofit): LoginService =
retrofit.create()
}
17 changes: 17 additions & 0 deletions app/src/main/java/com/paw/key/data/dto/request/LoginRequestDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.paw.key.data.dto.request

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class LoginRequestDto (
@SerialName("email")
val email: String,
)
// 테스트용입니다


fun LoginRequestDto.toEntity(): LoginRequestDto {
val email = this.email
return LoginRequestDto(email)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.paw.key.data.dto.response

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class LoginResponseDto (
@SerialName("AccessToken")
val AccessToken: String,
@SerialName("RefreshToken")
val RefreshToken: String
)
// 테스트용입니다
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.paw.key.data.remote.datasource.datasourceimpl

import com.paw.key.data.dto.request.LoginRequestDto
import com.paw.key.data.dto.response.BaseResponse
import com.paw.key.data.dto.response.LoginResponseDto
import com.paw.key.data.remote.datasource.login.AuthRemoteDataSource
import com.paw.key.data.service.login.LoginService
import javax.inject.Inject

class AuthRemoteDataSourceImpl @Inject constructor(
private val loginService: LoginService,
) : AuthRemoteDataSource {
override suspend fun login(
providerToken: String,
provider: String,
): BaseResponse<LoginResponseDto> =
loginService.login(providerToken, LoginRequestDto(provider))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.paw.key.data.remote.datasource.datasourceimpl

import android.content.Context
import androidx.credentials.CredentialManager
import androidx.credentials.GetCredentialRequest
import com.google.android.libraries.identity.googleid.GetGoogleIdOption
import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential
import com.paw.key.BuildConfig
import com.paw.key.core.util.suspendRunCatching
import com.paw.key.data.dto.request.LoginRequestDto
import com.paw.key.data.dto.response.BaseResponse
import com.paw.key.data.dto.response.LoginResponseDto
import com.paw.key.data.remote.datasource.login.AuthRemoteDataSource
import com.paw.key.data.remote.datasource.login.GoogleAuthDataSource
import com.paw.key.data.service.login.LoginService
import javax.inject.Inject

class GoogleAuthDataSourceImpl @Inject constructor(
private val credentialManager: CredentialManager,
) : GoogleAuthDataSource {
override suspend fun signIn(context: Context): Result<GoogleIdTokenCredential> =
suspendRunCatching {
val googleIdOption = GetGoogleIdOption.Builder()
.setFilterByAuthorizedAccounts(false)
.setAutoSelectEnabled(false)
.setServerClientId(BuildConfig.GOOGLE_WEB_CLIENT_ID)
.build()

val request = GetCredentialRequest.Builder()
.addCredentialOption(googleIdOption)
.build()

val response = credentialManager.getCredential(context, request)
GoogleIdTokenCredential.createFrom(response.credential.data)
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package com.paw.key.data.remote.datasource.home

import com.paw.key.data.dto.request.home.HomeRegionRequest
import com.paw.key.data.service.home.HomeRegionService
import com.paw.key.data.service.home.RegionCurrentService
import javax.inject.Inject

class RegionCurrentDataSource @Inject constructor(
private val service: RegionCurrentService
private val service: HomeRegionService
) {
suspend fun RegionCurrent(userId: Int) =
service.RegionCurrent(userId)
suspend fun regionCurrent(userId: Int) =
service.regionCurrent(userId)
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.paw.key.data.remote.datasource.login

import com.paw.key.data.dto.response.BaseResponse
import com.paw.key.data.dto.response.LoginResponseDto

interface AuthRemoteDataSource {
suspend fun login(providerToken: String, provider: String): BaseResponse<LoginResponseDto>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.paw.key.data.remote.datasource.login

import android.content.Context
import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential
import com.paw.key.data.dto.response.BaseResponse
import com.paw.key.data.dto.response.LoginResponseDto

interface GoogleAuthDataSource {
suspend fun signIn(context: Context): Result<GoogleIdTokenCredential>
}
Loading