Skip to content
Closed

Dev #11

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
38 changes: 38 additions & 0 deletions .github/workflows/generate-keystore.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Generate Release Keystore

on:
workflow_dispatch:

permissions:
contents: read

jobs:
generate:
runs-on: ubuntu-latest

steps:
- name: Generate Release Keystore
run: |
keytool -genkeypair -alias consoleflow -keyalg RSA -keysize 2048 -validity 10000 -keystore release.keystore -storepass consoleflow123 -keypass consoleflow123 -dname "CN=consoleflow, OU=App, O=consoleflow, L=Unknown, ST=Unknown, C=US"

echo ""
echo "================================================"
echo " COPY THESE VALUES TO GITHUB SECRETS"
echo "================================================"
echo ""
echo "Secret name: KEYSTORE_B64"
echo "Secret value (copy everything between the lines):"
echo "----"
base64 -w 0 release.keystore
echo ""
echo "----"
echo ""
echo "Secret name: KEY_ALIAS"
echo "Secret value: consoleflow"
echo ""
echo "Secret name: KEYSTORE_PASSWORD"
echo "Secret value: consoleflow123"
echo ""
echo "Secret name: KEY_PASSWORD"
echo "Secret value: consoleflow123"
Comment on lines +14 to +37

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Keystore leaked in logs 🐞 Bug ⛨ Security

The new generate-keystore workflow prints the base64-encoded release keystore and its hardcoded
passwords to the GitHub Actions logs, exposing the signing private key to anyone with log access.
This can enable malicious actors to sign and distribute counterfeit “official” releases.
Agent Prompt
## Issue description
The workflow `.github/workflows/generate-keystore.yml` prints the release keystore (`base64 -w 0 release.keystore`) and hardcoded passwords to stdout, which ends up in CI logs and leaks signing material.

## Issue Context
Release signing keys must never be printed or stored in logs. Even for a manually triggered workflow, logs are typically accessible to many users/roles and may be retained.

## Fix Focus Areas
- Remove or heavily restrict this workflow; do not output keystore/passwords to logs.
- If you must generate in CI, upload the keystore as a short-lived artifact and protect the environment with required reviewers; do not echo secrets.
- Use randomly generated passwords (or inputs) rather than hardcoded values.

## Fix Focus Areas (code references)
- .github/workflows/generate-keystore.yml[14-37]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

echo ""
47 changes: 47 additions & 0 deletions .github/workflows/quick-apk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Quick APK

on:
workflow_dispatch:
push:

permissions:
contents: read

jobs:
build:
name: Build quick APK
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
cache: gradle

- name: Make Gradle wrapper executable
run: chmod +x ./gradlew

- name: Build debug APK
run: ./gradlew assembleDebug --no-daemon

- name: Rename APK
id: rename
run: |
APK_PATH=$(find app/build/outputs/apk/debug -name '*.apk' | head -n 1)
SHORT_SHA="${GITHUB_SHA::7}"
NEW_NAME="ConsoleFlow-quick-${SHORT_SHA}.apk"
cp "$APK_PATH" "$NEW_NAME"
echo "apk_path=$NEW_NAME" >> "$GITHUB_OUTPUT"

- name: Upload APK artifact
uses: actions/upload-artifact@v4
with:
name: ConsoleFlow-quick-apk
path: ${{ steps.rename.outputs.apk_path }}
if-no-files-found: error
retention-days: 14
23 changes: 17 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ permissions:

jobs:
build:
name: Build APK and Replace Release
name: Build Release APK and Replace Release
runs-on: ubuntu-latest

steps:
Expand Down Expand Up @@ -64,15 +64,26 @@ jobs:
gh release delete "$TAG" -y
fi

- name: Build Debug APK
run: ./gradlew assembleDebug --no-daemon
- name: Restore keystore from secret
env:
KEYSTORE_B64: ${{ secrets.KEYSTORE_B64 }}
run: |
echo "$KEYSTORE_B64" | base64 --decode > release.keystore

- name: Build Release APK
env:
KEYSTORE_FILE: ${{ github.workspace }}/release.keystore
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
run: ./gradlew assembleRelease --no-daemon

- name: Locate and Rename APK
id: apk
run: |
ORIGINAL_PATH=$(find app/build/outputs/apk/debug -name "*.apk" | head -1)
ORIGINAL_PATH=$(find app/build/outputs/apk/release -name "*.apk" | head -1)
NEW_NAME="${{ steps.metadata.outputs.apk_custom_name }}"
NEW_PATH="app/build/outputs/apk/debug/$NEW_NAME"
NEW_PATH="app/build/outputs/apk/release/$NEW_NAME"

mv "$ORIGINAL_PATH" "$NEW_PATH"
echo "path=$NEW_PATH" >> $GITHUB_OUTPUT
Expand All @@ -85,4 +96,4 @@ jobs:
prerelease: ${{ steps.metadata.outputs.pre }}
body: ${{ steps.metadata.outputs.body }}
files: ${{ steps.apk.outputs.path }}
generate_release_notes: true
generate_release_notes: true
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.keystore
*.jks
release.keystore
debug.keystore
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Changelog

## v2.2.8

### What is new

- Added a **new dedicated download management system** with its own page.
- Added **full support** for controllers, keyboard, mouse, and TV remotes.
- Fixed some issues and made other improvements.
- New app logo
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
**A lightweight, developer-focused Android web browser that brings desktop-like debugging to mobile.**

[![Open Source](https://img.shields.io/badge/Open%20Source-Yes!-brightgreen?style=for-the-badge)](#)
[![GitHub stars](https://img.shields.io/github/stars/SANDRO00O/ConsoleFlow-mobile?style=for-the-badge&logo=github)](https://github.com/SANDRO00O/ConsoleFlow-mobile/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/SANDRO00O/ConsoleFlow-mobile?style=for-the-badge&logo=github)](https://github.com/SANDRO00O/ConsoleFlow-mobile/network/members)
[![License](https://img.shields.io/badge/License-MIT-green?style=for-the-badge)](https://github.com/SANDRO00O/ConsoleFlow-mobile/blob/main/LICENSE)
[![Downloads](https://img.shields.io/github/downloads/SANDRO00O/ConsoleFlow-mobile/total?logo=github)](https://github.com/SANDRO00O/ConsoleFlow-mobile/releases)
[![Downloads last month](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgithub.com%2Fkitswas%2Ffdroid-metrics-dashboard%2Fraw%2Frefs%2Fheads%2Fmain%2Fprocessed%2Fmonthly%2Fspace.karrarnazim.ConsoleFlow.json&query=%24.total_downloads&logo=fdroid&label=Downloads%20last%20month)](https://f-droid.org/en/packages/space.karrarnazim.ConsoleFlow/)

<br>

Expand Down Expand Up @@ -50,6 +50,7 @@
- **Bookmarks & History:** Built-in local storage manager for your favorite sites and browsing history.
- **Native Downloads:** Integrated with Android's native `DownloadManager` for stable file downloading.
- **Sleek UI:** Custom dark-themed start page, error pages, menus, and Android 12+ Splash Screen support.
- **Full TV Support:** Optimized for Android TV and TV remotes, with complete controller, keyboard, mouse, and remote navigation support.

## Tech Stack & Libraries

Expand Down
16 changes: 13 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,22 @@ defaultConfig {
applicationId "space.karrarnazim.ConsoleFlow"
minSdk 24
targetSdk 35
versionCode 8
versionName "2.1.8"
versionCode 13
versionName "2.2.8"
}

signingConfigs {
release {
storeFile file(System.getenv("KEYSTORE_FILE") ?: "$rootDir/release.keystore")
storePassword System.getenv("KEYSTORE_PASSWORD")
keyAlias System.getenv("KEY_ALIAS")
keyPassword System.getenv("KEY_PASSWORD")
}
}

buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
Expand Down Expand Up @@ -44,4 +54,4 @@ implementation 'com.google.android.material:material:1.12.0'
implementation 'androidx.recyclerview:recyclerview:1.3.2'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
}
}
47 changes: 45 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,48 @@
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<!-- Download service permissions -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC"
android:minSdkVersion="34" />
<!-- Shows download-complete notifications on Android 13+ -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"
android:minSdkVersion="33" />

<!-- Touch is NOT required — allows install on Android TV / Fire TV / tablets -->
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
<!-- Leanback (Android TV platform) — optional, enables TV launcher icon -->
<uses-feature android:name="android.software.leanback" android:required="false" />

<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher"
android:banner="@drawable/tv_banner"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:hardwareAccelerated="true"
android:usesCleartextTraffic="true">

<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize|keyboardHidden|smallestScreenSize|screenLayout"
android:configChanges="orientation|screenSize|keyboardHidden|smallestScreenSize|screenLayout|keyboard|navigation"
android:exported="true"
android:launchMode="singleTask"
android:theme="@style/AppTheme.SplashScreen"
android:windowSoftInputMode="adjustPan">
<!-- Phone / tablet launcher -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- Android TV / Fire TV launcher (shows app on TV home screen) -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
<!-- URL intent handling -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
Expand All @@ -41,9 +62,31 @@

<activity
android:name=".SettingsActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard|navigation"
android:exported="false"
android:theme="@style/AppTheme"
android:windowSoftInputMode="adjustPan" />

<activity
android:name=".AboutActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard|navigation"
android:exported="false"
android:theme="@style/AppTheme"
android:windowSoftInputMode="adjustPan" />

<!-- Downloads page activity -->
<activity
android:name=".DownloadsActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard|navigation"
android:exported="false"
android:theme="@style/AppTheme"
android:windowSoftInputMode="adjustPan" />

<!-- Foreground download service — dataSync type required on API 34+ -->
<service
android:name=".DownloadService"
android:exported="false"
android:foregroundServiceType="dataSync" />

</application>
</manifest>
8 changes: 8 additions & 0 deletions app/src/main/assets/banner.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading