All checks were successful
PR Checks / android-build (pull_request) Successful in 10m30s
The app is purely an HTTPS API client, but the manifest left usesCleartextTraffic implicit, which SonarQube S5332 flags (cleartext is implicitly permitted on older Android and a merged library manifest could re-enable it). Add an explicit network security config: - main/release: base-config cleartextTrafficPermitted="false" (no cleartext). - debug override (app/src/debug/res/xml): re-permits cleartext to loopback (127.0.0.1/localhost) only, for local dev against http://127.0.0.1:3000. This mirrors ServerUrl's rule (HTTPS required in release, HTTP allowed in debug via allowInsecureHttp = BuildConfig.DEBUG) at the platform socket layer. It also fixes a latent gap: at targetSdk 28+ the platform default already blocks cleartext, so the debug loopback path only actually works with the explicit domain-config now added. Docs updated in RunicGateway/docs (android/PLAN.md M1). Co-Authored-By: Claude <noreply@anthropic.com>
81 lines
4.1 KiB
XML
81 lines
4.1 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- SPDX-License-Identifier: GPL-3.0-or-later -->
|
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
|
|
<!-- The app is purely an HTTPS API client of a shard's website backend. -->
|
|
<uses-permission android:name="android.permission.INTERNET" />
|
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
|
|
|
<!-- Opt-in push notifications (M7): the runtime notification permission (API 33+)
|
|
and a foreground service that holds the persistent ntfy connection open — the
|
|
embedded UnifiedPush distributor, so no separate app is needed (PLAN.md §11). -->
|
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
|
|
|
<application
|
|
android:name=".RunicGatewayApp"
|
|
android:allowBackup="true"
|
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
|
android:fullBackupContent="@xml/backup_rules"
|
|
android:icon="@mipmap/ic_launcher"
|
|
android:label="@string/app_name"
|
|
android:networkSecurityConfig="@xml/network_security_config"
|
|
android:roundIcon="@mipmap/ic_launcher_round"
|
|
android:supportsRtl="true"
|
|
android:theme="@style/Theme.RunicGateway">
|
|
|
|
<!-- singleTop so the SSO Custom Tab returning via the deep link reuses the
|
|
running task (onNewIntent) instead of stacking a second activity. -->
|
|
<activity
|
|
android:name=".MainActivity"
|
|
android:exported="true"
|
|
android:launchMode="singleTop"
|
|
android:theme="@style/Theme.RunicGateway">
|
|
<intent-filter>
|
|
<action android:name="android.intent.action.MAIN" />
|
|
<category android:name="android.intent.category.LAUNCHER" />
|
|
</intent-filter>
|
|
|
|
<!-- Native SSO callback (M9, PLAN.md §4.2). The bridge deep-links the
|
|
one-time authorization code back to this fixed, app-owned custom
|
|
scheme; it must match SsoAuthManager.REDIRECT_URI and the backend's
|
|
MOBILE_AUTH_REDIRECT_URIS allowlist exactly. This is the permanent
|
|
fallback on every build (docs/android/APP_LINKS.md). -->
|
|
<intent-filter>
|
|
<action android:name="android.intent.action.VIEW" />
|
|
<category android:name="android.intent.category.DEFAULT" />
|
|
<category android:name="android.intent.category.BROWSABLE" />
|
|
<data
|
|
android:scheme="runicgateway"
|
|
android:host="auth"
|
|
android:path="/callback" />
|
|
</intent-filter>
|
|
|
|
<!-- App Links hardening (docs/android/APP_LINKS.md): a verified https
|
|
callback that only the domain's real owner can claim. autoVerify
|
|
needs a literal host, so ${appLinkHost} is baked at build time
|
|
(build.gradle.kts). The generic build leaves it as the reserved
|
|
runic-gateway.invalid sentinel — the filter then matches no real
|
|
link and never verifies. A white-label build sets -PappLinkHost. -->
|
|
<intent-filter android:autoVerify="true">
|
|
<action android:name="android.intent.action.VIEW" />
|
|
<category android:name="android.intent.category.DEFAULT" />
|
|
<category android:name="android.intent.category.BROWSABLE" />
|
|
<data
|
|
android:scheme="https"
|
|
android:host="${appLinkHost}"
|
|
android:path="/mobile/callback" />
|
|
</intent-filter>
|
|
</activity>
|
|
|
|
<!-- The embedded distributor's persistent ntfy connection (M7, PLAN.md §11).
|
|
dataSync foreground type; not exported — started only by PushManager. -->
|
|
<service
|
|
android:name=".core.push.PushService"
|
|
android:exported="false"
|
|
android:foregroundServiceType="dataSync" />
|
|
</application>
|
|
|
|
</manifest>
|