@ttoss/cloud-auth 0.3.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/template.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { CloudFormationTemplate } from '@ttoss/cloudformation';
1
2
  import { PASSWORD_MINIMUM_LENGTH } from './config';
2
3
 
3
4
  const CognitoUserPoolLogicalId = 'CognitoUserPool';
@@ -6,13 +7,57 @@ const CognitoUserPoolClientLogicalId = 'CognitoUserPoolClient';
6
7
 
7
8
  const CognitoIdentityPoolLogicalId = 'CognitoIdentityPool';
8
9
 
9
- export const createAuthTemplate = () => {
10
- const template = {
10
+ type Role =
11
+ | string
12
+ | {
13
+ 'Fn::ImportValue': string;
14
+ };
15
+
16
+ export const createAuthTemplate = ({
17
+ autoVerifiedAttributes = ['email'],
18
+ identityPool = true,
19
+ roles,
20
+ schema,
21
+ usernameAttributes = ['email'],
22
+ }: {
23
+ autoVerifiedAttributes?: Array<'email' | 'phone_number'> | null | false;
24
+ identityPool?: boolean;
25
+ roles?: {
26
+ authenticated?: Role;
27
+ unauthenticated?: Role;
28
+ };
29
+ /**
30
+ * https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cognito-userpool-schemaattribute.html
31
+ */
32
+ schema?: {
33
+ AttributeDataType?: 'Boolean' | 'DateTime' | 'Number' | 'String';
34
+ DeveloperOnlyAttribute?: boolean;
35
+ Mutable?: boolean;
36
+ Name?: string;
37
+ NumberAttributeConstraints?: {
38
+ MaxValue?: string;
39
+ MinValue?: string;
40
+ };
41
+ Required?: boolean;
42
+ StringAttributeConstraints?: {
43
+ MaxLength: string;
44
+ MinLength: string;
45
+ };
46
+ }[];
47
+ usernameAttributes?: Array<'email' | 'phone_number'> | null;
48
+ } = {}) => {
49
+ const AutoVerifiedAttributes =
50
+ Array.isArray(autoVerifiedAttributes) && autoVerifiedAttributes.length > 0
51
+ ? autoVerifiedAttributes
52
+ : [];
53
+
54
+ const template: CloudFormationTemplate = {
55
+ AWSTemplateFormatVersion: '2010-09-09',
11
56
  Resources: {
12
57
  [CognitoUserPoolLogicalId]: {
13
58
  Type: 'AWS::Cognito::UserPool',
14
59
  Properties: {
15
- AutoVerifiedAttributes: ['email'],
60
+ AutoVerifiedAttributes,
16
61
  Policies: {
17
62
  PasswordPolicy: {
18
63
  MinimumLength: PASSWORD_MINIMUM_LENGTH,
@@ -23,7 +68,8 @@ export const createAuthTemplate = () => {
23
68
  TemporaryPasswordValidityDays: 30,
24
69
  },
25
70
  },
26
- UsernameAttributes: ['email'],
71
+ Schema: schema,
72
+ UsernameAttributes: usernameAttributes,
27
73
  UsernameConfiguration: {
28
74
  CaseSensitive: false,
29
75
  },
@@ -41,36 +87,6 @@ export const createAuthTemplate = () => {
41
87
  },
42
88
  },
43
89
  },
44
- /**
45
- * https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-identitypool.html
46
- */
47
- [CognitoIdentityPoolLogicalId]: {
48
- Type: 'AWS::Cognito::IdentityPool',
49
- Properties: {
50
- AllowUnauthenticatedIdentities: true,
51
- CognitoIdentityProviders: [
52
- {
53
- ClientId: {
54
- Ref: CognitoUserPoolClientLogicalId,
55
- },
56
- ProviderName: {
57
- 'Fn::GetAtt': [CognitoUserPoolLogicalId, 'ProviderName'],
58
- },
59
- },
60
- ],
61
- },
62
- },
63
- /**
64
- * https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-identitypoolroleattachment.html
65
- */
66
- // CognitoIdentityPoolRoleAttachment: {
67
- // Type: 'AWS::Cognito::IdentityPoolRoleAttachment',
68
- // Properties: {
69
- // IdentityPoolId: {
70
- // Ref: CognitoIdentityPoolLogicalId,
71
- // },
72
- // },
73
- // },
74
90
  },
75
91
  Outputs: {
76
92
  Region: {
@@ -107,22 +123,69 @@ export const createAuthTemplate = () => {
107
123
  },
108
124
  },
109
125
  },
110
- IdentityPoolId: {
111
- Description: 'You use this value on Amplify Auth `identityPoolId`.',
112
- Value: {
113
- Ref: CognitoIdentityPoolLogicalId,
114
- },
115
- Export: {
116
- Name: {
117
- 'Fn::Join': [
118
- ':',
119
- [{ Ref: 'AWS::StackName' }, 'CognitoIdentityPoolId'],
120
- ],
126
+ },
127
+ };
128
+
129
+ if (identityPool) {
130
+ /**
131
+ * https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-identitypool.html
132
+ */
133
+ template.Resources[CognitoIdentityPoolLogicalId] = {
134
+ Type: 'AWS::Cognito::IdentityPool',
135
+ Properties: {
136
+ AllowUnauthenticatedIdentities: true,
137
+ CognitoIdentityProviders: [
138
+ {
139
+ ClientId: {
140
+ Ref: CognitoUserPoolClientLogicalId,
141
+ },
142
+ ProviderName: {
143
+ 'Fn::GetAtt': [CognitoUserPoolLogicalId, 'ProviderName'],
144
+ },
145
+ },
146
+ ],
147
+ },
148
+ };
149
+
150
+ if (roles) {
151
+ /**
152
+ * https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-identitypoolroleattachment.html
153
+ */
154
+ template.Resources.CognitoIdentityPoolRoleAttachment = {
155
+ Type: 'AWS::Cognito::IdentityPoolRoleAttachment',
156
+ Properties: {
157
+ IdentityPoolId: {
158
+ Ref: CognitoIdentityPoolLogicalId,
121
159
  },
160
+ Roles: roles,
122
161
  },
162
+ };
163
+ }
164
+
165
+ if (!template.Outputs) {
166
+ template.Outputs = {};
167
+ }
168
+
169
+ template.Outputs.IdentityPoolId = {
170
+ Description: 'You use this value on Amplify Auth `identityPoolId`.',
171
+ Value: {
172
+ Ref: CognitoIdentityPoolLogicalId,
123
173
  },
124
- },
125
- };
174
+ Export: {
175
+ Name: {
176
+ 'Fn::Join': [
177
+ ':',
178
+ [{ Ref: 'AWS::StackName' }, 'CognitoIdentityPoolId'],
179
+ ],
180
+ },
181
+ },
182
+ };
183
+ }
126
184
 
127
185
  return template;
128
186
  };
187
+
188
+ createAuthTemplate.CognitoUserPoolLogicalId = CognitoUserPoolLogicalId;
189
+ createAuthTemplate.CognitoUserPoolClientLogicalId =
190
+ CognitoUserPoolClientLogicalId;
191
+ createAuthTemplate.CognitoIdentityPoolLogicalId = CognitoIdentityPoolLogicalId;
@@ -0,0 +1,80 @@
1
+ import { createAuthTemplate } from '../../src';
2
+
3
+ test('do not add schema if not provided', () => {
4
+ const template = createAuthTemplate();
5
+ expect(template.Resources.CognitoUserPool.Properties.Schema).toBeUndefined();
6
+ });
7
+
8
+ test('add schema if provided', () => {
9
+ const schema = [
10
+ {
11
+ AttributeDataType: 'String' as const,
12
+ DeveloperOnlyAttribute: false,
13
+ Mutable: true,
14
+ Name: 'email',
15
+ Required: true,
16
+ StringAttributeConstraints: {
17
+ MaxLength: '2048',
18
+ MinLength: '0',
19
+ },
20
+ },
21
+ ];
22
+
23
+ const template = createAuthTemplate({ schema });
24
+ expect(template.Resources.CognitoUserPool.Properties.Schema).toEqual(schema);
25
+ });
26
+
27
+ test('should have autoVerifiedAttributes equal email by default', () => {
28
+ const template = createAuthTemplate();
29
+ expect(
30
+ template.Resources.CognitoUserPool.Properties.AutoVerifiedAttributes
31
+ ).toEqual(['email']);
32
+ });
33
+
34
+ test.each([[], null, false])(
35
+ 'should have autoVerifiedAttributes undefined: %p',
36
+ (autoVerifiedAttributes: any) => {
37
+ const template = createAuthTemplate({ autoVerifiedAttributes });
38
+ expect(
39
+ template.Resources.CognitoUserPool.Properties.AutoVerifiedAttributes
40
+ ).toEqual([]);
41
+ }
42
+ );
43
+
44
+ test.each([true, undefined])(
45
+ 'should have identity pool by default or true: %p',
46
+ (identityPool) => {
47
+ const template = createAuthTemplate({ identityPool });
48
+ expect(template.Resources.CognitoIdentityPool).toBeDefined();
49
+ expect(template.Outputs?.IdentityPoolId).toBeDefined();
50
+ }
51
+ );
52
+
53
+ test('should not have identity pool if false', () => {
54
+ const template = createAuthTemplate({ identityPool: false });
55
+ expect(template.Resources.CognitoIdentityPool).toBeUndefined();
56
+ expect(template.Outputs?.IdentityPoolId).toBeUndefined();
57
+ });
58
+
59
+ test('should have identity pool role attachment with roles', () => {
60
+ const roles = {
61
+ authenticated: 'arn:aws:iam::123456789012:role/authenticated',
62
+ unauthenticated: 'arn:aws:iam::123456789012:role/unauthenticated',
63
+ };
64
+ const template = createAuthTemplate({ roles });
65
+ expect(
66
+ template.Resources.CognitoIdentityPoolRoleAttachment.Properties.Roles
67
+ ).toEqual(roles);
68
+ });
69
+
70
+ test('should not have identity pool role attachment without roles', () => {
71
+ const template = createAuthTemplate();
72
+ expect(template.Resources.CognitoIdentityPoolRoleAttachment).toBeUndefined();
73
+ });
74
+
75
+ test('default usernameAttributes should be email', () => {
76
+ const template = createAuthTemplate();
77
+ expect(
78
+ template.Resources.CognitoUserPool.Properties.UsernameAttributes
79
+ ).toEqual(['email']);
80
+ });