diff --git a/PROJECT_STATE.md b/PROJECT_STATE.md index 59ef3ad..246202e 100644 --- a/PROJECT_STATE.md +++ b/PROJECT_STATE.md @@ -92,3 +92,11 @@ Infrastructure: - Improved UX: no manual code entry required - Portal onboarding now production-ready + +## v1.1.0 - 2026-05-03 +- Added portal-based Android app download system +- Secure APK delivery through OTB Billing (authenticated route) +- "Download Android App" button added to OTB Cloud service card +- Centralized app distribution strategy established +- Foundation laid for future Follow-me and additional app downloads + diff --git a/README.md b/README.md index 478ff21..37513d9 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ +## v1.1.0 (2026-05-03) +- Portal-based Android app downloads +- Secure APK delivery via authenticated route +- OTB Cloud card now includes app download button + ## v1.0.0 (2026-05-03) - Clickable portal invite links - Direct account activation from email diff --git a/VERSION b/VERSION index 0ec25f7..795460f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v1.0.0 +v1.1.0 diff --git a/backend/routes/portal_services.py b/backend/routes/portal_services.py index 6c65904..5359276 100644 --- a/backend/routes/portal_services.py +++ b/backend/routes/portal_services.py @@ -1,4 +1,5 @@ -from flask import Blueprint, render_template, session, redirect, url_for, flash +from pathlib import Path +from flask import send_file, abort, Blueprint, render_template, session, redirect, url_for, flash import hmac, hashlib, time, urllib.parse, os OTB_PORTAL_SHARED_SECRET = os.getenv("OTB_PORTAL_SHARED_SECRET", "!2Eas678") @@ -115,3 +116,42 @@ def portal_launch_otb_cloud(): url = build_otb_cloud_handoff_url(uid, email) return redirect(url) + + +@portal_services_bp.route("/portal/downloads/apps//latest") +def portal_download_latest_app(app_slug): + client = get_portal_client() + if not client: + return redirect("/portal") + + allowed_apps = { + "otb-cloud": { + "filename": "latest.apk", + "download_name": "otb-cloud-latest.apk", + }, + "follow-me": { + "filename": "latest.apk", + "download_name": "follow-me-latest.apk", + }, + } + + if app_slug not in allowed_apps: + abort(404) + + base_dir = Path(__file__).resolve().parents[2] / "downloads" / "apps" / app_slug + file_path = (base_dir / allowed_apps[app_slug]["filename"]).resolve() + + try: + if base_dir.resolve() not in file_path.parents: + abort(403) + if not file_path.exists() or not file_path.is_file(): + abort(404) + except Exception: + abort(404) + + return send_file( + str(file_path), + as_attachment=True, + download_name=allowed_apps[app_slug]["download_name"], + mimetype="application/vnd.android.package-archive", + ) diff --git a/bump.sh b/bump.sh index d5096d5..027ba61 100755 --- a/bump.sh +++ b/bump.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -e -VERSION="v0.3.0" +VERSION="v1.1.0" DATE="$(date +%Y-%m-%d)" STAMP="$(date +%Y%m%d-%H%M%S)" @@ -20,25 +20,25 @@ echo "===== UPDATE PROJECT_STATE.md =====" cat <> PROJECT_STATE.md ## $VERSION - $DATE -- Portal onboarding flow upgraded -- Email invites now include clickable activation link -- /portal/set-password now supports direct email+code login -- Auto session creation from invite link -- Improved UX: no manual code entry required -- Portal onboarding now production-ready +- Added portal-based Android app download system +- Secure APK delivery through OTB Billing (authenticated route) +- "Download Android App" button added to OTB Cloud service card +- Centralized app distribution strategy established +- Foundation laid for future Follow-me and additional app downloads STATE echo "===== UPDATE README.md =====" sed -i "1i\\ ## $VERSION ($DATE)\\ -- Clickable portal invite links\\ -- Direct account activation from email\\ -- Improved onboarding UX\\ +- Portal-based Android app downloads\\ +- Secure APK delivery via authenticated route\\ +- OTB Cloud card now includes app download button\\ " README.md echo "===== VERIFY PYTHON =====" python3 -m py_compile backend/app.py +python3 -m py_compile backend/routes/portal_services.py echo "===== CREATE FULL BACKUP =====" zip -r "/home/def/backuphere/otb_billing-$VERSION-$STAMP.zip" . >/dev/null @@ -47,7 +47,7 @@ echo "===== GIT ADD =====" git add . echo "===== GIT COMMIT =====" -git commit -m "Release $VERSION - Portal onboarding flow complete (email link activation)" +git commit -m "Release $VERSION - Portal app download system + OTB Cloud integration" echo "===== GIT TAG =====" git tag "$VERSION" diff --git a/downloads/apps/otb-cloud/latest.apk b/downloads/apps/otb-cloud/latest.apk new file mode 120000 index 0000000..18b399f --- /dev/null +++ b/downloads/apps/otb-cloud/latest.apk @@ -0,0 +1 @@ +otb-cloud-v0.3.3.apk \ No newline at end of file diff --git a/downloads/apps/otb-cloud/otb-cloud-v0.3.3.apk b/downloads/apps/otb-cloud/otb-cloud-v0.3.3.apk new file mode 100755 index 0000000..4ac2e66 Binary files /dev/null and b/downloads/apps/otb-cloud/otb-cloud-v0.3.3.apk differ diff --git a/templates/portal/services_here.html b/templates/portal/services_here.html index f24b805..7fbde26 100644 --- a/templates/portal/services_here.html +++ b/templates/portal/services_here.html @@ -45,10 +45,16 @@ -
+
{% if service.enabled %} {{ service.button_text }} + + {% if service.name == "OTB Cloud Backup & Storage" %} + + Download Android App + + {% endif %} {% else %} {% endif %} @@ -57,6 +63,8 @@ {% endfor %} + +