UNPKG

@aws-amplify/core

Version:
330 lines (306 loc) • 9.19 kB
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import { ConsoleLogger } from './Logger'; import { AmplifyError } from './errors'; import { AuthConfigUserAttributes, LegacyUserAttributeKey, OAuthConfig, OAuthProvider, } from './singleton/Auth/types'; import { ResourcesConfig } from './singleton/types'; const logger = new ConsoleLogger('parseAWSExports'); const authTypeMapping: Record<any, any> = { API_KEY: 'apiKey', AWS_IAM: 'iam', AMAZON_COGNITO_USER_POOLS: 'userPool', OPENID_CONNECT: 'oidc', NONE: 'none', AWS_LAMBDA: 'lambda', // `LAMBDA` is an incorrect value that was added during the v6 rewrite. // Keeping it as a valid value until v7 to prevent breaking customers who might // be relying on it as a workaround. // ref: https://github.com/aws-amplify/amplify-js/pull/12922 // TODO: @v7 remove next line LAMBDA: 'lambda', }; /** * Converts the object imported from `aws-exports.js` or `amplifyconfiguration.json` files generated by * the Amplify CLI into an object that conforms to the {@link ResourcesConfig}. * * @param config A configuration object imported from `aws-exports.js` or `amplifyconfiguration.json`. * * @returns An object that conforms to the {@link ResourcesConfig} . */ export const parseAWSExports = ( config: Record<string, any> = {}, ): ResourcesConfig => { if (!Object.prototype.hasOwnProperty.call(config, 'aws_project_region')) { throw new AmplifyError({ name: 'InvalidParameterException', message: 'Invalid config parameter.', recoverySuggestion: 'Ensure passing the config object imported from `amplifyconfiguration.json`.', }); } const { aws_appsync_apiKey, aws_appsync_authenticationType, aws_appsync_graphqlEndpoint, aws_appsync_region, aws_bots_config, aws_cognito_identity_pool_id, aws_cognito_sign_up_verification_method, aws_cognito_mfa_configuration, aws_cognito_mfa_types, aws_cognito_password_protection_settings, aws_cognito_verification_mechanisms, aws_cognito_signup_attributes, aws_cognito_social_providers, aws_cognito_username_attributes, aws_mandatory_sign_in, aws_mobile_analytics_app_id, aws_mobile_analytics_app_region, aws_user_files_s3_bucket, aws_user_files_s3_bucket_region, aws_user_files_s3_dangerously_connect_to_http_endpoint_for_testing, aws_user_pools_id, aws_user_pools_web_client_id, geo, oauth, predictions, aws_cloud_logic_custom, Notifications, modelIntrospection, } = config; const amplifyConfig: ResourcesConfig = {}; // Analytics if (aws_mobile_analytics_app_id) { amplifyConfig.Analytics = { Pinpoint: { appId: aws_mobile_analytics_app_id, region: aws_mobile_analytics_app_region, }, }; } // Notifications const { InAppMessaging, Push } = Notifications ?? {}; if (InAppMessaging?.AWSPinpoint || Push?.AWSPinpoint) { if (InAppMessaging?.AWSPinpoint) { const { appId, region } = InAppMessaging.AWSPinpoint; amplifyConfig.Notifications = { InAppMessaging: { Pinpoint: { appId, region, }, }, }; } if (Push?.AWSPinpoint) { const { appId, region } = Push.AWSPinpoint; amplifyConfig.Notifications = { ...amplifyConfig.Notifications, PushNotification: { Pinpoint: { appId, region, }, }, }; } } // Interactions if (Array.isArray(aws_bots_config)) { amplifyConfig.Interactions = { LexV1: Object.fromEntries(aws_bots_config.map(bot => [bot.name, bot])), }; } // API if (aws_appsync_graphqlEndpoint) { const defaultAuthMode = authTypeMapping[aws_appsync_authenticationType]; if (!defaultAuthMode) { logger.debug( `Invalid authentication type ${aws_appsync_authenticationType}. Falling back to IAM.`, ); } amplifyConfig.API = { GraphQL: { endpoint: aws_appsync_graphqlEndpoint, apiKey: aws_appsync_apiKey, region: aws_appsync_region, defaultAuthMode: defaultAuthMode ?? 'iam', }, }; if (modelIntrospection) { amplifyConfig.API.GraphQL!.modelIntrospection = modelIntrospection; } } // Auth const mfaConfig = aws_cognito_mfa_configuration ? { status: aws_cognito_mfa_configuration && aws_cognito_mfa_configuration.toLowerCase(), totpEnabled: aws_cognito_mfa_types?.includes('TOTP') ?? false, smsEnabled: aws_cognito_mfa_types?.includes('SMS') ?? false, } : undefined; const passwordFormatConfig = aws_cognito_password_protection_settings ? { minLength: aws_cognito_password_protection_settings.passwordPolicyMinLength, requireLowercase: aws_cognito_password_protection_settings.passwordPolicyCharacters?.includes( 'REQUIRES_LOWERCASE', ) ?? false, requireUppercase: aws_cognito_password_protection_settings.passwordPolicyCharacters?.includes( 'REQUIRES_UPPERCASE', ) ?? false, requireNumbers: aws_cognito_password_protection_settings.passwordPolicyCharacters?.includes( 'REQUIRES_NUMBERS', ) ?? false, requireSpecialCharacters: aws_cognito_password_protection_settings.passwordPolicyCharacters?.includes( 'REQUIRES_SYMBOLS', ) ?? false, } : undefined; const mergedUserAttributes: LegacyUserAttributeKey[] = Array.from( new Set([ ...(aws_cognito_verification_mechanisms ?? []), ...(aws_cognito_signup_attributes ?? []), ]), ); const userAttributes: AuthConfigUserAttributes = mergedUserAttributes.reduce( (attributes: AuthConfigUserAttributes, key: LegacyUserAttributeKey) => ({ ...attributes, // All user attributes generated by the CLI are required [key.toLowerCase()]: { required: true }, }), {}, ); const loginWithEmailEnabled = aws_cognito_username_attributes?.includes('EMAIL') ?? false; const loginWithPhoneEnabled = aws_cognito_username_attributes?.includes('PHONE_NUMBER') ?? false; if (aws_cognito_identity_pool_id || aws_user_pools_id) { amplifyConfig.Auth = { Cognito: { identityPoolId: aws_cognito_identity_pool_id, allowGuestAccess: aws_mandatory_sign_in !== 'enable', signUpVerificationMethod: aws_cognito_sign_up_verification_method, userAttributes, userPoolClientId: aws_user_pools_web_client_id, userPoolId: aws_user_pools_id, mfa: mfaConfig, passwordFormat: passwordFormatConfig, loginWith: { username: !(loginWithEmailEnabled || loginWithPhoneEnabled), email: loginWithEmailEnabled, phone: loginWithPhoneEnabled, }, }, }; } const hasOAuthConfig = oauth ? Object.keys(oauth).length > 0 : false; const hasSocialProviderConfig = aws_cognito_social_providers ? aws_cognito_social_providers.length > 0 : false; if (amplifyConfig.Auth && hasOAuthConfig) { amplifyConfig.Auth.Cognito.loginWith = { ...amplifyConfig.Auth.Cognito.loginWith, oauth: { ...getOAuthConfig(oauth), ...(hasSocialProviderConfig && { providers: parseSocialProviders(aws_cognito_social_providers), }), }, }; } // Storage if (aws_user_files_s3_bucket) { amplifyConfig.Storage = { S3: { bucket: aws_user_files_s3_bucket, region: aws_user_files_s3_bucket_region, dangerouslyConnectToHttpEndpointForTesting: aws_user_files_s3_dangerously_connect_to_http_endpoint_for_testing, }, }; } // Geo if (geo) { const { amazon_location_service } = geo; amplifyConfig.Geo = { LocationService: { maps: amazon_location_service.maps, geofenceCollections: amazon_location_service.geofenceCollections, searchIndices: amazon_location_service.search_indices, region: amazon_location_service.region, }, }; } // REST API if (aws_cloud_logic_custom) { amplifyConfig.API = { ...amplifyConfig.API, REST: (aws_cloud_logic_custom as any[]).reduce( (acc, api: Record<string, any>) => { const { name, endpoint, region, service } = api; return { ...acc, [name]: { endpoint, ...(service ? { service } : undefined), ...(region ? { region } : undefined), }, }; }, {}, ), }; } // Predictions if (predictions) { // map VoiceId from speechGenerator defaults to voiceId const { VoiceId: voiceId } = predictions?.convert?.speechGenerator?.defaults ?? {}; amplifyConfig.Predictions = voiceId ? { ...predictions, convert: { ...predictions.convert, speechGenerator: { ...predictions.convert.speechGenerator, defaults: { voiceId }, }, }, } : predictions; } return amplifyConfig; }; const getRedirectUrl = (redirectStr: string): string[] => redirectStr?.split(',') ?? []; const getOAuthConfig = ({ domain, scope, redirectSignIn, redirectSignOut, responseType, }: Record<string, any>): OAuthConfig => ({ domain, scopes: scope, redirectSignIn: getRedirectUrl(redirectSignIn), redirectSignOut: getRedirectUrl(redirectSignOut), responseType, }); const parseSocialProviders = (aws_cognito_social_providers: string[]) => { return aws_cognito_social_providers.map((provider: string) => { const updatedProvider = provider.toLowerCase(); return updatedProvider.charAt(0).toUpperCase() + updatedProvider.slice(1); }) as OAuthProvider[]; };