UNPKG

supertokens-auth-react

Version:

ReactJS SDK that provides login functionality with SuperTokens.

586 lines (578 loc) 26.5 kB
"use strict"; var genericComponentOverrideContext = require("./genericComponentOverrideContext.js"); var EmailPasswordWebJS = require("supertokens-web-js/recipe/emailpassword"); var index = require("./authRecipe-shared2.js"); var types = require("./multifactorauth-shared.js"); var constants = require("./emailpassword-shared4.js"); var utils = require("./authRecipe-shared.js"); var validators = require("./emailpassword-shared5.js"); function _interopDefault(e) { return e && e.__esModule ? e : { default: e }; } var EmailPasswordWebJS__default = /*#__PURE__*/ _interopDefault(EmailPasswordWebJS); var getFunctionOverrides = function (onHandleEvent) { return function (originalImp) { return genericComponentOverrideContext.__assign(genericComponentOverrideContext.__assign({}, originalImp), { submitNewPassword: function (input) { return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () { var response; return genericComponentOverrideContext.__generator(this, function (_a) { switch (_a.label) { case 0: return [ 4 /*yield*/, originalImp.submitNewPassword( genericComponentOverrideContext.__assign( genericComponentOverrideContext.__assign({}, input), { formFields: [input.formFields[0]] } ) ), ]; case 1: response = _a.sent(); if (response.status === "OK") { onHandleEvent({ action: "PASSWORD_RESET_SUCCESSFUL", userContext: input.userContext, }); } return [2 /*return*/, response]; } }); }); }, sendPasswordResetEmail: function (input) { return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () { var response; return genericComponentOverrideContext.__generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, originalImp.sendPasswordResetEmail(input)]; case 1: response = _a.sent(); if (response.status === "OK") { onHandleEvent({ action: "RESET_PASSWORD_EMAIL_SENT", email: input.formFields.find(function (_a) { var id = _a.id; return id === "email"; }).value, userContext: input.userContext, }); } return [2 /*return*/, response]; } }); }); }, signUp: function (input) { return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () { var payloadBeforeCall, response, payloadAfterCall; return genericComponentOverrideContext.__generator(this, function (_c) { switch (_c.label) { case 0: _c.trys.push([0, 2, , 3]); return [ 4 /*yield*/, types.Session.getInstanceOrThrow().getAccessTokenPayloadSecurely({ userContext: input.userContext, }), ]; case 1: payloadBeforeCall = _c.sent(); return [3 /*break*/, 3]; case 2: _c.sent(); // If getAccessTokenPayloadSecurely threw, that generally means we have no active session payloadBeforeCall = undefined; return [3 /*break*/, 3]; case 3: return [4 /*yield*/, originalImp.signUp(input)]; case 4: response = _c.sent(); if (!(response.status === "OK")) return [3 /*break*/, 9]; payloadAfterCall = void 0; _c.label = 5; case 5: _c.trys.push([5, 7, , 8]); return [ 4 /*yield*/, types.Session.getInstanceOrThrow().getAccessTokenPayloadSecurely({ userContext: input.userContext, }), ]; case 6: payloadAfterCall = _c.sent(); return [3 /*break*/, 8]; case 7: _c.sent(); // If getAccessTokenPayloadSecurely threw, that generally means we have no active session payloadAfterCall = undefined; return [3 /*break*/, 8]; case 8: onHandleEvent({ action: "SUCCESS", isNewRecipeUser: true, createdNewSession: payloadAfterCall !== undefined && (payloadBeforeCall === undefined || payloadBeforeCall.sessionHandle !== payloadAfterCall.sessionHandle), user: response.user, userContext: input.userContext, }); _c.label = 9; case 9: return [2 /*return*/, response]; } }); }); }, signIn: function (input) { return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () { var payloadBeforeCall, response, payloadAfterCall; return genericComponentOverrideContext.__generator(this, function (_c) { switch (_c.label) { case 0: _c.trys.push([0, 2, , 3]); return [ 4 /*yield*/, types.Session.getInstanceOrThrow().getAccessTokenPayloadSecurely({ userContext: input.userContext, }), ]; case 1: payloadBeforeCall = _c.sent(); return [3 /*break*/, 3]; case 2: _c.sent(); // If getAccessTokenPayloadSecurely threw, that generally means we have no active session payloadBeforeCall = undefined; return [3 /*break*/, 3]; case 3: return [4 /*yield*/, originalImp.signIn(input)]; case 4: response = _c.sent(); if (!(response.status === "OK")) return [3 /*break*/, 9]; payloadAfterCall = void 0; _c.label = 5; case 5: _c.trys.push([5, 7, , 8]); return [ 4 /*yield*/, types.Session.getInstanceOrThrow().getAccessTokenPayloadSecurely({ userContext: input.userContext, }), ]; case 6: payloadAfterCall = _c.sent(); return [3 /*break*/, 8]; case 7: _c.sent(); // If getAccessTokenPayloadSecurely threw, that generally means we have no active session payloadAfterCall = undefined; return [3 /*break*/, 8]; case 8: onHandleEvent({ action: "SUCCESS", isNewRecipeUser: false, createdNewSession: payloadAfterCall !== undefined && (payloadBeforeCall === undefined || payloadBeforeCall.sessionHandle !== payloadAfterCall.sessionHandle), user: response.user, userContext: input.userContext, }); _c.label = 9; case 9: return [2 /*return*/, response]; } }); }); }, }); }; }; /* Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved. * * This software is licensed under the Apache License, Version 2.0 (the * "License") as published by the Apache Software Foundation. * * You may not use this file except in compliance with the License. You may * obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ function normaliseEmailPasswordConfig(config) { if (config === undefined) { config = {}; } var signInAndUpFeature = normaliseSignInAndUpFeature(config.signInAndUpFeature); var signUpPasswordField = signInAndUpFeature.signUpForm.formFields.find(function (field) { return field.id === "password"; }); var signUpEmailField = signInAndUpFeature.signUpForm.formFields.find(function (field) { return field.id === "email"; }); var resetPasswordUsingTokenFeature = normaliseResetPasswordUsingTokenFeature( signUpPasswordField.validate, signUpEmailField, config.resetPasswordUsingTokenFeature ); var override = genericComponentOverrideContext.__assign( { functions: function (originalImplementation) { return originalImplementation; }, }, config.override ); return genericComponentOverrideContext.__assign( genericComponentOverrideContext.__assign({}, utils.normaliseAuthRecipe(config)), { signInAndUpFeature: signInAndUpFeature, resetPasswordUsingTokenFeature: resetPasswordUsingTokenFeature, override: override, } ); } function normaliseSignInAndUpFeature(config) { if (config === undefined) { config = {}; } var signUpForm = normaliseSignUpFormFeatureConfig(config.signUpForm); /* * Default Sign In corresponds to computed Sign Up fields filtered by email and password only. * i.e. If the user overrides sign Up fields, that is propagated to default sign In fields. * Exception made of the password validator which only verifies that the value is not empty for login * https://github.com/supertokens/supertokens-auth-react/issues/21 */ var defaultSignInFields = signUpForm.formFields.reduce(function (signInFieldsAccumulator, field) { if (field.id === "email") { return genericComponentOverrideContext.__spreadArray( genericComponentOverrideContext.__spreadArray([], signInFieldsAccumulator, true), [field], false ); } if (field.id === "password") { return genericComponentOverrideContext.__spreadArray( genericComponentOverrideContext.__spreadArray([], signInFieldsAccumulator, true), [ genericComponentOverrideContext.__assign(genericComponentOverrideContext.__assign({}, field), { autoComplete: "current-password", validate: validators.defaultLoginPasswordValidator, }), ], false ); } return signInFieldsAccumulator; }, []); var signInForm = normaliseSignInFormFeatureConfig(defaultSignInFields, config.signInForm); return { signUpForm: signUpForm, signInForm: signInForm, }; } function normaliseSignUpFormFeatureConfig(config) { if (config === undefined) { config = {}; } var defaultFormFields = getDefaultFormFields(); var userFormFields = []; if (config.formFields !== undefined) { userFormFields = config.formFields; } var formFields = mergeFormFields(defaultFormFields, userFormFields); var style = config.style !== undefined ? config.style : ""; return { style: style, formFields: formFields, }; } function normaliseSignInFormFeatureConfig(defaultFormFields, config) { if (config === undefined) { config = {}; } var userFormFields = []; if (config.formFields !== undefined) { userFormFields = config.formFields // Filter on email and password only. .filter(function (field) { return constants.MANDATORY_FORM_FIELDS_ID_ARRAY.includes(field.id); }) // Sign In fields are never optional. .map(function (field) { return genericComponentOverrideContext.__assign(genericComponentOverrideContext.__assign({}, field), { optional: false, }); }); } var formFields = mergeFormFields(defaultFormFields, userFormFields); var style = config.style !== undefined ? config.style : ""; return { style: style, formFields: formFields, }; } function getDefaultFormFields() { return [getDefaultEmailFormField(), getDefaultPasswordFormField()]; } function getDefaultEmailFormField() { return { id: "email", label: "EMAIL_PASSWORD_EMAIL_LABEL", placeholder: "EMAIL_PASSWORD_EMAIL_PLACEHOLDER", validate: validators.defaultEmailValidator, optional: false, autoComplete: "email", }; } function getDefaultPasswordFormField() { return { id: "password", label: "EMAIL_PASSWORD_PASSWORD_LABEL", placeholder: "EMAIL_PASSWORD_PASSWORD_PLACEHOLDER", validate: validators.defaultPasswordValidator, optional: false, autoComplete: "new-password", }; } function normaliseResetPasswordUsingTokenFeature(signUpPasswordFieldValidate, signUpEmailField, config) { if (config === undefined) { config = {}; } var disableDefaultUI = config.disableDefaultUI === true; var submitNewPasswordFormStyle = config.submitNewPasswordForm !== undefined && config.submitNewPasswordForm.style !== undefined ? config.submitNewPasswordForm.style : ""; var submitNewPasswordForm = { style: submitNewPasswordFormStyle, formFields: [ { id: "password", label: "EMAIL_PASSWORD_NEW_PASSWORD_LABEL", placeholder: "EMAIL_PASSWORD_NEW_PASSWORD_PLACEHOLDER", validate: signUpPasswordFieldValidate, optional: false, autoComplete: "new-password", }, { id: "confirm-password", label: "EMAIL_PASSWORD_CONFIRM_PASSWORD_LABEL", placeholder: "EMAIL_PASSWORD_CONFIRM_PASSWORD_PLACEHOLDER", validate: signUpPasswordFieldValidate, optional: false, autoComplete: "new-password", }, ], }; var enterEmailFormStyle = config.enterEmailForm !== undefined && config.enterEmailForm.style !== undefined ? config.enterEmailForm.style : ""; var enterEmailForm = { style: enterEmailFormStyle, formFields: [ genericComponentOverrideContext.__assign( genericComponentOverrideContext.__assign({}, getDefaultEmailFormField()), { validate: signUpEmailField.validate, placeholder: "", autofocus: true } ), ], }; return { disableDefaultUI: disableDefaultUI, submitNewPasswordForm: submitNewPasswordForm, enterEmailForm: enterEmailForm, }; } /* * mergeFormFields by keeping the provided order, defaultFormFields or merged first, and unmerged userFormFields after. */ function mergeFormFields(defaultFormFields, userFormFields) { // Create a new array with default fields. var mergedFormFields = defaultFormFields; // Loop through user provided fields. for (var i = 0; i < userFormFields.length; i++) { var userField = userFormFields[i]; var isNewField = true; // Loop through the merged fields array. for (var j = 0; j < mergedFormFields.length; j++) { var mergedField = mergedFormFields[j]; // If id is equal, merge the fields if (userField.id === mergedField.id) { // Make sure that email and password are kept mandatory. var optional = mergedField.optional; // Init with default value. // If user provided value, overwrite. if (userField.optional !== undefined) { optional = userField.optional; } // If "email" or "password", always mandatory. if (constants.MANDATORY_FORM_FIELDS_ID_ARRAY.includes(userField.id)) { optional = false; } // Merge. mergedFormFields[j] = genericComponentOverrideContext.__assign( genericComponentOverrideContext.__assign( genericComponentOverrideContext.__assign({}, mergedFormFields[j]), userField ), { optional: optional } ); isNewField = false; break; } } // If new field, push to mergeFormFields. if (isNewField) { mergedFormFields.push( genericComponentOverrideContext.__assign( { optional: false, placeholder: userField.label, validate: validators.defaultValidate }, userField ) ); } } return mergedFormFields.map(function (field) { return getFormattedFormField(field); }); } function getFormattedFormField(field) { var _this = this; // Fields with the 'nonOptionalErrorMsg' property must have a valid message defined if (field.optional === false && field.nonOptionalErrorMsg === "") { throw new Error("nonOptionalErrorMsg for field ".concat(field.id, " cannot be an empty string")); } return genericComponentOverrideContext.__assign(genericComponentOverrideContext.__assign({}, field), { validate: function (value) { return genericComponentOverrideContext.__awaiter(_this, void 0, void 0, function () { return genericComponentOverrideContext.__generator(this, function (_a) { switch (_a.label) { case 0: // Absent or not optional empty field if (value === "" && field.optional === false) { if (field.nonOptionalErrorMsg !== undefined) { return [2 /*return*/, field.nonOptionalErrorMsg]; } return [2 /*return*/, "ERROR_NON_OPTIONAL"]; } return [4 /*yield*/, field.validate(value)]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }, }); } /* Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved. * * This software is licensed under the Apache License, Version 2.0 (the * "License") as published by the Apache Software Foundation. * * You may not use this file except in compliance with the License. You may * obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ /* * Class. */ var EmailPassword = /** @class */ (function (_super) { genericComponentOverrideContext.__extends(EmailPassword, _super); function EmailPassword(config, webJSRecipe) { if (webJSRecipe === void 0) { webJSRecipe = EmailPasswordWebJS__default.default; } var _this = _super.call(this, config) || this; _this.webJSRecipe = webJSRecipe; _this.recipeID = EmailPassword.RECIPE_ID; _this.firstFactorIds = [types.FactorIds.EMAILPASSWORD]; _this.getDefaultRedirectionURL = function (context) { return genericComponentOverrideContext.__awaiter(_this, void 0, void 0, function () { return genericComponentOverrideContext.__generator(this, function (_a) { if (context.action === "RESET_PASSWORD") { return [ 2 /*return*/, genericComponentOverrideContext.getDefaultRedirectionURLForPath( this.config, constants.DEFAULT_RESET_PASSWORD_PATH, context ), ]; } return [2 /*return*/, this.getAuthRecipeDefaultRedirectionURL(context)]; }); }); }; return _this; } EmailPassword.prototype.getFirstFactorsForAuthPage = function () { return this.firstFactorIds; }; EmailPassword.init = function (config) { var normalisedConfig = normaliseEmailPasswordConfig(config); return { recipeID: EmailPassword.RECIPE_ID, authReact: function (appInfo) { EmailPassword.instance = new EmailPassword( genericComponentOverrideContext.__assign( genericComponentOverrideContext.__assign({}, normalisedConfig), { appInfo: appInfo, recipeId: EmailPassword.RECIPE_ID } ) ); return EmailPassword.instance; }, webJS: EmailPasswordWebJS__default.default.init( genericComponentOverrideContext.__assign( genericComponentOverrideContext.__assign({}, normalisedConfig), { override: { functions: function (originalImpl, builder) { var functions = getFunctionOverrides(normalisedConfig.onHandleEvent); builder.override(functions); builder.override(normalisedConfig.override.functions); return originalImpl; }, }, } ) ), }; }; EmailPassword.getInstanceOrThrow = function () { if (EmailPassword.instance === undefined) { var error = "No instance of EmailPassword found. Make sure to call the EmailPassword.init method." + "See https://supertokens.io/docs/emailpassword/quick-setup/frontend"; // eslint-disable-next-line supertokens-auth-react/no-direct-window-object if (typeof window === "undefined") { error = error + genericComponentOverrideContext.SSR_ERROR; } throw Error(error); } return EmailPassword.instance; }; /* * Tests methods. */ EmailPassword.reset = function () { if (!genericComponentOverrideContext.isTest()) { return; } EmailPassword.instance = undefined; return; }; EmailPassword.RECIPE_ID = "emailpassword"; return EmailPassword; })(index.AuthRecipe); exports.EmailPassword = EmailPassword;