UNPKG

@aws-amplify/ui

Version:

`@aws-amplify/ui` contains low-level logic & styles for stand-alone usage or re-use in framework-specific implementations.

113 lines (110 loc) 5.34 kB
import { Amplify } from 'aws-amplify'; import { resendSignUpCode, resetPassword, confirmResetPassword, confirmSignUp, confirmSignIn, signUp, signIn, getCurrentUser } from 'aws-amplify/auth'; import '@aws-amplify/core/internals/utils'; import 'aws-amplify/utils'; import '../../utils/setUserAgent/constants.mjs'; import '../../types/authenticator/user.mjs'; import '../../types/authenticator/attributes.mjs'; import { hasSpecialChars } from '../../helpers/authenticator/utils.mjs'; import '../../helpers/accountSettings/utils.mjs'; // Cognito does not allow a password length less then 8 characters const DEFAULT_COGNITO_PASSWORD_MIN_LENGTH = 8; const isInvalidUserAtributes = (userAttributes) => Array.isArray(userAttributes); const parseUserAttributes = (userAttributes) => { if (!userAttributes) { return undefined; } // `aws-amplify` versions <= 6.0.5 return an array of `userAttributes` rather than an object if (isInvalidUserAtributes(userAttributes)) { return Object.entries(userAttributes).map(([_, value]) => Object.keys(value)[0]); } return Object.keys(userAttributes); }; const defaultServices = { async getAmplifyConfig() { const result = Amplify.getConfig(); const cliConfig = result.Auth?.Cognito; const { loginWith, userAttributes } = result.Auth?.Cognito ?? {}; const parsedLoginMechanisms = loginWith ? Object.entries(loginWith) .filter(([key, _value]) => key !== 'oauth') .filter(([_key, value]) => !!value) .map((keyValueArray) => { return keyValueArray[0] === 'phone' // the key for phone_number is phone in getConfig but everywhere else we treat is as phone_number ? 'phone_number' : keyValueArray[0]; }) : undefined; const parsedSignupAttributes = parseUserAttributes(userAttributes); const parsedSocialProviders = loginWith?.oauth?.providers ? loginWith.oauth.providers?.map((provider) => provider.toString().toLowerCase()) : undefined; return { ...cliConfig, loginMechanisms: parsedLoginMechanisms, signUpAttributes: parsedSignupAttributes, socialProviders: parsedSocialProviders, }; }, getCurrentUser, handleSignIn: signIn, handleSignUp: signUp, handleConfirmSignIn: confirmSignIn, handleConfirmSignUp: confirmSignUp, handleForgotPasswordSubmit: confirmResetPassword, handleForgotPassword: resetPassword, handleResendSignUpCode: resendSignUpCode, // Validation hooks for overriding async validateCustomSignUp(_, __) { }, async validateFormPassword(formData, touchData, passwordSettings) { const { password } = formData; const { password: touched_password } = touchData; /** * If the password is not touched, * or if the password settings are not set, we don't need to validate it. */ if (!touched_password || !passwordSettings) return null; const password_complexity = []; const policyMinLength = passwordSettings.minLength ?? DEFAULT_COGNITO_PASSWORD_MIN_LENGTH; if (password.length < policyMinLength) { password_complexity.push(`Password must have at least ${policyMinLength} characters`); } if (passwordSettings.requireLowercase && !/[a-z]/.test(password)) password_complexity.push('Password must have lower case letters'); if (passwordSettings.requireUppercase && !/[A-Z]/.test(password)) password_complexity.push('Password must have upper case letters'); if (passwordSettings.requireNumbers && !/[0-9]/.test(password)) password_complexity.push('Password must have numbers'); // https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-policies.html if (passwordSettings.requireSpecialCharacters && !hasSpecialChars(password)) password_complexity.push('Password must have special characters'); /** * Only return an error if there is at least one error. */ return password_complexity.length !== 0 ? { password: password_complexity } : null; }, async validateConfirmPassword(formData, touchData) { const { password, confirm_password } = formData; const { confirm_password: touched_confirm_password, password: touched_password, } = touchData; if (!password && !confirm_password) { // these inputs are clean, don't complain yet return null; } else if ((password || confirm_password) && password !== confirm_password && ((touched_confirm_password && touched_password) || (password?.length >= 6 && confirm_password?.length >= 6))) { // Only return an error if both fields have text entered, // the passwords do not match, and the fields have been // touched or the password and confirm password is longer then or equal to 6. return { confirm_password: 'Your passwords must match', }; } }, async validatePreferredUsername(_, __) { }, }; export { defaultServices };