diff --git a/backend/routes/portal_services.py b/backend/routes/portal_services.py index 23dfed0..6718bac 100644 --- a/backend/routes/portal_services.py +++ b/backend/routes/portal_services.py @@ -1,4 +1,8 @@ from flask import 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") +OTB_CLOUD_URL = os.getenv("OTB_CLOUD_URL", "https://otb-cloud.outsidethebox.top") portal_services_bp = Blueprint("portal_services", __name__) @@ -37,7 +41,7 @@ def portal_services_home(): "summary": "Create and manage your GPS tracking network. Free for up to 2 users.", "status": "beta", "enabled": True, - "href": "https://follow-me.outsidethebox.top", + "href": "/portal/services/follow-me-launch", "button_text": "Open Follow-me", }, { @@ -49,6 +53,15 @@ def portal_services_home(): "href": "#", "button_text": "Coming Soon", }, + { + "key": "otb_cloud", + "name": "OTB Cloud Backup & Storage", + "summary": "Secure backup and storage for documents, photos, videos, and device uploads.", + "status": "beta", + "enabled": True, + "href": "/portal/services/otb-cloud-launch", + "button_text": "Open OTB Cloud", + }, { "key": "miner_rentals", "name": "Miner Rentals", @@ -66,3 +79,44 @@ def portal_services_home(): client_name=client_name, services=services, ) + + +def build_otb_cloud_handoff_url(uid, email): + ts = str(int(time.time())) + payload = f"{uid}|{email}|{ts}".encode("utf-8") + sig = hmac.new( + OTB_PORTAL_SHARED_SECRET.encode(), + payload, + hashlib.sha256 + ).hexdigest() + + query = urllib.parse.urlencode({ + "uid": uid, + "email": email, + "ts": ts, + "sig": sig, + }) + + return f"{OTB_CLOUD_URL}/auth/handoff?{query}" + + +@portal_services_bp.route("/portal/services/otb-cloud-launch") +def portal_launch_otb_cloud(): + if not _portal_user_is_logged_in(): + flash("Please sign in to access services.", "warning") + return redirect(url_for("portal_login")) + + uid = ( + session.get("portal_user_id") + or session.get("client_id") + or session.get("user_id") + ) + + email = ( + session.get("portal_email") + or session.get("email") + or "unknown@example.com" + ) + + url = build_otb_cloud_handoff_url(uid, email) + return redirect(url)