Skip to content

Commit e8e58c7

Browse files
committed
fix: webauthn mfa integration
- Fixes minor issues with email selection logic - Updates post init callbacks to use webauthn factor id - Bumps version to `0.30.3`
1 parent 1fc0305 commit e8e58c7

File tree

4 files changed

+14
-19
lines changed

4 files changed

+14
-19
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88

99
## [unreleased]
1010

11+
## [0.30.3] - 2025-08-28
12+
- Fixes webauthn MFA integration
13+
1114
## [0.30.2] - 2025-08-14
1215
- Adds Webauthn user editing support to the Dashboard
1316

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@
8282

8383
setup(
8484
name="supertokens_python",
85-
version="0.30.2",
85+
version="0.30.3",
8686
author="SuperTokens",
8787
license="Apache 2.0",
8888
author_email="[email protected]",

supertokens_python/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from __future__ import annotations
1616

1717
SUPPORTED_CDI_VERSIONS = ["5.3"]
18-
VERSION = "0.30.2"
18+
VERSION = "0.30.3"
1919
TELEMETRY = "/telemetry"
2020
USER_COUNT = "/users/count"
2121
USER_DELETE = "/user/remove"

supertokens_python/recipe/webauthn/recipe.py

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def callback():
132132
async def get_available_secondary_factor_ids(
133133
_: TenantConfig,
134134
) -> List[str]:
135-
return ["emailpassword"]
135+
return [FactorIds.WEBAUTHN]
136136

137137
mfa_instance.add_func_to_get_all_available_secondary_factor_ids_from_other_recipes(
138138
GetAllAvailableSecondaryFactorIdsFromOtherRecipesFunc(
@@ -143,11 +143,11 @@ async def get_available_secondary_factor_ids(
143143
async def user_setup(user: User, _: Dict[str, Any]) -> List[str]:
144144
for login_method in user.login_methods:
145145
# We don't check for tenantId here because if we find the user
146-
# with emailpassword loginMethod from different tenant, then
146+
# with webauthn loginMethod from different tenant, then
147147
# we assume the factor is setup for this user. And as part of factor
148148
# completion, we associate that loginMethod with the session's tenantId
149149
if login_method.recipe_id == self.recipe_id:
150-
return ["emailpassword"]
150+
return [FactorIds.WEBAUTHN]
151151

152152
return []
153153

@@ -174,7 +174,8 @@ async def get_emails_for_factor(
174174

175175
# We order the login methods based on `time_joined` (oldest first)
176176
ordered_login_methods = sorted(
177-
user.login_methods, key=lambda lm: lm.time_joined, reverse=True
177+
user.login_methods,
178+
key=lambda lm: lm.time_joined,
178179
)
179180
# We take the ones that belong to this recipe
180181
recipe_ordered_login_methods = list(
@@ -185,7 +186,7 @@ async def get_emails_for_factor(
185186
)
186187

187188
result: List[str] = []
188-
if len(recipe_ordered_login_methods) == 0:
189+
if len(recipe_ordered_login_methods) != 0:
189190
# If there are login methods belonging to this recipe, the factor is set up
190191
# In this case we only list email addresses that have a password associated with them
191192

@@ -234,14 +235,14 @@ async def get_emails_for_factor(
234235
# If there is at least one real email address linked to the user, we only suggest real addresses
235236
result = [
236237
lm.email
237-
for lm in recipe_ordered_login_methods
238+
for lm in ordered_login_methods
238239
if lm.email is not None and not is_fake_email(lm.email)
239240
]
240241
else:
241242
# Else we use the fake ones
242243
result = [
243244
lm.email
244-
for lm in recipe_ordered_login_methods
245+
for lm in ordered_login_methods
245246
if lm.email is not None and is_fake_email(lm.email)
246247
]
247248

@@ -264,17 +265,8 @@ async def get_emails_for_factor(
264265
if email != session_login_method.email
265266
]
266267

267-
# If the list is empty we generate an email address to make the flow where the user is never asked for
268-
# an email address easier to implement. In many cases when the user adds an email-password factor, they
269-
# actually only want to add a password and do not care about the associated email address.
270-
# Custom implementations can choose to ignore this, and ask the user for the email anyway.
271-
if len(result) == 0:
272-
result.append(
273-
f"{session_recipe_user_id.get_as_string()}@stfakeemail.supertokens.com"
274-
)
275-
276268
return GetEmailsForFactorOkResult(
277-
factor_id_to_emails_map={"emailpassword": result}
269+
factor_id_to_emails_map={FactorIds.WEBAUTHN: result}
278270
)
279271

280272
mfa_instance.add_func_to_get_emails_for_factor_from_other_recipes(

0 commit comments

Comments
 (0)