Skip to content

feat(security): implement screenshot protection across the application #3130

Draft
AnuragMishra-akm wants to merge 4 commits intoopenMF:developmentfrom
AnuragMishra-akm:development
Draft

feat(security): implement screenshot protection across the application #3130
AnuragMishra-akm wants to merge 4 commits intoopenMF:developmentfrom
AnuragMishra-akm:development

Conversation

@AnuragMishra-akm
Copy link
Copy Markdown

@AnuragMishra-akm AnuragMishra-akm commented Mar 20, 2026

Fixes - (https://mifosforge.jira.com/browse/MM-573)(https://mifosforge.jira.com/browse/MM-569) [LOW] SEC-023: Add Screenshot Protection Description: Added the Screenshot prevention feature to the whole app. Now no one can take a screenshot. It runs on the device successfully.

  • [✅] Run the static analysis check ./gradlew check or ci-prepush.sh to make sure you didn't break anything

Summary by CodeRabbit

  • New Features

    • Screenshot/screen-recording protection added across platforms; Android now actively prevents captures and the login screen uses this protection.
  • Chores

    • Podspec package version updated to 0.0.1.
    • Build configuration adjusted to disable legacy license-generation tasks and refine cross-project build behavior.

AnuragMishra-akm and others added 3 commits March 18, 2026 21:49
- added FLAG_SECURE to MainActivity for global protection on Android
- created SecureScreen KMP utility in core:ui module
- applied screenshot prevention to sensitive screens including login, passcode, account details, and notifications
Disables the oss-licenses-plugin task and sets a default artifact
attribute to resolve the "Multiple artifacts exist" build failure
caused by Gradle 8.11 and the multiplatform shared module.
feat(security): implement screenshot protection across the application
@AnuragMishra-akm AnuragMishra-akm requested a review from a team March 20, 2026 18:15
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 20, 2026

📝 Walkthrough

Walkthrough

Adds a multiplatform SecureScreen composable (expect/actual) with an Android implementation that manages FLAG_SECURE, integrates SecureScreen into LoginScreen and MainActivity, and adds a Gradle subprojects block to adjust/disable OssLicenses tasks and artifact resolution.

Changes

Cohort / File(s) Summary
Build Configuration
build.gradle.kts
Added subprojects { ... } to set artifactType = "android-classes-jar" for configurations containing OssLicenses and disable tasks whose names contain OssLicensesTask.
Multiplatform SecureScreen
core/ui/src/commonMain/kotlin/.../SecureScreen.kt, core/ui/src/androidMain/kotlin/.../SecureScreen.android.kt, core/ui/src/desktopMain/kotlin/.../SecureScreen.desktop.kt, core/ui/src/nativeMain/kotlin/.../SecureScreen.native.kt
Introduced @Composable expect fun SecureScreen() and platform actual implementations. Android applies FLAG_SECURE with a reference counter; desktop/native are no-op placeholders.
Integration: Activity & Login
cmp-android/src/main/kotlin/.../MainActivity.kt, feature/auth/src/commonMain/kotlin/.../LoginScreen.kt
MainActivity sets WindowManager.LayoutParams.FLAG_SECURE on window; LoginScreen now calls SecureScreen() at start of the composable.
CocoaPods / Podspec
cmp-shared/cmp_shared.podspec
Changed spec.version 1.00.0.1, removed --no-configuration-cache from Gradle invocation in script_phases, and adjusted spec.resources path to use backslashes.

Sequence Diagram(s)

sequenceDiagram
    participant Compose as Composable (SecureScreen)
    participant Context as LocalContext / Activity
    participant Window as Window
    participant Counter as secureScreenCount

    Compose->>Context: Resolve Activity from context wrappers
    Context-->>Compose: Activity with window
    Compose->>Counter: increment()
    Note right of Counter: count++
    Compose->>Window: set FLAG_SECURE
    Window-->>Compose: FLAG_SECURE applied

    Note over Compose,Counter: Composable active

    Compose->>Counter: onDispose -> decrement()
    Note right of Counter: count--
    alt count <= 0
        Compose->>Window: clear FLAG_SECURE
        Window-->>Compose: FLAG_SECURE cleared
        Counter->>Counter: reset to 0
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Suggested reviewers

  • Arinyadav1

Poem

🐰 I hop through frames both near and far,
Counting shields beneath each star,
When screens assemble, I sit tight,
FLAG_SECURE keeps secrets out of sight,
A little rabbit guarding byte by byte.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(security): implement screenshot protection across the application' directly and comprehensively describes the main change: adding screenshot protection functionality throughout the app, which aligns perfectly with all the file changes (SecureScreen API, platform implementations, and integration into LoginScreen).

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@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: 3

🧹 Nitpick comments (1)
core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/SecureScreen.kt (1)

14-19: Make the common contract explicitly best-effort.

The KDoc reads as if SecureScreen() always blocks capture, but the desktop/native actuals are no-ops. That makes it easy for shared UI to assume protection exists on unsupported targets. Please document the unsupported platforms here, or expose capability so callers can branch explicitly.

📝 Suggested documentation update
 /**
- * A composable that enables screenshot protection for the current screen.
- * On Android, this adds WindowManager.LayoutParams.FLAG_SECURE to the window.
+ * Requests screenshot protection for the current screen on platforms that support it.
+ *
+ * Android: adds WindowManager.LayoutParams.FLAG_SECURE to the hosting window.
+ * Desktop/native: currently no-op.
  */
 `@Composable`
 expect fun SecureScreen()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/SecureScreen.kt`
around lines 14 - 19, The KDoc and expect declaration for SecureScreen currently
imply it always blocks screen capture, but actual implementations on
desktop/native are no-ops; update the common contract to state this is a
best-effort protection and explicitly list unsupported targets (e.g., desktop /
native) in the KDoc for SecureScreen, or add a capability check API (e.g.,
SecureScreen.isSupported(): Boolean) alongside the expect fun SecureScreen() so
callers can branch when protection is unavailable; reference the SecureScreen
expect function and the new isSupported capability in your change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@build.gradle.kts`:
- Around line 74-77: The current tasks.configureEach block indiscriminately
disables any task whose name contains "OssLicensesTask", which breaks OSS
license metadata for all modules; instead, restrict the disablement to the
specific failing module/task by checking the module (project) identity before
toggling the task. Modify the condition around the
name.contains("OssLicensesTask") check to also verify the project (e.g.,
project.name or project.path equals the specific module name) or target the
specific task by its exact name (using tasks.named("ExactOssLicensesTaskName")
or checking task.project.name) so only that one module/task is disabled while
leaving OssLicensesTask enabled elsewhere.

In `@cmp-shared/cmp_shared.podspec`:
- Line 53: Replace the hard-coded backslash path in spec.resources with a
platform-safe join: update the assignment to use Ruby's File.join (referencing
spec.resources) so the resource glob is built with File.join('build', 'compose',
'cocoapods', 'compose-resources') instead of the backslash string; this ensures
Dir.glob sees correct separators and the Compose assets are matched on all
platforms.

In
`@core/ui/src/androidMain/kotlin/org/mifos/mobile/core/ui/utils/SecureScreen.android.kt`:
- Around line 25-46: SecureScreen currently always increments secureScreenCount
and clears FLAG_SECURE on last dispose, which can remove the app-level
FLAG_SECURE set in MainActivity.onCreate(); change SecureScreen() so it only
marks/increments/clears when this instance actually enabled the flag: inside
SecureScreen() check window.attributes.flags &
WindowManager.LayoutParams.FLAG_SECURE == 0 before calling window.addFlags(...)
and set a local didSetFlag boolean; increment secureScreenCount only when
didSetFlag is true; onDispose only decrement secureScreenCount and call
window.clearFlags(...) if didSetFlag was true and secureScreenCount reaches 0,
leaving the app-level flag set by MainActivity.onCreate() untouched.

---

Nitpick comments:
In
`@core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/SecureScreen.kt`:
- Around line 14-19: The KDoc and expect declaration for SecureScreen currently
imply it always blocks screen capture, but actual implementations on
desktop/native are no-ops; update the common contract to state this is a
best-effort protection and explicitly list unsupported targets (e.g., desktop /
native) in the KDoc for SecureScreen, or add a capability check API (e.g.,
SecureScreen.isSupported(): Boolean) alongside the expect fun SecureScreen() so
callers can branch when protection is unavailable; reference the SecureScreen
expect function and the new isSupported capability in your change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f905f667-0919-4d67-8fcc-246821dcc126

📥 Commits

Reviewing files that changed from the base of the PR and between f638e19 and 946f676.

📒 Files selected for processing (8)
  • build.gradle.kts
  • cmp-android/src/main/kotlin/cmp/android/app/MainActivity.kt
  • cmp-shared/cmp_shared.podspec
  • core/ui/src/androidMain/kotlin/org/mifos/mobile/core/ui/utils/SecureScreen.android.kt
  • core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/SecureScreen.kt
  • core/ui/src/desktopMain/kotlin/org/mifos/mobile/core/ui/utils/SecureScreen.desktop.kt
  • core/ui/src/nativeMain/kotlin/org/mifos/mobile/core/ui/utils/SecureScreen.native.kt
  • feature/auth/src/commonMain/kotlin/org/mifos/mobile/feature/auth/login/LoginScreen.kt

Comment thread build.gradle.kts
Comment on lines +74 to +77
tasks.configureEach {
if (name.contains("OssLicensesTask", ignoreCase = true)) {
enabled = false
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Gradle files referencing the OSS licenses plugin/tasks:"
rg -n --glob '*.gradle*' -g '!**/build/**' 'oss.?licenses|OssLicenses'

echo
echo "Code or manifests referencing OSS notices surfaces:"
rg -n -g '!**/build/**' 'OssLicensesMenuActivity|open_source_licenses|oss_licenses'

Repository: openMF/mifos-mobile

Length of output: 1015


Avoid disabling the OSS licenses plugin globally.

The codebase actively surfaces OSS notices via OssLicensesMenuActivity (used in core/ui and declared in the manifest), which depends on metadata generated by OssLicensesTask. Globally disabling this task prevents license data from being generated, causing users to see non-functional or missing OSS notices—a compliance regression. Scope the workaround to the specific failing module/task instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@build.gradle.kts` around lines 74 - 77, The current tasks.configureEach block
indiscriminately disables any task whose name contains "OssLicensesTask", which
breaks OSS license metadata for all modules; instead, restrict the disablement
to the specific failing module/task by checking the module (project) identity
before toggling the task. Modify the condition around the
name.contains("OssLicensesTask") check to also verify the project (e.g.,
project.name or project.path equals the specific module name) or target the
specific task by its exact name (using tasks.named("ExactOssLicensesTaskName")
or checking task.project.name) so only that one module/task is disabled while
leaving OssLicensesTask enabled elsewhere.

}
]
spec.resources = ['build/compose/cocoapods/compose-resources']
spec.resources = ['build\compose\cocoapods\compose-resources']
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

In a CocoaPods podspec on macOS, should spec.resourcespaths use forward slashes /File.join, and do Windows-style backslashes break resource glob matching?

💡 Result:

In CocoaPods podspecs on macOS, spec.resources paths should use forward slashes (/). These paths are Ruby file glob patterns processed by Ruby's Dir.glob, which expects forward slashes as path separators universally, including on Windows where backslashes act as escape characters in glob patterns and break matching. Use forward slashes directly (e.g., spec.resources = 'Resources//.png') or File.join for dynamic paths (e.g., spec.resources = File.join('Resources', '', '.png')), as File.join produces forward slashes on all platforms. Windows-style backslashes (e.g., Resources\\*.png) will break resource glob matching because Dir.glob interprets \ as escaping the next metacharacter, preventing proper pattern matching against actual filesystem paths (which Ruby normalizes to forward slashes internally). Official CocoaPods documentation and all examples use forward slashes exclusively. Ruby's cross-platform path handling ensures forward slashes work everywhere for globs.

Citations:


Use File.join for spec.resources to ensure proper glob matching.

The backslash path separators in spec.resources = ['build\compose\cocoapods\compose-resources'] will break glob matching. Ruby's Dir.glob interprets backslashes as escape characters in glob patterns, preventing the resource glob from matching the intended directory on all platforms. This will cause the Compose assets to be omitted from the iOS pod.

🔧 Proposed fix
-    spec.resources = ['build\compose\cocoapods\compose-resources']
+    spec.resources = [File.join('build', 'compose', 'cocoapods', 'compose-resources')]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmp-shared/cmp_shared.podspec` at line 53, Replace the hard-coded backslash
path in spec.resources with a platform-safe join: update the assignment to use
Ruby's File.join (referencing spec.resources) so the resource glob is built with
File.join('build', 'compose', 'cocoapods', 'compose-resources') instead of the
backslash string; this ensures Dir.glob sees correct separators and the Compose
assets are matched on all platforms.

Comment on lines +25 to +46
private var secureScreenCount = 0

@Composable
actual fun SecureScreen() {
val context = LocalContext.current
DisposableEffect(Unit) {
val activity = context.findActivity()
val window = activity?.window

if (window != null) {
secureScreenCount++
window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
}

onDispose {
val activityOnDispose = context.findActivity()
val windowOnDispose = activityOnDispose?.window
if (windowOnDispose != null) {
secureScreenCount--
if (secureScreenCount <= 0) {
windowOnDispose.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
secureScreenCount = 0
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "MainActivity FLAG_SECURE setup:"
fd -g 'MainActivity.kt' -x sed -n '48,53p' {}

echo
echo "SecureScreen Android add/clear logic:"
fd -g 'SecureScreen.android.kt' -x sed -n '25,49p' {}

Repository: openMF/mifos-mobile

Length of output: 1183


🏁 Script executed:

cat -n core/ui/src/androidMain/kotlin/org/mifos/mobile/core/ui/utils/SecureScreen.android.kt

Repository: openMF/mifos-mobile

Length of output: 2341


🏁 Script executed:

rg "FLAG_SECURE" --type kotlin -B 2 -A 2

Repository: openMF/mifos-mobile

Length of output: 2852


Don't clear the app-level FLAG_SECURE set by MainActivity.

MainActivity.onCreate() (line 52) sets FLAG_SECURE unconditionally for the entire app. This effect clears that flag as soon as the last SecureScreen() leaves composition, re-enabling screenshots throughout the app when navigating away from login/passcode/account screens. Only clear the flag if SecureScreen itself enabled it.

🔒 Proposed fix
 private var secureScreenCount = 0
+private var initialSecureFlagState = false
 
 `@Composable`
 actual fun SecureScreen() {
     val context = LocalContext.current
     DisposableEffect(Unit) {
-        val activity = context.findActivity()
-        val window = activity?.window
+        val window = context.findActivity()?.window
 
         if (window != null) {
-            secureScreenCount++
-            window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
+            if (secureScreenCount == 0) {
+                initialSecureFlagState =
+                    (window.attributes.flags and WindowManager.LayoutParams.FLAG_SECURE) != 0
+                if (!initialSecureFlagState) {
+                    window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
+                }
+            }
+            secureScreenCount++
         }
 
         onDispose {
-            val activityOnDispose = context.findActivity()
-            val windowOnDispose = activityOnDispose?.window
-            if (windowOnDispose != null) {
-                secureScreenCount--
-                if (secureScreenCount <= 0) {
-                    windowOnDispose.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
-                    secureScreenCount = 0
+            if (window != null) {
+                secureScreenCount = (secureScreenCount - 1).coerceAtLeast(0)
+                if (secureScreenCount == 0) {
+                    if (!initialSecureFlagState) {
+                        window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
+                    }
+                    initialSecureFlagState = false
                 }
             }
         }
     }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@core/ui/src/androidMain/kotlin/org/mifos/mobile/core/ui/utils/SecureScreen.android.kt`
around lines 25 - 46, SecureScreen currently always increments secureScreenCount
and clears FLAG_SECURE on last dispose, which can remove the app-level
FLAG_SECURE set in MainActivity.onCreate(); change SecureScreen() so it only
marks/increments/clears when this instance actually enabled the flag: inside
SecureScreen() check window.attributes.flags &
WindowManager.LayoutParams.FLAG_SECURE == 0 before calling window.addFlags(...)
and set a local didSetFlag boolean; increment secureScreenCount only when
didSetFlag is true; onDispose only decrement secureScreenCount and call
window.clearFlags(...) if didSetFlag was true and secureScreenCount reaches 0,
leaving the app-level flag set by MainActivity.onCreate() untouched.

@amanna13
Copy link
Copy Markdown
Member

@AnuragMishra-akm Welcome to the community. Please give it a read before starting to contribute https://mifosforge.jira.com/wiki/spaces/MP/pages/4537024513/Welcome+to+the+Mifos+Mobile+Apps+Community.
Join the slack channel for communication. Links for all are given in the docs itself.

This tickets are yet to be properly groomed. You are free to take any OnDeck tickets across all projects.

Copy link
Copy Markdown
Contributor

@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: 1

♻️ Duplicate comments (1)
cmp-shared/cmp_shared.podspec (1)

53-53: ⚠️ Potential issue | 🟠 Major

spec.resources path separator is still unsafe for CocoaPods globbing.

Line 53 uses backslashes; this has already been flagged and remains unresolved. Use File.join (or forward slashes) so resources are reliably discovered.

🔧 Proposed fix
-    spec.resources = ['build\compose\cocoapods\compose-resources']
+    spec.resources = [File.join('build', 'compose', 'cocoapods', 'compose-resources')]
#!/bin/bash
# Detect backslash-based podspec resource paths
rg -n "spec\.resources\s*=\s*\['.*\\\\.*'\]" cmp-shared/cmp_shared.podspec
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmp-shared/cmp_shared.podspec` at line 53, spec.resources currently uses
backslashes which break CocoaPods globbing; update the assignment to use forward
slashes or File.join so the path is portable. Locate the spec.resources =
['build\compose\cocoapods\compose-resources'] line (symbol: spec.resources) and
replace the backslash-separated literal with either a forward-slash string
'build/compose/cocoapods/compose-resources' or construct the path with
File.join('build', 'compose', 'cocoapods', 'compose-resources') to ensure
reliable resource discovery.
🧹 Nitpick comments (1)
cmp-shared/cmp_shared.podspec (1)

34-52: Add trailing comma to satisfy RuboCop array-literal convention.

spec.script_phases is a multiline array and requires a trailing comma after the last element per RuboCop's Style/TrailingCommaInArrayLiteral rule.

🔧 Proposed fix
-        }
+        },
     ]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmp-shared/cmp_shared.podspec` around lines 34 - 52, The array assigned to
spec.script_phases lacks the required trailing comma; update the array literal
for spec.script_phases (the hash with :name => 'Build cmp_shared',
:execution_position, :shell_path, :script) by adding a trailing comma after the
final element so it conforms to RuboCop's Style/TrailingCommaInArrayLiteral
rule; locate the spec.script_phases assignment and append the trailing comma
immediately after the closing brace of the script hash.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@cmp-shared/cmp_shared.podspec`:
- Line 3: The podspec's declared version (spec.version in cmp_shared.podspec) is
0.0.1 but the committed lockfile (cmp-ios/Podfile.lock) pins cmp_shared as 1.0;
either update spec.version back to "1.0" in cmp_shared.podspec or, if 0.0.1 is
intentional, run pod install inside cmp-ios to regenerate cmp-ios/Podfile.lock
and commit that updated lockfile in the same PR so the podspec and Podfile.lock
stay consistent (ensure you verify the pod declaration pod 'cmp_shared', :path
=> '../cmp-shared' reflects the intended behavior).

---

Duplicate comments:
In `@cmp-shared/cmp_shared.podspec`:
- Line 53: spec.resources currently uses backslashes which break CocoaPods
globbing; update the assignment to use forward slashes or File.join so the path
is portable. Locate the spec.resources =
['build\compose\cocoapods\compose-resources'] line (symbol: spec.resources) and
replace the backslash-separated literal with either a forward-slash string
'build/compose/cocoapods/compose-resources' or construct the path with
File.join('build', 'compose', 'cocoapods', 'compose-resources') to ensure
reliable resource discovery.

---

Nitpick comments:
In `@cmp-shared/cmp_shared.podspec`:
- Around line 34-52: The array assigned to spec.script_phases lacks the required
trailing comma; update the array literal for spec.script_phases (the hash with
:name => 'Build cmp_shared', :execution_position, :shell_path, :script) by
adding a trailing comma after the final element so it conforms to RuboCop's
Style/TrailingCommaInArrayLiteral rule; locate the spec.script_phases assignment
and append the trailing comma immediately after the closing brace of the script
hash.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c6f3cb7d-6b7b-49a0-82a0-78997002db43

📥 Commits

Reviewing files that changed from the base of the PR and between 946f676 and 8efd8d8.

📒 Files selected for processing (1)
  • cmp-shared/cmp_shared.podspec

Pod::Spec.new do |spec|
spec.name = 'cmp_shared'
spec.version = '1.0'
spec.version = '0.0.1'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify podspec version vs lockfile pinned version
rg -n "spec\.version" cmp-shared/cmp_shared.podspec
rg -n "cmp_shared \(" cmp-ios/Podfile.lock

Repository: openMF/mifos-mobile

Length of output: 171


🏁 Script executed:

#!/bin/bash
# Get full context of cmp_shared in Podfile.lock
head -30 cmp-ios/Podfile.lock | cat -n

# Check if there's a Podfile in the repo
find . -name "Podfile" -type f | head -5

Repository: openMF/mifos-mobile

Length of output: 482


🏁 Script executed:

#!/bin/bash
# Get the Podfile to see how cmp_shared is declared
if [ -f "cmp-ios/Podfile" ]; then
  cat -n cmp-ios/Podfile | grep -A5 -B5 "cmp_shared" || echo "cmp_shared not found in Podfile"
fi

# Also check the full podspec to see version context
cat -n cmp-shared/cmp_shared.podspec | head -15

Repository: openMF/mifos-mobile

Length of output: 1212


Version in podspec must match committed Podfile.lock.

Line 3 sets spec.version to 0.0.1, but cmp-ios/Podfile.lock currently pins cmp_shared (1.0). Since the Podfile declares pod 'cmp_shared', :path => '../cmp-shared' without a version constraint, CocoaPods reads the version from the podspec. The next pod install will regenerate the lockfile with version 0.0.1, causing lockfile churn and CI inconsistency.

Either update the version back to 1.0, or regenerate and commit cmp-ios/Podfile.lock with the new version in the same PR.

🔧 Proposed fix
-    spec.version                  = '0.0.1'
+    spec.version                  = '1.0'

Or, if 0.0.1 is intentional, run pod install in cmp-ios/ and commit the updated lockfile.

📝 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
spec.version = '0.0.1'
spec.version = '1.0'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmp-shared/cmp_shared.podspec` at line 3, The podspec's declared version
(spec.version in cmp_shared.podspec) is 0.0.1 but the committed lockfile
(cmp-ios/Podfile.lock) pins cmp_shared as 1.0; either update spec.version back
to "1.0" in cmp_shared.podspec or, if 0.0.1 is intentional, run pod install
inside cmp-ios to regenerate cmp-ios/Podfile.lock and commit that updated
lockfile in the same PR so the podspec and Podfile.lock stay consistent (ensure
you verify the pod declaration pod 'cmp_shared', :path => '../cmp-shared'
reflects the intended behavior).

@niyajali
Copy link
Copy Markdown
Collaborator

niyajali commented Apr 1, 2026

@AnuragMishra-akm Hello, thank you for your pull request. Currently, our developers and contributors are required to upload screenshots and videos showcasing their changes. Enabling this feature will prevent them from capturing screenshots. There is a field within the class that allows us to check if the user has enabled this setting. We need to extend this functionality across all platforms, not just Android. Therefore, please make this pull request a draft and enhance it accordingly. Inform us once all changes are complete and it is ready for review.

@niyajali
Copy link
Copy Markdown
Collaborator

niyajali commented Apr 1, 2026

and the purpose of the ticket is to stop screenshots on specific screens, not the entire application.

@niyajali niyajali marked this pull request as draft April 3, 2026 15:01
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.

3 participants