From 31a0c3c8c541921a55b75ccc542d1da704ead763 Mon Sep 17 00:00:00 2001 From: Keith Smith Date: Fri, 26 Dec 2025 22:08:05 -0700 Subject: [PATCH] Add middleware to allow mobile app iframe embedding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created Django middleware that detects requests from the KeepItGoing mobile app (via User-Agent) and removes X-Frame-Options header to allow iframe embedding. Changes: - Created tasks/middleware/mobile_app.py with AllowMobileAppFramingMiddleware - Added middleware to settings after XFrameOptionsMiddleware - Detects Capacitor WebView User-Agent patterns - Removes X-Frame-Options only for mobile app, keeps protection for browsers This allows the mobile app to embed the website in an iframe while maintaining clickjacking protection for regular web browsers. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- config/settings/base.py | 1 + tasks/middleware/__init__.py | 3 +++ tasks/middleware/mobile_app.py | 39 ++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 tasks/middleware/__init__.py create mode 100644 tasks/middleware/mobile_app.py diff --git a/config/settings/base.py b/config/settings/base.py index 1725362..280f088 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -44,6 +44,7 @@ MIDDLEWARE = [ 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'tasks.middleware.AllowMobileAppFramingMiddleware', # Allow mobile app iframe embedding ] ROOT_URLCONF = 'config.urls' diff --git a/tasks/middleware/__init__.py b/tasks/middleware/__init__.py new file mode 100644 index 0000000..4eb4b28 --- /dev/null +++ b/tasks/middleware/__init__.py @@ -0,0 +1,3 @@ +from .mobile_app import AllowMobileAppFramingMiddleware + +__all__ = ['AllowMobileAppFramingMiddleware'] diff --git a/tasks/middleware/mobile_app.py b/tasks/middleware/mobile_app.py new file mode 100644 index 0000000..23ec683 --- /dev/null +++ b/tasks/middleware/mobile_app.py @@ -0,0 +1,39 @@ +""" +Middleware to allow iframe embedding for the KeepItGoing mobile app. + +The mobile app uses Capacitor WebView which embeds the website in an iframe. +This middleware detects requests from the mobile app and removes X-Frame-Options +header to allow iframe embedding, while keeping clickjacking protection for +regular web browsers. +""" + + +class AllowMobileAppFramingMiddleware: + """ + Remove X-Frame-Options header for requests from KeepItGoing mobile app. + + The mobile app uses a Capacitor WebView with a specific User-Agent pattern. + We detect these requests and allow iframe embedding for them. + """ + + def __init__(self, get_response): + self.get_response = get_response + + def __call__(self, request): + response = self.get_response(request) + + # Check if request is from KeepItGoing mobile app + user_agent = request.META.get('HTTP_USER_AGENT', '') + + # Capacitor apps include "CapacitorHttp" or the app package name in User-Agent + is_mobile_app = ( + 'CapacitorHttp' in user_agent or + 'com.firebugit.keepitgoing' in user_agent or + 'KeepItGoing' in user_agent and 'Mobile' in user_agent + ) + + # Remove X-Frame-Options for mobile app requests + if is_mobile_app and 'X-Frame-Options' in response: + del response['X-Frame-Options'] + + return response