diff --git a/packages/amplify-category-storage/src/provider-utils/awscloudformation/service-walkthroughs/s3-resource-api.ts b/packages/amplify-category-storage/src/provider-utils/awscloudformation/service-walkthroughs/s3-resource-api.ts index 6d18f7d7460..145d62de77a 100644 --- a/packages/amplify-category-storage/src/provider-utils/awscloudformation/service-walkthroughs/s3-resource-api.ts +++ b/packages/amplify-category-storage/src/provider-utils/awscloudformation/service-walkthroughs/s3-resource-api.ts @@ -1,8 +1,8 @@ import { $TSContext, AmplifyCategories, AmplifySupportedService, CLISubCommandType, stateManager } from 'amplify-cli-core'; import { AmplifyS3ResourceStackTransform } from '../cdk-stack-builder/s3-stack-transform'; -import { S3UserInputTriggerFunctionParams, S3UserInputs } from '../service-walkthrough-types/s3-user-input-types'; +import { S3UserInputs, S3UserInputTriggerFunctionParams } from '../service-walkthrough-types/s3-user-input-types'; import { S3InputState } from './s3-user-input-state'; -import { createNewLambdaAndUpdateCFN, migrateStorageCategory, isMigrateStorageRequired } from './s3-walkthrough'; +import { createNewLambdaAndUpdateCFN, isMigrateStorageRequired, migrateStorageCategory } from './s3-walkthrough'; /** * @returns Name of S3 resource or undefined @@ -70,10 +70,23 @@ export async function s3CreateStorageResource(context: $TSContext, storageInput: if (storageResourceName) { throw new Error('Add Storage Failed.. already exists'); } + //validate bucket Name + if( storageInput.bucketName ) { + s3ValidateBucketName( storageInput.bucketName ); + } await s3APIHelperTransformAndSaveState(context, storageInput, CLISubCommandType.ADD); return storageInput; } +export function s3ValidateBucketName( bucketName:string ){ + const regexp = '^[a-z0-9-]{3,47}$'; + const isValidBucketName = new RegExp(regexp, 'g').test(bucketName) + if( !isValidBucketName ){ + throw new Error('Bucket name can only use the following characters: a-z 0-9 - and should have minimum 3 character and max of 47 character') + } + return true; +} + /** * Create new lambda and add as Storage Lambda trigger * note:- (legacy logic, should be moved to addLambdaTrigger - to support multiple lambda triggers) diff --git a/packages/amplify-e2e-core/src/categories/storage.ts b/packages/amplify-e2e-core/src/categories/storage.ts index fa633bf14e1..c08bb8e67e8 100644 --- a/packages/amplify-e2e-core/src/categories/storage.ts +++ b/packages/amplify-e2e-core/src/categories/storage.ts @@ -487,9 +487,6 @@ export function addS3WithTrigger(cwd: string, settings: any): Promise { .sendCarriageReturn() .wait('Do you want to add a Lambda Trigger for your S3 Bucket') .sendConfirmYes() - .wait('Select from the following options') - .send(KEY_DOWN_ARROW) - .sendCarriageReturn() .wait('Do you want to edit the local') .sendConfirmNo() .sendCarriageReturn() @@ -541,10 +538,7 @@ export function addS3StorageWithIdpAuth(projectDir: string): Promise { return new Promise((resolve, reject) => { let chain = spawn(getCLIPath(), ['add', 'storage'], { cwd: projectDir, stripColors: true }); - singleSelect(chain.wait('Select from one of the below mentioned services:'), 'Content (Images, audio, video, etc.)', [ - 'Content (Images, audio, video, etc.)', - 'NoSQL Database', - ]); + chain.wait('Select from one of the below mentioned services:').sendCarriageReturn(); //select - Content (Images, audio, video, etc.) chain .wait('Provide a friendly name for your resource that will be used to label this category in the project:') @@ -561,6 +555,13 @@ export function addS3StorageWithIdpAuth(projectDir: string): Promise { ['create/update', 'read', 'delete'], ['create/update', 'read', 'delete'], ); + chain.wait('What kind of access do you want for Authenticated users?') + .send(' ') //'create/update' + .sendKeyDown() + .send(' ') //'read' + .sendKeyDown() + .send(' ') //'delete' + .sendCarriageReturn() chain.wait('Do you want to add a Lambda Trigger for your S3 Bucket?').sendConfirmNo(); @@ -577,31 +578,33 @@ export function addS3StorageWithIdpAuth(projectDir: string): Promise { export function addS3Storage(projectDir: string): Promise { return new Promise((resolve, reject) => { let chain = spawn(getCLIPath(), ['add', 'storage'], { cwd: projectDir, stripColors: true }); - - singleSelect(chain.wait('Select from one of the below mentioned services:'), 'Content (Images, audio, video, etc.)', [ - 'Content (Images, audio, video, etc.)', - 'NoSQL Database', - ]); - + chain.wait('Select from one of the below mentioned services:').sendCarriageReturn(); //'Content (Images, audio, video, etc.)' chain .wait('Provide a friendly name for your resource that will be used to label this category in the project:') .sendCarriageReturn() .wait('Provide bucket name:') .sendCarriageReturn(); - singleSelect(chain.wait('Who should have access:'), 'Auth and guest users', ['Auth users only', 'Auth and guest users']); - - multiSelect( - chain.wait('What kind of access do you want for Authenticated users?'), - ['create/update', 'read', 'delete'], - ['create/update', 'read', 'delete'], - ); - - multiSelect( - chain.wait('What kind of access do you want for Guest users?'), - ['create/update', 'read', 'delete'], - ['create/update', 'read', 'delete'], - ); + chain.wait('Who should have access:') + .sendKeyDown() + .send(' ') + .sendCarriageReturn() + + chain.wait('What kind of access do you want for Authenticated users?') + .send(' ') //'create/update' + .sendKeyDown() + .send(' ') //'read' + .sendKeyDown() + .send(' ') //'delete' + .sendCarriageReturn() + + chain.wait('What kind of access do you want for Guest users?') + .send(' ') //'create/update' + .sendKeyDown() + .send(' ') //'read' + .sendKeyDown() + .send(' ') //'delete' + .sendCarriageReturn() chain.wait('Do you want to add a Lambda Trigger for your S3 Bucket?').sendConfirmNo(); @@ -636,10 +639,9 @@ export function addS3StorageWithSettings(projectDir: string, settings: AddStorag return new Promise((resolve, reject) => { let chain = spawn(getCLIPath(), ['add', 'storage'], { cwd: projectDir, stripColors: true }); - singleSelect(chain.wait('Select from one of the below mentioned services:'), 'Content (Images, audio, video, etc.)', [ - 'Content (Images, audio, video, etc.)', - 'NoSQL Database', - ]); + chain.wait('Select from one of the below mentioned services:') + .send(' ') //'Content (Images, audio, video, etc.)' + .sendCarriageReturn() chain .wait('Provide a friendly name for your resource that will be used to label this category in the project:') @@ -647,19 +649,26 @@ export function addS3StorageWithSettings(projectDir: string, settings: AddStorag .wait('Provide bucket name:') .sendLine(settings.bucketName); - singleSelect(chain.wait('Who should have access:'), 'Auth and guest users', ['Auth users only', 'Auth and guest users']); - - multiSelect( - chain.wait('What kind of access do you want for Authenticated users?'), - ['create/update', 'read', 'delete'], - ['create/update', 'read', 'delete'], - ); - - multiSelect( - chain.wait('What kind of access do you want for Guest users?'), - ['create/update', 'read', 'delete'], - ['create/update', 'read', 'delete'], - ); + chain.wait('Who should have access:') + .sendKeyDown() + .send(' ') + .sendCarriageReturn() + + chain.wait('What kind of access do you want for Authenticated users?') + .send(' ') //'create/update' + .sendKeyDown() + .send(' ') //'read' + .sendKeyDown() + .send(' ') //'delete' + .sendCarriageReturn() + + chain.wait('What kind of access do you want for Guest users?') + .send(' ') //'create/update' + .sendKeyDown() + .send(' ') //'read' + .sendKeyDown() + .send(' ') //'delete' + .sendCarriageReturn() chain.wait('Do you want to add a Lambda Trigger for your S3 Bucket?').sendConfirmNo();