We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Clear `prefers_web_public_view` cookie when logging in or registering an account
In #19902, we added functionality to remember who had accessed Zulip as a spectator and immediately take them to the spectator experience.  We probably want to clear the `prefers_web_public_view` cookie when logging in via `do_login` or registering a new account, since the user likely doesn't want to get the spectator experience on future visits to the site.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `zerver/views/home.py`
Content:
```
1 import logging
2 import secrets
3 from typing import List, Optional, Tuple
4 
5 from django.conf import settings
6 from django.http import HttpRequest, HttpResponse
7 from django.shortcuts import redirect, render
8 from django.utils.cache import patch_cache_control
9 
10 from zerver.context_processors import get_valid_realm_from_request
11 from zerver.decorator import web_public_view, zulip_login_required, zulip_redirect_to_login
12 from zerver.forms import ToSForm
13 from zerver.lib.actions import do_change_tos_version, realm_user_count
14 from zerver.lib.compatibility import is_outdated_desktop_app, is_unsupported_browser
15 from zerver.lib.home import build_page_params_for_home_page_load, get_user_permission_info
16 from zerver.lib.request import RequestNotes
17 from zerver.lib.streams import access_stream_by_name
18 from zerver.lib.subdomains import get_subdomain
19 from zerver.lib.utils import statsd
20 from zerver.models import PreregistrationUser, Realm, Stream, UserProfile
21 from zerver.views.auth import get_safe_redirect_to
22 from zerver.views.portico import hello_view
23 
24 
25 def need_accept_tos(user_profile: Optional[UserProfile]) -> bool:
26     if user_profile is None:
27         return False
28 
29     if settings.TERMS_OF_SERVICE is None:  # nocoverage
30         return False
31 
32     if settings.TOS_VERSION is None:
33         return False
34 
35     return int(settings.TOS_VERSION.split(".")[0]) > user_profile.major_tos_version()
36 
37 
38 @zulip_login_required
39 def accounts_accept_terms(request: HttpRequest) -> HttpResponse:
40     assert request.user.is_authenticated
41 
42     if request.method == "POST":
43         form = ToSForm(request.POST)
44         if form.is_valid():
45             do_change_tos_version(request.user, settings.TOS_VERSION)
46             return redirect(home)
47     else:
48         form = ToSForm()
49 
50     email = request.user.delivery_email
51     special_message_template = None
52     if request.user.tos_version is None and settings.FIRST_TIME_TOS_TEMPLATE is not None:
53         special_message_template = "zerver/" + settings.FIRST_TIME_TOS_TEMPLATE
54     return render(
55         request,
56         "zerver/accounts_accept_terms.html",
57         context={
58             "form": form,
59             "email": email,
60             "special_message_template": special_message_template,
61         },
62     )
63 
64 
65 def detect_narrowed_window(
66     request: HttpRequest, user_profile: Optional[UserProfile]
67 ) -> Tuple[List[List[str]], Optional[Stream], Optional[str]]:
68     """This function implements Zulip's support for a mini Zulip window
69     that just handles messages from a single narrow"""
70     if user_profile is None:
71         return [], None, None
72 
73     narrow: List[List[str]] = []
74     narrow_stream = None
75     narrow_topic = request.GET.get("topic")
76 
77     if request.GET.get("stream"):
78         try:
79             # TODO: We should support stream IDs and PMs here as well.
80             narrow_stream_name = request.GET.get("stream")
81             (narrow_stream, ignored_sub) = access_stream_by_name(user_profile, narrow_stream_name)
82             narrow = [["stream", narrow_stream.name]]
83         except Exception:
84             logging.warning("Invalid narrow requested, ignoring", extra=dict(request=request))
85         if narrow_stream is not None and narrow_topic is not None:
86             narrow.append(["topic", narrow_topic])
87     return narrow, narrow_stream, narrow_topic
88 
89 
90 def update_last_reminder(user_profile: Optional[UserProfile]) -> None:
91     """Reset our don't-spam-users-with-email counter since the
92     user has since logged in
93     """
94     if user_profile is None:
95         return
96 
97     if user_profile.last_reminder is not None:  # nocoverage
98         # TODO: Look into the history of last_reminder; we may have
99         # eliminated that as a useful concept for non-bot users.
100         user_profile.last_reminder = None
101         user_profile.save(update_fields=["last_reminder"])
102 
103 
104 def home(request: HttpRequest) -> HttpResponse:
105     if not settings.ROOT_DOMAIN_LANDING_PAGE:
106         return home_real(request)
107 
108     # If settings.ROOT_DOMAIN_LANDING_PAGE, sends the user the landing
109     # page, not the login form, on the root domain
110 
111     subdomain = get_subdomain(request)
112     if subdomain != Realm.SUBDOMAIN_FOR_ROOT_DOMAIN:
113         return home_real(request)
114 
115     return hello_view(request)
116 
117 
118 @web_public_view
119 def home_real(request: HttpRequest) -> HttpResponse:
120     # Before we do any real work, check if the app is banned.
121     client_user_agent = request.META.get("HTTP_USER_AGENT", "")
122     (insecure_desktop_app, banned_desktop_app, auto_update_broken) = is_outdated_desktop_app(
123         client_user_agent
124     )
125     if banned_desktop_app:
126         return render(
127             request,
128             "zerver/insecure_desktop_app.html",
129             context={
130                 "auto_update_broken": auto_update_broken,
131             },
132         )
133     (unsupported_browser, browser_name) = is_unsupported_browser(client_user_agent)
134     if unsupported_browser:
135         return render(
136             request,
137             "zerver/unsupported_browser.html",
138             context={
139                 "browser_name": browser_name,
140             },
141         )
142 
143     # We need to modify the session object every two weeks or it will expire.
144     # This line makes reloading the page a sufficient action to keep the
145     # session alive.
146     request.session.modified = True
147 
148     if request.user.is_authenticated:
149         user_profile = request.user
150         realm = user_profile.realm
151     else:
152         realm = get_valid_realm_from_request(request)
153 
154         # TODO: Ideally, we'd open Zulip directly as a spectator if
155         # the URL had clicked a link to content on a web-public
156         # stream.  We could maybe do this by parsing `next`, but it's
157         # not super convenient with Zulip's hash-based URL scheme.
158 
159         # The "Access without an account" button on the login page
160         # submits a POST to this page with this hidden field set.
161         if request.POST.get("prefers_web_public_view") == "true":
162             request.session["prefers_web_public_view"] = True
163             # We serve a redirect here, rather than serving a page, to
164             # avoid browser "Confirm form resubmission" prompts on reload.
165             redirect_to = get_safe_redirect_to(request.POST.get("next"), realm.uri)
166             return redirect(redirect_to)
167 
168         prefers_web_public_view = request.session.get("prefers_web_public_view")
169         if not prefers_web_public_view:
170             # For users who haven't opted into the spectator
171             # experience, we redirect to the login page.
172             return zulip_redirect_to_login(request, settings.HOME_NOT_LOGGED_IN)
173 
174         # For users who have selected public access, we load the
175         # spectator experience.  We fall through to the shared code
176         # for loading the application, with user_profile=None encoding
177         # that we're a spectator, not a logged-in user.
178         user_profile = None
179 
180     update_last_reminder(user_profile)
181 
182     statsd.incr("views.home")
183 
184     # If a user hasn't signed the current Terms of Service, send them there
185     if need_accept_tos(user_profile):
186         return accounts_accept_terms(request)
187 
188     narrow, narrow_stream, narrow_topic = detect_narrowed_window(request, user_profile)
189 
190     if user_profile is not None:
191         first_in_realm = realm_user_count(user_profile.realm) == 1
192         # If you are the only person in the realm and you didn't invite
193         # anyone, we'll continue to encourage you to do so on the frontend.
194         prompt_for_invites = (
195             first_in_realm
196             and not PreregistrationUser.objects.filter(referred_by=user_profile).count()
197         )
198         needs_tutorial = user_profile.tutorial_status == UserProfile.TUTORIAL_WAITING
199 
200     else:
201         first_in_realm = False
202         prompt_for_invites = False
203         # The current tutorial doesn't super make sense for logged-out users.
204         needs_tutorial = False
205 
206     queue_id, page_params = build_page_params_for_home_page_load(
207         request=request,
208         user_profile=user_profile,
209         realm=realm,
210         insecure_desktop_app=insecure_desktop_app,
211         narrow=narrow,
212         narrow_stream=narrow_stream,
213         narrow_topic=narrow_topic,
214         first_in_realm=first_in_realm,
215         prompt_for_invites=prompt_for_invites,
216         needs_tutorial=needs_tutorial,
217     )
218 
219     log_data = RequestNotes.get_notes(request).log_data
220     assert log_data is not None
221     log_data["extra"] = f"[{queue_id}]"
222 
223     csp_nonce = secrets.token_hex(24)
224 
225     user_permission_info = get_user_permission_info(user_profile)
226 
227     response = render(
228         request,
229         "zerver/app/index.html",
230         context={
231             "user_profile": user_profile,
232             "page_params": page_params,
233             "csp_nonce": csp_nonce,
234             "color_scheme": user_permission_info.color_scheme,
235         },
236     )
237     patch_cache_control(response, no_cache=True, no_store=True, must_revalidate=True)
238     return response
239 
240 
241 @zulip_login_required
242 def desktop_home(request: HttpRequest) -> HttpResponse:
243     return redirect(home)
244
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/zerver/views/home.py b/zerver/views/home.py
--- a/zerver/views/home.py
+++ b/zerver/views/home.py
@@ -148,6 +148,10 @@
     if request.user.is_authenticated:
         user_profile = request.user
         realm = user_profile.realm
+
+        # User is logged in and hence no longer `prefers_web_public_view`.
+        if "prefers_web_public_view" in request.session.keys():
+            del request.session["prefers_web_public_view"]
     else:
         realm = get_valid_realm_from_request(request)

{"golden_diff": "diff --git a/zerver/views/home.py b/zerver/views/home.py\n--- a/zerver/views/home.py\n+++ b/zerver/views/home.py\n@@ -148,6 +148,10 @@\n     if request.user.is_authenticated:\n         user_profile = request.user\n         realm = user_profile.realm\n+\n+        # User is logged in and hence no longer `prefers_web_public_view`.\n+        if \"prefers_web_public_view\" in request.session.keys():\n+            del request.session[\"prefers_web_public_view\"]\n     else:\n         realm = get_valid_realm_from_request(request)\n", "issue": "Clear `prefers_web_public_view` cookie when logging in or registering an account\nIn #19902, we added functionality to remember who had accessed Zulip as a spectator and immediately take them to the spectator experience.  We probably want to clear the `prefers_web_public_view` cookie when logging in via `do_login` or registering a new account, since the user likely doesn't want to get the spectator experience on future visits to the site.\n", "before_files": [{"content": "import logging\nimport secrets\nfrom typing import List, Optional, Tuple\n\nfrom django.conf import settings\nfrom django.http import HttpRequest, HttpResponse\nfrom django.shortcuts import redirect, render\nfrom django.utils.cache import patch_cache_control\n\nfrom zerver.context_processors import get_valid_realm_from_request\nfrom zerver.decorator import web_public_view, zulip_login_required, zulip_redirect_to_login\nfrom zerver.forms import ToSForm\nfrom zerver.lib.actions import do_change_tos_version, realm_user_count\nfrom zerver.lib.compatibility import is_outdated_desktop_app, is_unsupported_browser\nfrom zerver.lib.home import build_page_params_for_home_page_load, get_user_permission_info\nfrom zerver.lib.request import RequestNotes\nfrom zerver.lib.streams import access_stream_by_name\nfrom zerver.lib.subdomains import get_subdomain\nfrom zerver.lib.utils import statsd\nfrom zerver.models import PreregistrationUser, Realm, Stream, UserProfile\nfrom zerver.views.auth import get_safe_redirect_to\nfrom zerver.views.portico import hello_view\n\n\ndef need_accept_tos(user_profile: Optional[UserProfile]) -> bool:\n    if user_profile is None:\n        return False\n\n    if settings.TERMS_OF_SERVICE is None:  # nocoverage\n        return False\n\n    if settings.TOS_VERSION is None:\n        return False\n\n    return int(settings.TOS_VERSION.split(\".\")[0]) > user_profile.major_tos_version()\n\n\n@zulip_login_required\ndef accounts_accept_terms(request: HttpRequest) -> HttpResponse:\n    assert request.user.is_authenticated\n\n    if request.method == \"POST\":\n        form = ToSForm(request.POST)\n        if form.is_valid():\n            do_change_tos_version(request.user, settings.TOS_VERSION)\n            return redirect(home)\n    else:\n        form = ToSForm()\n\n    email = request.user.delivery_email\n    special_message_template = None\n    if request.user.tos_version is None and settings.FIRST_TIME_TOS_TEMPLATE is not None:\n        special_message_template = \"zerver/\" + settings.FIRST_TIME_TOS_TEMPLATE\n    return render(\n        request,\n        \"zerver/accounts_accept_terms.html\",\n        context={\n            \"form\": form,\n            \"email\": email,\n            \"special_message_template\": special_message_template,\n        },\n    )\n\n\ndef detect_narrowed_window(\n    request: HttpRequest, user_profile: Optional[UserProfile]\n) -> Tuple[List[List[str]], Optional[Stream], Optional[str]]:\n    \"\"\"This function implements Zulip's support for a mini Zulip window\n    that just handles messages from a single narrow\"\"\"\n    if user_profile is None:\n        return [], None, None\n\n    narrow: List[List[str]] = []\n    narrow_stream = None\n    narrow_topic = request.GET.get(\"topic\")\n\n    if request.GET.get(\"stream\"):\n        try:\n            # TODO: We should support stream IDs and PMs here as well.\n            narrow_stream_name = request.GET.get(\"stream\")\n            (narrow_stream, ignored_sub) = access_stream_by_name(user_profile, narrow_stream_name)\n            narrow = [[\"stream\", narrow_stream.name]]\n        except Exception:\n            logging.warning(\"Invalid narrow requested, ignoring\", extra=dict(request=request))\n        if narrow_stream is not None and narrow_topic is not None:\n            narrow.append([\"topic\", narrow_topic])\n    return narrow, narrow_stream, narrow_topic\n\n\ndef update_last_reminder(user_profile: Optional[UserProfile]) -> None:\n    \"\"\"Reset our don't-spam-users-with-email counter since the\n    user has since logged in\n    \"\"\"\n    if user_profile is None:\n        return\n\n    if user_profile.last_reminder is not None:  # nocoverage\n        # TODO: Look into the history of last_reminder; we may have\n        # eliminated that as a useful concept for non-bot users.\n        user_profile.last_reminder = None\n        user_profile.save(update_fields=[\"last_reminder\"])\n\n\ndef home(request: HttpRequest) -> HttpResponse:\n    if not settings.ROOT_DOMAIN_LANDING_PAGE:\n        return home_real(request)\n\n    # If settings.ROOT_DOMAIN_LANDING_PAGE, sends the user the landing\n    # page, not the login form, on the root domain\n\n    subdomain = get_subdomain(request)\n    if subdomain != Realm.SUBDOMAIN_FOR_ROOT_DOMAIN:\n        return home_real(request)\n\n    return hello_view(request)\n\n\n@web_public_view\ndef home_real(request: HttpRequest) -> HttpResponse:\n    # Before we do any real work, check if the app is banned.\n    client_user_agent = request.META.get(\"HTTP_USER_AGENT\", \"\")\n    (insecure_desktop_app, banned_desktop_app, auto_update_broken) = is_outdated_desktop_app(\n        client_user_agent\n    )\n    if banned_desktop_app:\n        return render(\n            request,\n            \"zerver/insecure_desktop_app.html\",\n            context={\n                \"auto_update_broken\": auto_update_broken,\n            },\n        )\n    (unsupported_browser, browser_name) = is_unsupported_browser(client_user_agent)\n    if unsupported_browser:\n        return render(\n            request,\n            \"zerver/unsupported_browser.html\",\n            context={\n                \"browser_name\": browser_name,\n            },\n        )\n\n    # We need to modify the session object every two weeks or it will expire.\n    # This line makes reloading the page a sufficient action to keep the\n    # session alive.\n    request.session.modified = True\n\n    if request.user.is_authenticated:\n        user_profile = request.user\n        realm = user_profile.realm\n    else:\n        realm = get_valid_realm_from_request(request)\n\n        # TODO: Ideally, we'd open Zulip directly as a spectator if\n        # the URL had clicked a link to content on a web-public\n        # stream.  We could maybe do this by parsing `next`, but it's\n        # not super convenient with Zulip's hash-based URL scheme.\n\n        # The \"Access without an account\" button on the login page\n        # submits a POST to this page with this hidden field set.\n        if request.POST.get(\"prefers_web_public_view\") == \"true\":\n            request.session[\"prefers_web_public_view\"] = True\n            # We serve a redirect here, rather than serving a page, to\n            # avoid browser \"Confirm form resubmission\" prompts on reload.\n            redirect_to = get_safe_redirect_to(request.POST.get(\"next\"), realm.uri)\n            return redirect(redirect_to)\n\n        prefers_web_public_view = request.session.get(\"prefers_web_public_view\")\n        if not prefers_web_public_view:\n            # For users who haven't opted into the spectator\n            # experience, we redirect to the login page.\n            return zulip_redirect_to_login(request, settings.HOME_NOT_LOGGED_IN)\n\n        # For users who have selected public access, we load the\n        # spectator experience.  We fall through to the shared code\n        # for loading the application, with user_profile=None encoding\n        # that we're a spectator, not a logged-in user.\n        user_profile = None\n\n    update_last_reminder(user_profile)\n\n    statsd.incr(\"views.home\")\n\n    # If a user hasn't signed the current Terms of Service, send them there\n    if need_accept_tos(user_profile):\n        return accounts_accept_terms(request)\n\n    narrow, narrow_stream, narrow_topic = detect_narrowed_window(request, user_profile)\n\n    if user_profile is not None:\n        first_in_realm = realm_user_count(user_profile.realm) == 1\n        # If you are the only person in the realm and you didn't invite\n        # anyone, we'll continue to encourage you to do so on the frontend.\n        prompt_for_invites = (\n            first_in_realm\n            and not PreregistrationUser.objects.filter(referred_by=user_profile).count()\n        )\n        needs_tutorial = user_profile.tutorial_status == UserProfile.TUTORIAL_WAITING\n\n    else:\n        first_in_realm = False\n        prompt_for_invites = False\n        # The current tutorial doesn't super make sense for logged-out users.\n        needs_tutorial = False\n\n    queue_id, page_params = build_page_params_for_home_page_load(\n        request=request,\n        user_profile=user_profile,\n        realm=realm,\n        insecure_desktop_app=insecure_desktop_app,\n        narrow=narrow,\n        narrow_stream=narrow_stream,\n        narrow_topic=narrow_topic,\n        first_in_realm=first_in_realm,\n        prompt_for_invites=prompt_for_invites,\n        needs_tutorial=needs_tutorial,\n    )\n\n    log_data = RequestNotes.get_notes(request).log_data\n    assert log_data is not None\n    log_data[\"extra\"] = f\"[{queue_id}]\"\n\n    csp_nonce = secrets.token_hex(24)\n\n    user_permission_info = get_user_permission_info(user_profile)\n\n    response = render(\n        request,\n        \"zerver/app/index.html\",\n        context={\n            \"user_profile\": user_profile,\n            \"page_params\": page_params,\n            \"csp_nonce\": csp_nonce,\n            \"color_scheme\": user_permission_info.color_scheme,\n        },\n    )\n    patch_cache_control(response, no_cache=True, no_store=True, must_revalidate=True)\n    return response\n\n\n@zulip_login_required\ndef desktop_home(request: HttpRequest) -> HttpResponse:\n    return redirect(home)\n", "path": "zerver/views/home.py"}], "after_files": [{"content": "import logging\nimport secrets\nfrom typing import List, Optional, Tuple\n\nfrom django.conf import settings\nfrom django.http import HttpRequest, HttpResponse\nfrom django.shortcuts import redirect, render\nfrom django.utils.cache import patch_cache_control\n\nfrom zerver.context_processors import get_valid_realm_from_request\nfrom zerver.decorator import web_public_view, zulip_login_required, zulip_redirect_to_login\nfrom zerver.forms import ToSForm\nfrom zerver.lib.actions import do_change_tos_version, realm_user_count\nfrom zerver.lib.compatibility import is_outdated_desktop_app, is_unsupported_browser\nfrom zerver.lib.home import build_page_params_for_home_page_load, get_user_permission_info\nfrom zerver.lib.request import RequestNotes\nfrom zerver.lib.streams import access_stream_by_name\nfrom zerver.lib.subdomains import get_subdomain\nfrom zerver.lib.utils import statsd\nfrom zerver.models import PreregistrationUser, Realm, Stream, UserProfile\nfrom zerver.views.auth import get_safe_redirect_to\nfrom zerver.views.portico import hello_view\n\n\ndef need_accept_tos(user_profile: Optional[UserProfile]) -> bool:\n    if user_profile is None:\n        return False\n\n    if settings.TERMS_OF_SERVICE is None:  # nocoverage\n        return False\n\n    if settings.TOS_VERSION is None:\n        return False\n\n    return int(settings.TOS_VERSION.split(\".\")[0]) > user_profile.major_tos_version()\n\n\n@zulip_login_required\ndef accounts_accept_terms(request: HttpRequest) -> HttpResponse:\n    assert request.user.is_authenticated\n\n    if request.method == \"POST\":\n        form = ToSForm(request.POST)\n        if form.is_valid():\n            do_change_tos_version(request.user, settings.TOS_VERSION)\n            return redirect(home)\n    else:\n        form = ToSForm()\n\n    email = request.user.delivery_email\n    special_message_template = None\n    if request.user.tos_version is None and settings.FIRST_TIME_TOS_TEMPLATE is not None:\n        special_message_template = \"zerver/\" + settings.FIRST_TIME_TOS_TEMPLATE\n    return render(\n        request,\n        \"zerver/accounts_accept_terms.html\",\n        context={\n            \"form\": form,\n            \"email\": email,\n            \"special_message_template\": special_message_template,\n        },\n    )\n\n\ndef detect_narrowed_window(\n    request: HttpRequest, user_profile: Optional[UserProfile]\n) -> Tuple[List[List[str]], Optional[Stream], Optional[str]]:\n    \"\"\"This function implements Zulip's support for a mini Zulip window\n    that just handles messages from a single narrow\"\"\"\n    if user_profile is None:\n        return [], None, None\n\n    narrow: List[List[str]] = []\n    narrow_stream = None\n    narrow_topic = request.GET.get(\"topic\")\n\n    if request.GET.get(\"stream\"):\n        try:\n            # TODO: We should support stream IDs and PMs here as well.\n            narrow_stream_name = request.GET.get(\"stream\")\n            (narrow_stream, ignored_sub) = access_stream_by_name(user_profile, narrow_stream_name)\n            narrow = [[\"stream\", narrow_stream.name]]\n        except Exception:\n            logging.warning(\"Invalid narrow requested, ignoring\", extra=dict(request=request))\n        if narrow_stream is not None and narrow_topic is not None:\n            narrow.append([\"topic\", narrow_topic])\n    return narrow, narrow_stream, narrow_topic\n\n\ndef update_last_reminder(user_profile: Optional[UserProfile]) -> None:\n    \"\"\"Reset our don't-spam-users-with-email counter since the\n    user has since logged in\n    \"\"\"\n    if user_profile is None:\n        return\n\n    if user_profile.last_reminder is not None:  # nocoverage\n        # TODO: Look into the history of last_reminder; we may have\n        # eliminated that as a useful concept for non-bot users.\n        user_profile.last_reminder = None\n        user_profile.save(update_fields=[\"last_reminder\"])\n\n\ndef home(request: HttpRequest) -> HttpResponse:\n    if not settings.ROOT_DOMAIN_LANDING_PAGE:\n        return home_real(request)\n\n    # If settings.ROOT_DOMAIN_LANDING_PAGE, sends the user the landing\n    # page, not the login form, on the root domain\n\n    subdomain = get_subdomain(request)\n    if subdomain != Realm.SUBDOMAIN_FOR_ROOT_DOMAIN:\n        return home_real(request)\n\n    return hello_view(request)\n\n\n@web_public_view\ndef home_real(request: HttpRequest) -> HttpResponse:\n    # Before we do any real work, check if the app is banned.\n    client_user_agent = request.META.get(\"HTTP_USER_AGENT\", \"\")\n    (insecure_desktop_app, banned_desktop_app, auto_update_broken) = is_outdated_desktop_app(\n        client_user_agent\n    )\n    if banned_desktop_app:\n        return render(\n            request,\n            \"zerver/insecure_desktop_app.html\",\n            context={\n                \"auto_update_broken\": auto_update_broken,\n            },\n        )\n    (unsupported_browser, browser_name) = is_unsupported_browser(client_user_agent)\n    if unsupported_browser:\n        return render(\n            request,\n            \"zerver/unsupported_browser.html\",\n            context={\n                \"browser_name\": browser_name,\n            },\n        )\n\n    # We need to modify the session object every two weeks or it will expire.\n    # This line makes reloading the page a sufficient action to keep the\n    # session alive.\n    request.session.modified = True\n\n    if request.user.is_authenticated:\n        user_profile = request.user\n        realm = user_profile.realm\n\n        # User is logged in and hence no longer `prefers_web_public_view`.\n        if \"prefers_web_public_view\" in request.session.keys():\n            del request.session[\"prefers_web_public_view\"]\n    else:\n        realm = get_valid_realm_from_request(request)\n\n        # TODO: Ideally, we'd open Zulip directly as a spectator if\n        # the URL had clicked a link to content on a web-public\n        # stream.  We could maybe do this by parsing `next`, but it's\n        # not super convenient with Zulip's hash-based URL scheme.\n\n        # The \"Access without an account\" button on the login page\n        # submits a POST to this page with this hidden field set.\n        if request.POST.get(\"prefers_web_public_view\") == \"true\":\n            request.session[\"prefers_web_public_view\"] = True\n            # We serve a redirect here, rather than serving a page, to\n            # avoid browser \"Confirm form resubmission\" prompts on reload.\n            redirect_to = get_safe_redirect_to(request.POST.get(\"next\"), realm.uri)\n            return redirect(redirect_to)\n\n        prefers_web_public_view = request.session.get(\"prefers_web_public_view\")\n        if not prefers_web_public_view:\n            # For users who haven't opted into the spectator\n            # experience, we redirect to the login page.\n            return zulip_redirect_to_login(request, settings.HOME_NOT_LOGGED_IN)\n\n        # For users who have selected public access, we load the\n        # spectator experience.  We fall through to the shared code\n        # for loading the application, with user_profile=None encoding\n        # that we're a spectator, not a logged-in user.\n        user_profile = None\n\n    update_last_reminder(user_profile)\n\n    statsd.incr(\"views.home\")\n\n    # If a user hasn't signed the current Terms of Service, send them there\n    if need_accept_tos(user_profile):\n        return accounts_accept_terms(request)\n\n    narrow, narrow_stream, narrow_topic = detect_narrowed_window(request, user_profile)\n\n    if user_profile is not None:\n        first_in_realm = realm_user_count(user_profile.realm) == 1\n        # If you are the only person in the realm and you didn't invite\n        # anyone, we'll continue to encourage you to do so on the frontend.\n        prompt_for_invites = (\n            first_in_realm\n            and not PreregistrationUser.objects.filter(referred_by=user_profile).count()\n        )\n        needs_tutorial = user_profile.tutorial_status == UserProfile.TUTORIAL_WAITING\n\n    else:\n        first_in_realm = False\n        prompt_for_invites = False\n        # The current tutorial doesn't super make sense for logged-out users.\n        needs_tutorial = False\n\n    queue_id, page_params = build_page_params_for_home_page_load(\n        request=request,\n        user_profile=user_profile,\n        realm=realm,\n        insecure_desktop_app=insecure_desktop_app,\n        narrow=narrow,\n        narrow_stream=narrow_stream,\n        narrow_topic=narrow_topic,\n        first_in_realm=first_in_realm,\n        prompt_for_invites=prompt_for_invites,\n        needs_tutorial=needs_tutorial,\n    )\n\n    log_data = RequestNotes.get_notes(request).log_data\n    assert log_data is not None\n    log_data[\"extra\"] = f\"[{queue_id}]\"\n\n    csp_nonce = secrets.token_hex(24)\n\n    user_permission_info = get_user_permission_info(user_profile)\n\n    response = render(\n        request,\n        \"zerver/app/index.html\",\n        context={\n            \"user_profile\": user_profile,\n            \"page_params\": page_params,\n            \"csp_nonce\": csp_nonce,\n            \"color_scheme\": user_permission_info.color_scheme,\n        },\n    )\n    patch_cache_control(response, no_cache=True, no_store=True, must_revalidate=True)\n    return response\n\n\n@zulip_login_required\ndef desktop_home(request: HttpRequest) -> HttpResponse:\n    return redirect(home)\n", "path": "zerver/views/home.py"}]}