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

Add E2EE under premium flow #166

Closed
wants to merge 7 commits into from
Closed

Conversation

cp-megh-l
Copy link
Collaborator

@cp-megh-l cp-megh-l commented Jan 17, 2025

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for RevenueCat in-app purchases
    • Introduced user type categorization (Free/Premium)
    • Added encryption status for spaces
  • Changes

    • Modified MainActivity launch mode
    • Updated space creation and joining logic
    • Adjusted user and space models to support new features
  • Technical Updates

    • Updated Android SDK compilation version
    • Removed some key generation and distribution methods

@cp-megh-l cp-megh-l marked this pull request as draft January 17, 2025 10:58
Copy link

coderabbitai bot commented Jan 17, 2025

Walkthrough

This pull request introduces several significant changes across the project, focusing on integrating RevenueCat for in-app purchases, modifying space and user models, and updating space management logic. The changes include adding RevenueCat configuration, introducing user types (free and premium), enhancing space encryption handling, and updating build configurations. The modifications span multiple files in the app, data, and configuration layers, introducing new properties, methods, and dependency management strategies.

Changes

File Change Summary
app/build.gradle.kts - Added conditional REVENUECAT_API_KEY configuration
- Added RevenueCat purchases library dependency
app/src/main/AndroidManifest.xml - Changed MainActivity launch mode from singleTask to standard
app/src/main/java/com/canopas/yourspace/YourSpaceApplication.kt - Added RevenueCat library imports
- Configured Purchases logging and initialization
app/src/main/java/com/canopas/yourspace/ui/flow/pin/setpin/SetPinViewModel.kt - Removed try-catch block in processPin function
data/build.gradle.kts - Updated compileSdk from 34 to 35
data/src/main/java/com/canopas/yourspace/data/models/space/ApiSpace.kt - Added is_encryption_enabled property
data/src/main/java/com/canopas/yourspace/data/models/user/ApiUser.kt - Added FREE_USER and PREMIUM_USER constants
- Added user_type property
data/src/main/java/com/canopas/yourspace/data/repository/SpaceRepository.kt - Removed generateAndDistributeSenderKeysForExistingSpaces method
- Modified getAllSpaceInfo method logic
data/src/main/java/com/canopas/yourspace/data/service/space/ApiSpaceService.kt - Updated createSpace method with enableEncryption
- Modified joinSpace method with encryption and user type checks
- Added new private joinSpace method

Sequence Diagram

sequenceDiagram
    participant App as YourSpaceApplication
    participant RevenueCat
    participant User

    App->>RevenueCat: Configure Purchases
    App->>RevenueCat: Set Log Level to DEBUG
    User->>App: Interact with App
    alt User Type
        User->>App: Check User Type
        alt Premium User
            App->>App: Allow Advanced Features
        else Free User
            App->>App: Limit Features
        end
    end
Loading

Possibly related PRs

Suggested reviewers

  • cp-radhika-s

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary or Summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (10)
data/src/main/java/com/canopas/yourspace/data/service/space/ApiSpaceService.kt (6)

52-60: Consider using a custom exception for unauthorized actions.

Throwing IllegalStateException when a user attempts to create an encrypted space without the appropriate permissions may not be the best practice. It is more appropriate to use a custom exception or an AuthenticationException to clearly indicate the nature of the error.

Apply this diff to introduce a custom exception:

+class UnauthorizedActionException(message: String) : Exception(message)

 suspend fun createSpace(spaceName: String, enableEncryption: Boolean = false): String {
     val spaceId = UUID.randomUUID().toString()
     val docRef = spaceRef.document(spaceId)
     val currentUser = authService.currentUser ?: throw IllegalStateException("No authenticated user")

     if (enableEncryption && currentUser.user_type == FREE_USER) {
-        // Redirect to subscription page
-        throw IllegalStateException("User must be a premium user to enable encryption")
+        throw UnauthorizedActionException("User must be a premium user to enable encryption")
     }

57-60: Update comment to match implementation or implement redirection logic.

The comment // Redirect to subscription page suggests a redirection, but the implementation throws an exception. Either update the comment to reflect that an exception is thrown, or implement the redirection logic if appropriate.

Apply this diff to update the comment:

 if (enableEncryption && currentUser.user_type == FREE_USER) {
-    // Redirect to subscription page
+    // Throw exception because user must be a premium user to enable encryption
     throw UnauthorizedActionException("User must be a premium user to enable encryption")
 }

82-118: Simplify the flow control in joinSpace method.

The when block with multiple conditions and nested logic may be hard to read and maintain. Consider refactoring the method to simplify the logic and improve readability.

Here's a possible refactor:

suspend fun joinSpace(spaceId: String, role: Int = SPACE_MEMBER_ROLE_MEMBER, enableEncryption: Boolean? = null) {
    val user = authService.currentUser ?: throw IllegalStateException("No authenticated user")
    val isEncryptionEnabled = enableEncryption ?: getSpace(spaceId)?.is_encryption_enabled
        ?: throw IllegalStateException("Space not found")

    if (isEncryptionEnabled && user.user_type == FREE_USER) {
        throw UnauthorizedActionException("User must be a premium user to join an encrypted space")
    }

    joinSpace(spaceId, user, role)

    if (isEncryptionEnabled && user.user_type == PREMIUM_USER) {
        // Update the "docUpdatedAt" so others see membership changed
        val docRef = spaceGroupKeysDoc(spaceId)
        docRef.update("doc_updated_at", System.currentTimeMillis()).await()

        // Distribute sender key to all members
        distributeSenderKeyToSpaceMembers(spaceId, user.id)
    } else if (!isEncryptionEnabled && user.user_type == PREMIUM_USER) {
        // Notify user about joining an unencrypted space
        // Implementation of notification logic goes here
    }
}

89-91: Clarify the handling of subscription redirection.

As in the createSpace method, the comment suggests redirection to a subscription page, but the code throws an exception. Ensure consistency in how this scenario is handled and consider implementing the redirection logic if applicable.

Apply this diff to update the comment:

 when {
     isEncryptionEnabled && user.user_type == FREE_USER -> {
-        // Redirect to subscription page
+        // Throw exception because user must be a premium user to join an encrypted space
         throw UnauthorizedActionException("User must be a premium user to join an encrypted space")
     }

120-141: Handle exceptions more specifically in joinSpace method.

Catching a general Exception may obscure specific issues that could be handled differently. Consider catching specific exceptions or rethrowing them with additional context.

Apply this diff to catch specific exceptions:

 try {
     spaceMemberRef(spaceId)
         .document(user.id).also {
             val member = ApiSpaceMember(
                 space_id = spaceId,
                 user_id = user.id,
                 role = role,
                 identity_key_public = user.identity_key_public,
                 location_enabled = true
             )
             it.set(member).await()
         }
     apiUserService.addSpaceId(user.id, spaceId)
-} catch (e: Exception) {
+} catch (e: FirebaseFirestoreException) {
     Timber.e(e, "Failed to join space $spaceId")
     throw e
 }

83-86: Improve error message when space is not found.

Throwing IllegalStateException("Space not found") may not provide enough context. Consider using a more specific exception with additional details.

Apply this diff to improve the exception:

 val isEncryptionEnabled = enableEncryption ?: kotlin.run {
     getSpace(spaceId)?.is_encryption_enabled ?: throw IllegalArgumentException("Space with ID $spaceId not found")
 }
data/src/main/java/com/canopas/yourspace/data/models/user/ApiUser.kt (1)

13-15: Consider using an enum for user_type for type safety.

Using an enum class instead of constants for FREE_USER and PREMIUM_USER can enhance type safety and readability.

Apply this diff to define an enum:

-const val FREE_USER = 0
-const val PREMIUM_USER = 1

+enum class UserType(val value: Int) {
+    FREE_USER(0),
+    PREMIUM_USER(1)
+}

 data class ApiUser(
     val id: String = UUID.randomUUID().toString(),
     // ...
-    val user_type: Int = FREE_USER,
+    val user_type: UserType = UserType.FREE_USER,
     // ...
 )

And update usages accordingly.

data/src/main/java/com/canopas/yourspace/data/models/space/ApiSpace.kt (1)

14-14: Document the is_encryption_enabled property.

Adding documentation to the is_encryption_enabled property will help other developers understand its purpose and default behavior.

Apply this diff to add a comment:

data class ApiSpace(
    val id: String = UUID.randomUUID().toString(),
    val admin_id: String = "",
    val name: String = "",
    /** Indicates whether encryption is enabled for this space. */
    val is_encryption_enabled: Boolean = false,
    val created_at: Long? = System.currentTimeMillis()
)
data/src/main/java/com/canopas/yourspace/data/repository/SpaceRepository.kt (1)

Line range hint 1-300: Consider these architectural recommendations for E2EE premium integration:

  1. Implement clear state transitions for encryption status when users upgrade/downgrade between free and premium
  2. Add migration strategy for existing encrypted spaces
  3. Consider adding encryption status indicators in the SpaceInfo model
  4. Document the new E2EE architecture for maintainability

Would you like me to help create a detailed architectural document covering these aspects?

app/build.gradle.kts (1)

234-236: Consider using a version catalog for dependency management.

Move the RevenueCat version to a centralized version catalog for better dependency management.

Create a new file gradle/libs.versions.toml:

[versions]
revenuecat = "7.0.0"

[libraries]
revenuecat = { module = "com.revenuecat.purchases:purchases", version.ref = "revenuecat" }

Then update the dependency:

-    implementation("com.revenuecat.purchases:purchases:7.0.0")
+    implementation(libs.revenuecat)
🧰 Tools
🪛 GitHub Actions: Android Build

[warning] Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f7ed458 and 9d8440f.

📒 Files selected for processing (9)
  • app/build.gradle.kts (2 hunks)
  • app/src/main/AndroidManifest.xml (1 hunks)
  • app/src/main/java/com/canopas/yourspace/YourSpaceApplication.kt (2 hunks)
  • app/src/main/java/com/canopas/yourspace/ui/flow/pin/setpin/SetPinViewModel.kt (0 hunks)
  • data/build.gradle.kts (1 hunks)
  • data/src/main/java/com/canopas/yourspace/data/models/space/ApiSpace.kt (1 hunks)
  • data/src/main/java/com/canopas/yourspace/data/models/user/ApiUser.kt (2 hunks)
  • data/src/main/java/com/canopas/yourspace/data/repository/SpaceRepository.kt (1 hunks)
  • data/src/main/java/com/canopas/yourspace/data/service/space/ApiSpaceService.kt (3 hunks)
💤 Files with no reviewable changes (1)
  • app/src/main/java/com/canopas/yourspace/ui/flow/pin/setpin/SetPinViewModel.kt
🧰 Additional context used
🪛 GitHub Actions: Android Build
data/build.gradle.kts

[warning] Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0

app/build.gradle.kts

[error] 70-70: Build script references missing local.properties file


[warning] Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0

🔇 Additional comments (8)
data/src/main/java/com/canopas/yourspace/data/service/space/ApiSpaceService.kt (2)

100-115: Ensure notification logic is implemented for unencrypted spaces.

The comments indicate that users should be notified when joining unencrypted spaces. However, there is no implementation of this notification. Consider adding the necessary logic to inform premium users about the implications.

Do you want to implement the notification logic to alert premium users when they join unencrypted spaces? If so, I can help draft the necessary code.


110-112: Ensure sender key distribution handles errors gracefully.

In distributeSenderKeyToSpaceMembers, ensure that any exceptions during distribution do not leave the system in an inconsistent state. Consider adding error handling or retries if necessary.

Would you like to review the distributeSenderKeyToSpaceMembers function to ensure robust error handling?

data/src/main/java/com/canopas/yourspace/data/models/user/ApiUser.kt (1)

30-30: Default values should reflect the intended default state.

The user_type defaulting to FREE_USER may be acceptable, but ensure that this aligns with business logic, especially if new user types are added in the future.

Please confirm that all instances where ApiUser is instantiated without specifying user_type should indeed default to FREE_USER.

data/src/main/java/com/canopas/yourspace/data/repository/SpaceRepository.kt (2)

71-72: LGTM! Simplified list emptiness check.

The change from filtering null values to directly checking if the list is empty is a cleaner approach.


Line range hint 1-300: Verify the E2EE key management strategy after removal of sender keys generation.

The removal of generateAndDistributeSenderKeysForExistingSpaces method suggests a significant change in how E2E encryption keys are managed. Since this PR moves E2EE under the premium flow, we need to ensure:

  1. The key generation and distribution logic has been properly migrated to the premium flow
  2. Existing spaces' encryption is handled correctly during the transition
  3. There's proper fallback for non-premium users

Let's verify the E2EE implementation:

✅ Verification successful

E2EE implementation properly handles premium flow transition

The codebase shows a well-structured E2EE implementation with proper premium-gating:

  • Free users are prevented from enabling encryption or joining encrypted spaces
  • Premium users get appropriate warnings when joining unencrypted spaces
  • Key management infrastructure remains intact with proper validation
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for new E2EE key management implementation
echo "Searching for E2EE related implementations..."

# Look for premium-related encryption handling
rg -l "premium.*encrypt|encrypt.*premium" --type kotlin

# Look for key generation and distribution logic
ast-grep --pattern 'fun $FUNC($PARAMS) {
  $$$
  encrypt$$$
  $$$
}'

# Check for migration handling
rg -l "migration.*encrypt|encrypt.*migration" --type kotlin

Length of output: 370


Script:

#!/bin/bash
# Search for the removed method and E2EE related code
echo "Searching for sender keys and E2EE implementations..."

# Look for the removed method
rg -l "generateAndDistributeSenderKeysForExistingSpaces" --type kotlin

# Look for E2EE related code with various terms
rg -l "e2e|end.?to.?end|crypto|encrypt|decrypt|keys?" --type kotlin

# Check ApiSpaceService.kt content
echo "\nChecking ApiSpaceService.kt content:"
rg "premium.*encrypt|encrypt.*premium" data/src/main/java/com/canopas/yourspace/data/service/space/ApiSpaceService.kt -A 5 -B 5

Length of output: 5237

data/build.gradle.kts (1)

Line range hint 1-100: Address Gradle deprecation warnings.

The build is using deprecated Gradle features that will be incompatible with Gradle 9.0.

🧰 Tools
🪛 GitHub Actions: Android Build

[warning] Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0

app/src/main/java/com/canopas/yourspace/YourSpaceApplication.kt (1)

65-65: Verify RevenueCat initialization order.

The RevenueCat initialization is placed before user-specific operations but after Places API initialization. This seems appropriate, but please verify that no premium features are accessed before this point.

✅ Verification successful

RevenueCat initialization order is correct

The initialization order is safe as all premium features are properly gated through the server-side API and user type checks. No premium features or RevenueCat purchase checks occur before the initialization in Application.onCreate().

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any RevenueCat purchase checks or premium feature access
# that might occur before application onCreate()
rg -l "Purchases\." | xargs rg "onCreate|onStart|onResume" -B 5 -A 5

Length of output: 953


Script:

#!/bin/bash
# Search for RevenueCat purchase checks and premium feature access patterns
echo "=== RevenueCat Purchase Checks ==="
rg "Purchases\.(shared|cache|check|get|is)"

echo -e "\n=== Premium Feature Patterns ==="
rg -i "premium|subscription|purchas(e|ed)|entitlement"

echo -e "\n=== Early Lifecycle Access ==="
ast-grep --pattern 'class $_ : Application {
  $$$
  override fun onCreate() {
    $$$
  }
}'

Length of output: 2787

app/src/main/AndroidManifest.xml (1)

27-27: ⚠️ Potential issue

Reconsider changing MainActivity launch mode to standard.

Changing from singleTask to standard allows multiple instances of MainActivity, which could lead to:

  1. Inconsistent encryption states across instances
  2. Premium status verification issues
  3. Memory leaks from multiple encryption contexts

Consider keeping it as singleTask or implementing proper state synchronization across instances.

Comment on lines +82 to +86
suspend fun joinSpace(spaceId: String, role: Int = SPACE_MEMBER_ROLE_MEMBER, enableEncryption: Boolean? = null) {
val user = authService.currentUser ?: throw IllegalStateException("No authenticated user")
spaceMemberRef(spaceId)
.document(user.id).also {
val member = ApiSpaceMember(
space_id = spaceId,
user_id = user.id,
role = role,
identity_key_public = user.identity_key_public,
location_enabled = true
)
it.set(member).await()
val isEncryptionEnabled = enableEncryption ?: kotlin.run {
getSpace(spaceId)?.is_encryption_enabled ?: throw IllegalStateException("Space not found")
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid potential nullability issue with getSpace method.

The getSpace method could return null, leading to a NullPointerException when accessing is_encryption_enabled. Consider using the safe call operator or adding a null check.

Apply this diff to safely handle the null case:

 val isEncryptionEnabled = enableEncryption ?: kotlin.run {
-    getSpace(spaceId)?.is_encryption_enabled ?: throw IllegalStateException("Space not found")
+    getSpace(spaceId)?.is_encryption_enabled ?: false
 }

Alternatively, ensure that a proper exception is thrown if the space is not found.

Committable suggestion skipped: line range outside the PR's diff.

@@ -8,7 +8,7 @@ plugins {

android {
namespace = "com.canopas.yourspace.data"
compileSdk = 34
compileSdk = 35
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Revert compileSdk to 34.

compileSdk 35 is not yet released. The current latest version is 34.

-    compileSdk = 35
+    compileSdk = 34
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
compileSdk = 35
compileSdk = 34
🧰 Tools
🪛 GitHub Actions: Android Build

[warning] Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0

Comment on lines 234 to 236
// RevenueCat
implementation("com.revenuecat.purchases:purchases:7.0.0")

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add ProGuard rules for RevenueCat.

RevenueCat requires specific ProGuard rules to work correctly in release builds.

Add the following to your proguard-rules.pro file:

+# RevenueCat ProGuard Rules
+-keep class com.revenuecat.purchases.** { *; }
+-keep class com.android.billingclient.** { *; }

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 GitHub Actions: Android Build

[warning] Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0

Comment on lines +66 to +76
if (System.getenv("REVENUECAT_API_KEY") != null) {
buildConfigField("String", "REVENUECAT_API_KEY", "\"${System.getenv("REVENUECAT_API_KEY")}\"")
} else {
val p = Properties()
p.load(project.rootProject.file("local.properties").reader())
buildConfigField(
"String",
"REVENUECAT_API_KEY",
"\"${p.getProperty("REVENUECAT_API_KEY")}\""
)
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Improve error handling for missing RevenueCat API key.

The current implementation will crash if REVENUECAT_API_KEY is missing from local.properties.

         if (System.getenv("REVENUECAT_API_KEY") != null) {
             buildConfigField("String", "REVENUECAT_API_KEY", "\"${System.getenv("REVENUECAT_API_KEY")}\"")
         } else {
             val p = Properties()
-            p.load(project.rootProject.file("local.properties").reader())
-            buildConfigField(
-                "String",
-                "REVENUECAT_API_KEY",
-                "\"${p.getProperty("REVENUECAT_API_KEY")}\""
-            )
+            val localProperties = project.rootProject.file("local.properties")
+            if (localProperties.exists()) {
+                p.load(localProperties.reader())
+                val apiKey = p.getProperty("REVENUECAT_API_KEY") ?: ""
+                buildConfigField("String", "REVENUECAT_API_KEY", "\"$apiKey\"")
+            } else {
+                buildConfigField("String", "REVENUECAT_API_KEY", "\"\"")
+                logger.warn("local.properties file not found. REVENUECAT_API_KEY will be empty.")
+            }
         }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (System.getenv("REVENUECAT_API_KEY") != null) {
buildConfigField("String", "REVENUECAT_API_KEY", "\"${System.getenv("REVENUECAT_API_KEY")}\"")
} else {
val p = Properties()
p.load(project.rootProject.file("local.properties").reader())
buildConfigField(
"String",
"REVENUECAT_API_KEY",
"\"${p.getProperty("REVENUECAT_API_KEY")}\""
)
}
if (System.getenv("REVENUECAT_API_KEY") != null) {
buildConfigField("String", "REVENUECAT_API_KEY", "\"${System.getenv("REVENUECAT_API_KEY")}\"")
} else {
val p = Properties()
val localProperties = project.rootProject.file("local.properties")
if (localProperties.exists()) {
p.load(localProperties.reader())
val apiKey = p.getProperty("REVENUECAT_API_KEY") ?: ""
buildConfigField("String", "REVENUECAT_API_KEY", "\"$apiKey\"")
} else {
buildConfigField("String", "REVENUECAT_API_KEY", "\"\"")
logger.warn("local.properties file not found. REVENUECAT_API_KEY will be empty.")
}
}
🧰 Tools
🪛 GitHub Actions: Android Build

[error] 70-70: Build script references missing local.properties file


[warning] Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0

Comment on lines 64 to 65
Purchases.logLevel = LogLevel.DEBUG
Purchases.configure(PurchasesConfiguration.Builder(this, BuildConfig.REVENUECAT_API_KEY).build())
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Restrict RevenueCat debug logging to debug builds only.

Debug logging is currently enabled for all builds, which could expose sensitive information in production. Consider wrapping this in a debug check.

-Purchases.logLevel = LogLevel.DEBUG
+if (BuildConfig.DEBUG) {
+    Purchases.logLevel = LogLevel.DEBUG
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Purchases.logLevel = LogLevel.DEBUG
Purchases.configure(PurchasesConfiguration.Builder(this, BuildConfig.REVENUECAT_API_KEY).build())
if (BuildConfig.DEBUG) {
Purchases.logLevel = LogLevel.DEBUG
}
Purchases.configure(PurchasesConfiguration.Builder(this, BuildConfig.REVENUECAT_API_KEY).build())

@cp-megh-l cp-megh-l closed this Jan 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant