We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
no webauthn device register possible
**Describe the bug**
If webauthn device is already registered authentication works without any issue.

But as long as no webauthn device is configured one can neither enforce it in the validation flow nor manually in the user profile.
**To Reproduce**
Steps to reproduce the behavior:
1. delete webauthn device
2. logout
3. login
4. try to add webauthn device in user profile settings

**Expected behavior**
webauthn device can be registered

**Logs**
<details>
    <summary>Stacktrace from authentik</summary>

```
Traceback (most recent call last):
  File "/authentik/flows/views/executor.py", line 291, in get
    stage_response = self.current_stage_view.dispatch(request)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/ak-root/venv/lib/python3.12/site-packages/django/views/generic/base.py", line 143, in dispatch
    return handler(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/authentik/flows/stage.py", line 95, in get
    challenge = self._get_challenge(*args, **kwargs)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/authentik/flows/stage.py", line 172, in _get_challenge
    challenge = self.get_challenge(*args, **kwargs)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/authentik/stages/authenticator_webauthn/stage.py", line 114, in get_challenge
    "registration": loads(options_to_json(registration_options)),
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/ak-root/venv/lib/python3.12/site-packages/webauthn/helpers/options_to_json.py", line 71, in options_to_json
    ] = _selection.authenticator_attachment.value
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
builtins.AttributeError: 'str' object has no attribute 'value'
```
</details>


**Version and Deployment (please complete the following information):**
- authentik version: 2024.2.1
- Deployment: helm



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `authentik/stages/authenticator_webauthn/stage.py`
Content:
```
1 """WebAuthn stage"""
2 
3 from json import loads
4 
5 from django.http import HttpRequest, HttpResponse
6 from django.http.request import QueryDict
7 from rest_framework.fields import CharField
8 from rest_framework.serializers import ValidationError
9 from webauthn import options_to_json
10 from webauthn.helpers.bytes_to_base64url import bytes_to_base64url
11 from webauthn.helpers.exceptions import InvalidRegistrationResponse
12 from webauthn.helpers.structs import (
13     AuthenticatorSelectionCriteria,
14     PublicKeyCredentialCreationOptions,
15     ResidentKeyRequirement,
16     UserVerificationRequirement,
17 )
18 from webauthn.registration.generate_registration_options import generate_registration_options
19 from webauthn.registration.verify_registration_response import (
20     VerifiedRegistration,
21     verify_registration_response,
22 )
23 
24 from authentik.core.api.utils import JSONDictField
25 from authentik.core.models import User
26 from authentik.flows.challenge import (
27     Challenge,
28     ChallengeResponse,
29     ChallengeTypes,
30     WithUserInfoChallenge,
31 )
32 from authentik.flows.stage import ChallengeStageView
33 from authentik.stages.authenticator_webauthn.models import AuthenticateWebAuthnStage, WebAuthnDevice
34 from authentik.stages.authenticator_webauthn.utils import get_origin, get_rp_id
35 
36 SESSION_KEY_WEBAUTHN_CHALLENGE = "authentik/stages/authenticator_webauthn/challenge"
37 
38 
39 class AuthenticatorWebAuthnChallenge(WithUserInfoChallenge):
40     """WebAuthn Challenge"""
41 
42     registration = JSONDictField()
43     component = CharField(default="ak-stage-authenticator-webauthn")
44 
45 
46 class AuthenticatorWebAuthnChallengeResponse(ChallengeResponse):
47     """WebAuthn Challenge response"""
48 
49     response = JSONDictField()
50     component = CharField(default="ak-stage-authenticator-webauthn")
51 
52     request: HttpRequest
53     user: User
54 
55     def validate_response(self, response: dict) -> dict:
56         """Validate webauthn challenge response"""
57         challenge = self.request.session[SESSION_KEY_WEBAUTHN_CHALLENGE]
58 
59         try:
60             registration: VerifiedRegistration = verify_registration_response(
61                 credential=response,
62                 expected_challenge=challenge,
63                 expected_rp_id=get_rp_id(self.request),
64                 expected_origin=get_origin(self.request),
65             )
66         except InvalidRegistrationResponse as exc:
67             self.stage.logger.warning("registration failed", exc=exc)
68             raise ValidationError(f"Registration failed. Error: {exc}") from None
69 
70         credential_id_exists = WebAuthnDevice.objects.filter(
71             credential_id=bytes_to_base64url(registration.credential_id)
72         ).first()
73         if credential_id_exists:
74             raise ValidationError("Credential ID already exists.")
75 
76         return registration
77 
78 
79 class AuthenticatorWebAuthnStageView(ChallengeStageView):
80     """WebAuthn stage"""
81 
82     response_class = AuthenticatorWebAuthnChallengeResponse
83 
84     def get_challenge(self, *args, **kwargs) -> Challenge:
85         # clear session variables prior to starting a new registration
86         self.request.session.pop(SESSION_KEY_WEBAUTHN_CHALLENGE, None)
87         stage: AuthenticateWebAuthnStage = self.executor.current_stage
88         user = self.get_pending_user()
89 
90         # library accepts none so we store null in the database, but if there is a value
91         # set, cast it to string to ensure it's not a django class
92         authenticator_attachment = stage.authenticator_attachment
93         if authenticator_attachment:
94             authenticator_attachment = str(authenticator_attachment)
95 
96         registration_options: PublicKeyCredentialCreationOptions = generate_registration_options(
97             rp_id=get_rp_id(self.request),
98             rp_name=self.request.brand.branding_title,
99             user_id=user.uid.encode("utf-8"),
100             user_name=user.username,
101             user_display_name=user.name,
102             authenticator_selection=AuthenticatorSelectionCriteria(
103                 resident_key=ResidentKeyRequirement(str(stage.resident_key_requirement)),
104                 user_verification=UserVerificationRequirement(str(stage.user_verification)),
105                 authenticator_attachment=authenticator_attachment,
106             ),
107         )
108 
109         self.request.session[SESSION_KEY_WEBAUTHN_CHALLENGE] = registration_options.challenge
110         self.request.session.save()
111         return AuthenticatorWebAuthnChallenge(
112             data={
113                 "type": ChallengeTypes.NATIVE.value,
114                 "registration": loads(options_to_json(registration_options)),
115             }
116         )
117 
118     def get_response_instance(self, data: QueryDict) -> AuthenticatorWebAuthnChallengeResponse:
119         response: AuthenticatorWebAuthnChallengeResponse = super().get_response_instance(data)
120         response.request = self.request
121         response.user = self.get_pending_user()
122         return response
123 
124     def challenge_valid(self, response: ChallengeResponse) -> HttpResponse:
125         # Webauthn Challenge has already been validated
126         webauthn_credential: VerifiedRegistration = response.validated_data["response"]
127         existing_device = WebAuthnDevice.objects.filter(
128             credential_id=bytes_to_base64url(webauthn_credential.credential_id)
129         ).first()
130         if not existing_device:
131             WebAuthnDevice.objects.create(
132                 user=self.get_pending_user(),
133                 public_key=bytes_to_base64url(webauthn_credential.credential_public_key),
134                 credential_id=bytes_to_base64url(webauthn_credential.credential_id),
135                 sign_count=webauthn_credential.sign_count,
136                 rp_id=get_rp_id(self.request),
137                 name="WebAuthn Device",
138             )
139         else:
140             return self.executor.stage_invalid("Device with Credential ID already exists.")
141         return self.executor.stage_ok()
142 
143     def cleanup(self):
144         self.request.session.pop(SESSION_KEY_WEBAUTHN_CHALLENGE, None)
145
```
--- 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/authentik/stages/authenticator_webauthn/stage.py b/authentik/stages/authenticator_webauthn/stage.py
--- a/authentik/stages/authenticator_webauthn/stage.py
+++ b/authentik/stages/authenticator_webauthn/stage.py
@@ -10,6 +10,7 @@
 from webauthn.helpers.bytes_to_base64url import bytes_to_base64url
 from webauthn.helpers.exceptions import InvalidRegistrationResponse
 from webauthn.helpers.structs import (
+    AuthenticatorAttachment,
     AuthenticatorSelectionCriteria,
     PublicKeyCredentialCreationOptions,
     ResidentKeyRequirement,
@@ -91,7 +92,7 @@
         # set, cast it to string to ensure it's not a django class
         authenticator_attachment = stage.authenticator_attachment
         if authenticator_attachment:
-            authenticator_attachment = str(authenticator_attachment)
+            authenticator_attachment = AuthenticatorAttachment(str(authenticator_attachment))
 
         registration_options: PublicKeyCredentialCreationOptions = generate_registration_options(
             rp_id=get_rp_id(self.request),

{"golden_diff": "diff --git a/authentik/stages/authenticator_webauthn/stage.py b/authentik/stages/authenticator_webauthn/stage.py\n--- a/authentik/stages/authenticator_webauthn/stage.py\n+++ b/authentik/stages/authenticator_webauthn/stage.py\n@@ -10,6 +10,7 @@\n from webauthn.helpers.bytes_to_base64url import bytes_to_base64url\n from webauthn.helpers.exceptions import InvalidRegistrationResponse\n from webauthn.helpers.structs import (\n+    AuthenticatorAttachment,\n     AuthenticatorSelectionCriteria,\n     PublicKeyCredentialCreationOptions,\n     ResidentKeyRequirement,\n@@ -91,7 +92,7 @@\n         # set, cast it to string to ensure it's not a django class\n         authenticator_attachment = stage.authenticator_attachment\n         if authenticator_attachment:\n-            authenticator_attachment = str(authenticator_attachment)\n+            authenticator_attachment = AuthenticatorAttachment(str(authenticator_attachment))\n \n         registration_options: PublicKeyCredentialCreationOptions = generate_registration_options(\n             rp_id=get_rp_id(self.request),\n", "issue": "no webauthn device register possible\n**Describe the bug**\r\nIf webauthn device is already registered authentication works without any issue.\r\n\r\nBut as long as no webauthn device is configured one can neither enforce it in the validation flow nor manually in the user profile.\r\n**To Reproduce**\r\nSteps to reproduce the behavior:\r\n1. delete webauthn device\r\n2. logout\r\n3. login\r\n4. try to add webauthn device in user profile settings\r\n\r\n**Expected behavior**\r\nwebauthn device can be registered\r\n\r\n**Logs**\r\n<details>\r\n    <summary>Stacktrace from authentik</summary>\r\n\r\n```\r\nTraceback (most recent call last):\r\n  File \"/authentik/flows/views/executor.py\", line 291, in get\r\n    stage_response = self.current_stage_view.dispatch(request)\r\n                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n  File \"/ak-root/venv/lib/python3.12/site-packages/django/views/generic/base.py\", line 143, in dispatch\r\n    return handler(request, *args, **kwargs)\r\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n  File \"/authentik/flows/stage.py\", line 95, in get\r\n    challenge = self._get_challenge(*args, **kwargs)\r\n                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n  File \"/authentik/flows/stage.py\", line 172, in _get_challenge\r\n    challenge = self.get_challenge(*args, **kwargs)\r\n                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n  File \"/authentik/stages/authenticator_webauthn/stage.py\", line 114, in get_challenge\r\n    \"registration\": loads(options_to_json(registration_options)),\r\n                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n  File \"/ak-root/venv/lib/python3.12/site-packages/webauthn/helpers/options_to_json.py\", line 71, in options_to_json\r\n    ] = _selection.authenticator_attachment.value\r\n        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\nbuiltins.AttributeError: 'str' object has no attribute 'value'\r\n```\r\n</details>\r\n\r\n\r\n**Version and Deployment (please complete the following information):**\r\n- authentik version: 2024.2.1\r\n- Deployment: helm\r\n\r\n\n", "before_files": [{"content": "\"\"\"WebAuthn stage\"\"\"\n\nfrom json import loads\n\nfrom django.http import HttpRequest, HttpResponse\nfrom django.http.request import QueryDict\nfrom rest_framework.fields import CharField\nfrom rest_framework.serializers import ValidationError\nfrom webauthn import options_to_json\nfrom webauthn.helpers.bytes_to_base64url import bytes_to_base64url\nfrom webauthn.helpers.exceptions import InvalidRegistrationResponse\nfrom webauthn.helpers.structs import (\n    AuthenticatorSelectionCriteria,\n    PublicKeyCredentialCreationOptions,\n    ResidentKeyRequirement,\n    UserVerificationRequirement,\n)\nfrom webauthn.registration.generate_registration_options import generate_registration_options\nfrom webauthn.registration.verify_registration_response import (\n    VerifiedRegistration,\n    verify_registration_response,\n)\n\nfrom authentik.core.api.utils import JSONDictField\nfrom authentik.core.models import User\nfrom authentik.flows.challenge import (\n    Challenge,\n    ChallengeResponse,\n    ChallengeTypes,\n    WithUserInfoChallenge,\n)\nfrom authentik.flows.stage import ChallengeStageView\nfrom authentik.stages.authenticator_webauthn.models import AuthenticateWebAuthnStage, WebAuthnDevice\nfrom authentik.stages.authenticator_webauthn.utils import get_origin, get_rp_id\n\nSESSION_KEY_WEBAUTHN_CHALLENGE = \"authentik/stages/authenticator_webauthn/challenge\"\n\n\nclass AuthenticatorWebAuthnChallenge(WithUserInfoChallenge):\n    \"\"\"WebAuthn Challenge\"\"\"\n\n    registration = JSONDictField()\n    component = CharField(default=\"ak-stage-authenticator-webauthn\")\n\n\nclass AuthenticatorWebAuthnChallengeResponse(ChallengeResponse):\n    \"\"\"WebAuthn Challenge response\"\"\"\n\n    response = JSONDictField()\n    component = CharField(default=\"ak-stage-authenticator-webauthn\")\n\n    request: HttpRequest\n    user: User\n\n    def validate_response(self, response: dict) -> dict:\n        \"\"\"Validate webauthn challenge response\"\"\"\n        challenge = self.request.session[SESSION_KEY_WEBAUTHN_CHALLENGE]\n\n        try:\n            registration: VerifiedRegistration = verify_registration_response(\n                credential=response,\n                expected_challenge=challenge,\n                expected_rp_id=get_rp_id(self.request),\n                expected_origin=get_origin(self.request),\n            )\n        except InvalidRegistrationResponse as exc:\n            self.stage.logger.warning(\"registration failed\", exc=exc)\n            raise ValidationError(f\"Registration failed. Error: {exc}\") from None\n\n        credential_id_exists = WebAuthnDevice.objects.filter(\n            credential_id=bytes_to_base64url(registration.credential_id)\n        ).first()\n        if credential_id_exists:\n            raise ValidationError(\"Credential ID already exists.\")\n\n        return registration\n\n\nclass AuthenticatorWebAuthnStageView(ChallengeStageView):\n    \"\"\"WebAuthn stage\"\"\"\n\n    response_class = AuthenticatorWebAuthnChallengeResponse\n\n    def get_challenge(self, *args, **kwargs) -> Challenge:\n        # clear session variables prior to starting a new registration\n        self.request.session.pop(SESSION_KEY_WEBAUTHN_CHALLENGE, None)\n        stage: AuthenticateWebAuthnStage = self.executor.current_stage\n        user = self.get_pending_user()\n\n        # library accepts none so we store null in the database, but if there is a value\n        # set, cast it to string to ensure it's not a django class\n        authenticator_attachment = stage.authenticator_attachment\n        if authenticator_attachment:\n            authenticator_attachment = str(authenticator_attachment)\n\n        registration_options: PublicKeyCredentialCreationOptions = generate_registration_options(\n            rp_id=get_rp_id(self.request),\n            rp_name=self.request.brand.branding_title,\n            user_id=user.uid.encode(\"utf-8\"),\n            user_name=user.username,\n            user_display_name=user.name,\n            authenticator_selection=AuthenticatorSelectionCriteria(\n                resident_key=ResidentKeyRequirement(str(stage.resident_key_requirement)),\n                user_verification=UserVerificationRequirement(str(stage.user_verification)),\n                authenticator_attachment=authenticator_attachment,\n            ),\n        )\n\n        self.request.session[SESSION_KEY_WEBAUTHN_CHALLENGE] = registration_options.challenge\n        self.request.session.save()\n        return AuthenticatorWebAuthnChallenge(\n            data={\n                \"type\": ChallengeTypes.NATIVE.value,\n                \"registration\": loads(options_to_json(registration_options)),\n            }\n        )\n\n    def get_response_instance(self, data: QueryDict) -> AuthenticatorWebAuthnChallengeResponse:\n        response: AuthenticatorWebAuthnChallengeResponse = super().get_response_instance(data)\n        response.request = self.request\n        response.user = self.get_pending_user()\n        return response\n\n    def challenge_valid(self, response: ChallengeResponse) -> HttpResponse:\n        # Webauthn Challenge has already been validated\n        webauthn_credential: VerifiedRegistration = response.validated_data[\"response\"]\n        existing_device = WebAuthnDevice.objects.filter(\n            credential_id=bytes_to_base64url(webauthn_credential.credential_id)\n        ).first()\n        if not existing_device:\n            WebAuthnDevice.objects.create(\n                user=self.get_pending_user(),\n                public_key=bytes_to_base64url(webauthn_credential.credential_public_key),\n                credential_id=bytes_to_base64url(webauthn_credential.credential_id),\n                sign_count=webauthn_credential.sign_count,\n                rp_id=get_rp_id(self.request),\n                name=\"WebAuthn Device\",\n            )\n        else:\n            return self.executor.stage_invalid(\"Device with Credential ID already exists.\")\n        return self.executor.stage_ok()\n\n    def cleanup(self):\n        self.request.session.pop(SESSION_KEY_WEBAUTHN_CHALLENGE, None)\n", "path": "authentik/stages/authenticator_webauthn/stage.py"}], "after_files": [{"content": "\"\"\"WebAuthn stage\"\"\"\n\nfrom json import loads\n\nfrom django.http import HttpRequest, HttpResponse\nfrom django.http.request import QueryDict\nfrom rest_framework.fields import CharField\nfrom rest_framework.serializers import ValidationError\nfrom webauthn import options_to_json\nfrom webauthn.helpers.bytes_to_base64url import bytes_to_base64url\nfrom webauthn.helpers.exceptions import InvalidRegistrationResponse\nfrom webauthn.helpers.structs import (\n    AuthenticatorAttachment,\n    AuthenticatorSelectionCriteria,\n    PublicKeyCredentialCreationOptions,\n    ResidentKeyRequirement,\n    UserVerificationRequirement,\n)\nfrom webauthn.registration.generate_registration_options import generate_registration_options\nfrom webauthn.registration.verify_registration_response import (\n    VerifiedRegistration,\n    verify_registration_response,\n)\n\nfrom authentik.core.api.utils import JSONDictField\nfrom authentik.core.models import User\nfrom authentik.flows.challenge import (\n    Challenge,\n    ChallengeResponse,\n    ChallengeTypes,\n    WithUserInfoChallenge,\n)\nfrom authentik.flows.stage import ChallengeStageView\nfrom authentik.stages.authenticator_webauthn.models import AuthenticateWebAuthnStage, WebAuthnDevice\nfrom authentik.stages.authenticator_webauthn.utils import get_origin, get_rp_id\n\nSESSION_KEY_WEBAUTHN_CHALLENGE = \"authentik/stages/authenticator_webauthn/challenge\"\n\n\nclass AuthenticatorWebAuthnChallenge(WithUserInfoChallenge):\n    \"\"\"WebAuthn Challenge\"\"\"\n\n    registration = JSONDictField()\n    component = CharField(default=\"ak-stage-authenticator-webauthn\")\n\n\nclass AuthenticatorWebAuthnChallengeResponse(ChallengeResponse):\n    \"\"\"WebAuthn Challenge response\"\"\"\n\n    response = JSONDictField()\n    component = CharField(default=\"ak-stage-authenticator-webauthn\")\n\n    request: HttpRequest\n    user: User\n\n    def validate_response(self, response: dict) -> dict:\n        \"\"\"Validate webauthn challenge response\"\"\"\n        challenge = self.request.session[SESSION_KEY_WEBAUTHN_CHALLENGE]\n\n        try:\n            registration: VerifiedRegistration = verify_registration_response(\n                credential=response,\n                expected_challenge=challenge,\n                expected_rp_id=get_rp_id(self.request),\n                expected_origin=get_origin(self.request),\n            )\n        except InvalidRegistrationResponse as exc:\n            self.stage.logger.warning(\"registration failed\", exc=exc)\n            raise ValidationError(f\"Registration failed. Error: {exc}\") from None\n\n        credential_id_exists = WebAuthnDevice.objects.filter(\n            credential_id=bytes_to_base64url(registration.credential_id)\n        ).first()\n        if credential_id_exists:\n            raise ValidationError(\"Credential ID already exists.\")\n\n        return registration\n\n\nclass AuthenticatorWebAuthnStageView(ChallengeStageView):\n    \"\"\"WebAuthn stage\"\"\"\n\n    response_class = AuthenticatorWebAuthnChallengeResponse\n\n    def get_challenge(self, *args, **kwargs) -> Challenge:\n        # clear session variables prior to starting a new registration\n        self.request.session.pop(SESSION_KEY_WEBAUTHN_CHALLENGE, None)\n        stage: AuthenticateWebAuthnStage = self.executor.current_stage\n        user = self.get_pending_user()\n\n        # library accepts none so we store null in the database, but if there is a value\n        # set, cast it to string to ensure it's not a django class\n        authenticator_attachment = stage.authenticator_attachment\n        if authenticator_attachment:\n            authenticator_attachment = AuthenticatorAttachment(str(authenticator_attachment))\n\n        registration_options: PublicKeyCredentialCreationOptions = generate_registration_options(\n            rp_id=get_rp_id(self.request),\n            rp_name=self.request.brand.branding_title,\n            user_id=user.uid.encode(\"utf-8\"),\n            user_name=user.username,\n            user_display_name=user.name,\n            authenticator_selection=AuthenticatorSelectionCriteria(\n                resident_key=ResidentKeyRequirement(str(stage.resident_key_requirement)),\n                user_verification=UserVerificationRequirement(str(stage.user_verification)),\n                authenticator_attachment=authenticator_attachment,\n            ),\n        )\n\n        self.request.session[SESSION_KEY_WEBAUTHN_CHALLENGE] = registration_options.challenge\n        self.request.session.save()\n        return AuthenticatorWebAuthnChallenge(\n            data={\n                \"type\": ChallengeTypes.NATIVE.value,\n                \"registration\": loads(options_to_json(registration_options)),\n            }\n        )\n\n    def get_response_instance(self, data: QueryDict) -> AuthenticatorWebAuthnChallengeResponse:\n        response: AuthenticatorWebAuthnChallengeResponse = super().get_response_instance(data)\n        response.request = self.request\n        response.user = self.get_pending_user()\n        return response\n\n    def challenge_valid(self, response: ChallengeResponse) -> HttpResponse:\n        # Webauthn Challenge has already been validated\n        webauthn_credential: VerifiedRegistration = response.validated_data[\"response\"]\n        existing_device = WebAuthnDevice.objects.filter(\n            credential_id=bytes_to_base64url(webauthn_credential.credential_id)\n        ).first()\n        if not existing_device:\n            WebAuthnDevice.objects.create(\n                user=self.get_pending_user(),\n                public_key=bytes_to_base64url(webauthn_credential.credential_public_key),\n                credential_id=bytes_to_base64url(webauthn_credential.credential_id),\n                sign_count=webauthn_credential.sign_count,\n                rp_id=get_rp_id(self.request),\n                name=\"WebAuthn Device\",\n            )\n        else:\n            return self.executor.stage_invalid(\"Device with Credential ID already exists.\")\n        return self.executor.stage_ok()\n\n    def cleanup(self):\n        self.request.session.pop(SESSION_KEY_WEBAUTHN_CHALLENGE, None)\n", "path": "authentik/stages/authenticator_webauthn/stage.py"}]}