Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
4c7efb2
update package-lock.json
Jul 10, 2024
02dbdba
Prettier code style
Jul 10, 2024
df34524
add changeset
Jul 10, 2024
847b4bd
update construct
Jul 11, 2024
d7b9546
update API.md
Jul 11, 2024
d727d15
export CustomAttributes in index.ts
Jul 11, 2024
9c30b9f
update API.MD
Jul 11, 2024
8c69e22
export CustomAttributesString
Jul 11, 2024
1ae3aca
update API.md
Jul 11, 2024
4bf657c
export CustomAttributeBase in index.ts
Jul 11, 2024
6a8621a
update API.md
Jul 11, 2024
5bd714e
updated CustomAttribute type name
Jul 11, 2024
b241964
updated bindbindCustomAttribute method
Jul 11, 2024
a09c518
removed bindCustomAttributes unit test and updated creates user attri…
Jul 11, 2024
3b7cf75
updated index export
Jul 11, 2024
35503b8
updated API.md
Jul 11, 2024
4de16d7
updated bindCustomAttribute method
Jul 12, 2024
e00f6a4
Update blue-turkeys-trade.md
fangyuwu7 Jul 12, 2024
458be4e
Update blue-turkeys-trade.md
fangyuwu7 Jul 12, 2024
de683c1
update type CustomAttributeBoolean
Jul 12, 2024
f728168
update /API.md
Jul 12, 2024
74f3952
update type CustomAttributesBoolean
Jul 12, 2024
2e871d8
update API.md
Jul 12, 2024
afd8f91
refactor top level cli error handling (#1730)
Amplifiyer Jul 12, 2024
3ef167e
update construct.ts
Jul 13, 2024
54089c7
update construct.ts
Jul 13, 2024
e20ed2f
remove prefix custom:
Jul 14, 2024
8c770f1
Delete .changeset/empty-cameras-smile.md
fangyuwu7 Jul 15, 2024
e8c6d16
Delete packages/cli/src/ampx.ts
fangyuwu7 Jul 15, 2024
df6d008
Delete packages/sandbox/src/file_watching_sandbox.ts
fangyuwu7 Jul 15, 2024
dae422a
update unit test and bind function
Jul 15, 2024
568b644
merge main
Jul 15, 2024
400d0bd
update
Jul 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/blue-turkeys-trade.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@aws-amplify/auth-construct': minor
---

Add customAttributes into userAttributes
35 changes: 34 additions & 1 deletion packages/auth-construct/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import { AuthResources } from '@aws-amplify/plugin-types';
import { aws_cognito } from 'aws-cdk-lib';
import { BackendOutputStorageStrategy } from '@aws-amplify/plugin-types';
import { Construct } from 'constructs';
import { NumberAttributeConstraints } from 'aws-cdk-lib/aws-cognito';
import { ResourceProvider } from '@aws-amplify/plugin-types';
import { SecretValue } from 'aws-cdk-lib';
import { StandardAttributes } from 'aws-cdk-lib/aws-cognito';
import { StringAttributeConstraints } from 'aws-cdk-lib/aws-cognito';
import { UserPoolIdentityProviderSamlMetadata } from 'aws-cdk-lib/aws-cognito';

// @public
Expand Down Expand Up @@ -43,13 +45,41 @@ export type AuthProps = {
phone?: PhoneNumberLogin;
externalProviders?: ExternalProviderOptions;
};
userAttributes?: StandardAttributes;
userAttributes?: UserAttributes;
multifactor?: MFA;
accountRecovery?: keyof typeof aws_cognito.AccountRecovery;
groups?: string[];
outputStorageStrategy?: BackendOutputStorageStrategy<AuthOutput>;
};

// @public
export type CustomAttribute = CustomAttributeString | CustomAttributeNumber | CustomAttributeBoolean | CustomAttributeDateTime;

// @public
export type CustomAttributeBase = {
mutable?: boolean;
};

// @public
export type CustomAttributeBoolean = CustomAttributeBase & {
dataType: 'Boolean';
};

// @public
export type CustomAttributeDateTime = CustomAttributeBase & {
dataType: 'DateTime';
};

// @public
export type CustomAttributeNumber = CustomAttributeBase & NumberAttributeConstraints & {
dataType: 'Number';
};

// @public
export type CustomAttributeString = CustomAttributeBase & StringAttributeConstraints & {
dataType: 'String';
};

// @public
export type EmailLogin = true | EmailLoginSettings;

Expand Down Expand Up @@ -136,6 +166,9 @@ export type TriggerEvent = (typeof triggerEvents)[number];
// @public
export const triggerEvents: readonly ["createAuthChallenge", "customMessage", "defineAuthChallenge", "postAuthentication", "postConfirmation", "preAuthentication", "preSignUp", "preTokenGeneration", "userMigration", "verifyAuthChallengeResponse"];

// @public
export type UserAttributes = StandardAttributes & Record<`custom:${string}`, CustomAttribute>;

// @public (undocumented)
export type VerificationEmailWithCode = {
verificationEmailStyle?: 'CODE';
Expand Down
71 changes: 71 additions & 0 deletions packages/auth-construct/src/construct.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,35 @@ void describe('Auth construct', () => {
familyName: {
required: true,
},
'custom:display_name': {
dataType: 'String',
mutable: true,
maxLen: 100,
minLen: 0,
},
'custom:tenant_id': {
dataType: 'Number',
mutable: false,
max: 66,
min: 1,
},
'custom:register_date': {
dataType: 'DateTime',
mutable: true,
},
'custom:is_member': {
dataType: 'Boolean',
mutable: false,
},
'custom:year_as_member': {
dataType: 'Number',
max: 90,
min: 0,
},
'custom:favorite_song': {
dataType: 'String',
mutable: true,
},
},
});
const template = Template.fromStack(stack);
Expand All @@ -621,6 +650,48 @@ void describe('Auth construct', () => {
Name: 'family_name',
Required: true,
},
{
AttributeDataType: 'String',
Name: 'display_name',
Mutable: true,
StringAttributeConstraints: {
MaxLength: '100',
MinLength: '0',
},
},
{
AttributeDataType: 'Number',
Name: 'tenant_id',
Mutable: false,
NumberAttributeConstraints: {
MaxValue: '66',
MinValue: '1',
},
},
{
AttributeDataType: 'DateTime',
Name: 'register_date',
Mutable: true,
},
{
AttributeDataType: 'Boolean',
Name: 'is_member',
Mutable: false,
},
{
AttributeDataType: 'Number',
Name: 'year_as_member',
Mutable: true,
NumberAttributeConstraints: {
MaxValue: '90',
MinValue: '0',
},
},
{
AttributeDataType: 'String',
Name: 'favorite_song',
Mutable: true,
},
],
});
});
Expand Down
81 changes: 80 additions & 1 deletion packages/auth-construct/src/construct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ import {
CfnUserPoolClient,
CfnUserPoolGroup,
CfnUserPoolIdentityProvider,
CustomAttributeConfig,
ICustomAttribute,
Mfa,
MfaSecondFactor,
OAuthScope,
OidcAttributeRequestMethod,
ProviderAttribute,
StandardAttribute,
UserPool,
UserPoolClient,
UserPoolDomain,
Expand All @@ -38,6 +41,7 @@ import { AuthOutput, authOutputKey } from '@aws-amplify/backend-output-schemas';
import {
AttributeMapping,
AuthProps,
CustomAttribute,
EmailLoginSettings,
ExternalProviderOptions,
} from './types.js';
Expand Down Expand Up @@ -347,6 +351,51 @@ export class AmplifyAuth
};
};

/**
* Define bindCustomAttribute to meet requirements of the Cognito API to call the bind method
*/
private bindCustomAttribute = (
key: string,
attribute: CustomAttribute
): CustomAttributeConfig & ICustomAttribute => {
const baseConfig: CustomAttributeConfig = {
dataType: attribute.dataType,

mutable: attribute.mutable ?? true,
};

let constraints = {};
// Conditionally add constraint properties based on dataType.
if (attribute.dataType === 'String') {
constraints = {
stringConstraints: {
minLen: attribute.minLen,

maxLen: attribute.maxLen,
},
};
} else if (attribute.dataType === 'Number') {
constraints = {
numberConstraints: {
min: attribute.min,

max: attribute.max,
},
};
}
//The final config object includes baseConfig and conditionally added constraint properties.
const config = {
...baseConfig,

...constraints,
};

return {
...config,

bind: () => config,
};
};
/**
* Process props into UserPoolProps (set defaults if needed)
*/
Expand Down Expand Up @@ -404,6 +453,32 @@ export class AmplifyAuth
);
}

const { standardAttributes, customAttributes } = Object.entries(
props.userAttributes ?? {}
).reduce(
(
acc: {
standardAttributes: { [key: string]: StandardAttribute };
customAttributes: {
[key: string]: CustomAttributeConfig & ICustomAttribute;
};
},
[key, value]
) => {
if (key.startsWith('custom:')) {
const attributeKey = key.replace(/^custom:/i, '');
acc.customAttributes[attributeKey] = this.bindCustomAttribute(
attributeKey,
value
);
} else {
acc.standardAttributes[key] = value;
}
return acc;
},
{ standardAttributes: {}, customAttributes: {} }
);

const userPoolProps: UserPoolProps = {
signInCaseSensitive: DEFAULTS.SIGN_IN_CASE_SENSITIVE,
signInAliases: {
Expand All @@ -423,8 +498,12 @@ export class AmplifyAuth
standardAttributes: {
email: DEFAULTS.IS_REQUIRED_ATTRIBUTE.email(emailEnabled),
phoneNumber: DEFAULTS.IS_REQUIRED_ATTRIBUTE.phoneNumber(phoneEnabled),
...(props.userAttributes ? props.userAttributes : {}),
...standardAttributes,
},
customAttributes: {
...customAttributes,
},

selfSignUpEnabled: DEFAULTS.ALLOW_SELF_SIGN_UP,
mfa: mfaMode,
mfaMessage: this.getMFAMessage(props.multifactor),
Expand Down
7 changes: 7 additions & 0 deletions packages/auth-construct/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ export {
TriggerEvent,
IdentityProviderProps,
AttributeMapping,
UserAttributes,
CustomAttribute,
CustomAttributeString,
CustomAttributeNumber,
CustomAttributeBoolean,
CustomAttributeDateTime,
CustomAttributeBase,
} from './types.js';
export { AmplifyAuth } from './construct.js';
export { triggerEvents } from './trigger_events.js';
54 changes: 53 additions & 1 deletion packages/auth-construct/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { triggerEvents } from './trigger_events.js';
import { BackendOutputStorageStrategy } from '@aws-amplify/plugin-types';
import { AuthOutput } from '@aws-amplify/backend-output-schemas';
import {
NumberAttributeConstraints,
StandardAttributes,
StringAttributeConstraints,
UserPoolIdentityProviderSamlMetadata,
} from 'aws-cdk-lib/aws-cognito';
export type VerificationEmailWithLink = {
Expand Down Expand Up @@ -327,6 +329,56 @@ export type ExternalProviderOptions = {
*/
export type TriggerEvent = (typeof triggerEvents)[number];

/**
* CustomAttributeBase is a type that represents the base properties for a custom attribute
*/
export type CustomAttributeBase = {
/**
* @default {true}
*/
mutable?: boolean;
};
/**
* CustomAttributeString represents a custom attribute of type string.
*/
export type CustomAttributeString = CustomAttributeBase &
StringAttributeConstraints & {
dataType: 'String';
};
/**
* CustomAttributeNumber represents a custom attribute of type number.
*/
export type CustomAttributeNumber = CustomAttributeBase &
NumberAttributeConstraints & {
dataType: 'Number';
};
/**
* CustomAttributeBoolean represents a custom attribute of type boolean.
*/
export type CustomAttributeBoolean = CustomAttributeBase & {
dataType: 'Boolean';
};
/**
* CustomAttributeDateTime represents a custom attribute of type dataTime.
*/
export type CustomAttributeDateTime = CustomAttributeBase & {
dataType: 'DateTime';
};
/**
* CustomAttributes is a union type that represents all the different types of custom attributes.
*/
export type CustomAttribute =
| CustomAttributeString
| CustomAttributeNumber
| CustomAttributeBoolean
| CustomAttributeDateTime;
/**
* UserAttributes represents the combined attributes of a user, including
* standard attributes and any number of custom attributes defined with a 'custom:' prefix.
*/
export type UserAttributes = StandardAttributes &
Record<`custom:${string}`, CustomAttribute>;

/**
* Input props for the AmplifyAuth construct
*/
Expand Down Expand Up @@ -362,7 +414,7 @@ export type AuthProps = {
* The set of attributes that are required for every user in the user pool. Read more on attributes here - https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-attributes.html
* @default - email/phone will be added as required user attributes if they are included as login methods
*/
userAttributes?: StandardAttributes;
userAttributes?: UserAttributes;
/**
* Configure whether users can or are required to use multifactor (MFA) to sign in.
*/
Expand Down