Skip to content

Commit

Permalink
feat(cognito): user pool client - prevent user existence errors
Browse files Browse the repository at this point in the history
Adds a toggle to the Cognito L2 constructs to suppress user existence errors.

It is enabled by default as per [the documentation](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-managing-errors.html).

Fixes aws#7406

Signed-off-by: Duarte Nunes <duarte@uma.ni>
  • Loading branch information
duarten authored May 12, 2020
1 parent acab26d commit c7f15f2
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 4 deletions.
16 changes: 15 additions & 1 deletion packages/@aws-cdk/aws-cognito/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,20 @@ pool.addClient('app-client', {
});
```

An app client can be configured to prevent user existence errors. This
instructs the Cognito authentication API to return generic authentication
failure responses instead of an UserNotFoundException. By default, the flag
is not set, which means different things for existing and new stacks. See the
[documentation](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-managing-errors.html)
for the full details on the behavior of this flag.

```ts
const pool = new UserPool(this, 'Pool');
pool.addClient('app-client', {
preventUserExistenceErrors: true,
});
```

### Domains

After setting up an [app client](#app-clients), the address for the user pool's sign-up and sign-in webpages can be
Expand Down Expand Up @@ -429,4 +443,4 @@ pool.addDomain('CustomDomain', {

Read more about [Using the Amazon Cognito
Domain](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-assign-domain-prefix.html) and [Using Your Own
Domain](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-add-custom-domain.html).
Domain](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-add-custom-domain.html).
17 changes: 17 additions & 0 deletions packages/@aws-cdk/aws-cognito/lib/user-pool-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,15 @@ export interface UserPoolClientOptions {
* @default - see defaults in `OAuthSettings`
*/
readonly oAuth?: OAuthSettings;

/**
* Whether Cognito returns a UserNotFoundException exception when the
* user does not exist in the user pool (false), or whether it returns
* another type of error that doesn't reveal the user's absence.
* @see https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-managing-errors.html
* @default true for new stacks
*/
readonly preventUserExistenceErrors?: boolean;
}

/**
Expand Down Expand Up @@ -234,6 +243,7 @@ export class UserPoolClient extends Resource implements IUserPoolClient {
allowedOAuthScopes: this.configureOAuthScopes(props.oAuth),
callbackUrLs: (props.oAuth?.callbackUrls && props.oAuth?.callbackUrls.length > 0) ? props.oAuth?.callbackUrls : undefined,
allowedOAuthFlowsUserPoolClient: props.oAuth ? true : undefined,
preventUserExistenceErrors: this.configurePreventUserExistenceErrors(props.preventUserExistenceErrors),
});

this.userPoolClientId = resource.ref;
Expand Down Expand Up @@ -297,4 +307,11 @@ export class UserPoolClient extends Resource implements IUserPoolClient {
}
return undefined;
}

private configurePreventUserExistenceErrors(prevent?: boolean): string | undefined {
if (prevent === undefined) {
return undefined;
}
return prevent ? 'ENABLED' : 'LEGACY';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,9 @@
"ALLOW_USER_SRP_AUTH",
"ALLOW_REFRESH_TOKEN_AUTH"
],
"GenerateSecret": true
"GenerateSecret": true,
"PreventUserExistenceErrors": "ENABLED"
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ userpool.addClient('myuserpoolclient', {
],
callbackUrls: [ 'https://redirect-here.myapp.com' ],
},
});
preventUserExistenceErrors: true,
});
53 changes: 53 additions & 0 deletions packages/@aws-cdk/aws-cognito/test/user-pool-client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,4 +283,57 @@ describe('User Pool Client', () => {
AllowedOAuthScopes: [ 'aws.cognito.signin.user.admin' ],
});
});

test('enable user existence errors prevention', () => {
// GIVEN
const stack = new Stack();
const pool = new UserPool(stack, 'Pool');

// WHEN
new UserPoolClient(stack, 'Client', {
userPool: pool,
preventUserExistenceErrors: true,
});

// THEN
expect(stack).toHaveResource('AWS::Cognito::UserPoolClient', {
UserPoolId: stack.resolve(pool.userPoolId),
PreventUserExistenceErrors: 'ENABLED',
});
});

test('disable user existence errors prevention', () => {
// GIVEN
const stack = new Stack();
const pool = new UserPool(stack, 'Pool');

// WHEN
new UserPoolClient(stack, 'Client', {
userPool: pool,
preventUserExistenceErrors: false,
});

// THEN
expect(stack).toHaveResource('AWS::Cognito::UserPoolClient', {
UserPoolId: stack.resolve(pool.userPoolId),
PreventUserExistenceErrors: 'LEGACY',
});
});

test('user existence errors prevention is absent by default', () => {
// GIVEN
const stack = new Stack();
const pool = new UserPool(stack, 'Pool');

// WHEN
new UserPoolClient(stack, 'Client', {
userPool: pool,
});

// THEN
expect(stack).toHaveResource('AWS::Cognito::UserPoolClient', {
UserPoolId: stack.resolve(pool.userPoolId),
PreventUserExistenceErrors: ABSENT,
});
});
});

0 comments on commit c7f15f2

Please sign in to comment.