Coverage for apps / core / middleware.py: 100%

29 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-11 00:40 +0000

1import re 

2 

3 

4class DeviceDetectionMiddleware: 

5 """Middleware to detect legacy browsers that can't run modern React. 

6 

7 Sets request.is_legacy_device = True for browsers that need the legacy frontend: 

8 - iOS < 11 (Safari lacks ES6 module support) 

9 - Internet Explorer (all versions) 

10 - Edge Legacy (non-Chromium, pre-2020) 

11 - Chrome < 60 

12 - Firefox < 55 

13 

14 Note: Actual redirects are handled by Nginx for performance (see nginx/nginx.conf). 

15 This middleware provides the detection flag for use in views/templates if needed. 

16 """ 

17 

18 # Pattern to match iOS version from user agent 

19 IOS_PATTERN = re.compile(r'(?:iPhone|iPad|iPod).*OS (\d+)_') 

20 

21 # Pattern to match Chrome version 

22 CHROME_PATTERN = re.compile(r'Chrome/(\d+)\.') 

23 

24 # Pattern to match Firefox version 

25 FIREFOX_PATTERN = re.compile(r'Firefox/(\d+)\.') 

26 

27 def __init__(self, get_response): 

28 self.get_response = get_response 

29 

30 def __call__(self, request): 

31 request.is_legacy_device = self._is_legacy_device(request) 

32 return self.get_response(request) 

33 

34 def _is_legacy_device(self, request): 

35 """Check if the request is from a browser that can't run modern React.""" 

36 user_agent = request.META.get('HTTP_USER_AGENT', '') 

37 if not user_agent: 

38 return False 

39 

40 # iOS < 11 

41 match = self.IOS_PATTERN.search(user_agent) 

42 if match: 

43 return int(match.group(1)) < 11 

44 

45 # Internet Explorer 

46 if 'MSIE ' in user_agent or 'Trident/' in user_agent: 

47 return True 

48 

49 # Edge Legacy (non-Chromium) 

50 if 'Edge/' in user_agent and 'Edg/' not in user_agent: 

51 return True 

52 

53 # Chrome < 60 

54 if 'Chrome/' in user_agent and 'Edg' not in user_agent and 'OPR/' not in user_agent: 

55 match = self.CHROME_PATTERN.search(user_agent) 

56 if match and int(match.group(1)) < 60: 

57 return True 

58 

59 # Firefox < 55 

60 match = self.FIREFOX_PATTERN.search(user_agent) 

61 if match and int(match.group(1)) < 55: 

62 return True 

63 

64 return False 

← Back to Dashboard