Skip to content

Commit 0834fe5

Browse files
committed
refactor: Fix circular dependency error in emailverification recipe and fix tests failures
1 parent e31b60d commit 0834fe5

File tree

10 files changed

+200
-196
lines changed

10 files changed

+200
-196
lines changed

supertokens_python/recipe/emailpassword/recipe.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,11 @@ def __init__(
115115
)
116116

117117
def callback():
118-
email_veriifcation_recipe = EmailVerificationRecipe.get_instance()
119-
email_veriifcation_recipe.add_get_email_for_user_id_func(
120-
self.get_email_for_user_id
121-
)
118+
ev_recipe = EmailVerificationRecipe.get_instance_optional()
119+
if ev_recipe:
120+
ev_recipe.add_get_email_for_user_id_func(
121+
self.get_email_for_user_id
122+
)
122123

123124
PostSTInitCallbacks.add_post_init_callback(callback)
124125

supertokens_python/recipe/emailverification/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,17 @@
1515

1616
from typing import TYPE_CHECKING, Callable
1717

18-
from supertokens_python.recipe.emailverification import ev_claim
1918
from . import exceptions as ex
2019
from . import utils
2120
from .emaildelivery import services as emaildelivery_services
22-
from .recipe import EmailVerificationRecipe
21+
from . import recipe
2322

2423
InputOverrideConfig = utils.OverrideConfig
2524
ParentRecipeEmailVerificationConfig = utils.ParentRecipeEmailVerificationConfig
2625
exception = ex
2726
SMTPService = emaildelivery_services.SMTPService
28-
EmailVerificationClaim = ev_claim.EmailVerificationClaim
27+
EmailVerificationClaim = recipe.EmailVerificationClaim
28+
EmailVerificationRecipe = recipe.EmailVerificationRecipe
2929

3030

3131
if TYPE_CHECKING:

supertokens_python/recipe/emailverification/api/implementation.py

Lines changed: 2 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -13,137 +13,7 @@
1313
# under the License.
1414
from __future__ import annotations
1515

16-
from typing import TYPE_CHECKING, Any, Dict, Union, Optional
17-
18-
from supertokens_python.logger import log_debug_message
19-
from supertokens_python.recipe.emailverification import (
20-
EmailVerificationRecipe,
21-
EmailVerificationClaim,
22-
)
23-
from supertokens_python.recipe.emailverification.interfaces import (
24-
APIInterface,
25-
CreateEmailVerificationTokenEmailAlreadyVerifiedError,
26-
EmailVerifyPostInvalidTokenError,
27-
EmailVerifyPostOkResult,
28-
GenerateEmailVerifyTokenPostEmailAlreadyVerifiedError,
29-
GenerateEmailVerifyTokenPostOkResult,
30-
IsEmailVerifiedGetOkResult,
31-
VerifyEmailUsingTokenOkResult,
32-
EmailDoesnotExistError,
33-
GetEmailForUserIdOkResult,
34-
)
35-
from supertokens_python.recipe.session.interfaces import SessionContainer
16+
from typing import TYPE_CHECKING
3617

3718
if TYPE_CHECKING:
38-
from supertokens_python.recipe.emailverification.interfaces import APIOptions
39-
40-
from supertokens_python.recipe.emailverification.types import (
41-
VerificationEmailTemplateVarsUser,
42-
VerificationEmailTemplateVars,
43-
)
44-
45-
46-
class APIImplementation(APIInterface):
47-
async def email_verify_post(
48-
self,
49-
token: str,
50-
api_options: APIOptions,
51-
user_context: Dict[str, Any],
52-
session: Optional[SessionContainer] = None,
53-
) -> Union[EmailVerifyPostOkResult, EmailVerifyPostInvalidTokenError]:
54-
response = await api_options.recipe_implementation.verify_email_using_token(
55-
token, user_context
56-
)
57-
if isinstance(response, VerifyEmailUsingTokenOkResult):
58-
if session is not None:
59-
await session.fetch_and_set_claim(EmailVerificationClaim, user_context)
60-
61-
return EmailVerifyPostOkResult(response.user)
62-
return EmailVerifyPostInvalidTokenError()
63-
64-
async def is_email_verified_get(
65-
self,
66-
api_options: APIOptions,
67-
user_context: Dict[str, Any],
68-
session: Optional[SessionContainer] = None,
69-
) -> IsEmailVerifiedGetOkResult:
70-
if session is None:
71-
raise Exception("Session is undefined. Should not come here.")
72-
await session.fetch_and_set_claim(EmailVerificationClaim, user_context)
73-
is_verified = await session.get_claim_value(
74-
EmailVerificationClaim, user_context
75-
)
76-
# TODO: Type of is_verified should be bool. It's any for now.
77-
78-
if is_verified is None:
79-
raise Exception(
80-
"Should never come here: EmailVerificationClaim failed to set value"
81-
)
82-
83-
return IsEmailVerifiedGetOkResult(is_verified)
84-
85-
async def generate_email_verify_token_post(
86-
self,
87-
api_options: APIOptions,
88-
user_context: Dict[str, Any],
89-
session: SessionContainer,
90-
) -> Union[
91-
GenerateEmailVerifyTokenPostOkResult,
92-
GenerateEmailVerifyTokenPostEmailAlreadyVerifiedError,
93-
]:
94-
if session is None:
95-
raise Exception("Session is undefined. Should not come here.")
96-
97-
user_id = session.get_user_id(user_context)
98-
email_info = await EmailVerificationRecipe.get_instance().get_email_for_user_id(
99-
user_id, user_context
100-
)
101-
102-
if isinstance(email_info, EmailDoesnotExistError):
103-
log_debug_message(
104-
"Email verification email not sent to user %s because it doesn't have an email address.",
105-
user_id,
106-
)
107-
return GenerateEmailVerifyTokenPostEmailAlreadyVerifiedError()
108-
if isinstance(email_info, GetEmailForUserIdOkResult):
109-
response = (
110-
await api_options.recipe_implementation.create_email_verification_token(
111-
user_id,
112-
email_info.email,
113-
user_context,
114-
)
115-
)
116-
117-
if isinstance(
118-
response, CreateEmailVerificationTokenEmailAlreadyVerifiedError
119-
):
120-
log_debug_message(
121-
"Email verification email not sent to %s because it is already verified.",
122-
email_info.email,
123-
)
124-
return GenerateEmailVerifyTokenPostEmailAlreadyVerifiedError()
125-
126-
email_verify_link = (
127-
api_options.app_info.website_domain.get_as_string_dangerous()
128-
+ api_options.app_info.website_base_path.get_as_string_dangerous()
129-
+ "/verify-email/"
130-
+ "?token="
131-
+ response.token
132-
+ "&rid="
133-
+ api_options.recipe_id
134-
)
135-
136-
log_debug_message("Sending email verification email to %s", email_info)
137-
email_verification_email_delivery_input = VerificationEmailTemplateVars(
138-
user=VerificationEmailTemplateVarsUser(user_id, email_info.email),
139-
email_verify_link=email_verify_link,
140-
user_context=user_context,
141-
)
142-
await api_options.email_delivery.ingredient_interface_impl.send_email(
143-
email_verification_email_delivery_input, user_context
144-
)
145-
return GenerateEmailVerifyTokenPostOkResult()
146-
147-
raise Exception(
148-
"Should never come here: UNKNOWN_USER_ID or invalid result from get_email_for_user_id"
149-
)
19+
pass

supertokens_python/recipe/emailverification/ev_claim.py

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,6 @@
1414
from __future__ import annotations
1515
from typing import Dict, Any
1616

17-
from supertokens_python.recipe.emailverification import EmailVerificationRecipe
18-
from supertokens_python.recipe.emailverification.interfaces import (
19-
GetEmailForUserIdOkResult,
20-
EmailDoesnotExistError,
21-
)
2217
from supertokens_python.recipe.session.claim_base_classes.boolean_claim import (
2318
BooleanClaim,
2419
BooleanClaimValidators,
@@ -71,28 +66,3 @@ def is_verified(
7166
return IsVerifiedSCV(
7267
self.claim, has_value_res, refetch_time_on_false_in_seconds
7368
)
74-
75-
76-
class EmailVerificationClaimClass(BooleanClaim):
77-
def __init__(self):
78-
async def fetch_value(user_id: str, user_context: Dict[str, Any]) -> bool:
79-
recipe = EmailVerificationRecipe.get_instance()
80-
email_info = await recipe.get_email_for_user_id(user_id, user_context)
81-
82-
if isinstance(email_info, GetEmailForUserIdOkResult):
83-
return await recipe.recipe_implementation.is_email_verified(
84-
user_id, email_info.email, user_context
85-
)
86-
if isinstance(email_info, EmailDoesnotExistError):
87-
# we consider people without email addresses as validated
88-
return True
89-
raise Exception(
90-
"Should never come here: UNKNOWN_USER_ID or invalid result from get_email_for_user"
91-
)
92-
93-
super().__init__("st-ev", fetch_value)
94-
95-
self.validators = EmailVerificationClaimValidators(claim=self)
96-
97-
98-
EmailVerificationClaim = EmailVerificationClaimClass()

0 commit comments

Comments
 (0)