diff --git a/lib/build/recipe/dashboard/api/userdetails/userPasswordPut.js b/lib/build/recipe/dashboard/api/userdetails/userPasswordPut.js index d4fed4a91..136b55cf1 100644 --- a/lib/build/recipe/dashboard/api/userdetails/userPasswordPut.js +++ b/lib/build/recipe/dashboard/api/userdetails/userPasswordPut.js @@ -79,7 +79,7 @@ const userPasswordPut = (_, tenantId, options, userContext) => let passwordFormFields = recipe_1.default .getInstanceOrThrowError() .config.signUpFeature.formFields.filter((field) => field.id === constants_1.FORM_FIELD_PASSWORD_ID); - let passwordValidationError = yield passwordFormFields[0].validate(newPassword); + let passwordValidationError = yield passwordFormFields[0].validate(newPassword, tenantId); if (passwordValidationError !== undefined) { return { status: "INVALID_PASSWORD_ERROR", @@ -111,7 +111,7 @@ const userPasswordPut = (_, tenantId, options, userContext) => let passwordFormFields = recipe_2.default .getInstanceOrThrowError() .config.signUpFeature.formFields.filter((field) => field.id === constants_1.FORM_FIELD_PASSWORD_ID); - let passwordValidationError = yield passwordFormFields[0].validate(newPassword); + let passwordValidationError = yield passwordFormFields[0].validate(newPassword, tenantId); if (passwordValidationError !== undefined) { return { status: "INVALID_PASSWORD_ERROR", diff --git a/lib/build/recipe/dashboard/api/userdetails/userPut.d.ts b/lib/build/recipe/dashboard/api/userdetails/userPut.d.ts index 08684b279..6bc884816 100644 --- a/lib/build/recipe/dashboard/api/userdetails/userPut.d.ts +++ b/lib/build/recipe/dashboard/api/userdetails/userPut.d.ts @@ -20,7 +20,7 @@ declare type Response = }; export declare const userPut: ( _: APIInterface, - ___: string, + tenantId: string, options: APIOptions, userContext: any ) => Promise; diff --git a/lib/build/recipe/dashboard/api/userdetails/userPut.js b/lib/build/recipe/dashboard/api/userdetails/userPut.js index cb628ea4d..af1a8aaae 100644 --- a/lib/build/recipe/dashboard/api/userdetails/userPut.js +++ b/lib/build/recipe/dashboard/api/userdetails/userPut.js @@ -51,13 +51,13 @@ const recipe_5 = __importDefault(require("../../../usermetadata/recipe")); const usermetadata_1 = __importDefault(require("../../../usermetadata")); const constants_1 = require("../../../emailpassword/constants"); const utils_2 = require("../../../passwordless/utils"); -const updateEmailForRecipeId = (recipeId, userId, email, userContext) => +const updateEmailForRecipeId = (recipeId, userId, email, tenantId, userContext) => __awaiter(void 0, void 0, void 0, function* () { if (recipeId === "emailpassword") { let emailFormFields = recipe_1.default .getInstanceOrThrowError() .config.signUpFeature.formFields.filter((field) => field.id === constants_1.FORM_FIELD_EMAIL_ID); - let validationError = yield emailFormFields[0].validate(email); + let validationError = yield emailFormFields[0].validate(email, tenantId); if (validationError !== undefined) { return { status: "INVALID_EMAIL_ERROR", @@ -82,7 +82,7 @@ const updateEmailForRecipeId = (recipeId, userId, email, userContext) => let emailFormFields = recipe_2.default .getInstanceOrThrowError() .config.signUpFeature.formFields.filter((field) => field.id === constants_1.FORM_FIELD_EMAIL_ID); - let validationError = yield emailFormFields[0].validate(email); + let validationError = yield emailFormFields[0].validate(email, tenantId); if (validationError !== undefined) { return { status: "INVALID_EMAIL_ERROR", @@ -117,7 +117,7 @@ const updateEmailForRecipeId = (recipeId, userId, email, userContext) => validationError = validationResult; } } else { - const validationResult = yield passwordlessConfig.validateEmailAddress(email); + const validationResult = yield passwordlessConfig.validateEmailAddress(email, tenantId); if (validationResult !== undefined) { isValidEmail = false; validationError = validationResult; @@ -157,7 +157,7 @@ const updateEmailForRecipeId = (recipeId, userId, email, userContext) => validationError = validationResult; } } else { - const validationResult = yield passwordlessConfig.validateEmailAddress(email); + const validationResult = yield passwordlessConfig.validateEmailAddress(email, tenantId); if (validationResult !== undefined) { isValidEmail = false; validationError = validationResult; @@ -191,7 +191,7 @@ const updateEmailForRecipeId = (recipeId, userId, email, userContext) => */ throw new Error("Should never come here"); }); -const updatePhoneForRecipeId = (recipeId, userId, phone, userContext) => +const updatePhoneForRecipeId = (recipeId, userId, phone, tenantId, userContext) => __awaiter(void 0, void 0, void 0, function* () { if (recipeId === "passwordless") { let isValidPhone = true; @@ -204,7 +204,7 @@ const updatePhoneForRecipeId = (recipeId, userId, phone, userContext) => validationError = validationResult; } } else { - const validationResult = yield passwordlessConfig.validatePhoneNumber(phone); + const validationResult = yield passwordlessConfig.validatePhoneNumber(phone, tenantId); if (validationResult !== undefined) { isValidPhone = false; validationError = validationResult; @@ -244,7 +244,7 @@ const updatePhoneForRecipeId = (recipeId, userId, phone, userContext) => validationError = validationResult; } } else { - const validationResult = yield passwordlessConfig.validatePhoneNumber(phone); + const validationResult = yield passwordlessConfig.validatePhoneNumber(phone, tenantId); if (validationResult !== undefined) { isValidPhone = false; validationError = validationResult; @@ -278,7 +278,7 @@ const updatePhoneForRecipeId = (recipeId, userId, phone, userContext) => */ throw new Error("Should never come here"); }); -const userPut = (_, ___, options, userContext) => +const userPut = (_, tenantId, options, userContext) => __awaiter(void 0, void 0, void 0, function* () { const requestBody = yield options.req.getJSONBody(); const userId = requestBody.userId; @@ -357,6 +357,7 @@ const userPut = (_, ___, options, userContext) => userResponse.recipe, userId, email.trim(), + tenantId, userContext ); if (emailUpdateResponse.status !== "OK") { @@ -368,6 +369,7 @@ const userPut = (_, ___, options, userContext) => userResponse.recipe, userId, phone.trim(), + tenantId, userContext ); if (phoneUpdateResponse.status !== "OK") { diff --git a/lib/build/recipe/emailpassword/api/generatePasswordResetToken.js b/lib/build/recipe/emailpassword/api/generatePasswordResetToken.js index bd2cbb149..90c591fa1 100644 --- a/lib/build/recipe/emailpassword/api/generatePasswordResetToken.js +++ b/lib/build/recipe/emailpassword/api/generatePasswordResetToken.js @@ -56,7 +56,8 @@ function generatePasswordResetToken(apiImplementation, tenantId, options, userCo // step 1 let formFields = yield utils_2.validateFormFieldsOrThrowError( options.config.resetPasswordUsingTokenFeature.formFieldsForGenerateTokenForm, - (yield options.req.getJSONBody()).formFields + (yield options.req.getJSONBody()).formFields, + tenantId ); let result = yield apiImplementation.generatePasswordResetTokenPOST({ formFields, diff --git a/lib/build/recipe/emailpassword/api/passwordReset.js b/lib/build/recipe/emailpassword/api/passwordReset.js index 2170f7f03..9fc50b87b 100644 --- a/lib/build/recipe/emailpassword/api/passwordReset.js +++ b/lib/build/recipe/emailpassword/api/passwordReset.js @@ -62,7 +62,8 @@ function passwordReset(apiImplementation, tenantId, options, userContext) { // step 1 let formFields = yield utils_2.validateFormFieldsOrThrowError( options.config.resetPasswordUsingTokenFeature.formFieldsForPasswordResetForm, - (yield options.req.getJSONBody()).formFields + (yield options.req.getJSONBody()).formFields, + tenantId ); let token = (yield options.req.getJSONBody()).token; if (token === undefined) { diff --git a/lib/build/recipe/emailpassword/api/signin.js b/lib/build/recipe/emailpassword/api/signin.js index dd25133eb..0351b9064 100644 --- a/lib/build/recipe/emailpassword/api/signin.js +++ b/lib/build/recipe/emailpassword/api/signin.js @@ -56,7 +56,8 @@ function signInAPI(apiImplementation, tenantId, options, userContext) { // step 1 let formFields = yield utils_2.validateFormFieldsOrThrowError( options.config.signInFeature.formFields, - (yield options.req.getJSONBody()).formFields + (yield options.req.getJSONBody()).formFields, + tenantId ); let result = yield apiImplementation.signInPOST({ formFields, diff --git a/lib/build/recipe/emailpassword/api/signup.js b/lib/build/recipe/emailpassword/api/signup.js index b70407e07..fa66ca4c9 100644 --- a/lib/build/recipe/emailpassword/api/signup.js +++ b/lib/build/recipe/emailpassword/api/signup.js @@ -62,7 +62,8 @@ function signUpAPI(apiImplementation, tenantId, options, userContext) { // step 1 let formFields = yield utils_2.validateFormFieldsOrThrowError( options.config.signUpFeature.formFields, - (yield options.req.getJSONBody()).formFields + (yield options.req.getJSONBody()).formFields, + tenantId ); let result = yield apiImplementation.signUpPOST({ formFields, diff --git a/lib/build/recipe/emailpassword/api/utils.d.ts b/lib/build/recipe/emailpassword/api/utils.d.ts index 5579f71cc..998bf0c28 100644 --- a/lib/build/recipe/emailpassword/api/utils.d.ts +++ b/lib/build/recipe/emailpassword/api/utils.d.ts @@ -2,7 +2,8 @@ import { NormalisedFormField } from "../types"; export declare function validateFormFieldsOrThrowError( configFormFields: NormalisedFormField[], - formFieldsRaw: any + formFieldsRaw: any, + tenantId: string ): Promise< { id: string; diff --git a/lib/build/recipe/emailpassword/api/utils.js b/lib/build/recipe/emailpassword/api/utils.js index bbf03c787..e8e5a8417 100644 --- a/lib/build/recipe/emailpassword/api/utils.js +++ b/lib/build/recipe/emailpassword/api/utils.js @@ -39,7 +39,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.validateFormFieldsOrThrowError = void 0; const error_1 = __importDefault(require("../error")); const constants_1 = require("../constants"); -function validateFormFieldsOrThrowError(configFormFields, formFieldsRaw) { +function validateFormFieldsOrThrowError(configFormFields, formFieldsRaw, tenantId) { return __awaiter(this, void 0, void 0, function* () { // first we check syntax ---------------------------- if (formFieldsRaw === undefined) { @@ -67,7 +67,7 @@ function validateFormFieldsOrThrowError(configFormFields, formFieldsRaw) { return field; }); // then run validators through them----------------------- - yield validateFormOrThrowError(formFields, configFormFields); + yield validateFormOrThrowError(formFields, configFormFields, tenantId); return formFields; }); } @@ -80,7 +80,7 @@ function newBadRequestError(message) { } // We check that the number of fields in input and config form field is the same. // We check that each item in the config form field is also present in the input form field -function validateFormOrThrowError(inputs, configFormFields) { +function validateFormOrThrowError(inputs, configFormFields, tenantId) { return __awaiter(this, void 0, void 0, function* () { let validationErrors = []; if (configFormFields.length !== inputs.length) { @@ -99,7 +99,7 @@ function validateFormOrThrowError(inputs, configFormFields) { }); } else { // Otherwise, use validate function. - const error = yield field.validate(input.value); + const error = yield field.validate(input.value, tenantId); // If error, add it. if (error !== undefined) { validationErrors.push({ diff --git a/lib/build/recipe/emailpassword/emaildelivery/services/backwardCompatibility/index.d.ts b/lib/build/recipe/emailpassword/emaildelivery/services/backwardCompatibility/index.d.ts index 77620015d..3f9e44647 100644 --- a/lib/build/recipe/emailpassword/emaildelivery/services/backwardCompatibility/index.d.ts +++ b/lib/build/recipe/emailpassword/emaildelivery/services/backwardCompatibility/index.d.ts @@ -1,5 +1,5 @@ // @ts-nocheck -import { TypeEmailPasswordEmailDeliveryInput, User, RecipeInterface } from "../../../types"; +import { TypeEmailPasswordEmailDeliveryInput, RecipeInterface } from "../../../types"; import { NormalisedAppinfo } from "../../../../../types"; import { EmailDeliveryInterface } from "../../../../../ingredients/emaildelivery/types"; export default class BackwardCompatibilityService @@ -7,19 +7,7 @@ export default class BackwardCompatibilityService private recipeInterfaceImpl; private isInServerlessEnv; private appInfo; - private resetPasswordUsingTokenFeature; - constructor( - recipeInterfaceImpl: RecipeInterface, - appInfo: NormalisedAppinfo, - isInServerlessEnv: boolean, - resetPasswordUsingTokenFeature?: { - createAndSendCustomEmail?: ( - user: User, - passwordResetURLWithToken: string, - userContext: any - ) => Promise; - } - ); + constructor(recipeInterfaceImpl: RecipeInterface, appInfo: NormalisedAppinfo, isInServerlessEnv: boolean); sendEmail: ( input: TypeEmailPasswordEmailDeliveryInput & { userContext: any; diff --git a/lib/build/recipe/emailpassword/emaildelivery/services/backwardCompatibility/index.js b/lib/build/recipe/emailpassword/emaildelivery/services/backwardCompatibility/index.js index 96f394f0d..6cd37e689 100644 --- a/lib/build/recipe/emailpassword/emaildelivery/services/backwardCompatibility/index.js +++ b/lib/build/recipe/emailpassword/emaildelivery/services/backwardCompatibility/index.js @@ -33,7 +33,7 @@ var __awaiter = Object.defineProperty(exports, "__esModule", { value: true }); const passwordResetFunctions_1 = require("../../../passwordResetFunctions"); class BackwardCompatibilityService { - constructor(recipeInterfaceImpl, appInfo, isInServerlessEnv, resetPasswordUsingTokenFeature) { + constructor(recipeInterfaceImpl, appInfo, isInServerlessEnv) { this.sendEmail = (input) => __awaiter(this, void 0, void 0, function* () { let user = yield this.recipeInterfaceImpl.getUserById({ @@ -49,15 +49,15 @@ class BackwardCompatibilityService { user.email = input.user.email; try { if (!this.isInServerlessEnv) { - this.resetPasswordUsingTokenFeature - .createAndSendCustomEmail(user, input.passwordResetLink, input.userContext) + passwordResetFunctions_1 + .createAndSendEmailUsingSupertokensService(this.appInfo, user, input.passwordResetLink) .catch((_) => {}); } else { // see https://github.com/supertokens/supertokens-node/pull/135 - yield this.resetPasswordUsingTokenFeature.createAndSendCustomEmail( + yield passwordResetFunctions_1.createAndSendEmailUsingSupertokensService( + this.appInfo, user, - input.passwordResetLink, - input.userContext + input.passwordResetLink ); } } catch (_) {} @@ -65,20 +65,6 @@ class BackwardCompatibilityService { this.recipeInterfaceImpl = recipeInterfaceImpl; this.isInServerlessEnv = isInServerlessEnv; this.appInfo = appInfo; - { - let inputCreateAndSendCustomEmail = - resetPasswordUsingTokenFeature === null || resetPasswordUsingTokenFeature === void 0 - ? void 0 - : resetPasswordUsingTokenFeature.createAndSendCustomEmail; - this.resetPasswordUsingTokenFeature = - inputCreateAndSendCustomEmail !== undefined - ? { - createAndSendCustomEmail: inputCreateAndSendCustomEmail, - } - : { - createAndSendCustomEmail: passwordResetFunctions_1.createAndSendCustomEmail(this.appInfo), - }; - } } } exports.default = BackwardCompatibilityService; diff --git a/lib/build/recipe/emailpassword/index.d.ts b/lib/build/recipe/emailpassword/index.d.ts index 654045cc6..b230b3a82 100644 --- a/lib/build/recipe/emailpassword/index.d.ts +++ b/lib/build/recipe/emailpassword/index.d.ts @@ -68,6 +68,7 @@ export default class Wrapper { password?: string; userContext?: any; applyPasswordPolicy?: boolean; + tenantIdForPasswordPolicy?: string; }): Promise< | { status: "OK" | "UNKNOWN_USER_ID_ERROR" | "EMAIL_ALREADY_EXISTS_ERROR"; diff --git a/lib/build/recipe/emailpassword/index.js b/lib/build/recipe/emailpassword/index.js index c942897ef..7c31cf370 100644 --- a/lib/build/recipe/emailpassword/index.js +++ b/lib/build/recipe/emailpassword/index.js @@ -101,9 +101,14 @@ class Wrapper { }); } static updateEmailOrPassword(input) { - return recipe_1.default - .getInstanceOrThrowError() - .recipeInterfaceImpl.updateEmailOrPassword(Object.assign({ userContext: {} }, input)); + return recipe_1.default.getInstanceOrThrowError().recipeInterfaceImpl.updateEmailOrPassword( + Object.assign(Object.assign({ userContext: {} }, input), { + tenantIdForPasswordPolicy: + input.tenantIdForPasswordPolicy === undefined + ? constants_1.DEFAULT_TENANT_ID + : input.tenantIdForPasswordPolicy, + }) + ); } static createResetPasswordLink(userId, tenantId, userContext) { return __awaiter(this, void 0, void 0, function* () { diff --git a/lib/build/recipe/emailpassword/passwordResetFunctions.d.ts b/lib/build/recipe/emailpassword/passwordResetFunctions.d.ts index 56b10c948..38959a2d7 100644 --- a/lib/build/recipe/emailpassword/passwordResetFunctions.d.ts +++ b/lib/build/recipe/emailpassword/passwordResetFunctions.d.ts @@ -1,6 +1,8 @@ // @ts-nocheck import { User } from "./types"; import { NormalisedAppinfo } from "../../types"; -export declare function createAndSendCustomEmail( - appInfo: NormalisedAppinfo -): (user: User, passwordResetURLWithToken: string) => Promise; +export declare function createAndSendEmailUsingSupertokensService( + appInfo: NormalisedAppinfo, + user: User, + passwordResetURLWithToken: string +): Promise; diff --git a/lib/build/recipe/emailpassword/passwordResetFunctions.js b/lib/build/recipe/emailpassword/passwordResetFunctions.js index 535499e39..98f749e5e 100644 --- a/lib/build/recipe/emailpassword/passwordResetFunctions.js +++ b/lib/build/recipe/emailpassword/passwordResetFunctions.js @@ -50,56 +50,55 @@ var __importDefault = return mod && mod.__esModule ? mod : { default: mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.createAndSendCustomEmail = void 0; +exports.createAndSendEmailUsingSupertokensService = void 0; const axios_1 = __importDefault(require("axios")); const logger_1 = require("../../logger"); -function createAndSendCustomEmail(appInfo) { - return (user, passwordResetURLWithToken) => - __awaiter(this, void 0, void 0, function* () { - // related issue: https://github.com/supertokens/supertokens-node/issues/38 - if (process.env.TEST_MODE === "testing") { - return; +function createAndSendEmailUsingSupertokensService(appInfo, user, passwordResetURLWithToken) { + return __awaiter(this, void 0, void 0, function* () { + // related issue: https://github.com/supertokens/supertokens-node/issues/38 + if (process.env.TEST_MODE === "testing") { + return; + } + try { + yield axios_1.default({ + method: "POST", + url: "https://api.supertokens.io/0/st/auth/password/reset", + data: { + email: user.email, + appName: appInfo.appName, + passwordResetURL: passwordResetURLWithToken, + }, + headers: { + "api-version": 0, + }, + }); + logger_1.logDebugMessage(`Password reset email sent to ${user.email}`); + } catch (error) { + logger_1.logDebugMessage("Error sending password reset email"); + if (axios_1.default.isAxiosError(error)) { + const err = error; + if (err.response) { + logger_1.logDebugMessage(`Error status: ${err.response.status}`); + logger_1.logDebugMessage(`Error response: ${JSON.stringify(err.response.data)}`); + } else { + logger_1.logDebugMessage(`Error: ${err.message}`); + } + } else { + logger_1.logDebugMessage(`Error: ${JSON.stringify(error)}`); } - try { - yield axios_1.default({ - method: "POST", - url: "https://api.supertokens.io/0/st/auth/password/reset", - data: { + logger_1.logDebugMessage("Logging the input below:"); + logger_1.logDebugMessage( + JSON.stringify( + { email: user.email, appName: appInfo.appName, passwordResetURL: passwordResetURLWithToken, }, - headers: { - "api-version": 0, - }, - }); - logger_1.logDebugMessage(`Password reset email sent to ${user.email}`); - } catch (error) { - logger_1.logDebugMessage("Error sending password reset email"); - if (axios_1.default.isAxiosError(error)) { - const err = error; - if (err.response) { - logger_1.logDebugMessage(`Error status: ${err.response.status}`); - logger_1.logDebugMessage(`Error response: ${JSON.stringify(err.response.data)}`); - } else { - logger_1.logDebugMessage(`Error: ${err.message}`); - } - } else { - logger_1.logDebugMessage(`Error: ${JSON.stringify(error)}`); - } - logger_1.logDebugMessage("Logging the input below:"); - logger_1.logDebugMessage( - JSON.stringify( - { - email: user.email, - appName: appInfo.appName, - passwordResetURL: passwordResetURLWithToken, - }, - null, - 2 - ) - ); - } - }); + null, + 2 + ) + ); + } + }); } -exports.createAndSendCustomEmail = createAndSendCustomEmail; +exports.createAndSendEmailUsingSupertokensService = createAndSendEmailUsingSupertokensService; diff --git a/lib/build/recipe/emailpassword/recipeImplementation.js b/lib/build/recipe/emailpassword/recipeImplementation.js index a4170a97f..5ab61cd8b 100644 --- a/lib/build/recipe/emailpassword/recipeImplementation.js +++ b/lib/build/recipe/emailpassword/recipeImplementation.js @@ -159,7 +159,7 @@ function getRecipeInterface(querier, getEmailPasswordConfig) { const passwordField = formFields.filter( (el) => el.id === constants_1.FORM_FIELD_PASSWORD_ID )[0]; - const error = yield passwordField.validate(input.password); + const error = yield passwordField.validate(input.password, input.tenantIdForPasswordPolicy); if (error !== undefined) { return { status: "PASSWORD_POLICY_VIOLATED_ERROR", diff --git a/lib/build/recipe/emailpassword/types.d.ts b/lib/build/recipe/emailpassword/types.d.ts index ab3674b65..53c0e1bae 100644 --- a/lib/build/recipe/emailpassword/types.d.ts +++ b/lib/build/recipe/emailpassword/types.d.ts @@ -26,7 +26,7 @@ export declare type TypeNormalisedInput = { }; export declare type TypeInputFormField = { id: string; - validate?: (value: any) => Promise; + validate?: (value: any, tenantId: string) => Promise; optional?: boolean; }; export declare type TypeFormField = { @@ -38,7 +38,7 @@ export declare type TypeInputSignUp = { }; export declare type NormalisedFormField = { id: string; - validate: (value: any) => Promise; + validate: (value: any, tenantId: string) => Promise; optional: boolean; }; export declare type TypeNormalisedInputSignUp = { @@ -47,12 +47,6 @@ export declare type TypeNormalisedInputSignUp = { export declare type TypeNormalisedInputSignIn = { formFields: NormalisedFormField[]; }; -export declare type TypeInputResetPasswordUsingTokenFeature = { - /** - * @deprecated Please use emailDelivery config instead - */ - createAndSendCustomEmail?: (user: User, passwordResetURLWithToken: string, userContext: any) => Promise; -}; export declare type TypeNormalisedInputResetPasswordUsingTokenFeature = { formFieldsForGenerateTokenForm: NormalisedFormField[]; formFieldsForPasswordResetForm: NormalisedFormField[]; @@ -66,7 +60,6 @@ export declare type User = { export declare type TypeInput = { signUpFeature?: TypeInputSignUp; emailDelivery?: EmailDeliveryTypeInput; - resetPasswordUsingTokenFeature?: TypeInputResetPasswordUsingTokenFeature; override?: { functions?: ( originalImplementation: RecipeInterface, @@ -143,6 +136,7 @@ export declare type RecipeInterface = { password?: string; userContext: any; applyPasswordPolicy?: boolean; + tenantIdForPasswordPolicy: string; }): Promise< | { status: "OK" | "UNKNOWN_USER_ID_ERROR" | "EMAIL_ALREADY_EXISTS_ERROR"; diff --git a/lib/build/recipe/emailpassword/utils.js b/lib/build/recipe/emailpassword/utils.js index 064ecd8ea..06e998f29 100644 --- a/lib/build/recipe/emailpassword/utils.js +++ b/lib/build/recipe/emailpassword/utils.js @@ -76,18 +76,11 @@ function validateAndNormaliseUserInput(recipeInstance, appInfo, config) { : _a.service; /** * following code is for backward compatibility. - * if user has not passed emailDelivery config, we - * use the createAndSendCustomEmail config. If the user - * has not passed even that config, we use the default - * createAndSendCustomEmail implementation which calls our supertokens API + * if user has not passed emailDelivery config, we use the default + * createAndSendEmailUsingSupertokensService implementation which calls our supertokens API */ if (emailService === undefined) { - emailService = new backwardCompatibility_1.default( - recipeImpl, - appInfo, - isInServerlessEnv, - config === null || config === void 0 ? void 0 : config.resetPasswordUsingTokenFeature - ); + emailService = new backwardCompatibility_1.default(recipeImpl, appInfo, isInServerlessEnv); } return Object.assign(Object.assign({}, config === null || config === void 0 ? void 0 : config.emailDelivery), { /** diff --git a/lib/build/recipe/emailverification/emailVerificationFunctions.d.ts b/lib/build/recipe/emailverification/emailVerificationFunctions.d.ts index f09fbc85b..0dd678d38 100644 --- a/lib/build/recipe/emailverification/emailVerificationFunctions.d.ts +++ b/lib/build/recipe/emailverification/emailVerificationFunctions.d.ts @@ -1,6 +1,8 @@ // @ts-nocheck import { User } from "./types"; import { NormalisedAppinfo } from "../../types"; -export declare function createAndSendCustomEmail( - appInfo: NormalisedAppinfo -): (user: User, emailVerifyURLWithToken: string) => Promise; +export declare function createAndSendEmailUsingSupertokensService( + appInfo: NormalisedAppinfo, + user: User, + emailVerifyURLWithToken: string +): Promise; diff --git a/lib/build/recipe/emailverification/emailVerificationFunctions.js b/lib/build/recipe/emailverification/emailVerificationFunctions.js index 29b7b92a2..b590e17ed 100644 --- a/lib/build/recipe/emailverification/emailVerificationFunctions.js +++ b/lib/build/recipe/emailverification/emailVerificationFunctions.js @@ -50,55 +50,54 @@ var __importDefault = return mod && mod.__esModule ? mod : { default: mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.createAndSendCustomEmail = void 0; +exports.createAndSendEmailUsingSupertokensService = void 0; const axios_1 = __importDefault(require("axios")); const logger_1 = require("../../logger"); -function createAndSendCustomEmail(appInfo) { - return (user, emailVerifyURLWithToken) => - __awaiter(this, void 0, void 0, function* () { - if (process.env.TEST_MODE === "testing") { - return; +function createAndSendEmailUsingSupertokensService(appInfo, user, emailVerifyURLWithToken) { + return __awaiter(this, void 0, void 0, function* () { + if (process.env.TEST_MODE === "testing") { + return; + } + try { + yield axios_1.default({ + method: "POST", + url: "https://api.supertokens.io/0/st/auth/email/verify", + data: { + email: user.email, + appName: appInfo.appName, + emailVerifyURL: emailVerifyURLWithToken, + }, + headers: { + "api-version": 0, + }, + }); + logger_1.logDebugMessage(`Email sent to ${user.email}`); + } catch (error) { + logger_1.logDebugMessage("Error sending verification email"); + if (axios_1.default.isAxiosError(error)) { + const err = error; + if (err.response) { + logger_1.logDebugMessage(`Error status: ${err.response.status}`); + logger_1.logDebugMessage(`Error response: ${JSON.stringify(err.response.data)}`); + } else { + logger_1.logDebugMessage(`Error: ${err.message}`); + } + } else { + logger_1.logDebugMessage(`Error: ${JSON.stringify(error)}`); } - try { - yield axios_1.default({ - method: "POST", - url: "https://api.supertokens.io/0/st/auth/email/verify", - data: { + logger_1.logDebugMessage("Logging the input below:"); + logger_1.logDebugMessage( + JSON.stringify( + { email: user.email, appName: appInfo.appName, emailVerifyURL: emailVerifyURLWithToken, }, - headers: { - "api-version": 0, - }, - }); - logger_1.logDebugMessage(`Email sent to ${user.email}`); - } catch (error) { - logger_1.logDebugMessage("Error sending verification email"); - if (axios_1.default.isAxiosError(error)) { - const err = error; - if (err.response) { - logger_1.logDebugMessage(`Error status: ${err.response.status}`); - logger_1.logDebugMessage(`Error response: ${JSON.stringify(err.response.data)}`); - } else { - logger_1.logDebugMessage(`Error: ${err.message}`); - } - } else { - logger_1.logDebugMessage(`Error: ${JSON.stringify(error)}`); - } - logger_1.logDebugMessage("Logging the input below:"); - logger_1.logDebugMessage( - JSON.stringify( - { - email: user.email, - appName: appInfo.appName, - emailVerifyURL: emailVerifyURLWithToken, - }, - null, - 2 - ) - ); - } - }); + null, + 2 + ) + ); + } + }); } -exports.createAndSendCustomEmail = createAndSendCustomEmail; +exports.createAndSendEmailUsingSupertokensService = createAndSendEmailUsingSupertokensService; diff --git a/lib/build/recipe/emailverification/emaildelivery/services/backwardCompatibility/index.d.ts b/lib/build/recipe/emailverification/emaildelivery/services/backwardCompatibility/index.d.ts index 6a681f11d..e49c3c040 100644 --- a/lib/build/recipe/emailverification/emaildelivery/services/backwardCompatibility/index.d.ts +++ b/lib/build/recipe/emailverification/emaildelivery/services/backwardCompatibility/index.d.ts @@ -1,21 +1,12 @@ // @ts-nocheck -import { TypeEmailVerificationEmailDeliveryInput, User } from "../../../types"; +import { TypeEmailVerificationEmailDeliveryInput } from "../../../types"; import { NormalisedAppinfo } from "../../../../../types"; import { EmailDeliveryInterface } from "../../../../../ingredients/emaildelivery/types"; export default class BackwardCompatibilityService implements EmailDeliveryInterface { private appInfo; private isInServerlessEnv; - private createAndSendCustomEmail; - constructor( - appInfo: NormalisedAppinfo, - isInServerlessEnv: boolean, - createAndSendCustomEmail?: ( - user: User, - emailVerificationURLWithToken: string, - userContext: any - ) => Promise - ); + constructor(appInfo: NormalisedAppinfo, isInServerlessEnv: boolean); sendEmail: ( input: TypeEmailVerificationEmailDeliveryInput & { userContext: any; diff --git a/lib/build/recipe/emailverification/emaildelivery/services/backwardCompatibility/index.js b/lib/build/recipe/emailverification/emaildelivery/services/backwardCompatibility/index.js index 67e5311b1..7867c3be3 100644 --- a/lib/build/recipe/emailverification/emaildelivery/services/backwardCompatibility/index.js +++ b/lib/build/recipe/emailverification/emaildelivery/services/backwardCompatibility/index.js @@ -33,28 +33,26 @@ var __awaiter = Object.defineProperty(exports, "__esModule", { value: true }); const emailVerificationFunctions_1 = require("../../../emailVerificationFunctions"); class BackwardCompatibilityService { - constructor(appInfo, isInServerlessEnv, createAndSendCustomEmail) { + constructor(appInfo, isInServerlessEnv) { this.sendEmail = (input) => __awaiter(this, void 0, void 0, function* () { try { if (!this.isInServerlessEnv) { - this.createAndSendCustomEmail( - input.user, - input.emailVerifyLink, - input.userContext - ).catch((_) => {}); + emailVerificationFunctions_1 + .createAndSendEmailUsingSupertokensService(this.appInfo, input.user, input.emailVerifyLink) + .catch((_) => {}); } else { // see https://github.com/supertokens/supertokens-node/pull/135 - yield this.createAndSendCustomEmail(input.user, input.emailVerifyLink, input.userContext); + yield emailVerificationFunctions_1.createAndSendEmailUsingSupertokensService( + this.appInfo, + input.user, + input.emailVerifyLink + ); } } catch (_) {} }); this.appInfo = appInfo; this.isInServerlessEnv = isInServerlessEnv; - this.createAndSendCustomEmail = - createAndSendCustomEmail === undefined - ? emailVerificationFunctions_1.createAndSendCustomEmail(this.appInfo) - : createAndSendCustomEmail; } } exports.default = BackwardCompatibilityService; diff --git a/lib/build/recipe/emailverification/types.d.ts b/lib/build/recipe/emailverification/types.d.ts index 42733fe7c..0a72560af 100644 --- a/lib/build/recipe/emailverification/types.d.ts +++ b/lib/build/recipe/emailverification/types.d.ts @@ -23,10 +23,6 @@ export declare type TypeInput = { status: "EMAIL_DOES_NOT_EXIST_ERROR" | "UNKNOWN_USER_ID_ERROR"; } >; - /** - * @deprecated Please use emailDelivery config instead - */ - createAndSendCustomEmail?: (user: User, emailVerificationURLWithToken: string, userContext: any) => Promise; override?: { functions?: ( originalImplementation: RecipeInterface, diff --git a/lib/build/recipe/emailverification/utils.js b/lib/build/recipe/emailverification/utils.js index 39cbd35eb..e1adb446c 100644 --- a/lib/build/recipe/emailverification/utils.js +++ b/lib/build/recipe/emailverification/utils.js @@ -34,17 +34,11 @@ function validateAndNormaliseUserInput(_, appInfo, config) { let emailService = (_a = config.emailDelivery) === null || _a === void 0 ? void 0 : _a.service; /** * following code is for backward compatibility. - * if user has not passed emailDelivery config, we - * use the createAndSendCustomEmail config. If the user - * has not passed even that config, we use the default - * createAndSendCustomEmail implementation which calls our supertokens API + * if user has not passed emailDelivery config, we use the default + * createAndSendEmailUsingSupertokensService implementation which calls our supertokens API */ if (emailService === undefined) { - emailService = new backwardCompatibility_1.default( - appInfo, - isInServerlessEnv, - config.createAndSendCustomEmail - ); + emailService = new backwardCompatibility_1.default(appInfo, isInServerlessEnv); } return Object.assign(Object.assign({}, config.emailDelivery), { /** diff --git a/lib/build/recipe/passwordless/api/createCode.js b/lib/build/recipe/passwordless/api/createCode.js index 17dd34bf3..587bb43fe 100644 --- a/lib/build/recipe/passwordless/api/createCode.js +++ b/lib/build/recipe/passwordless/api/createCode.js @@ -85,7 +85,7 @@ function createCode(apiImplementation, tenantId, options, userContext) { (options.config.contactMethod === "EMAIL" || options.config.contactMethod === "EMAIL_OR_PHONE") ) { email = email.trim(); - const validateError = yield options.config.validateEmailAddress(email); + const validateError = yield options.config.validateEmailAddress(email, tenantId); if (validateError !== undefined) { utils_1.send200Response(options.res, { status: "GENERAL_ERROR", @@ -98,7 +98,7 @@ function createCode(apiImplementation, tenantId, options, userContext) { phoneNumber !== undefined && (options.config.contactMethod === "PHONE" || options.config.contactMethod === "EMAIL_OR_PHONE") ) { - const validateError = yield options.config.validatePhoneNumber(phoneNumber); + const validateError = yield options.config.validatePhoneNumber(phoneNumber, tenantId); if (validateError !== undefined) { utils_1.send200Response(options.res, { status: "GENERAL_ERROR", diff --git a/lib/build/recipe/passwordless/api/implementation.js b/lib/build/recipe/passwordless/api/implementation.js index 42652a59f..c555e612d 100644 --- a/lib/build/recipe/passwordless/api/implementation.js +++ b/lib/build/recipe/passwordless/api/implementation.js @@ -110,7 +110,10 @@ function getAPIImplementation() { userInputCode: input.options.config.getCustomUserInputCode === undefined ? undefined - : yield input.options.config.getCustomUserInputCode(input.userContext), + : yield input.options.config.getCustomUserInputCode( + input.tenantId, + input.userContext + ), tenantId: input.tenantId, } : { @@ -119,7 +122,10 @@ function getAPIImplementation() { userInputCode: input.options.config.getCustomUserInputCode === undefined ? undefined - : yield input.options.config.getCustomUserInputCode(input.userContext), + : yield input.options.config.getCustomUserInputCode( + input.tenantId, + input.userContext + ), tenantId: input.tenantId, } ); @@ -238,7 +244,7 @@ function getAPIImplementation() { userInputCode: input.options.config.getCustomUserInputCode === undefined ? undefined - : yield input.options.config.getCustomUserInputCode(input.userContext), + : yield input.options.config.getCustomUserInputCode(input.tenantId, input.userContext), tenantId: input.tenantId, }); if (response.status === "USER_INPUT_CODE_ALREADY_USED_ERROR") { diff --git a/lib/build/recipe/passwordless/emaildelivery/services/backwardCompatibility/index.d.ts b/lib/build/recipe/passwordless/emaildelivery/services/backwardCompatibility/index.d.ts index 2f0015dda..533582631 100644 --- a/lib/build/recipe/passwordless/emaildelivery/services/backwardCompatibility/index.d.ts +++ b/lib/build/recipe/passwordless/emaildelivery/services/backwardCompatibility/index.d.ts @@ -4,20 +4,8 @@ import { EmailDeliveryInterface } from "../../../../../ingredients/emaildelivery import { NormalisedAppinfo } from "../../../../../types"; export default class BackwardCompatibilityService implements EmailDeliveryInterface { - private createAndSendCustomEmail; - constructor( - appInfo: NormalisedAppinfo, - createAndSendCustomEmail?: ( - input: { - email: string; - userInputCode?: string; - urlWithLinkCode?: string; - codeLifetime: number; - preAuthSessionId: string; - }, - userContext: any - ) => Promise - ); + private appInfo; + constructor(appInfo: NormalisedAppinfo); sendEmail: ( input: TypePasswordlessEmailDeliveryInput & { userContext: any; diff --git a/lib/build/recipe/passwordless/emaildelivery/services/backwardCompatibility/index.js b/lib/build/recipe/passwordless/emaildelivery/services/backwardCompatibility/index.js index 241629b1a..884d2db11 100644 --- a/lib/build/recipe/passwordless/emaildelivery/services/backwardCompatibility/index.js +++ b/lib/build/recipe/passwordless/emaildelivery/services/backwardCompatibility/index.js @@ -38,87 +38,80 @@ var __importDefault = Object.defineProperty(exports, "__esModule", { value: true }); const axios_1 = __importDefault(require("axios")); const logger_1 = require("../../../../../logger"); -function defaultCreateAndSendCustomEmail(appInfo) { - return (input, _) => - __awaiter(this, void 0, void 0, function* () { - if (process.env.TEST_MODE === "testing") { - return; +function createAndSendEmailUsingSupertokensService(input) { + return __awaiter(this, void 0, void 0, function* () { + if (process.env.TEST_MODE === "testing") { + return; + } + try { + yield axios_1.default({ + method: "POST", + url: "https://api.supertokens.io/0/st/auth/passwordless/login", + data: { + email: input.email, + appName: input.appInfo.appName, + codeLifetime: input.codeLifetime, + urlWithLinkCode: input.urlWithLinkCode, + userInputCode: input.userInputCode, + }, + headers: { + "api-version": 0, + }, + }); + logger_1.logDebugMessage(`Email sent to ${input.email}`); + } catch (error) { + logger_1.logDebugMessage("Error sending passwordless login email"); + if (axios_1.default.isAxiosError(error)) { + const err = error; + if (err.response) { + logger_1.logDebugMessage(`Error status: ${err.response.status}`); + logger_1.logDebugMessage(`Error response: ${JSON.stringify(err.response.data)}`); + } else { + logger_1.logDebugMessage(`Error: ${err.message}`); + } + } else { + logger_1.logDebugMessage(`Error: ${JSON.stringify(error)}`); } - try { - yield axios_1.default({ - method: "POST", - url: "https://api.supertokens.io/0/st/auth/passwordless/login", - data: { + logger_1.logDebugMessage("Logging the input below:"); + logger_1.logDebugMessage( + JSON.stringify( + { email: input.email, - appName: appInfo.appName, + appName: input.appInfo.appName, codeLifetime: input.codeLifetime, urlWithLinkCode: input.urlWithLinkCode, userInputCode: input.userInputCode, }, - headers: { - "api-version": 0, - }, - }); - logger_1.logDebugMessage(`Email sent to ${input.email}`); - } catch (error) { - logger_1.logDebugMessage("Error sending passwordless login email"); - if (axios_1.default.isAxiosError(error)) { - const err = error; - if (err.response) { - logger_1.logDebugMessage(`Error status: ${err.response.status}`); - logger_1.logDebugMessage(`Error response: ${JSON.stringify(err.response.data)}`); - } else { - logger_1.logDebugMessage(`Error: ${err.message}`); - } - } else { - logger_1.logDebugMessage(`Error: ${JSON.stringify(error)}`); - } - logger_1.logDebugMessage("Logging the input below:"); - logger_1.logDebugMessage( - JSON.stringify( - { - email: input.email, - appName: appInfo.appName, - codeLifetime: input.codeLifetime, - urlWithLinkCode: input.urlWithLinkCode, - userInputCode: input.userInputCode, - }, - null, - 2 - ) - ); - /** - * if the error is thrown from API, the response object - * will be of type `{err: string}` - */ - if (axios_1.default.isAxiosError(error) && error.response !== undefined) { - if (error.response.data.err !== undefined) { - throw Error(error.response.data.err); - } + null, + 2 + ) + ); + /** + * if the error is thrown from API, the response object + * will be of type `{err: string}` + */ + if (axios_1.default.isAxiosError(error) && error.response !== undefined) { + if (error.response.data.err !== undefined) { + throw Error(error.response.data.err); } - throw error; } - }); + throw error; + } + }); } class BackwardCompatibilityService { - constructor(appInfo, createAndSendCustomEmail) { + constructor(appInfo) { this.sendEmail = (input) => __awaiter(this, void 0, void 0, function* () { - yield this.createAndSendCustomEmail( - { - email: input.email, - userInputCode: input.userInputCode, - urlWithLinkCode: input.urlWithLinkCode, - preAuthSessionId: input.preAuthSessionId, - codeLifetime: input.codeLifetime, - }, - input.userContext - ); + yield createAndSendEmailUsingSupertokensService({ + appInfo: this.appInfo, + email: input.email, + userInputCode: input.userInputCode, + urlWithLinkCode: input.urlWithLinkCode, + codeLifetime: input.codeLifetime, + }); }); - this.createAndSendCustomEmail = - createAndSendCustomEmail === undefined - ? defaultCreateAndSendCustomEmail(appInfo) - : createAndSendCustomEmail; + this.appInfo = appInfo; } } exports.default = BackwardCompatibilityService; diff --git a/lib/build/recipe/passwordless/recipe.js b/lib/build/recipe/passwordless/recipe.js index 24813943b..fff815b69 100644 --- a/lib/build/recipe/passwordless/recipe.js +++ b/lib/build/recipe/passwordless/recipe.js @@ -146,7 +146,7 @@ class Recipe extends recipeModule_1.default { __awaiter(this, void 0, void 0, function* () { let userInputCode = this.config.getCustomUserInputCode !== undefined - ? yield this.config.getCustomUserInputCode(input.userContext) + ? yield this.config.getCustomUserInputCode(input.tenantId, input.userContext) : undefined; const codeInfo = yield this.recipeInterfaceImpl.createCode( "email" in input diff --git a/lib/build/recipe/passwordless/smsdelivery/services/backwardCompatibility/index.d.ts b/lib/build/recipe/passwordless/smsdelivery/services/backwardCompatibility/index.d.ts index d1477c878..66c9c0498 100644 --- a/lib/build/recipe/passwordless/smsdelivery/services/backwardCompatibility/index.d.ts +++ b/lib/build/recipe/passwordless/smsdelivery/services/backwardCompatibility/index.d.ts @@ -1,22 +1,8 @@ // @ts-nocheck import { TypePasswordlessSmsDeliveryInput } from "../../../types"; import { SmsDeliveryInterface } from "../../../../../ingredients/smsdelivery/types"; -import { NormalisedAppinfo } from "../../../../../types"; export default class BackwardCompatibilityService implements SmsDeliveryInterface { - private createAndSendCustomSms; - constructor( - appInfo: NormalisedAppinfo, - createAndSendCustomSms?: ( - input: { - phoneNumber: string; - userInputCode?: string; - urlWithLinkCode?: string; - codeLifetime: number; - preAuthSessionId: string; - }, - userContext: any - ) => Promise - ); + constructor(); sendSms: ( input: TypePasswordlessSmsDeliveryInput & { userContext: any; diff --git a/lib/build/recipe/passwordless/smsdelivery/services/backwardCompatibility/index.js b/lib/build/recipe/passwordless/smsdelivery/services/backwardCompatibility/index.js index 887b67227..99ab642e0 100644 --- a/lib/build/recipe/passwordless/smsdelivery/services/backwardCompatibility/index.js +++ b/lib/build/recipe/passwordless/smsdelivery/services/backwardCompatibility/index.js @@ -40,109 +40,102 @@ const axios_1 = __importDefault(require("axios")); const supertokens_1 = require("../../../../../ingredients/smsdelivery/services/supertokens"); const supertokens_2 = __importDefault(require("../../../../../supertokens")); const logger_1 = require("../../../../../logger"); -function defaultCreateAndSendCustomSms(_) { - return (input, _) => - __awaiter(this, void 0, void 0, function* () { - let supertokens = supertokens_2.default.getInstanceOrThrowError(); - let appName = supertokens.appInfo.appName; - try { - yield axios_1.default({ - method: "post", - url: supertokens_1.SUPERTOKENS_SMS_SERVICE_URL, - data: { - smsInput: { - appName, - type: "PASSWORDLESS_LOGIN", - phoneNumber: input.phoneNumber, - userInputCode: input.userInputCode, - urlWithLinkCode: input.urlWithLinkCode, - codeLifetime: input.codeLifetime, - }, - }, - headers: { - "api-version": "0", +function createAndSendSmsUsingSupertokensService(input) { + return __awaiter(this, void 0, void 0, function* () { + let supertokens = supertokens_2.default.getInstanceOrThrowError(); + let appName = supertokens.appInfo.appName; + try { + yield axios_1.default({ + method: "post", + url: supertokens_1.SUPERTOKENS_SMS_SERVICE_URL, + data: { + smsInput: { + appName, + type: "PASSWORDLESS_LOGIN", + phoneNumber: input.phoneNumber, + userInputCode: input.userInputCode, + urlWithLinkCode: input.urlWithLinkCode, + codeLifetime: input.codeLifetime, }, - }); - logger_1.logDebugMessage(`Passwordless login SMS sent to ${input.phoneNumber}`); - return; - } catch (error) { - logger_1.logDebugMessage("Error sending passwordless login SMS"); - if (axios_1.default.isAxiosError(error)) { - const err = error; - if (err.response) { - logger_1.logDebugMessage(`Error status: ${err.response.status}`); - logger_1.logDebugMessage(`Error response: ${JSON.stringify(err.response.data)}`); - } else { - logger_1.logDebugMessage(`Error: ${err.message}`); - } - if (err.response) { - if (err.response.status !== 429) { - /** - * if the error is thrown from API, the response object - * will be of type `{err: string}` - */ - if (err.response.data.err !== undefined) { - throw Error(err.response.data.err); - } else { - throw err; - } + }, + headers: { + "api-version": "0", + }, + }); + logger_1.logDebugMessage(`Passwordless login SMS sent to ${input.phoneNumber}`); + return; + } catch (error) { + logger_1.logDebugMessage("Error sending passwordless login SMS"); + if (axios_1.default.isAxiosError(error)) { + const err = error; + if (err.response) { + logger_1.logDebugMessage(`Error status: ${err.response.status}`); + logger_1.logDebugMessage(`Error response: ${JSON.stringify(err.response.data)}`); + } else { + logger_1.logDebugMessage(`Error: ${err.message}`); + } + if (err.response) { + if (err.response.status !== 429) { + /** + * if the error is thrown from API, the response object + * will be of type `{err: string}` + */ + if (err.response.data.err !== undefined) { + throw Error(err.response.data.err); + } else { + throw err; } - } else { - throw err; } } else { - logger_1.logDebugMessage(`Error: ${JSON.stringify(error)}`); - throw error; + throw err; } + } else { + logger_1.logDebugMessage(`Error: ${JSON.stringify(error)}`); + throw error; } - console.log( - "Free daily SMS quota reached. If you want to use SuperTokens to send SMS, please sign up on supertokens.com to get your SMS API key, else you can also define your own method by overriding the service. For now, we are logging it below:" - ); - /** - * if we do console.log(`SMS content: ${input}`); - * Output would be: - * SMS content: [object Object] - */ - /** - * JSON.stringify takes 3 inputs - * - value: usually an object or array, to be converted - * - replacer: An array of strings and numbers that acts - * as an approved list for selecting the object - * properties that will be stringified - * - space: Adds indentation, white space, and line break characters - * to the return-value JSON text to make it easier to read - * - * console.log(JSON.stringify({"a": 1, "b": 2})) - * Output: - * {"a":1,"b":2} - * - * console.log(JSON.stringify({"a": 1, "b": 2}, null, 2)) - * Output: - * { - * "a": 1, - * "b": 2 - * } - */ - console.log(`\nSMS content: ${JSON.stringify(input, null, 2)}`); - }); + } + console.log( + "Free daily SMS quota reached. If you want to use SuperTokens to send SMS, please sign up on supertokens.com to get your SMS API key, else you can also define your own method by overriding the service. For now, we are logging it below:" + ); + /** + * if we do console.log(`SMS content: ${input}`); + * Output would be: + * SMS content: [object Object] + */ + /** + * JSON.stringify takes 3 inputs + * - value: usually an object or array, to be converted + * - replacer: An array of strings and numbers that acts + * as an approved list for selecting the object + * properties that will be stringified + * - space: Adds indentation, white space, and line break characters + * to the return-value JSON text to make it easier to read + * + * console.log(JSON.stringify({"a": 1, "b": 2})) + * Output: + * {"a":1,"b":2} + * + * console.log(JSON.stringify({"a": 1, "b": 2}, null, 2)) + * Output: + * { + * "a": 1, + * "b": 2 + * } + */ + console.log(`\nSMS content: ${JSON.stringify(input, null, 2)}`); + }); } class BackwardCompatibilityService { - constructor(appInfo, createAndSendCustomSms) { + constructor() { this.sendSms = (input) => __awaiter(this, void 0, void 0, function* () { - yield this.createAndSendCustomSms( - { - phoneNumber: input.phoneNumber, - userInputCode: input.userInputCode, - urlWithLinkCode: input.urlWithLinkCode, - preAuthSessionId: input.preAuthSessionId, - codeLifetime: input.codeLifetime, - }, - input.userContext - ); + yield createAndSendSmsUsingSupertokensService({ + phoneNumber: input.phoneNumber, + userInputCode: input.userInputCode, + urlWithLinkCode: input.urlWithLinkCode, + codeLifetime: input.codeLifetime, + }); }); - this.createAndSendCustomSms = - createAndSendCustomSms === undefined ? defaultCreateAndSendCustomSms(appInfo) : createAndSendCustomSms; } } exports.default = BackwardCompatibilityService; diff --git a/lib/build/recipe/passwordless/types.d.ts b/lib/build/recipe/passwordless/types.d.ts index a126017f2..5e0940de8 100644 --- a/lib/build/recipe/passwordless/types.d.ts +++ b/lib/build/recipe/passwordless/types.d.ts @@ -23,74 +23,28 @@ export declare type User = { export declare type TypeInput = ( | { contactMethod: "PHONE"; - validatePhoneNumber?: (phoneNumber: string) => Promise | string | undefined; - /** - * @deprecated Please use smsDelivery config instead - */ - createAndSendCustomTextMessage?: ( - input: { - phoneNumber: string; - userInputCode?: string; - urlWithLinkCode?: string; - codeLifetime: number; - preAuthSessionId: string; - }, - userContext: any - ) => Promise; + validatePhoneNumber?: ( + phoneNumber: string, + tenantId: string + ) => Promise | string | undefined; } | { contactMethod: "EMAIL"; - validateEmailAddress?: (email: string) => Promise | string | undefined; - /** - * @deprecated Please use emailDelivery config instead - */ - createAndSendCustomEmail?: ( - input: { - email: string; - userInputCode?: string; - urlWithLinkCode?: string; - codeLifetime: number; - preAuthSessionId: string; - }, - userContext: any - ) => Promise; + validateEmailAddress?: (email: string, tenantId: string) => Promise | string | undefined; } | { contactMethod: "EMAIL_OR_PHONE"; - validateEmailAddress?: (email: string) => Promise | string | undefined; - /** - * @deprecated Please use emailDelivery config instead - */ - createAndSendCustomEmail?: ( - input: { - email: string; - userInputCode?: string; - urlWithLinkCode?: string; - codeLifetime: number; - preAuthSessionId: string; - }, - userContext: any - ) => Promise; - validatePhoneNumber?: (phoneNumber: string) => Promise | string | undefined; - /** - * @deprecated Please use smsDelivery config instead - */ - createAndSendCustomTextMessage?: ( - input: { - phoneNumber: string; - userInputCode?: string; - urlWithLinkCode?: string; - codeLifetime: number; - preAuthSessionId: string; - }, - userContext: any - ) => Promise; + validateEmailAddress?: (email: string, tenantId: string) => Promise | string | undefined; + validatePhoneNumber?: ( + phoneNumber: string, + tenantId: string + ) => Promise | string | undefined; } ) & { flowType: "USER_INPUT_CODE" | "MAGIC_LINK" | "USER_INPUT_CODE_AND_MAGIC_LINK"; emailDelivery?: EmailDeliveryTypeInput; smsDelivery?: SmsDeliveryTypeInput; - getCustomUserInputCode?: (userContext: any) => Promise | string; + getCustomUserInputCode?: (tenantId: string, userContext: any) => Promise | string; override?: { functions?: ( originalImplementation: RecipeInterface, @@ -102,20 +56,26 @@ export declare type TypeInput = ( export declare type TypeNormalisedInput = ( | { contactMethod: "PHONE"; - validatePhoneNumber: (phoneNumber: string) => Promise | string | undefined; + validatePhoneNumber: ( + phoneNumber: string, + tenantId: string + ) => Promise | string | undefined; } | { contactMethod: "EMAIL"; - validateEmailAddress: (email: string) => Promise | string | undefined; + validateEmailAddress: (email: string, tenantId: string) => Promise | string | undefined; } | { contactMethod: "EMAIL_OR_PHONE"; - validateEmailAddress: (email: string) => Promise | string | undefined; - validatePhoneNumber: (phoneNumber: string) => Promise | string | undefined; + validateEmailAddress: (email: string, tenantId: string) => Promise | string | undefined; + validatePhoneNumber: ( + phoneNumber: string, + tenantId: string + ) => Promise | string | undefined; } ) & { flowType: "USER_INPUT_CODE" | "MAGIC_LINK" | "USER_INPUT_CODE_AND_MAGIC_LINK"; - getCustomUserInputCode?: (userContext: any) => Promise | string; + getCustomUserInputCode?: (tenantId: string, userContext: any) => Promise | string; getSmsDeliveryConfig: () => SmsDeliveryTypeInputWithService; getEmailDeliveryConfig: () => EmailDeliveryTypeInputWithService; override: { diff --git a/lib/build/recipe/passwordless/utils.js b/lib/build/recipe/passwordless/utils.js index 2bbe5e2e2..ac0f1dedf 100644 --- a/lib/build/recipe/passwordless/utils.js +++ b/lib/build/recipe/passwordless/utils.js @@ -44,16 +44,13 @@ function validateAndNormaliseUserInput(_, appInfo, config) { function getEmailDeliveryConfig() { var _a; let emailService = (_a = config.emailDelivery) === null || _a === void 0 ? void 0 : _a.service; - let createAndSendCustomEmail = config.contactMethod === "PHONE" ? undefined : config.createAndSendCustomEmail; /** * following code is for backward compatibility. - * if user has not passed emailDelivery config, we - * use the createAndSendCustomEmail config. If the user - * has not passed even that config, we use the default - * createAndSendCustomEmail implementation + * if user has not passed emailDelivery config, we use the default + * createAndSendEmailUsingSupertokensService implementation */ if (emailService === undefined) { - emailService = new backwardCompatibility_1.default(appInfo, createAndSendCustomEmail); + emailService = new backwardCompatibility_1.default(appInfo); } let emailDelivery = Object.assign(Object.assign({}, config.emailDelivery), { /** @@ -74,8 +71,6 @@ function validateAndNormaliseUserInput(_, appInfo, config) { function getSmsDeliveryConfig() { var _a; let smsService = (_a = config.smsDelivery) === null || _a === void 0 ? void 0 : _a.service; - let createAndSendCustomTextMessage = - config.contactMethod === "EMAIL" ? undefined : config.createAndSendCustomTextMessage; /** * following code is for backward compatibility. * if user has not passed emailDelivery config, we @@ -84,7 +79,7 @@ function validateAndNormaliseUserInput(_, appInfo, config) { * createAndSendCustomTextMessage implementation */ if (smsService === undefined) { - smsService = new backwardCompatibility_2.default(appInfo, createAndSendCustomTextMessage); + smsService = new backwardCompatibility_2.default(); } let smsDelivery = Object.assign(Object.assign({}, config.smsDelivery), { /** diff --git a/lib/build/recipe/thirdparty/api/implementation.js b/lib/build/recipe/thirdparty/api/implementation.js index a53e18e75..6548e6d2c 100644 --- a/lib/build/recipe/thirdparty/api/implementation.js +++ b/lib/build/recipe/thirdparty/api/implementation.js @@ -68,6 +68,7 @@ function getAPIInterface() { userInfo.email = { id: yield provider.config.generateFakeEmail({ thirdPartyUserId: userInfo.thirdPartyUserId, + tenantId, userContext, }), isVerified: true, diff --git a/lib/build/recipe/thirdparty/types.d.ts b/lib/build/recipe/thirdparty/types.d.ts index 7913aa7cd..cbda028bc 100644 --- a/lib/build/recipe/thirdparty/types.d.ts +++ b/lib/build/recipe/thirdparty/types.d.ts @@ -70,7 +70,7 @@ declare type CommonProviderConfig = { userContext: any; }) => Promise; requireEmail?: boolean; - generateFakeEmail?: (input: { thirdPartyUserId: string; userContext: any }) => Promise; + generateFakeEmail?: (input: { thirdPartyUserId: string; tenantId: string; userContext: any }) => Promise; }; export declare type ProviderConfigForClientType = ProviderClientConfig & CommonProviderConfig; export declare type TypeProvider = { diff --git a/lib/build/recipe/thirdpartyemailpassword/emaildelivery/services/backwardCompatibility/index.d.ts b/lib/build/recipe/thirdpartyemailpassword/emaildelivery/services/backwardCompatibility/index.d.ts index be35a1981..e3b6e87a8 100644 --- a/lib/build/recipe/thirdpartyemailpassword/emaildelivery/services/backwardCompatibility/index.d.ts +++ b/lib/build/recipe/thirdpartyemailpassword/emaildelivery/services/backwardCompatibility/index.d.ts @@ -1,5 +1,5 @@ // @ts-nocheck -import { TypeThirdPartyEmailPasswordEmailDeliveryInput, User } from "../../../types"; +import { TypeThirdPartyEmailPasswordEmailDeliveryInput } from "../../../types"; import { RecipeInterface as EmailPasswordRecipeInterface } from "../../../../emailpassword"; import { NormalisedAppinfo } from "../../../../../types"; import { EmailDeliveryInterface } from "../../../../../ingredients/emaildelivery/types"; @@ -9,14 +9,7 @@ export default class BackwardCompatibilityService constructor( emailPasswordRecipeInterfaceImpl: EmailPasswordRecipeInterface, appInfo: NormalisedAppinfo, - isInServerlessEnv: boolean, - resetPasswordUsingTokenFeature?: { - createAndSendCustomEmail?: ( - user: User, - passwordResetURLWithToken: string, - userContext: any - ) => Promise; - } + isInServerlessEnv: boolean ); sendEmail: ( input: TypeThirdPartyEmailPasswordEmailDeliveryInput & { diff --git a/lib/build/recipe/thirdpartyemailpassword/emaildelivery/services/backwardCompatibility/index.js b/lib/build/recipe/thirdpartyemailpassword/emaildelivery/services/backwardCompatibility/index.js index c4057c084..ee09e5c75 100644 --- a/lib/build/recipe/thirdpartyemailpassword/emaildelivery/services/backwardCompatibility/index.js +++ b/lib/build/recipe/thirdpartyemailpassword/emaildelivery/services/backwardCompatibility/index.js @@ -40,7 +40,7 @@ const backwardCompatibility_1 = __importDefault( require("../../../../emailpassword/emaildelivery/services/backwardCompatibility") ); class BackwardCompatibilityService { - constructor(emailPasswordRecipeInterfaceImpl, appInfo, isInServerlessEnv, resetPasswordUsingTokenFeature) { + constructor(emailPasswordRecipeInterfaceImpl, appInfo, isInServerlessEnv) { this.sendEmail = (input) => __awaiter(this, void 0, void 0, function* () { yield this.emailPasswordBackwardCompatibilityService.sendEmail(input); @@ -49,8 +49,7 @@ class BackwardCompatibilityService { this.emailPasswordBackwardCompatibilityService = new backwardCompatibility_1.default( emailPasswordRecipeInterfaceImpl, appInfo, - isInServerlessEnv, - resetPasswordUsingTokenFeature + isInServerlessEnv ); } } diff --git a/lib/build/recipe/thirdpartyemailpassword/recipe.js b/lib/build/recipe/thirdpartyemailpassword/recipe.js index 9c7d03111..5cd5ea2ef 100644 --- a/lib/build/recipe/thirdpartyemailpassword/recipe.js +++ b/lib/build/recipe/thirdpartyemailpassword/recipe.js @@ -189,7 +189,6 @@ class Recipe extends recipeModule_1.default { signUpFeature: { formFields: this.config.signUpFeature.formFields, }, - resetPasswordUsingTokenFeature: this.config.resetPasswordUsingTokenFeature, }, { emailDelivery: this.emailDelivery, diff --git a/lib/build/recipe/thirdpartyemailpassword/types.d.ts b/lib/build/recipe/thirdpartyemailpassword/types.d.ts index a86e73a63..48df0bb9b 100644 --- a/lib/build/recipe/thirdpartyemailpassword/types.d.ts +++ b/lib/build/recipe/thirdpartyemailpassword/types.d.ts @@ -11,7 +11,6 @@ import { NormalisedFormField, TypeFormField, TypeInputFormField, - TypeInputResetPasswordUsingTokenFeature, APIOptions as EmailPasswordAPIOptionsOriginal, TypeEmailPasswordEmailDeliveryInput, RecipeInterface as EPRecipeInterface, @@ -54,7 +53,6 @@ export declare type TypeInput = { signUpFeature?: TypeInputSignUp; providers?: ProviderInput[]; emailDelivery?: EmailDeliveryTypeInput; - resetPasswordUsingTokenFeature?: TypeInputResetPasswordUsingTokenFeature; override?: { functions?: ( originalImplementation: RecipeInterface, @@ -70,7 +68,6 @@ export declare type TypeNormalisedInput = { emailPasswordRecipeImpl: EPRecipeInterface, isInServerlessEnv: boolean ) => EmailDeliveryTypeInputWithService; - resetPasswordUsingTokenFeature?: TypeInputResetPasswordUsingTokenFeature; override: { functions: ( originalImplementation: RecipeInterface, @@ -113,6 +110,7 @@ export declare type RecipeInterface = { [key: string]: any; }; }; + tenantId: string; userContext: any; }): Promise<{ status: "OK"; diff --git a/lib/build/recipe/thirdpartyemailpassword/utils.js b/lib/build/recipe/thirdpartyemailpassword/utils.js index daa8a505c..797bd9b35 100644 --- a/lib/build/recipe/thirdpartyemailpassword/utils.js +++ b/lib/build/recipe/thirdpartyemailpassword/utils.js @@ -28,7 +28,6 @@ function validateAndNormaliseUserInput(recipeInstance, appInfo, config) { appInfo, config === undefined ? undefined : config.signUpFeature ); - let resetPasswordUsingTokenFeature = config === undefined ? undefined : config.resetPasswordUsingTokenFeature; let providers = config === undefined || config.providers === undefined ? [] : config.providers; let override = Object.assign( { @@ -45,18 +44,11 @@ function validateAndNormaliseUserInput(recipeInstance, appInfo, config) { : _a.service; /** * following code is for backward compatibility. - * if user has not passed emailDelivery config, we - * use the createAndSendCustomEmail config. If the user - * has not passed even that config, we use the default - * createAndSendCustomEmail implementation + * if user has not passed emailDelivery config, we use the default + * createAndSendEmailUsingSupertokensService implementation */ if (emailService === undefined) { - emailService = new backwardCompatibility_1.default( - emailPasswordRecipeImpl, - appInfo, - isInServerlessEnv, - config === null || config === void 0 ? void 0 : config.resetPasswordUsingTokenFeature - ); + emailService = new backwardCompatibility_1.default(emailPasswordRecipeImpl, appInfo, isInServerlessEnv); } return Object.assign(Object.assign({}, config === null || config === void 0 ? void 0 : config.emailDelivery), { /** @@ -78,7 +70,6 @@ function validateAndNormaliseUserInput(recipeInstance, appInfo, config) { getEmailDeliveryConfig, signUpFeature, providers, - resetPasswordUsingTokenFeature, }; } exports.validateAndNormaliseUserInput = validateAndNormaliseUserInput; diff --git a/lib/build/recipe/thirdpartypasswordless/emaildelivery/services/backwardCompatibility/index.d.ts b/lib/build/recipe/thirdpartypasswordless/emaildelivery/services/backwardCompatibility/index.d.ts index 3e90372c3..29bbefd07 100644 --- a/lib/build/recipe/thirdpartypasswordless/emaildelivery/services/backwardCompatibility/index.d.ts +++ b/lib/build/recipe/thirdpartypasswordless/emaildelivery/services/backwardCompatibility/index.d.ts @@ -5,21 +5,7 @@ import { EmailDeliveryInterface } from "../../../../../ingredients/emaildelivery export default class BackwardCompatibilityService implements EmailDeliveryInterface { private passwordlessBackwardCompatibilityService; - constructor( - appInfo: NormalisedAppinfo, - passwordlessFeature?: { - createAndSendCustomEmail?: ( - input: { - email: string; - userInputCode?: string; - urlWithLinkCode?: string; - codeLifetime: number; - preAuthSessionId: string; - }, - userContext: any - ) => Promise; - } - ); + constructor(appInfo: NormalisedAppinfo); sendEmail: ( input: TypeThirdPartyPasswordlessEmailDeliveryInput & { userContext: any; diff --git a/lib/build/recipe/thirdpartypasswordless/emaildelivery/services/backwardCompatibility/index.js b/lib/build/recipe/thirdpartypasswordless/emaildelivery/services/backwardCompatibility/index.js index d61010ab5..8bf949cdb 100644 --- a/lib/build/recipe/thirdpartypasswordless/emaildelivery/services/backwardCompatibility/index.js +++ b/lib/build/recipe/thirdpartypasswordless/emaildelivery/services/backwardCompatibility/index.js @@ -40,18 +40,13 @@ const backwardCompatibility_1 = __importDefault( require("../../../../passwordless/emaildelivery/services/backwardCompatibility") ); class BackwardCompatibilityService { - constructor(appInfo, passwordlessFeature) { + constructor(appInfo) { this.sendEmail = (input) => __awaiter(this, void 0, void 0, function* () { yield this.passwordlessBackwardCompatibilityService.sendEmail(input); }); { - this.passwordlessBackwardCompatibilityService = new backwardCompatibility_1.default( - appInfo, - passwordlessFeature === null || passwordlessFeature === void 0 - ? void 0 - : passwordlessFeature.createAndSendCustomEmail - ); + this.passwordlessBackwardCompatibilityService = new backwardCompatibility_1.default(appInfo); } } } diff --git a/lib/build/recipe/thirdpartypasswordless/smsdelivery/services/backwardCompatibility/index.d.ts b/lib/build/recipe/thirdpartypasswordless/smsdelivery/services/backwardCompatibility/index.d.ts index 9e1f9745a..275e3e17f 100644 --- a/lib/build/recipe/thirdpartypasswordless/smsdelivery/services/backwardCompatibility/index.d.ts +++ b/lib/build/recipe/thirdpartypasswordless/smsdelivery/services/backwardCompatibility/index.d.ts @@ -1,25 +1,10 @@ // @ts-nocheck import { TypeThirdPartyPasswordlessSmsDeliveryInput } from "../../../types"; import { SmsDeliveryInterface } from "../../../../../ingredients/smsdelivery/types"; -import { NormalisedAppinfo } from "../../../../../types"; export default class BackwardCompatibilityService implements SmsDeliveryInterface { private passwordlessBackwardCompatibilityService; - constructor( - appInfo: NormalisedAppinfo, - passwordlessFeature?: { - createAndSendCustomTextMessage?: ( - input: { - phoneNumber: string; - userInputCode?: string; - urlWithLinkCode?: string; - codeLifetime: number; - preAuthSessionId: string; - }, - userContext: any - ) => Promise; - } - ); + constructor(); sendSms: ( input: TypeThirdPartyPasswordlessSmsDeliveryInput & { userContext: any; diff --git a/lib/build/recipe/thirdpartypasswordless/smsdelivery/services/backwardCompatibility/index.js b/lib/build/recipe/thirdpartypasswordless/smsdelivery/services/backwardCompatibility/index.js index 6fb2a2e25..617e5be76 100644 --- a/lib/build/recipe/thirdpartypasswordless/smsdelivery/services/backwardCompatibility/index.js +++ b/lib/build/recipe/thirdpartypasswordless/smsdelivery/services/backwardCompatibility/index.js @@ -40,17 +40,12 @@ const backwardCompatibility_1 = __importDefault( require("../../../../passwordless/smsdelivery/services/backwardCompatibility") ); class BackwardCompatibilityService { - constructor(appInfo, passwordlessFeature) { + constructor() { this.sendSms = (input) => __awaiter(this, void 0, void 0, function* () { yield this.passwordlessBackwardCompatibilityService.sendSms(input); }); - this.passwordlessBackwardCompatibilityService = new backwardCompatibility_1.default( - appInfo, - passwordlessFeature === null || passwordlessFeature === void 0 - ? void 0 - : passwordlessFeature.createAndSendCustomTextMessage - ); + this.passwordlessBackwardCompatibilityService = new backwardCompatibility_1.default(); } } exports.default = BackwardCompatibilityService; diff --git a/lib/build/recipe/thirdpartypasswordless/types.d.ts b/lib/build/recipe/thirdpartypasswordless/types.d.ts index 177e05efd..fec3217a3 100644 --- a/lib/build/recipe/thirdpartypasswordless/types.d.ts +++ b/lib/build/recipe/thirdpartypasswordless/types.d.ts @@ -45,68 +45,18 @@ export declare type User = ( export declare type TypeInput = ( | { contactMethod: "PHONE"; - validatePhoneNumber?: (phoneNumber: string) => Promise | string | undefined; - /** - * @deprecated Please use smsDelivery config instead - */ - createAndSendCustomTextMessage?: ( - input: { - phoneNumber: string; - userInputCode?: string; - urlWithLinkCode?: string; - codeLifetime: number; - preAuthSessionId: string; - }, - userContext: any - ) => Promise; + validatePhoneNumber?: ( + phoneNumber: string, + tenantId: string + ) => Promise | string | undefined; } | { contactMethod: "EMAIL"; - validateEmailAddress?: (email: string) => Promise | string | undefined; - /** - * @deprecated Please use emailDelivery config instead - */ - createAndSendCustomEmail?: ( - input: { - email: string; - userInputCode?: string; - urlWithLinkCode?: string; - codeLifetime: number; - preAuthSessionId: string; - }, - userContext: any - ) => Promise; + validateEmailAddress?: (email: string, tenantId: string) => Promise | string | undefined; } | { contactMethod: "EMAIL_OR_PHONE"; - validateEmailAddress?: (email: string) => Promise | string | undefined; - /** - * @deprecated Please use emailDelivery config instead - */ - createAndSendCustomEmail?: ( - input: { - email: string; - userInputCode?: string; - urlWithLinkCode?: string; - codeLifetime: number; - preAuthSessionId: string; - }, - userContext: any - ) => Promise; - validatePhoneNumber?: (phoneNumber: string) => Promise | string | undefined; - /** - * @deprecated Please use smsDelivery config instead - */ - createAndSendCustomTextMessage?: ( - input: { - phoneNumber: string; - userInputCode?: string; - urlWithLinkCode?: string; - codeLifetime: number; - preAuthSessionId: string; - }, - userContext: any - ) => Promise; + validateEmailAddress?: (email: string, tenantId: string) => Promise | string | undefined; } ) & { /** @@ -129,20 +79,26 @@ export declare type TypeInput = ( export declare type TypeNormalisedInput = ( | { contactMethod: "PHONE"; - validatePhoneNumber?: (phoneNumber: string) => Promise | string | undefined; + validatePhoneNumber?: ( + phoneNumber: string, + tenantId: string + ) => Promise | string | undefined; } | { contactMethod: "EMAIL"; - validateEmailAddress?: (email: string) => Promise | string | undefined; + validateEmailAddress?: (email: string, tenantId: string) => Promise | string | undefined; } | { contactMethod: "EMAIL_OR_PHONE"; - validateEmailAddress?: (email: string) => Promise | string | undefined; - validatePhoneNumber?: (phoneNumber: string) => Promise | string | undefined; + validateEmailAddress?: (email: string, tenantId: string) => Promise | string | undefined; + validatePhoneNumber?: ( + phoneNumber: string, + tenantId: string + ) => Promise | string | undefined; } ) & { flowType: "USER_INPUT_CODE" | "MAGIC_LINK" | "USER_INPUT_CODE_AND_MAGIC_LINK"; - getCustomUserInputCode?: (userContext: any) => Promise | string; + getCustomUserInputCode?: (tenantId: string, userContext: any) => Promise | string; providers: ProviderInput[]; getEmailDeliveryConfig: ( recipeImpl: RecipeInterface, diff --git a/lib/build/recipe/thirdpartypasswordless/utils.js b/lib/build/recipe/thirdpartypasswordless/utils.js index ffdfd159c..fea21a20f 100644 --- a/lib/build/recipe/thirdpartypasswordless/utils.js +++ b/lib/build/recipe/thirdpartypasswordless/utils.js @@ -39,20 +39,11 @@ function validateAndNormaliseUserInput(appInfo, config) { : _a.service; /** * following code is for backward compatibility. - * if user has not passed emailDelivery config, we - * use the createAndSendCustomEmail config. If the user - * has not passed even that config, we use the default - * createAndSendCustomEmail implementation + * if user has not passed emailDelivery config, we use the default + * createAndSendEmailUsingSupertokensService implementation */ if (emailService === undefined) { - emailService = new backwardCompatibility_1.default(appInfo, { - createAndSendCustomEmail: - (config === null || config === void 0 ? void 0 : config.contactMethod) !== "PHONE" - ? config === null || config === void 0 - ? void 0 - : config.createAndSendCustomEmail - : undefined, - }); + emailService = new backwardCompatibility_1.default(appInfo); } return Object.assign(Object.assign({}, config === null || config === void 0 ? void 0 : config.emailDelivery), { /** @@ -83,14 +74,7 @@ function validateAndNormaliseUserInput(appInfo, config) { * createAndSendCustomTextMessage implementation */ if (smsService === undefined) { - smsService = new backwardCompatibility_2.default(appInfo, { - createAndSendCustomTextMessage: - (config === null || config === void 0 ? void 0 : config.contactMethod) !== "EMAIL" - ? config === null || config === void 0 - ? void 0 - : config.createAndSendCustomTextMessage - : undefined, - }); + smsService = new backwardCompatibility_2.default(); } return Object.assign(Object.assign({}, config === null || config === void 0 ? void 0 : config.smsDelivery), { /** diff --git a/lib/ts/recipe/dashboard/api/userdetails/userPasswordPut.ts b/lib/ts/recipe/dashboard/api/userdetails/userPasswordPut.ts index f4023aef5..dc37669ba 100644 --- a/lib/ts/recipe/dashboard/api/userdetails/userPasswordPut.ts +++ b/lib/ts/recipe/dashboard/api/userdetails/userPasswordPut.ts @@ -63,7 +63,7 @@ export const userPasswordPut = async ( (field) => field.id === FORM_FIELD_PASSWORD_ID ); - let passwordValidationError = await passwordFormFields[0].validate(newPassword); + let passwordValidationError = await passwordFormFields[0].validate(newPassword, tenantId); if (passwordValidationError !== undefined) { return { @@ -99,7 +99,7 @@ export const userPasswordPut = async ( (field) => field.id === FORM_FIELD_PASSWORD_ID ); - let passwordValidationError = await passwordFormFields[0].validate(newPassword); + let passwordValidationError = await passwordFormFields[0].validate(newPassword, tenantId); if (passwordValidationError !== undefined) { return { diff --git a/lib/ts/recipe/dashboard/api/userdetails/userPut.ts b/lib/ts/recipe/dashboard/api/userdetails/userPut.ts index aa16f4980..a67f97322 100644 --- a/lib/ts/recipe/dashboard/api/userdetails/userPut.ts +++ b/lib/ts/recipe/dashboard/api/userdetails/userPut.ts @@ -37,6 +37,7 @@ const updateEmailForRecipeId = async ( recipeId: "emailpassword" | "thirdparty" | "passwordless" | "thirdpartyemailpassword" | "thirdpartypasswordless", userId: string, email: string, + tenantId: string, userContext: any ): Promise< | { @@ -55,7 +56,7 @@ const updateEmailForRecipeId = async ( (field) => field.id === FORM_FIELD_EMAIL_ID ); - let validationError = await emailFormFields[0].validate(email); + let validationError = await emailFormFields[0].validate(email, tenantId); if (validationError !== undefined) { return { @@ -86,7 +87,7 @@ const updateEmailForRecipeId = async ( (field) => field.id === FORM_FIELD_EMAIL_ID ); - let validationError = await emailFormFields[0].validate(email); + let validationError = await emailFormFields[0].validate(email, tenantId); if (validationError !== undefined) { return { @@ -130,7 +131,7 @@ const updateEmailForRecipeId = async ( validationError = validationResult; } } else { - const validationResult = await passwordlessConfig.validateEmailAddress(email); + const validationResult = await passwordlessConfig.validateEmailAddress(email, tenantId); if (validationResult !== undefined) { isValidEmail = false; @@ -180,7 +181,7 @@ const updateEmailForRecipeId = async ( validationError = validationResult; } } else { - const validationResult = await passwordlessConfig.validateEmailAddress(email); + const validationResult = await passwordlessConfig.validateEmailAddress(email, tenantId); if (validationResult !== undefined) { isValidEmail = false; @@ -226,6 +227,7 @@ const updatePhoneForRecipeId = async ( recipeId: "emailpassword" | "thirdparty" | "passwordless" | "thirdpartyemailpassword" | "thirdpartypasswordless", userId: string, phone: string, + tenantId: string, userContext: any ): Promise< | { @@ -253,7 +255,7 @@ const updatePhoneForRecipeId = async ( validationError = validationResult; } } else { - const validationResult = await passwordlessConfig.validatePhoneNumber(phone); + const validationResult = await passwordlessConfig.validatePhoneNumber(phone, tenantId); if (validationResult !== undefined) { isValidPhone = false; @@ -303,7 +305,7 @@ const updatePhoneForRecipeId = async ( validationError = validationResult; } } else { - const validationResult = await passwordlessConfig.validatePhoneNumber(phone); + const validationResult = await passwordlessConfig.validatePhoneNumber(phone, tenantId); if (validationResult !== undefined) { isValidPhone = false; @@ -347,7 +349,7 @@ const updatePhoneForRecipeId = async ( export const userPut = async ( _: APIInterface, - ___: string, + tenantId: string, options: APIOptions, userContext: any ): Promise => { @@ -443,6 +445,7 @@ export const userPut = async ( userResponse.recipe, userId, email.trim(), + tenantId, userContext ); @@ -456,6 +459,7 @@ export const userPut = async ( userResponse.recipe, userId, phone.trim(), + tenantId, userContext ); diff --git a/lib/ts/recipe/emailpassword/api/generatePasswordResetToken.ts b/lib/ts/recipe/emailpassword/api/generatePasswordResetToken.ts index b6eb23a8c..033571770 100644 --- a/lib/ts/recipe/emailpassword/api/generatePasswordResetToken.ts +++ b/lib/ts/recipe/emailpassword/api/generatePasswordResetToken.ts @@ -35,7 +35,8 @@ export default async function generatePasswordResetToken( value: string; }[] = await validateFormFieldsOrThrowError( options.config.resetPasswordUsingTokenFeature.formFieldsForGenerateTokenForm, - (await options.req.getJSONBody()).formFields + (await options.req.getJSONBody()).formFields, + tenantId ); let result = await apiImplementation.generatePasswordResetTokenPOST({ diff --git a/lib/ts/recipe/emailpassword/api/passwordReset.ts b/lib/ts/recipe/emailpassword/api/passwordReset.ts index f16fab61c..8b5303e07 100644 --- a/lib/ts/recipe/emailpassword/api/passwordReset.ts +++ b/lib/ts/recipe/emailpassword/api/passwordReset.ts @@ -36,7 +36,8 @@ export default async function passwordReset( value: string; }[] = await validateFormFieldsOrThrowError( options.config.resetPasswordUsingTokenFeature.formFieldsForPasswordResetForm, - (await options.req.getJSONBody()).formFields + (await options.req.getJSONBody()).formFields, + tenantId ); let token = (await options.req.getJSONBody()).token; diff --git a/lib/ts/recipe/emailpassword/api/signin.ts b/lib/ts/recipe/emailpassword/api/signin.ts index 86d8425ad..75f68878d 100644 --- a/lib/ts/recipe/emailpassword/api/signin.ts +++ b/lib/ts/recipe/emailpassword/api/signin.ts @@ -34,7 +34,8 @@ export default async function signInAPI( value: string; }[] = await validateFormFieldsOrThrowError( options.config.signInFeature.formFields, - (await options.req.getJSONBody()).formFields + (await options.req.getJSONBody()).formFields, + tenantId ); let result = await apiImplementation.signInPOST({ diff --git a/lib/ts/recipe/emailpassword/api/signup.ts b/lib/ts/recipe/emailpassword/api/signup.ts index 02d89d60b..1ae42d9ac 100644 --- a/lib/ts/recipe/emailpassword/api/signup.ts +++ b/lib/ts/recipe/emailpassword/api/signup.ts @@ -36,7 +36,8 @@ export default async function signUpAPI( value: string; }[] = await validateFormFieldsOrThrowError( options.config.signUpFeature.formFields, - (await options.req.getJSONBody()).formFields + (await options.req.getJSONBody()).formFields, + tenantId ); let result = await apiImplementation.signUpPOST({ diff --git a/lib/ts/recipe/emailpassword/api/utils.ts b/lib/ts/recipe/emailpassword/api/utils.ts index aca7cbab8..090180ba6 100644 --- a/lib/ts/recipe/emailpassword/api/utils.ts +++ b/lib/ts/recipe/emailpassword/api/utils.ts @@ -18,7 +18,8 @@ import { FORM_FIELD_EMAIL_ID } from "../constants"; export async function validateFormFieldsOrThrowError( configFormFields: NormalisedFormField[], - formFieldsRaw: any + formFieldsRaw: any, + tenantId: string ): Promise< { id: string; @@ -62,7 +63,7 @@ export async function validateFormFieldsOrThrowError( }); // then run validators through them----------------------- - await validateFormOrThrowError(formFields, configFormFields); + await validateFormOrThrowError(formFields, configFormFields, tenantId); return formFields; } @@ -81,7 +82,8 @@ async function validateFormOrThrowError( id: string; value: string; }[], - configFormFields: NormalisedFormField[] + configFormFields: NormalisedFormField[], + tenantId: string ) { let validationErrors: { id: string; error: string }[] = []; @@ -104,7 +106,7 @@ async function validateFormOrThrowError( }); } else { // Otherwise, use validate function. - const error = await field.validate(input.value); + const error = await field.validate(input.value, tenantId); // If error, add it. if (error !== undefined) { validationErrors.push({ diff --git a/lib/ts/recipe/emailpassword/emaildelivery/services/backwardCompatibility/index.ts b/lib/ts/recipe/emailpassword/emaildelivery/services/backwardCompatibility/index.ts index 6bdeaa072..ef38911fd 100644 --- a/lib/ts/recipe/emailpassword/emaildelivery/services/backwardCompatibility/index.ts +++ b/lib/ts/recipe/emailpassword/emaildelivery/services/backwardCompatibility/index.ts @@ -12,8 +12,8 @@ * License for the specific language governing permissions and limitations * under the License. */ -import { TypeEmailPasswordEmailDeliveryInput, User, RecipeInterface } from "../../../types"; -import { createAndSendCustomEmail as defaultCreateAndSendCustomEmail } from "../../../passwordResetFunctions"; +import { TypeEmailPasswordEmailDeliveryInput, RecipeInterface } from "../../../types"; +import { createAndSendEmailUsingSupertokensService } from "../../../passwordResetFunctions"; import { NormalisedAppinfo } from "../../../../../types"; import { EmailDeliveryInterface } from "../../../../../ingredients/emaildelivery/types"; @@ -22,36 +22,11 @@ export default class BackwardCompatibilityService private recipeInterfaceImpl: RecipeInterface; private isInServerlessEnv: boolean; private appInfo: NormalisedAppinfo; - private resetPasswordUsingTokenFeature: { - createAndSendCustomEmail: (user: User, passwordResetURLWithToken: string, userContext: any) => Promise; - }; - constructor( - recipeInterfaceImpl: RecipeInterface, - appInfo: NormalisedAppinfo, - isInServerlessEnv: boolean, - resetPasswordUsingTokenFeature?: { - createAndSendCustomEmail?: ( - user: User, - passwordResetURLWithToken: string, - userContext: any - ) => Promise; - } - ) { + constructor(recipeInterfaceImpl: RecipeInterface, appInfo: NormalisedAppinfo, isInServerlessEnv: boolean) { this.recipeInterfaceImpl = recipeInterfaceImpl; this.isInServerlessEnv = isInServerlessEnv; this.appInfo = appInfo; - { - let inputCreateAndSendCustomEmail = resetPasswordUsingTokenFeature?.createAndSendCustomEmail; - this.resetPasswordUsingTokenFeature = - inputCreateAndSendCustomEmail !== undefined - ? { - createAndSendCustomEmail: inputCreateAndSendCustomEmail, - } - : { - createAndSendCustomEmail: defaultCreateAndSendCustomEmail(this.appInfo), - }; - } } sendEmail = async (input: TypeEmailPasswordEmailDeliveryInput & { userContext: any }) => { @@ -68,16 +43,10 @@ export default class BackwardCompatibilityService user.email = input.user.email; try { if (!this.isInServerlessEnv) { - this.resetPasswordUsingTokenFeature - .createAndSendCustomEmail(user, input.passwordResetLink, input.userContext) - .catch((_) => {}); + createAndSendEmailUsingSupertokensService(this.appInfo, user, input.passwordResetLink).catch((_) => {}); } else { // see https://github.com/supertokens/supertokens-node/pull/135 - await this.resetPasswordUsingTokenFeature.createAndSendCustomEmail( - user, - input.passwordResetLink, - input.userContext - ); + await createAndSendEmailUsingSupertokensService(this.appInfo, user, input.passwordResetLink); } } catch (_) {} }; diff --git a/lib/ts/recipe/emailpassword/index.ts b/lib/ts/recipe/emailpassword/index.ts index 064cf7afb..ed87edf58 100644 --- a/lib/ts/recipe/emailpassword/index.ts +++ b/lib/ts/recipe/emailpassword/index.ts @@ -80,10 +80,13 @@ export default class Wrapper { password?: string; userContext?: any; applyPasswordPolicy?: boolean; + tenantIdForPasswordPolicy?: string; }) { return Recipe.getInstanceOrThrowError().recipeInterfaceImpl.updateEmailOrPassword({ userContext: {}, ...input, + tenantIdForPasswordPolicy: + input.tenantIdForPasswordPolicy === undefined ? DEFAULT_TENANT_ID : input.tenantIdForPasswordPolicy, }); } diff --git a/lib/ts/recipe/emailpassword/passwordResetFunctions.ts b/lib/ts/recipe/emailpassword/passwordResetFunctions.ts index d5671a545..c0a4a1ebe 100644 --- a/lib/ts/recipe/emailpassword/passwordResetFunctions.ts +++ b/lib/ts/recipe/emailpassword/passwordResetFunctions.ts @@ -18,51 +18,53 @@ import { NormalisedAppinfo } from "../../types"; import axios, { AxiosError } from "axios"; import { logDebugMessage } from "../../logger"; -export function createAndSendCustomEmail(appInfo: NormalisedAppinfo) { - return async (user: User, passwordResetURLWithToken: string) => { - // related issue: https://github.com/supertokens/supertokens-node/issues/38 - if (process.env.TEST_MODE === "testing") { - return; +export async function createAndSendEmailUsingSupertokensService( + appInfo: NormalisedAppinfo, + user: User, + passwordResetURLWithToken: string +) { + // related issue: https://github.com/supertokens/supertokens-node/issues/38 + if (process.env.TEST_MODE === "testing") { + return; + } + try { + await axios({ + method: "POST", + url: "https://api.supertokens.io/0/st/auth/password/reset", + data: { + email: user.email, + appName: appInfo.appName, + passwordResetURL: passwordResetURLWithToken, + }, + headers: { + "api-version": 0, + }, + }); + logDebugMessage(`Password reset email sent to ${user.email}`); + } catch (error) { + logDebugMessage("Error sending password reset email"); + if (axios.isAxiosError(error)) { + const err = error as AxiosError; + if (err.response) { + logDebugMessage(`Error status: ${err.response.status}`); + logDebugMessage(`Error response: ${JSON.stringify(err.response.data)}`); + } else { + logDebugMessage(`Error: ${err.message}`); + } + } else { + logDebugMessage(`Error: ${JSON.stringify(error)}`); } - try { - await axios({ - method: "POST", - url: "https://api.supertokens.io/0/st/auth/password/reset", - data: { + logDebugMessage("Logging the input below:"); + logDebugMessage( + JSON.stringify( + { email: user.email, appName: appInfo.appName, passwordResetURL: passwordResetURLWithToken, }, - headers: { - "api-version": 0, - }, - }); - logDebugMessage(`Password reset email sent to ${user.email}`); - } catch (error) { - logDebugMessage("Error sending password reset email"); - if (axios.isAxiosError(error)) { - const err = error as AxiosError; - if (err.response) { - logDebugMessage(`Error status: ${err.response.status}`); - logDebugMessage(`Error response: ${JSON.stringify(err.response.data)}`); - } else { - logDebugMessage(`Error: ${err.message}`); - } - } else { - logDebugMessage(`Error: ${JSON.stringify(error)}`); - } - logDebugMessage("Logging the input below:"); - logDebugMessage( - JSON.stringify( - { - email: user.email, - appName: appInfo.appName, - passwordResetURL: passwordResetURLWithToken, - }, - null, - 2 - ) - ); - } - }; + null, + 2 + ) + ); + } } diff --git a/lib/ts/recipe/emailpassword/recipeImplementation.ts b/lib/ts/recipe/emailpassword/recipeImplementation.ts index 658eaadac..31265e005 100644 --- a/lib/ts/recipe/emailpassword/recipeImplementation.ts +++ b/lib/ts/recipe/emailpassword/recipeImplementation.ts @@ -158,6 +158,7 @@ export default function getRecipeInterface( email?: string; password?: string; applyPasswordPolicy?: boolean; + tenantIdForPasswordPolicy: string; }): Promise< | { status: "OK" | "UNKNOWN_USER_ID_ERROR" | "EMAIL_ALREADY_EXISTS_ERROR"; @@ -168,7 +169,7 @@ export default function getRecipeInterface( let formFields = getEmailPasswordConfig().signUpFeature.formFields; if (input.password !== undefined) { const passwordField = formFields.filter((el) => el.id === FORM_FIELD_PASSWORD_ID)[0]; - const error = await passwordField.validate(input.password); + const error = await passwordField.validate(input.password, input.tenantIdForPasswordPolicy); if (error !== undefined) { return { status: "PASSWORD_POLICY_VIOLATED_ERROR", diff --git a/lib/ts/recipe/emailpassword/types.ts b/lib/ts/recipe/emailpassword/types.ts index 04d26fa56..ad678e7f5 100644 --- a/lib/ts/recipe/emailpassword/types.ts +++ b/lib/ts/recipe/emailpassword/types.ts @@ -42,7 +42,7 @@ export type TypeNormalisedInput = { export type TypeInputFormField = { id: string; - validate?: (value: any) => Promise; + validate?: (value: any, tenantId: string) => Promise; optional?: boolean; }; @@ -54,7 +54,7 @@ export type TypeInputSignUp = { export type NormalisedFormField = { id: string; - validate: (value: any) => Promise; + validate: (value: any, tenantId: string) => Promise; optional: boolean; }; @@ -66,13 +66,6 @@ export type TypeNormalisedInputSignIn = { formFields: NormalisedFormField[]; }; -export type TypeInputResetPasswordUsingTokenFeature = { - /** - * @deprecated Please use emailDelivery config instead - */ - createAndSendCustomEmail?: (user: User, passwordResetURLWithToken: string, userContext: any) => Promise; -}; - export type TypeNormalisedInputResetPasswordUsingTokenFeature = { formFieldsForGenerateTokenForm: NormalisedFormField[]; formFieldsForPasswordResetForm: NormalisedFormField[]; @@ -88,7 +81,6 @@ export type User = { export type TypeInput = { signUpFeature?: TypeInputSignUp; emailDelivery?: EmailDeliveryTypeInput; - resetPasswordUsingTokenFeature?: TypeInputResetPasswordUsingTokenFeature; override?: { functions?: ( originalImplementation: RecipeInterface, @@ -146,6 +138,7 @@ export type RecipeInterface = { password?: string; userContext: any; applyPasswordPolicy?: boolean; + tenantIdForPasswordPolicy: string; }): Promise< | { status: "OK" | "UNKNOWN_USER_ID_ERROR" | "EMAIL_ALREADY_EXISTS_ERROR"; diff --git a/lib/ts/recipe/emailpassword/utils.ts b/lib/ts/recipe/emailpassword/utils.ts index 0e93633ba..47c02c934 100644 --- a/lib/ts/recipe/emailpassword/utils.ts +++ b/lib/ts/recipe/emailpassword/utils.ts @@ -54,18 +54,11 @@ export function validateAndNormaliseUserInput( let emailService = config?.emailDelivery?.service; /** * following code is for backward compatibility. - * if user has not passed emailDelivery config, we - * use the createAndSendCustomEmail config. If the user - * has not passed even that config, we use the default - * createAndSendCustomEmail implementation which calls our supertokens API + * if user has not passed emailService config, we use the default + * createAndSendEmailUsingSupertokensService implementation which calls our supertokens API */ if (emailService === undefined) { - emailService = new BackwardCompatibilityService( - recipeImpl, - appInfo, - isInServerlessEnv, - config?.resetPasswordUsingTokenFeature - ); + emailService = new BackwardCompatibilityService(recipeImpl, appInfo, isInServerlessEnv); } return { ...config?.emailDelivery, diff --git a/lib/ts/recipe/emailverification/emailVerificationFunctions.ts b/lib/ts/recipe/emailverification/emailVerificationFunctions.ts index edc069713..103cd68dd 100644 --- a/lib/ts/recipe/emailverification/emailVerificationFunctions.ts +++ b/lib/ts/recipe/emailverification/emailVerificationFunctions.ts @@ -18,50 +18,52 @@ import { NormalisedAppinfo } from "../../types"; import axios, { AxiosError } from "axios"; import { logDebugMessage } from "../../logger"; -export function createAndSendCustomEmail(appInfo: NormalisedAppinfo) { - return async (user: User, emailVerifyURLWithToken: string) => { - if (process.env.TEST_MODE === "testing") { - return; +export async function createAndSendEmailUsingSupertokensService( + appInfo: NormalisedAppinfo, + user: User, + emailVerifyURLWithToken: string +) { + if (process.env.TEST_MODE === "testing") { + return; + } + try { + await axios({ + method: "POST", + url: "https://api.supertokens.io/0/st/auth/email/verify", + data: { + email: user.email, + appName: appInfo.appName, + emailVerifyURL: emailVerifyURLWithToken, + }, + headers: { + "api-version": 0, + }, + }); + logDebugMessage(`Email sent to ${user.email}`); + } catch (error) { + logDebugMessage("Error sending verification email"); + if (axios.isAxiosError(error)) { + const err = error as AxiosError; + if (err.response) { + logDebugMessage(`Error status: ${err.response.status}`); + logDebugMessage(`Error response: ${JSON.stringify(err.response.data)}`); + } else { + logDebugMessage(`Error: ${err.message}`); + } + } else { + logDebugMessage(`Error: ${JSON.stringify(error)}`); } - try { - await axios({ - method: "POST", - url: "https://api.supertokens.io/0/st/auth/email/verify", - data: { + logDebugMessage("Logging the input below:"); + logDebugMessage( + JSON.stringify( + { email: user.email, appName: appInfo.appName, emailVerifyURL: emailVerifyURLWithToken, }, - headers: { - "api-version": 0, - }, - }); - logDebugMessage(`Email sent to ${user.email}`); - } catch (error) { - logDebugMessage("Error sending verification email"); - if (axios.isAxiosError(error)) { - const err = error as AxiosError; - if (err.response) { - logDebugMessage(`Error status: ${err.response.status}`); - logDebugMessage(`Error response: ${JSON.stringify(err.response.data)}`); - } else { - logDebugMessage(`Error: ${err.message}`); - } - } else { - logDebugMessage(`Error: ${JSON.stringify(error)}`); - } - logDebugMessage("Logging the input below:"); - logDebugMessage( - JSON.stringify( - { - email: user.email, - appName: appInfo.appName, - emailVerifyURL: emailVerifyURLWithToken, - }, - null, - 2 - ) - ); - } - }; + null, + 2 + ) + ); + } } diff --git a/lib/ts/recipe/emailverification/emaildelivery/services/backwardCompatibility/index.ts b/lib/ts/recipe/emailverification/emaildelivery/services/backwardCompatibility/index.ts index c9b55d7aa..7e97fd89f 100644 --- a/lib/ts/recipe/emailverification/emaildelivery/services/backwardCompatibility/index.ts +++ b/lib/ts/recipe/emailverification/emaildelivery/services/backwardCompatibility/index.ts @@ -12,8 +12,8 @@ * License for the specific language governing permissions and limitations * under the License. */ -import { TypeEmailVerificationEmailDeliveryInput, User } from "../../../types"; -import { createAndSendCustomEmail as defaultCreateAndSendCustomEmail } from "../../../emailVerificationFunctions"; +import { TypeEmailVerificationEmailDeliveryInput } from "../../../types"; +import { createAndSendEmailUsingSupertokensService } from "../../../emailVerificationFunctions"; import { NormalisedAppinfo } from "../../../../../types"; import { EmailDeliveryInterface } from "../../../../../ingredients/emaildelivery/types"; @@ -21,36 +21,23 @@ export default class BackwardCompatibilityService implements EmailDeliveryInterface { private appInfo: NormalisedAppinfo; private isInServerlessEnv: boolean; - private createAndSendCustomEmail: ( - user: User, - emailVerificationURLWithToken: string, - userContext: any - ) => Promise; - constructor( - appInfo: NormalisedAppinfo, - isInServerlessEnv: boolean, - createAndSendCustomEmail?: ( - user: User, - emailVerificationURLWithToken: string, - userContext: any - ) => Promise - ) { + constructor(appInfo: NormalisedAppinfo, isInServerlessEnv: boolean) { this.appInfo = appInfo; this.isInServerlessEnv = isInServerlessEnv; - this.createAndSendCustomEmail = - createAndSendCustomEmail === undefined - ? defaultCreateAndSendCustomEmail(this.appInfo) - : createAndSendCustomEmail; } sendEmail = async (input: TypeEmailVerificationEmailDeliveryInput & { userContext: any }) => { try { if (!this.isInServerlessEnv) { - this.createAndSendCustomEmail(input.user, input.emailVerifyLink, input.userContext).catch((_) => {}); + createAndSendEmailUsingSupertokensService( + this.appInfo, + input.user, + input.emailVerifyLink + ).catch((_) => {}); } else { // see https://github.com/supertokens/supertokens-node/pull/135 - await this.createAndSendCustomEmail(input.user, input.emailVerifyLink, input.userContext); + await createAndSendEmailUsingSupertokensService(this.appInfo, input.user, input.emailVerifyLink); } } catch (_) {} }; diff --git a/lib/ts/recipe/emailverification/types.ts b/lib/ts/recipe/emailverification/types.ts index 33331bf31..933f5d83f 100644 --- a/lib/ts/recipe/emailverification/types.ts +++ b/lib/ts/recipe/emailverification/types.ts @@ -36,10 +36,6 @@ export type TypeInput = { } | { status: "EMAIL_DOES_NOT_EXIST_ERROR" | "UNKNOWN_USER_ID_ERROR" } >; - /** - * @deprecated Please use emailDelivery config instead - */ - createAndSendCustomEmail?: (user: User, emailVerificationURLWithToken: string, userContext: any) => Promise; override?: { functions?: ( originalImplementation: RecipeInterface, diff --git a/lib/ts/recipe/emailverification/utils.ts b/lib/ts/recipe/emailverification/utils.ts index 8b77b0af5..83c4441e9 100644 --- a/lib/ts/recipe/emailverification/utils.ts +++ b/lib/ts/recipe/emailverification/utils.ts @@ -33,17 +33,11 @@ export function validateAndNormaliseUserInput( let emailService = config.emailDelivery?.service; /** * following code is for backward compatibility. - * if user has not passed emailDelivery config, we - * use the createAndSendCustomEmail config. If the user - * has not passed even that config, we use the default - * createAndSendCustomEmail implementation which calls our supertokens API + * if user has not passed emailService config, we use the default + * createAndSendEmailUsingSupertokensService implementation which calls our supertokens API */ if (emailService === undefined) { - emailService = new BackwardCompatibilityService( - appInfo, - isInServerlessEnv, - config.createAndSendCustomEmail - ); + emailService = new BackwardCompatibilityService(appInfo, isInServerlessEnv); } return { ...config.emailDelivery, diff --git a/lib/ts/recipe/passwordless/api/createCode.ts b/lib/ts/recipe/passwordless/api/createCode.ts index 6bf47cb0f..bd94a27b9 100644 --- a/lib/ts/recipe/passwordless/api/createCode.ts +++ b/lib/ts/recipe/passwordless/api/createCode.ts @@ -59,7 +59,7 @@ export default async function createCode( (options.config.contactMethod === "EMAIL" || options.config.contactMethod === "EMAIL_OR_PHONE") ) { email = email.trim(); - const validateError = await options.config.validateEmailAddress(email); + const validateError = await options.config.validateEmailAddress(email, tenantId); if (validateError !== undefined) { send200Response(options.res, { status: "GENERAL_ERROR", @@ -73,7 +73,7 @@ export default async function createCode( phoneNumber !== undefined && (options.config.contactMethod === "PHONE" || options.config.contactMethod === "EMAIL_OR_PHONE") ) { - const validateError = await options.config.validatePhoneNumber(phoneNumber); + const validateError = await options.config.validatePhoneNumber(phoneNumber, tenantId); if (validateError !== undefined) { send200Response(options.res, { status: "GENERAL_ERROR", diff --git a/lib/ts/recipe/passwordless/api/implementation.ts b/lib/ts/recipe/passwordless/api/implementation.ts index 089a22002..58eb8f2e7 100644 --- a/lib/ts/recipe/passwordless/api/implementation.ts +++ b/lib/ts/recipe/passwordless/api/implementation.ts @@ -77,7 +77,10 @@ export default function getAPIImplementation(): APIInterface { userInputCode: input.options.config.getCustomUserInputCode === undefined ? undefined - : await input.options.config.getCustomUserInputCode(input.userContext), + : await input.options.config.getCustomUserInputCode( + input.tenantId, + input.userContext + ), tenantId: input.tenantId, } : { @@ -86,7 +89,10 @@ export default function getAPIImplementation(): APIInterface { userInputCode: input.options.config.getCustomUserInputCode === undefined ? undefined - : await input.options.config.getCustomUserInputCode(input.userContext), + : await input.options.config.getCustomUserInputCode( + input.tenantId, + input.userContext + ), tenantId: input.tenantId, } ); @@ -207,7 +213,7 @@ export default function getAPIImplementation(): APIInterface { userInputCode: input.options.config.getCustomUserInputCode === undefined ? undefined - : await input.options.config.getCustomUserInputCode(input.userContext), + : await input.options.config.getCustomUserInputCode(input.tenantId, input.userContext), tenantId: input.tenantId, }); diff --git a/lib/ts/recipe/passwordless/emaildelivery/services/backwardCompatibility/index.ts b/lib/ts/recipe/passwordless/emaildelivery/services/backwardCompatibility/index.ts index 909f38900..ae3da2c7a 100644 --- a/lib/ts/recipe/passwordless/emaildelivery/services/backwardCompatibility/index.ts +++ b/lib/ts/recipe/passwordless/emaildelivery/services/backwardCompatibility/index.ts @@ -18,129 +18,90 @@ import axios, { AxiosError } from "axios"; import { NormalisedAppinfo } from "../../../../../types"; import { logDebugMessage } from "../../../../../logger"; -function defaultCreateAndSendCustomEmail(appInfo: NormalisedAppinfo) { - return async ( - input: { - // Where the message should be delivered. - email: string; - // This has to be entered on the starting device to finish sign in/up - userInputCode?: string; - // Full url that the end-user can click to finish sign in/up - urlWithLinkCode?: string; - codeLifetime: number; - }, - _: any - ): Promise => { - if (process.env.TEST_MODE === "testing") { - return; +async function createAndSendEmailUsingSupertokensService(input: { + appInfo: NormalisedAppinfo; + // Where the message should be delivered. + email: string; + // This has to be entered on the starting device to finish sign in/up + userInputCode?: string; + // Full url that the end-user can click to finish sign in/up + urlWithLinkCode?: string; + codeLifetime: number; +}): Promise { + if (process.env.TEST_MODE === "testing") { + return; + } + try { + await axios({ + method: "POST", + url: "https://api.supertokens.io/0/st/auth/passwordless/login", + data: { + email: input.email, + appName: input.appInfo.appName, + codeLifetime: input.codeLifetime, + urlWithLinkCode: input.urlWithLinkCode, + userInputCode: input.userInputCode, + }, + headers: { + "api-version": 0, + }, + }); + logDebugMessage(`Email sent to ${input.email}`); + } catch (error) { + logDebugMessage("Error sending passwordless login email"); + if (axios.isAxiosError(error)) { + const err = error as AxiosError; + if (err.response) { + logDebugMessage(`Error status: ${err.response.status}`); + logDebugMessage(`Error response: ${JSON.stringify(err.response.data)}`); + } else { + logDebugMessage(`Error: ${err.message}`); + } + } else { + logDebugMessage(`Error: ${JSON.stringify(error)}`); } - try { - await axios({ - method: "POST", - url: "https://api.supertokens.io/0/st/auth/passwordless/login", - data: { + logDebugMessage("Logging the input below:"); + logDebugMessage( + JSON.stringify( + { email: input.email, - appName: appInfo.appName, + appName: input.appInfo.appName, codeLifetime: input.codeLifetime, urlWithLinkCode: input.urlWithLinkCode, userInputCode: input.userInputCode, }, - headers: { - "api-version": 0, - }, - }); - logDebugMessage(`Email sent to ${input.email}`); - } catch (error) { - logDebugMessage("Error sending passwordless login email"); - if (axios.isAxiosError(error)) { - const err = error as AxiosError; - if (err.response) { - logDebugMessage(`Error status: ${err.response.status}`); - logDebugMessage(`Error response: ${JSON.stringify(err.response.data)}`); - } else { - logDebugMessage(`Error: ${err.message}`); - } - } else { - logDebugMessage(`Error: ${JSON.stringify(error)}`); - } - logDebugMessage("Logging the input below:"); - logDebugMessage( - JSON.stringify( - { - email: input.email, - appName: appInfo.appName, - codeLifetime: input.codeLifetime, - urlWithLinkCode: input.urlWithLinkCode, - userInputCode: input.userInputCode, - }, - null, - 2 - ) - ); - /** - * if the error is thrown from API, the response object - * will be of type `{err: string}` - */ - if (axios.isAxiosError(error) && error.response !== undefined) { - if (error.response.data.err !== undefined) { - throw Error(error.response.data.err); - } + null, + 2 + ) + ); + /** + * if the error is thrown from API, the response object + * will be of type `{err: string}` + */ + if (axios.isAxiosError(error) && error.response !== undefined) { + if (error.response.data.err !== undefined) { + throw Error(error.response.data.err); } - throw error; } - }; + throw error; + } } export default class BackwardCompatibilityService implements EmailDeliveryInterface { - private createAndSendCustomEmail: ( - input: { - // Where the message should be delivered. - email: string; - // This has to be entered on the starting device to finish sign in/up - userInputCode?: string; - // Full url that the end-user can click to finish sign in/up - urlWithLinkCode?: string; - codeLifetime: number; - // Unlikely, but someone could display this (or a derived thing) to identify the device - preAuthSessionId: string; - }, - userContext: any - ) => Promise; + private appInfo: NormalisedAppinfo; - constructor( - appInfo: NormalisedAppinfo, - createAndSendCustomEmail?: ( - input: { - // Where the message should be delivered. - email: string; - // This has to be entered on the starting device to finish sign in/up - userInputCode?: string; - // Full url that the end-user can click to finish sign in/up - urlWithLinkCode?: string; - codeLifetime: number; - // Unlikely, but someone could display this (or a derived thing) to identify the device - preAuthSessionId: string; - }, - userContext: any - ) => Promise - ) { - this.createAndSendCustomEmail = - createAndSendCustomEmail === undefined - ? defaultCreateAndSendCustomEmail(appInfo) - : createAndSendCustomEmail; + constructor(appInfo: NormalisedAppinfo) { + this.appInfo = appInfo; } sendEmail = async (input: TypePasswordlessEmailDeliveryInput & { userContext: any }) => { - await this.createAndSendCustomEmail( - { - email: input.email, - userInputCode: input.userInputCode, - urlWithLinkCode: input.urlWithLinkCode, - preAuthSessionId: input.preAuthSessionId, - codeLifetime: input.codeLifetime, - }, - input.userContext - ); + await createAndSendEmailUsingSupertokensService({ + appInfo: this.appInfo, + email: input.email, + userInputCode: input.userInputCode, + urlWithLinkCode: input.urlWithLinkCode, + codeLifetime: input.codeLifetime, + }); }; } diff --git a/lib/ts/recipe/passwordless/recipe.ts b/lib/ts/recipe/passwordless/recipe.ts index 26e20e5a1..11b75bd97 100644 --- a/lib/ts/recipe/passwordless/recipe.ts +++ b/lib/ts/recipe/passwordless/recipe.ts @@ -231,7 +231,7 @@ export default class Recipe extends RecipeModule { ): Promise => { let userInputCode = this.config.getCustomUserInputCode !== undefined - ? await this.config.getCustomUserInputCode(input.userContext) + ? await this.config.getCustomUserInputCode(input.tenantId, input.userContext) : undefined; const codeInfo = await this.recipeInterfaceImpl.createCode( diff --git a/lib/ts/recipe/passwordless/smsdelivery/services/backwardCompatibility/index.ts b/lib/ts/recipe/passwordless/smsdelivery/services/backwardCompatibility/index.ts index a140fb03c..ee875a388 100644 --- a/lib/ts/recipe/passwordless/smsdelivery/services/backwardCompatibility/index.ts +++ b/lib/ts/recipe/passwordless/smsdelivery/services/backwardCompatibility/index.ts @@ -14,156 +14,112 @@ */ import { TypePasswordlessSmsDeliveryInput } from "../../../types"; import { SmsDeliveryInterface } from "../../../../../ingredients/smsdelivery/types"; -import { NormalisedAppinfo } from "../../../../../types"; import axios, { AxiosError } from "axios"; import { SUPERTOKENS_SMS_SERVICE_URL } from "../../../../../ingredients/smsdelivery/services/supertokens"; import Supertokens from "../../../../../supertokens"; import { logDebugMessage } from "../../../../../logger"; -function defaultCreateAndSendCustomSms(_: NormalisedAppinfo) { - return async ( - input: { - // Where the message should be delivered. - phoneNumber: string; - // This has to be entered on the starting device to finish sign in/up - userInputCode?: string; - // Full url that the end-user can click to finish sign in/up - urlWithLinkCode?: string; - codeLifetime: number; - }, - _: any - ): Promise => { - let supertokens = Supertokens.getInstanceOrThrowError(); - let appName = supertokens.appInfo.appName; - try { - await axios({ - method: "post", - url: SUPERTOKENS_SMS_SERVICE_URL, - data: { - smsInput: { - appName, - type: "PASSWORDLESS_LOGIN", - phoneNumber: input.phoneNumber, - userInputCode: input.userInputCode, - urlWithLinkCode: input.urlWithLinkCode, - codeLifetime: input.codeLifetime, - }, +async function createAndSendSmsUsingSupertokensService(input: { + // Where the message should be delivered. + phoneNumber: string; + // This has to be entered on the starting device to finish sign in/up + userInputCode?: string; + // Full url that the end-user can click to finish sign in/up + urlWithLinkCode?: string; + codeLifetime: number; +}): Promise { + let supertokens = Supertokens.getInstanceOrThrowError(); + let appName = supertokens.appInfo.appName; + try { + await axios({ + method: "post", + url: SUPERTOKENS_SMS_SERVICE_URL, + data: { + smsInput: { + appName, + type: "PASSWORDLESS_LOGIN", + phoneNumber: input.phoneNumber, + userInputCode: input.userInputCode, + urlWithLinkCode: input.urlWithLinkCode, + codeLifetime: input.codeLifetime, }, - headers: { - "api-version": "0", - }, - }); - logDebugMessage(`Passwordless login SMS sent to ${input.phoneNumber}`); - return; - } catch (error) { - logDebugMessage("Error sending passwordless login SMS"); - if (axios.isAxiosError(error)) { - const err = error as AxiosError; - if (err.response) { - logDebugMessage(`Error status: ${err.response.status}`); - logDebugMessage(`Error response: ${JSON.stringify(err.response.data)}`); - } else { - logDebugMessage(`Error: ${err.message}`); - } - if (err.response) { - if (err.response.status !== 429) { - /** - * if the error is thrown from API, the response object - * will be of type `{err: string}` - */ - if (err.response.data.err !== undefined) { - throw Error(err.response.data.err); - } else { - throw err; - } + }, + headers: { + "api-version": "0", + }, + }); + logDebugMessage(`Passwordless login SMS sent to ${input.phoneNumber}`); + return; + } catch (error) { + logDebugMessage("Error sending passwordless login SMS"); + if (axios.isAxiosError(error)) { + const err = error as AxiosError; + if (err.response) { + logDebugMessage(`Error status: ${err.response.status}`); + logDebugMessage(`Error response: ${JSON.stringify(err.response.data)}`); + } else { + logDebugMessage(`Error: ${err.message}`); + } + if (err.response) { + if (err.response.status !== 429) { + /** + * if the error is thrown from API, the response object + * will be of type `{err: string}` + */ + if (err.response.data.err !== undefined) { + throw Error(err.response.data.err); + } else { + throw err; } - } else { - throw err; } } else { - logDebugMessage(`Error: ${JSON.stringify(error)}`); - throw error; + throw err; } + } else { + logDebugMessage(`Error: ${JSON.stringify(error)}`); + throw error; } - console.log( - "Free daily SMS quota reached. If you want to use SuperTokens to send SMS, please sign up on supertokens.com to get your SMS API key, else you can also define your own method by overriding the service. For now, we are logging it below:" - ); - /** - * if we do console.log(`SMS content: ${input}`); - * Output would be: - * SMS content: [object Object] - */ - /** - * JSON.stringify takes 3 inputs - * - value: usually an object or array, to be converted - * - replacer: An array of strings and numbers that acts - * as an approved list for selecting the object - * properties that will be stringified - * - space: Adds indentation, white space, and line break characters - * to the return-value JSON text to make it easier to read - * - * console.log(JSON.stringify({"a": 1, "b": 2})) - * Output: - * {"a":1,"b":2} - * - * console.log(JSON.stringify({"a": 1, "b": 2}, null, 2)) - * Output: - * { - * "a": 1, - * "b": 2 - * } - */ - console.log(`\nSMS content: ${JSON.stringify(input, null, 2)}`); - }; + } + console.log( + "Free daily SMS quota reached. If you want to use SuperTokens to send SMS, please sign up on supertokens.com to get your SMS API key, else you can also define your own method by overriding the service. For now, we are logging it below:" + ); + /** + * if we do console.log(`SMS content: ${input}`); + * Output would be: + * SMS content: [object Object] + */ + /** + * JSON.stringify takes 3 inputs + * - value: usually an object or array, to be converted + * - replacer: An array of strings and numbers that acts + * as an approved list for selecting the object + * properties that will be stringified + * - space: Adds indentation, white space, and line break characters + * to the return-value JSON text to make it easier to read + * + * console.log(JSON.stringify({"a": 1, "b": 2})) + * Output: + * {"a":1,"b":2} + * + * console.log(JSON.stringify({"a": 1, "b": 2}, null, 2)) + * Output: + * { + * "a": 1, + * "b": 2 + * } + */ + console.log(`\nSMS content: ${JSON.stringify(input, null, 2)}`); } export default class BackwardCompatibilityService implements SmsDeliveryInterface { - private createAndSendCustomSms: ( - input: { - // Where the message should be delivered. - phoneNumber: string; - // This has to be entered on the starting device to finish sign in/up - userInputCode?: string; - // Full url that the end-user can click to finish sign in/up - urlWithLinkCode?: string; - codeLifetime: number; - // Unlikely, but someone could display this (or a derived thing) to identify the device - preAuthSessionId: string; - }, - userContext: any - ) => Promise; - - constructor( - appInfo: NormalisedAppinfo, - createAndSendCustomSms?: ( - input: { - // Where the message should be delivered. - phoneNumber: string; - // This has to be entered on the starting device to finish sign in/up - userInputCode?: string; - // Full url that the end-user can click to finish sign in/up - urlWithLinkCode?: string; - codeLifetime: number; - // Unlikely, but someone could display this (or a derived thing) to identify the device - preAuthSessionId: string; - }, - userContext: any - ) => Promise - ) { - this.createAndSendCustomSms = - createAndSendCustomSms === undefined ? defaultCreateAndSendCustomSms(appInfo) : createAndSendCustomSms; - } + constructor() {} sendSms = async (input: TypePasswordlessSmsDeliveryInput & { userContext: any }) => { - await this.createAndSendCustomSms( - { - phoneNumber: input.phoneNumber, - userInputCode: input.userInputCode, - urlWithLinkCode: input.urlWithLinkCode, - preAuthSessionId: input.preAuthSessionId, - codeLifetime: input.codeLifetime, - }, - input.userContext - ); + await createAndSendSmsUsingSupertokensService({ + phoneNumber: input.phoneNumber, + userInputCode: input.userInputCode, + urlWithLinkCode: input.urlWithLinkCode, + codeLifetime: input.codeLifetime, + }); }; } diff --git a/lib/ts/recipe/passwordless/types.ts b/lib/ts/recipe/passwordless/types.ts index 918f9a063..fb45a21df 100644 --- a/lib/ts/recipe/passwordless/types.ts +++ b/lib/ts/recipe/passwordless/types.ts @@ -41,92 +41,22 @@ export type User = { export type TypeInput = ( | { contactMethod: "PHONE"; - validatePhoneNumber?: (phoneNumber: string) => Promise | string | undefined; - - // Override to use custom template/contact method - /** - * @deprecated Please use smsDelivery config instead - */ - createAndSendCustomTextMessage?: ( - input: { - // Where the message should be delivered. - phoneNumber: string; - // This has to be entered on the starting device to finish sign in/up - userInputCode?: string; - // Full url that the end-user can click to finish sign in/up - urlWithLinkCode?: string; - codeLifetime: number; - // Unlikely, but someone could display this (or a derived thing) to identify the device - preAuthSessionId: string; - }, - userContext: any - ) => Promise; + validatePhoneNumber?: ( + phoneNumber: string, + tenantId: string + ) => Promise | string | undefined; } | { contactMethod: "EMAIL"; - validateEmailAddress?: (email: string) => Promise | string | undefined; - - // Override to use custom template/contact method - /** - * @deprecated Please use emailDelivery config instead - */ - createAndSendCustomEmail?: ( - input: { - // Where the message should be delivered. - email: string; - // This has to be entered on the starting device to finish sign in/up - userInputCode?: string; - // Full url that the end-user can click to finish sign in/up - urlWithLinkCode?: string; - codeLifetime: number; - // Unlikely, but someone could display this (or a derived thing) to identify the device - preAuthSessionId: string; - }, - userContext: any - ) => Promise; + validateEmailAddress?: (email: string, tenantId: string) => Promise | string | undefined; } | { contactMethod: "EMAIL_OR_PHONE"; - validateEmailAddress?: (email: string) => Promise | string | undefined; - - // Override to use custom template/contact method - /** - * @deprecated Please use emailDelivery config instead - */ - createAndSendCustomEmail?: ( - input: { - // Where the message should be delivered. - email: string; - // This has to be entered on the starting device to finish sign in/up - userInputCode?: string; - // Full url that the end-user can click to finish sign in/up - urlWithLinkCode?: string; - codeLifetime: number; - // Unlikely, but someone could display this (or a derived thing) to identify the device - preAuthSessionId: string; - }, - userContext: any - ) => Promise; - validatePhoneNumber?: (phoneNumber: string) => Promise | string | undefined; - - // Override to use custom template/contact method - /** - * @deprecated Please use smsDelivery config instead - */ - createAndSendCustomTextMessage?: ( - input: { - // Where the message should be delivered. - phoneNumber: string; - // This has to be entered on the starting device to finish sign in/up - userInputCode?: string; - // Full url that the end-user can click to finish sign in/up - urlWithLinkCode?: string; - codeLifetime: number; - // Unlikely, but someone could display this (or a derived thing) to identify the device - preAuthSessionId: string; - }, - userContext: any - ) => Promise; + validateEmailAddress?: (email: string, tenantId: string) => Promise | string | undefined; + validatePhoneNumber?: ( + phoneNumber: string, + tenantId: string + ) => Promise | string | undefined; } ) & { flowType: "USER_INPUT_CODE" | "MAGIC_LINK" | "USER_INPUT_CODE_AND_MAGIC_LINK"; @@ -136,7 +66,7 @@ export type TypeInput = ( // Override this to override how user input codes are generated // By default (=undefined) it is done in the Core - getCustomUserInputCode?: (userContext: any) => Promise | string; + getCustomUserInputCode?: (tenantId: string, userContext: any) => Promise | string; override?: { functions?: ( @@ -150,24 +80,29 @@ export type TypeInput = ( export type TypeNormalisedInput = ( | { contactMethod: "PHONE"; - validatePhoneNumber: (phoneNumber: string) => Promise | string | undefined; + validatePhoneNumber: ( + phoneNumber: string, + tenantId: string + ) => Promise | string | undefined; } | { contactMethod: "EMAIL"; - validateEmailAddress: (email: string) => Promise | string | undefined; + validateEmailAddress: (email: string, tenantId: string) => Promise | string | undefined; } | { contactMethod: "EMAIL_OR_PHONE"; - validateEmailAddress: (email: string) => Promise | string | undefined; - - validatePhoneNumber: (phoneNumber: string) => Promise | string | undefined; + validateEmailAddress: (email: string, tenantId: string) => Promise | string | undefined; + validatePhoneNumber: ( + phoneNumber: string, + tenantId: string + ) => Promise | string | undefined; } ) & { flowType: "USER_INPUT_CODE" | "MAGIC_LINK" | "USER_INPUT_CODE_AND_MAGIC_LINK"; // Override this to override how user input codes are generated // By default (=undefined) it is done in the Core - getCustomUserInputCode?: (userContext: any) => Promise | string; + getCustomUserInputCode?: (tenantId: string, userContext: any) => Promise | string; getSmsDeliveryConfig: () => SmsDeliveryTypeInputWithService; getEmailDeliveryConfig: () => EmailDeliveryTypeInputWithService; diff --git a/lib/ts/recipe/passwordless/utils.ts b/lib/ts/recipe/passwordless/utils.ts index 343eed274..06dceaa20 100644 --- a/lib/ts/recipe/passwordless/utils.ts +++ b/lib/ts/recipe/passwordless/utils.ts @@ -46,16 +46,13 @@ export function validateAndNormaliseUserInput( function getEmailDeliveryConfig() { let emailService = config.emailDelivery?.service; - let createAndSendCustomEmail = config.contactMethod === "PHONE" ? undefined : config.createAndSendCustomEmail; /** * following code is for backward compatibility. - * if user has not passed emailDelivery config, we - * use the createAndSendCustomEmail config. If the user - * has not passed even that config, we use the default - * createAndSendCustomEmail implementation + * if user has not passed emailService config, we use the default + * createAndSendEmailUsingSupertokensService implementation */ if (emailService === undefined) { - emailService = new BackwardCompatibilityEmailService(appInfo, createAndSendCustomEmail); + emailService = new BackwardCompatibilityEmailService(appInfo); } let emailDelivery = { ...config.emailDelivery, @@ -78,8 +75,6 @@ export function validateAndNormaliseUserInput( function getSmsDeliveryConfig() { let smsService = config.smsDelivery?.service; - let createAndSendCustomTextMessage = - config.contactMethod === "EMAIL" ? undefined : config.createAndSendCustomTextMessage; /** * following code is for backward compatibility. * if user has not passed emailDelivery config, we @@ -88,7 +83,7 @@ export function validateAndNormaliseUserInput( * createAndSendCustomTextMessage implementation */ if (smsService === undefined) { - smsService = new BackwardCompatibilitySmsService(appInfo, createAndSendCustomTextMessage); + smsService = new BackwardCompatibilitySmsService(); } let smsDelivery = { ...config.smsDelivery, diff --git a/lib/ts/recipe/thirdparty/api/implementation.ts b/lib/ts/recipe/thirdparty/api/implementation.ts index 353058182..84d215e6a 100644 --- a/lib/ts/recipe/thirdparty/api/implementation.ts +++ b/lib/ts/recipe/thirdparty/api/implementation.ts @@ -36,6 +36,7 @@ export default function getAPIInterface(): APIInterface { userInfo.email = { id: await provider.config.generateFakeEmail!({ thirdPartyUserId: userInfo.thirdPartyUserId, + tenantId, userContext, }), isVerified: true, diff --git a/lib/ts/recipe/thirdparty/types.ts b/lib/ts/recipe/thirdparty/types.ts index 4f4ac23f5..ac3aa0528 100644 --- a/lib/ts/recipe/thirdparty/types.ts +++ b/lib/ts/recipe/thirdparty/types.ts @@ -67,7 +67,7 @@ type CommonProviderConfig = { userContext: any; }) => Promise; requireEmail?: boolean; - generateFakeEmail?: (input: { thirdPartyUserId: string; userContext: any }) => Promise; + generateFakeEmail?: (input: { thirdPartyUserId: string; tenantId: string; userContext: any }) => Promise; }; export type ProviderConfigForClientType = ProviderClientConfig & CommonProviderConfig; diff --git a/lib/ts/recipe/thirdpartyemailpassword/emaildelivery/services/backwardCompatibility/index.ts b/lib/ts/recipe/thirdpartyemailpassword/emaildelivery/services/backwardCompatibility/index.ts index e6c6f07b1..c585bcb58 100644 --- a/lib/ts/recipe/thirdpartyemailpassword/emaildelivery/services/backwardCompatibility/index.ts +++ b/lib/ts/recipe/thirdpartyemailpassword/emaildelivery/services/backwardCompatibility/index.ts @@ -12,7 +12,7 @@ * License for the specific language governing permissions and limitations * under the License. */ -import { TypeThirdPartyEmailPasswordEmailDeliveryInput, User } from "../../../types"; +import { TypeThirdPartyEmailPasswordEmailDeliveryInput } from "../../../types"; import { RecipeInterface as EmailPasswordRecipeInterface } from "../../../../emailpassword"; import { NormalisedAppinfo } from "../../../../../types"; import EmailPasswordBackwardCompatibilityService from "../../../../emailpassword/emaildelivery/services/backwardCompatibility"; @@ -25,21 +25,13 @@ export default class BackwardCompatibilityService constructor( emailPasswordRecipeInterfaceImpl: EmailPasswordRecipeInterface, appInfo: NormalisedAppinfo, - isInServerlessEnv: boolean, - resetPasswordUsingTokenFeature?: { - createAndSendCustomEmail?: ( - user: User, - passwordResetURLWithToken: string, - userContext: any - ) => Promise; - } + isInServerlessEnv: boolean ) { { this.emailPasswordBackwardCompatibilityService = new EmailPasswordBackwardCompatibilityService( emailPasswordRecipeInterfaceImpl, appInfo, - isInServerlessEnv, - resetPasswordUsingTokenFeature + isInServerlessEnv ); } } diff --git a/lib/ts/recipe/thirdpartyemailpassword/recipe.ts b/lib/ts/recipe/thirdpartyemailpassword/recipe.ts index 65c2947eb..c9706f7c0 100644 --- a/lib/ts/recipe/thirdpartyemailpassword/recipe.ts +++ b/lib/ts/recipe/thirdpartyemailpassword/recipe.ts @@ -121,7 +121,6 @@ export default class Recipe extends RecipeModule { signUpFeature: { formFields: this.config.signUpFeature.formFields, }, - resetPasswordUsingTokenFeature: this.config.resetPasswordUsingTokenFeature, }, { emailDelivery: this.emailDelivery, diff --git a/lib/ts/recipe/thirdpartyemailpassword/recipeImplementation/emailPasswordRecipeImplementation.ts b/lib/ts/recipe/thirdpartyemailpassword/recipeImplementation/emailPasswordRecipeImplementation.ts index 853e8f7c2..0d2c7a2e3 100644 --- a/lib/ts/recipe/thirdpartyemailpassword/recipeImplementation/emailPasswordRecipeImplementation.ts +++ b/lib/ts/recipe/thirdpartyemailpassword/recipeImplementation/emailPasswordRecipeImplementation.ts @@ -67,6 +67,7 @@ export default function getRecipeInterface(recipeInterface: ThirdPartyEmailPassw password?: string; userContext: any; applyPasswordPolicy: boolean; + tenantIdForPasswordPolicy: string; }): Promise< | { status: "OK" | "UNKNOWN_USER_ID_ERROR" | "EMAIL_ALREADY_EXISTS_ERROR"; diff --git a/lib/ts/recipe/thirdpartyemailpassword/recipeImplementation/index.ts b/lib/ts/recipe/thirdpartyemailpassword/recipeImplementation/index.ts index 4ff5912bc..fe6c22a46 100644 --- a/lib/ts/recipe/thirdpartyemailpassword/recipeImplementation/index.ts +++ b/lib/ts/recipe/thirdpartyemailpassword/recipeImplementation/index.ts @@ -169,6 +169,7 @@ export default function getRecipeInterface( password?: string; userContext: any; applyPasswordPolicy?: boolean; + tenantIdForPasswordPolicy: string; } ): Promise< | { diff --git a/lib/ts/recipe/thirdpartyemailpassword/types.ts b/lib/ts/recipe/thirdpartyemailpassword/types.ts index c03c05861..988465a44 100644 --- a/lib/ts/recipe/thirdpartyemailpassword/types.ts +++ b/lib/ts/recipe/thirdpartyemailpassword/types.ts @@ -24,7 +24,6 @@ import { NormalisedFormField, TypeFormField, TypeInputFormField, - TypeInputResetPasswordUsingTokenFeature, APIOptions as EmailPasswordAPIOptionsOriginal, TypeEmailPasswordEmailDeliveryInput, RecipeInterface as EPRecipeInterface, @@ -74,7 +73,6 @@ export type TypeInput = { signUpFeature?: TypeInputSignUp; providers?: ProviderInput[]; emailDelivery?: EmailDeliveryTypeInput; - resetPasswordUsingTokenFeature?: TypeInputResetPasswordUsingTokenFeature; override?: { functions?: ( originalImplementation: RecipeInterface, @@ -91,7 +89,6 @@ export type TypeNormalisedInput = { emailPasswordRecipeImpl: EPRecipeInterface, isInServerlessEnv: boolean ) => EmailDeliveryTypeInputWithService; - resetPasswordUsingTokenFeature?: TypeInputResetPasswordUsingTokenFeature; override: { functions: ( originalImplementation: RecipeInterface, @@ -129,6 +126,7 @@ export type RecipeInterface = { fromIdTokenPayload?: { [key: string]: any }; fromUserInfoAPI?: { [key: string]: any }; }; + tenantId: string; userContext: any; }): Promise<{ status: "OK"; diff --git a/lib/ts/recipe/thirdpartyemailpassword/utils.ts b/lib/ts/recipe/thirdpartyemailpassword/utils.ts index 2c1577768..d23f86134 100644 --- a/lib/ts/recipe/thirdpartyemailpassword/utils.ts +++ b/lib/ts/recipe/thirdpartyemailpassword/utils.ts @@ -33,8 +33,6 @@ export function validateAndNormaliseUserInput( config === undefined ? undefined : config.signUpFeature ); - let resetPasswordUsingTokenFeature = config === undefined ? undefined : config.resetPasswordUsingTokenFeature; - let providers = config === undefined || config.providers === undefined ? [] : config.providers; let override = { @@ -47,18 +45,11 @@ export function validateAndNormaliseUserInput( let emailService = config?.emailDelivery?.service; /** * following code is for backward compatibility. - * if user has not passed emailDelivery config, we - * use the createAndSendCustomEmail config. If the user - * has not passed even that config, we use the default - * createAndSendCustomEmail implementation + * if user has not passed emailService config, we use the default + * createAndSendEmailUsingSupertokensService implementation */ if (emailService === undefined) { - emailService = new BackwardCompatibilityService( - emailPasswordRecipeImpl, - appInfo, - isInServerlessEnv, - config?.resetPasswordUsingTokenFeature - ); + emailService = new BackwardCompatibilityService(emailPasswordRecipeImpl, appInfo, isInServerlessEnv); } return { ...config?.emailDelivery, @@ -82,7 +73,6 @@ export function validateAndNormaliseUserInput( getEmailDeliveryConfig, signUpFeature, providers, - resetPasswordUsingTokenFeature, }; } diff --git a/lib/ts/recipe/thirdpartypasswordless/emaildelivery/services/backwardCompatibility/index.ts b/lib/ts/recipe/thirdpartypasswordless/emaildelivery/services/backwardCompatibility/index.ts index 914128178..ff8f183a0 100644 --- a/lib/ts/recipe/thirdpartypasswordless/emaildelivery/services/backwardCompatibility/index.ts +++ b/lib/ts/recipe/thirdpartypasswordless/emaildelivery/services/backwardCompatibility/index.ts @@ -21,30 +21,9 @@ export default class BackwardCompatibilityService implements EmailDeliveryInterface { private passwordlessBackwardCompatibilityService: PasswordlessBackwardCompatibilityService; - constructor( - appInfo: NormalisedAppinfo, - passwordlessFeature?: { - createAndSendCustomEmail?: ( - input: { - // Where the message should be delivered. - email: string; - // This has to be entered on the starting device to finish sign in/up - userInputCode?: string; - // Full url that the end-user can click to finish sign in/up - urlWithLinkCode?: string; - codeLifetime: number; - // Unlikely, but someone could display this (or a derived thing) to identify the device - preAuthSessionId: string; - }, - userContext: any - ) => Promise; - } - ) { + constructor(appInfo: NormalisedAppinfo) { { - this.passwordlessBackwardCompatibilityService = new PasswordlessBackwardCompatibilityService( - appInfo, - passwordlessFeature?.createAndSendCustomEmail - ); + this.passwordlessBackwardCompatibilityService = new PasswordlessBackwardCompatibilityService(appInfo); } } diff --git a/lib/ts/recipe/thirdpartypasswordless/smsdelivery/services/backwardCompatibility/index.ts b/lib/ts/recipe/thirdpartypasswordless/smsdelivery/services/backwardCompatibility/index.ts index ddffd8a65..7ccb6646a 100644 --- a/lib/ts/recipe/thirdpartypasswordless/smsdelivery/services/backwardCompatibility/index.ts +++ b/lib/ts/recipe/thirdpartypasswordless/smsdelivery/services/backwardCompatibility/index.ts @@ -14,36 +14,14 @@ */ import { TypeThirdPartyPasswordlessSmsDeliveryInput } from "../../../types"; import { SmsDeliveryInterface } from "../../../../../ingredients/smsdelivery/types"; -import { NormalisedAppinfo } from "../../../../../types"; import PasswordlessBackwardCompatibilityService from "../../../../passwordless/smsdelivery/services/backwardCompatibility"; export default class BackwardCompatibilityService implements SmsDeliveryInterface { private passwordlessBackwardCompatibilityService: PasswordlessBackwardCompatibilityService; - constructor( - appInfo: NormalisedAppinfo, - passwordlessFeature?: { - createAndSendCustomTextMessage?: ( - input: { - // Where the message should be delivered. - phoneNumber: string; - // This has to be entered on the starting device to finish sign in/up - userInputCode?: string; - // Full url that the end-user can click to finish sign in/up - urlWithLinkCode?: string; - codeLifetime: number; - // Unlikely, but someone could display this (or a derived thing) to identify the device - preAuthSessionId: string; - }, - userContext: any - ) => Promise; - } - ) { - this.passwordlessBackwardCompatibilityService = new PasswordlessBackwardCompatibilityService( - appInfo, - passwordlessFeature?.createAndSendCustomTextMessage - ); + constructor() { + this.passwordlessBackwardCompatibilityService = new PasswordlessBackwardCompatibilityService(); } sendSms = async (input: TypeThirdPartyPasswordlessSmsDeliveryInput & { userContext: any }) => { diff --git a/lib/ts/recipe/thirdpartypasswordless/types.ts b/lib/ts/recipe/thirdpartypasswordless/types.ts index 2fba9b2a4..2ab87b256 100644 --- a/lib/ts/recipe/thirdpartypasswordless/types.ts +++ b/lib/ts/recipe/thirdpartypasswordless/types.ts @@ -63,92 +63,18 @@ export type User = ( export type TypeInput = ( | { contactMethod: "PHONE"; - validatePhoneNumber?: (phoneNumber: string) => Promise | string | undefined; - - // Override to use custom template/contact method - /** - * @deprecated Please use smsDelivery config instead - */ - createAndSendCustomTextMessage?: ( - input: { - // Where the message should be delivered. - phoneNumber: string; - // This has to be entered on the starting device to finish sign in/up - userInputCode?: string; - // Full url that the end-user can click to finish sign in/up - urlWithLinkCode?: string; - codeLifetime: number; - // Unlikely, but someone could display this (or a derived thing) to identify the device - preAuthSessionId: string; - }, - userContext: any - ) => Promise; + validatePhoneNumber?: ( + phoneNumber: string, + tenantId: string + ) => Promise | string | undefined; } | { contactMethod: "EMAIL"; - validateEmailAddress?: (email: string) => Promise | string | undefined; - - // Override to use custom template/contact method - /** - * @deprecated Please use emailDelivery config instead - */ - createAndSendCustomEmail?: ( - input: { - // Where the message should be delivered. - email: string; - // This has to be entered on the starting device to finish sign in/up - userInputCode?: string; - // Full url that the end-user can click to finish sign in/up - urlWithLinkCode?: string; - codeLifetime: number; - // Unlikely, but someone could display this (or a derived thing) to identify the device - preAuthSessionId: string; - }, - userContext: any - ) => Promise; + validateEmailAddress?: (email: string, tenantId: string) => Promise | string | undefined; } | { contactMethod: "EMAIL_OR_PHONE"; - validateEmailAddress?: (email: string) => Promise | string | undefined; - - // Override to use custom template/contact method - /** - * @deprecated Please use emailDelivery config instead - */ - createAndSendCustomEmail?: ( - input: { - // Where the message should be delivered. - email: string; - // This has to be entered on the starting device to finish sign in/up - userInputCode?: string; - // Full url that the end-user can click to finish sign in/up - urlWithLinkCode?: string; - codeLifetime: number; - // Unlikely, but someone could display this (or a derived thing) to identify the device - preAuthSessionId: string; - }, - userContext: any - ) => Promise; - validatePhoneNumber?: (phoneNumber: string) => Promise | string | undefined; - - // Override to use custom template/contact method - /** - * @deprecated Please use smsDelivery config instead - */ - createAndSendCustomTextMessage?: ( - input: { - // Where the message should be delivered. - phoneNumber: string; - // This has to be entered on the starting device to finish sign in/up - userInputCode?: string; - // Full url that the end-user can click to finish sign in/up - urlWithLinkCode?: string; - codeLifetime: number; - // Unlikely, but someone could display this (or a derived thing) to identify the device - preAuthSessionId: string; - }, - userContext: any - ) => Promise; + validateEmailAddress?: (email: string, tenantId: string) => Promise | string | undefined; } ) & { /** @@ -175,23 +101,29 @@ export type TypeInput = ( export type TypeNormalisedInput = ( | { contactMethod: "PHONE"; - validatePhoneNumber?: (phoneNumber: string) => Promise | string | undefined; + validatePhoneNumber?: ( + phoneNumber: string, + tenantId: string + ) => Promise | string | undefined; } | { contactMethod: "EMAIL"; - validateEmailAddress?: (email: string) => Promise | string | undefined; + validateEmailAddress?: (email: string, tenantId: string) => Promise | string | undefined; } | { contactMethod: "EMAIL_OR_PHONE"; - validateEmailAddress?: (email: string) => Promise | string | undefined; - validatePhoneNumber?: (phoneNumber: string) => Promise | string | undefined; + validateEmailAddress?: (email: string, tenantId: string) => Promise | string | undefined; + validatePhoneNumber?: ( + phoneNumber: string, + tenantId: string + ) => Promise | string | undefined; } ) & { flowType: "USER_INPUT_CODE" | "MAGIC_LINK" | "USER_INPUT_CODE_AND_MAGIC_LINK"; // Override this to override how user input codes are generated // By default (=undefined) it is done in the Core - getCustomUserInputCode?: (userContext: any) => Promise | string; + getCustomUserInputCode?: (tenantId: string, userContext: any) => Promise | string; providers: ProviderInput[]; getEmailDeliveryConfig: ( recipeImpl: RecipeInterface, diff --git a/lib/ts/recipe/thirdpartypasswordless/utils.ts b/lib/ts/recipe/thirdpartypasswordless/utils.ts index b68a8eef5..50a1d2e9b 100644 --- a/lib/ts/recipe/thirdpartypasswordless/utils.ts +++ b/lib/ts/recipe/thirdpartypasswordless/utils.ts @@ -32,16 +32,11 @@ export function validateAndNormaliseUserInput(appInfo: NormalisedAppinfo, config let emailService = config?.emailDelivery?.service; /** * following code is for backward compatibility. - * if user has not passed emailDelivery config, we - * use the createAndSendCustomEmail config. If the user - * has not passed even that config, we use the default - * createAndSendCustomEmail implementation + * if user has not passed emailService config, we use the default + * createAndSendEmailUsingSupertokensService implementation */ if (emailService === undefined) { - emailService = new BackwardCompatibilityEmailService(appInfo, { - createAndSendCustomEmail: - config?.contactMethod !== "PHONE" ? config?.createAndSendCustomEmail : undefined, - }); + emailService = new BackwardCompatibilityEmailService(appInfo); } return { ...config?.emailDelivery, @@ -70,10 +65,7 @@ export function validateAndNormaliseUserInput(appInfo: NormalisedAppinfo, config * createAndSendCustomTextMessage implementation */ if (smsService === undefined) { - smsService = new BackwardCompatibilitySmsService(appInfo, { - createAndSendCustomTextMessage: - config?.contactMethod !== "EMAIL" ? config?.createAndSendCustomTextMessage : undefined, - }); + smsService = new BackwardCompatibilitySmsService(); } return { ...config?.smsDelivery,