11import os
22from typing import Any , Awaitable , Callable , Dict , List , Optional , Union
33
4+ import requests
45from dotenv import load_dotenv
56from supertokens_python import InputAppInfo , Supertokens , SupertokensConfig , init
67from supertokens_python .framework .request import BaseRequest
8586
8687from .store import save_code , save_url_with_token
8788
88- load_dotenv ()
89+ load_dotenv ("../auth-react.env" )
8990
9091
9192def get_api_port ():
@@ -296,8 +297,56 @@ async def exchange_auth_code_for_oauth_tokens(
296297 return oi
297298
298299
299- def custom_init ():
300- import mysite .store
300+ def get_core_url ():
301+ host = os .environ .get ("SUPERTOKENS_CORE_HOST" , "localhost" )
302+ port = os .environ .get ("SUPERTOKENS_CORE_PORT" , "3567" )
303+
304+ return f"http://localhost:{ host } :{ port } "
305+
306+
307+ def setup_core_app (
308+ * , appId : Optional [str ] = None , coreConfig : Optional [Dict [str , Any ]] = None
309+ ):
310+ core_url = get_core_url ()
311+
312+ if appId is None :
313+ appId = ""
314+
315+ if coreConfig is None :
316+ coreConfig = {}
317+
318+ response = requests .put (
319+ f"{ core_url } /recipe/multitenancy/app/v2" ,
320+ headers = {
321+ "Content-Type" : "application/json" ,
322+ },
323+ data = {
324+ "appId" : appId ,
325+ "coreConfig" : coreConfig ,
326+ },
327+ )
328+
329+ response_body = response .json ()
330+ assert response_body ["status" ] == "OK"
331+
332+ return f"{ core_url } /appid-{ appId } "
333+
334+
335+ def custom_init (
336+ * ,
337+ coreUrl : str = get_core_url (),
338+ accountLinkingConfig : Optional [Dict [str , Any ]] = None ,
339+ enabledRecipes : Optional [List [str ]] = None ,
340+ enabledProviders : Optional [List [str ]] = None ,
341+ passwordlessFlowType : Optional [str ] = "USER_INPUT_CODE_AND_MAGIC_LINK" ,
342+ passwordlessContactMethod : Optional [str ] = "EMAIL_OR_PHONE" ,
343+ mfaInfo : Optional [Dict [str , Any ]] = None ,
344+ ):
345+ if accountLinkingConfig is None :
346+ accountLinkingConfig = {}
347+
348+ if mfaInfo is None :
349+ mfaInfo = {}
301350
302351 AccountLinkingRecipe .reset ()
303352 UserRolesRecipe .reset ()
@@ -706,27 +755,27 @@ async def resend_code_post(
706755 ),
707756 ]
708757
709- if mysite . store . enabled_providers is not None :
758+ if enabledProviders is not None :
710759 providers_list = [
711760 provider
712761 for provider in providers_list
713- if provider .config .third_party_id in mysite . store . enabled_providers
762+ if provider .config .third_party_id in enabledProviders
714763 ]
715764
716- if mysite . store . contact_method is not None and mysite . store . flow_type is not None :
717- if mysite . store . contact_method == "PHONE" :
765+ if passwordlessContactMethod is not None and passwordlessFlowType is not None :
766+ if passwordlessContactMethod == "PHONE" :
718767 passwordless_init = passwordless .init (
719768 contact_config = ContactPhoneOnlyConfig (),
720- flow_type = mysite . store . flow_type ,
769+ flow_type = passwordlessFlowType , # type: ignore - type expects only certain literals
721770 sms_delivery = passwordless .SMSDeliveryConfig (CustomSMSService ()),
722771 override = passwordless .InputOverrideConfig (
723772 apis = override_passwordless_apis
724773 ),
725774 )
726- elif mysite . store . contact_method == "EMAIL" :
775+ elif passwordlessContactMethod == "EMAIL" :
727776 passwordless_init = passwordless .init (
728777 contact_config = ContactEmailOnlyConfig (),
729- flow_type = mysite . store . flow_type ,
778+ flow_type = passwordlessFlowType , # type: ignore - type expects only certain literals
730779 email_delivery = passwordless .EmailDeliveryConfig (
731780 CustomPlessEmailService ()
732781 ),
@@ -737,7 +786,7 @@ async def resend_code_post(
737786 else :
738787 passwordless_init = passwordless .init (
739788 contact_config = ContactEmailOrPhoneConfig (),
740- flow_type = mysite . store . flow_type ,
789+ flow_type = passwordlessFlowType , # type: ignore - type expects only certain literals
741790 email_delivery = passwordless .EmailDeliveryConfig (
742791 CustomPlessEmailService ()
743792 ),
@@ -780,8 +829,8 @@ async def get_factors_setup_for_user(
780829 user_context : Dict [str , Any ],
781830 ):
782831 res = await og_get_factors_setup_for_user (user , user_context )
783- if "alreadySetup" in mysite . store . mfa_info :
784- return mysite . store . mfa_info ["alreadySetup" ]
832+ if "alreadySetup" in mfaInfo :
833+ return mfaInfo ["alreadySetup" ]
785834 return res
786835
787836 og_assert_allowed_to_setup_factor = original_implementation .assert_allowed_to_setup_factor_else_throw_invalid_claim_error
@@ -793,8 +842,8 @@ async def assert_allowed_to_setup_factor_else_throw_invalid_claim_error(
793842 factors_set_up_for_user : Callable [[], Awaitable [List [str ]]],
794843 user_context : Dict [str , Any ],
795844 ):
796- if "allowedToSetup" in mysite . store . mfa_info :
797- if factor_id not in mysite . store . mfa_info ["allowedToSetup" ]:
845+ if "allowedToSetup" in mfaInfo :
846+ if factor_id not in mfaInfo ["allowedToSetup" ]:
798847 raise InvalidClaimsError (
799848 msg = "INVALID_CLAIMS" ,
800849 payload = [
@@ -834,8 +883,8 @@ async def get_mfa_requirements_for_auth(
834883 required_secondary_factors_for_tenant ,
835884 user_context ,
836885 )
837- if "requirements" in mysite . store . mfa_info :
838- return mysite . store . mfa_info ["requirements" ]
886+ if "requirements" in mfaInfo :
887+ return mfaInfo ["requirements" ]
839888 return res
840889
841890 original_implementation .get_mfa_requirements_for_auth = (
@@ -862,10 +911,10 @@ async def resync_session_and_fetch_mfa_info_put(
862911 )
863912
864913 if isinstance (res , ResyncSessionAndFetchMFAInfoPUTOkResult ):
865- if "alreadySetup" in mysite . store . mfa_info :
866- res .factors .already_setup = mysite . store . mfa_info ["alreadySetup" ][:]
914+ if "alreadySetup" in mfaInfo :
915+ res .factors .already_setup = mfaInfo ["alreadySetup" ][:]
867916
868- if "noContacts" in mysite . store . mfa_info :
917+ if "noContacts" in mfaInfo :
869918 res .emails = {}
870919 res .phone_numbers = {}
871920
@@ -926,7 +975,7 @@ async def resync_session_and_fetch_mfa_info_put(
926975 {
927976 "id" : "multifactorauth" ,
928977 "init" : multifactorauth .init (
929- first_factors = mysite . store . mfa_info .get ("firstFactors" , None ),
978+ first_factors = mfaInfo .get ("firstFactors" , None ),
930979 override = multifactorauth .OverrideConfig (
931980 functions = override_mfa_functions ,
932981 apis = override_mfa_apis ,
@@ -954,7 +1003,7 @@ async def resync_session_and_fetch_mfa_info_put(
9541003 "shouldAutomaticallyLink" : True ,
9551004 "shouldRequireVerification" : True ,
9561005 },
957- ** mysite . store . accountlinking_config ,
1006+ ** accountLinkingConfig ,
9581007 }
9591008
9601009 async def should_do_automatic_account_linking (
@@ -989,10 +1038,10 @@ async def should_do_automatic_account_linking(
9891038 }
9901039 )
9911040
992- if mysite . store . enabled_recipes is not None :
1041+ if enabledRecipes is not None :
9931042 new_recipe_list = []
9941043 for item in recipe_list :
995- for recipe_id in mysite . store . enabled_recipes :
1044+ for recipe_id in enabledRecipes :
9961045 if item ["id" ] in recipe_id :
9971046 new_recipe_list .append (item ["init" ]) # type: ignore
9981047 break
@@ -1003,7 +1052,7 @@ async def should_do_automatic_account_linking(
10031052 recipe_list = [item ["init" ] for item in recipe_list ]
10041053
10051054 init (
1006- supertokens_config = SupertokensConfig ("http://localhost:9000" ),
1055+ supertokens_config = SupertokensConfig (coreUrl ),
10071056 app_info = InputAppInfo (
10081057 app_name = "SuperTokens Demo" ,
10091058 api_domain = "localhost:" + get_api_port (),
0 commit comments