-
Notifications
You must be signed in to change notification settings - Fork 0
feat: 로그아웃, 회원탈퇴 api연결 #61
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
Changes from all commits
069ef6e
5e3a1a0
ae49028
7b1480e
e598405
bd0d5ab
de00f17
cc62951
bc9f20c
5bdd309
3e7c8d3
dea3a70
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,11 +9,13 @@ | |
| <include .../> | ||
| <exclude .../> | ||
| --> | ||
| <!-- 리프레시 토큰 등 인증 정보가 클라우드 백업에 포함되면 앱 삭제 후 재설치해도 자동 로그인되는 버그 발생 --> | ||
| <exclude domain="file" path="datastore/call_from_ai_token_prefs.preferences_pb"/> | ||
|
Comment on lines
+12
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
echo "== dataExtractionRules 참조 확인 =="
rg -n -C 3 'dataExtractionRules|fullBackupContent' -g 'AndroidManifest.xml' .
echo "== 현재 데이터 추출 규칙 확인 =="
cat -n app/src/main/res/xml/data_extraction_rules.xmlRepository: call-from-ai/CallFromAi_Android Length of output: 1729 🌐 Web query:
💡 Result: For devices running Android 12 (API level 31) and higher, the Citations:
🌐 Web query:
💡 Result: The statement is generally correct regarding how Android handles app data during migration. By default, the Android system includes application data in both cloud backups and device-to-device (D2D) transfers unless the application developer explicitly excludes it using configuration rules [1][2]. Key details regarding this process include: 1. Automatic Inclusion: For most apps targeting Android 6.0 (API level 23) or higher, Auto Backup is enabled by default [2]. If no specific backup or data extraction rules are defined, the system will attempt to transfer the app's data during a device migration [1]. 2. Configuration Rules: Developers can control this behavior using XML configuration files. - On Android 12 (API level 31) and higher, developers use the android:dataExtractionRules attribute in the AndroidManifest.xml to point to a configuration file that defines and rules [3][4]. - If the tag is not configured or does not include an explicit exclusion, the default behavior remains to transfer the application's data [1]. - Developers can use these rules to include or exclude specific domains (such as file, database, sharedpref, external, or root) and paths [3][5]. 3. Limitations: Not all app data is guaranteed to transfer [6][7]. The success of a transfer depends on: - The application developer's implementation: If an app does not use the standard Android backup framework or has explicitly excluded its data, that data will not be transferred [6][2]. - System limitations: Certain types of data, such as app data for apps not from the Google Play Store or data from apps that do not utilize Android backup, may not be included [6]. - Version compatibility: Rules for data extraction were refined in Android 12, requiring developers to ensure their backup configurations are compatible across different Android versions [1][4]. In summary, while the system defaults to including app data, developers retain the authority to exclude specific data or prevent it from being backed up/transferred entirely through defined extraction rules [1][4]. Users should be aware that the actual data transferred can vary by app [6][7]. Citations:
🌐 Web query:
💡 Result: The terms you mentioned relate to different layers and concepts within the Android backup and data transfer infrastructure: BackupDataTransport is not a standard public API class but rather refers to the underlying transport mechanism (often implementing the IBackupTransport interface) that handles the movement of backup data to storage or between devices [1][2][3]. DeviceShadowFileAgent is not a documented Android system class or standard API component. It is possible this is an internal identifier or a misunderstanding of how the system "shadows" or handles file-based backups during data migration. FullBackupContent refers to the android:fullBackupContent attribute in an app's AndroidManifest.xml [4][5]. This attribute allows developers to point to an XML resource file that defines rules for including or excluding specific files and directories during Auto Backup and device-to-device transfers [6][4][7]. When an app does not define data extraction rules (or an explicit fullBackupContent/dataExtractionRules configuration), the Android system's default behavior is to include almost all data within the application's local directory (such as /data/data/<package_name>/) in the backup set, provided that android:allowBackup is set to true (or is left as the default true) [4][5]. In the context of device-to-device transfers, the system uses these same rules. If no specific exclusions are defined, the backup agent—which is responsible for the interaction between the application and the backup system—will process all accessible data files unless otherwise restricted by the system's own security policies [8][6]. Because backup and restoration involve an app's private files, failure to explicitly define these rules can lead to the accidental inclusion of sensitive information (like tokens, cache, or device-specific identifiers) in transfers to other devices [4][7]. Citations:
🌐 Web query:
💡 Result: In the Android backup framework, there is no public or standard internal method named "shouldIncludeDeviceTransfer" within the BackupManagerService or related classes. The mechanism for determining what data is included in a device-to-device (D2D) transfer or cloud backup is primarily controlled through the application's backup configuration, specifically the backup_rules.xml file [1][2]. If an application is not including all expected app data during a device transfer, it is typically due to one of the following factors rather than a framework-level "shadow file" issue: 1. Configuration Rules (backup_rules.xml): Developers define which data to include or exclude for cloud backups and device-to-device transfers using the and tags in their configuration XML [1]. If data is missing, it is often because it falls under an excluded domain or path, or because the specific rules were not correctly configured to include the desired data [1][2]. 2. Transport Capabilities: Device-to-device transfer uses a specific transport mechanism (often the D2dTransport) [3][4]. Not all app data is guaranteed to be transferred if it does not meet the requirements of this transport or if the app has opted out of certain types of backups [1][2]. 3. Security and Encryption: Android may exclude data from backups—especially during automated processes—if the data is marked as sensitive or if the device does not meet specific security requirements (such as having a screen lock set for client-side encryption) [1][2]. 4. Backup Agent Implementation: Applications can override default behavior by implementing a BackupAgent [5]. If the agent is not correctly configured to handle full-backup or key-value data, or if it explicitly excludes files during the backup process, the data will not be available for transfer [6][5]. To debug issues where app data is missing after a transfer, developers should verify their backup_rules.xml to ensure proper inclusion of required domains (such as device_file, device_database, or root) [1] and confirm that the BackupAgent is not filtering out the files during the traversal of the backup file tree [6]. You can test this behavior by using the bmgr tool to simulate backups and inspect what data is being handled by the active transport [3][4]. Citations:
🤖 Prompt for AI Agents |
||
| </cloud-backup> | ||
| <!-- | ||
| <device-transfer> | ||
| <include .../> | ||
| <exclude .../> | ||
| </device-transfer> | ||
| --> | ||
| </data-extraction-rules> | ||
| </data-extraction-rules> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,31 +1,53 @@ | ||
| package kr.co.call.data.repositoryImpl | ||
|
|
||
| import kotlinx.coroutines.CancellationException | ||
| import kotlinx.coroutines.delay | ||
| import kr.co.call.data.util.safeApiResultUnit | ||
| import kr.co.call.datastore.TokenDataStore | ||
| import kr.co.call.domain.model.mypage.MyPageProfile | ||
| import kr.co.call.domain.repository.MyPageRepository | ||
| import kr.co.call.network.api.MyPageApi | ||
| import kr.co.call.network.util.ErrorResponseParser | ||
| import timber.log.Timber | ||
| import javax.inject.Inject | ||
|
|
||
| // TODO: API 연동 전 임시 구현체 | ||
| class MyPageRepositoryImpl @Inject constructor() : MyPageRepository { | ||
| class MyPageRepositoryImpl @Inject constructor( | ||
| private val myPageApi: MyPageApi, | ||
| private val tokenDataStore: TokenDataStore, | ||
| private val errorResponseParser: ErrorResponseParser | ||
| ) : MyPageRepository { | ||
|
|
||
| override suspend fun getMyProfile(): Result<MyPageProfile> { | ||
| delay(500) | ||
| return runCatching { | ||
| return Result.success( | ||
| MyPageProfile( | ||
| profileImageUrl = "", | ||
| nickname = "김수현", | ||
| tier = "Basic", | ||
| remainingTicketCount = 18, | ||
| appVersion = "1.0.0", | ||
| ) | ||
| } | ||
| ), | ||
| ) | ||
| } | ||
|
|
||
| override suspend fun logout() { | ||
| delay(300) | ||
| } | ||
| override suspend fun logout(): Result<Unit> = | ||
| safeApiResultUnit(errorResponseParser) { | ||
| myPageApi.logout() | ||
| }.mapCatching { | ||
| tokenDataStore.clearTokens() | ||
| } | ||
|
|
||
| override suspend fun deleteAccount() { | ||
| delay(300) | ||
| } | ||
| } | ||
| override suspend fun deleteAccount(): Result<Unit> = | ||
| safeApiResultUnit(errorResponseParser) { | ||
| myPageApi.deleteAccount() | ||
| }.onSuccess { | ||
| try { | ||
| tokenDataStore.clearTokens() | ||
| } catch (error: CancellationException) { | ||
| throw error | ||
| } catch (error: Throwable) { | ||
| Timber.w(error, "회원 탈퇴 후 토큰 삭제 실패") | ||
| } | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| package kr.co.call.data.repositoryImpl | ||
|
|
||
| import javax.inject.Inject | ||
| import kr.co.call.data.util.safeApiResultUnit | ||
| import kr.co.call.domain.model.onboarding.CharacterOnboardingInput | ||
| import kr.co.call.domain.model.onboarding.MemberOnboardingInput | ||
| import kr.co.call.domain.repository.OnboardingRepository | ||
| import kr.co.call.network.api.AICharacterApi | ||
| import kr.co.call.network.api.MyPageApi | ||
| import kr.co.call.network.dto.onboarding.CharacterTraitRequestDto | ||
| import kr.co.call.network.dto.onboarding.CreateCharacterRequestDto | ||
| import kr.co.call.network.dto.onboarding.UpdateMemberRequestDto | ||
| import kr.co.call.network.util.ErrorResponseParser | ||
|
|
||
| class OnboardingRepositoryImpl @Inject constructor( | ||
| private val myPageApi: MyPageApi, | ||
| private val aiCharacterApi: AICharacterApi, | ||
| private val errorResponseParser: ErrorResponseParser, | ||
| ) : OnboardingRepository { | ||
|
|
||
| override suspend fun submitMemberOnboarding( | ||
| submission: MemberOnboardingInput, | ||
| ): Result<Unit> = | ||
| safeApiResultUnit(errorResponseParser) { | ||
| myPageApi.updateMember( | ||
| request = UpdateMemberRequestDto( | ||
| lastName = submission.lastName, | ||
| firstName = submission.firstName, | ||
| imageUrl = submission.imageUrl, | ||
| gender = submission.gender, | ||
| birth = submission.birth, | ||
| mbti = submission.mbti, | ||
| job = submission.job, | ||
| ), | ||
| ) | ||
| } | ||
|
|
||
| override suspend fun submitCharacterOnboarding( | ||
| submission: CharacterOnboardingInput, | ||
| ): Result<Unit> = | ||
| safeApiResultUnit(errorResponseParser) { | ||
| aiCharacterApi.createCharacter( | ||
| request = CreateCharacterRequestDto( | ||
| lastName = submission.lastName, | ||
| firstName = submission.firstName, | ||
| gender = submission.gender, | ||
| age = submission.age, | ||
| job = submission.job, | ||
| imageUrl = submission.imageUrl, | ||
| spiceLevel = submission.spiceLevel, | ||
| preferTime = submission.preferTime, | ||
| mbti = submission.mbti, | ||
| speechStyle = submission.speechStyle, | ||
| relationshipStage = | ||
| submission.relationshipStage, | ||
| traits = submission.traits.map { trait -> | ||
| CharacterTraitRequestDto( | ||
| trait = trait.trait, | ||
| priority = trait.priority, | ||
| ) | ||
| }, | ||
| ), | ||
| ) | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.